@ledgerhq/coin-tezos
Version:
119 lines • 5.49 kB
JavaScript
;
// SPDX-FileCopyrightText: © 2026 LEDGER SAS
// SPDX-License-Identifier: Apache-2.0
Object.defineProperty(exports, "__esModule", { value: true });
exports.isUnstakingPosition = exports.isStakePosition = exports.isFinalizablePosition = exports.isDelegationPosition = void 0;
exports.fetchUnstakeRequests = fetchUnstakeRequests;
exports.buildStakesForAccount = buildStakesForAccount;
exports.getStakes = getStakes;
const logs_1 = require("@ledgerhq/logs");
const types_1 = require("../network/types");
const tzkt_1 = require("../network/tzkt");
const utils_1 = require("../utils");
const positionUid_1 = require("./positionUid");
var positionUid_2 = require("./positionUid");
Object.defineProperty(exports, "isDelegationPosition", { enumerable: true, get: function () { return positionUid_2.isDelegationPosition; } });
Object.defineProperty(exports, "isFinalizablePosition", { enumerable: true, get: function () { return positionUid_2.isFinalizablePosition; } });
Object.defineProperty(exports, "isStakePosition", { enumerable: true, get: function () { return positionUid_2.isStakePosition; } });
Object.defineProperty(exports, "isUnstakingPosition", { enumerable: true, get: function () { return positionUid_2.isUnstakingPosition; } });
function fetchUnstakeRequests(config, address, account) {
if (!(0, types_1.hasManagerKey)(account))
return Promise.resolve([]);
return (account.unstakedBalance ?? 0) > 0
? (0, tzkt_1.createTzktApi)(config).getUnstakeRequests(address)
: Promise.resolve([]);
}
function unstakeRequestToStake(address, req) {
// TzKT's status filter is unreliable; never build a position for a finalized request.
if (req.status !== 'pending' && req.status !== 'finalizable') {
(0, logs_1.log)('coin:tezos', 'unstakeRequestToStake: dropping non-active unstake request', {
requestId: req.id,
status: req.status,
});
return null;
}
if (req.actualAmount <= 0) {
(0, logs_1.log)('coin:tezos', 'unstakeRequestToStake: dropping non-positive unstake request', {
requestId: req.id,
actualAmount: req.actualAmount,
});
return null;
}
const createdAt = new Date(req.firstTime);
if (!Number.isFinite(createdAt.getTime())) {
(0, logs_1.log)('coin:tezos', 'unstakeRequestToStake: dropping unstake request with invalid firstTime', {
requestId: req.id,
firstTime: req.firstTime,
});
return null;
}
const isFinalizable = req.status === 'finalizable';
const prefix = isFinalizable ? positionUid_1.STAKING_UID_PREFIX.finalizable : positionUid_1.STAKING_UID_PREFIX.unstaking;
return {
uid: `${prefix}${req.id}`,
address,
...(req.baker?.address && { delegate: req.baker.address }),
state: isFinalizable ? 'inactive' : 'deactivating',
createdAt,
asset: { type: 'native' },
amount: BigInt(req.actualAmount),
actions: [],
};
}
function buildStakesForAccount(address, account, unstakeRequests) {
const balance = BigInt(account.balance ?? 0);
const stakedBalance = BigInt(account.stakedBalance ?? 0);
// Account-level unstaked total (the source validateIntent's gate uses), not the summed per-request
// positions below — so spendable stays gate-consistent even if a request is dropped or its fetch fails.
const unstakedBalance = BigInt(account.unstakedBalance ?? 0);
const delegateAddress = account.delegate?.address;
const unstakeStakes = [];
for (const req of unstakeRequests) {
const stake = unstakeRequestToStake(address, req);
if (stake)
unstakeStakes.push(stake);
}
const stakes = [];
if (delegateAddress) {
const { spendable: delegated, locked } = (0, utils_1.partitionNativeBalance)(balance, stakedBalance, unstakedBalance);
if (locked < stakedBalance + unstakedBalance) {
(0, logs_1.log)('coin:tezos', 'buildStakesForAccount: balance < staked + unstaked, clamping to 0', {
address,
balance: balance.toString(),
stakedBalance: stakedBalance.toString(),
unstakedBalance: unstakedBalance.toString(),
});
}
stakes.push({
uid: `${positionUid_1.STAKING_UID_PREFIX.delegation}${address}`,
address,
delegate: delegateAddress,
state: 'active',
asset: { type: 'native' },
amount: delegated,
actions: [],
});
}
if (stakedBalance > 0n) {
stakes.push({
uid: `${positionUid_1.STAKING_UID_PREFIX.stake}${address}`,
address,
...(delegateAddress && { delegate: delegateAddress }),
state: 'active',
asset: { type: 'native' },
amount: stakedBalance,
actions: [],
});
}
stakes.push(...unstakeStakes);
return stakes;
}
async function getStakes(context, address, _cursor) {
const config = await context.config();
const accountInfo = await (0, tzkt_1.createTzktApi)(config).getAccountByAddress(address);
if (!(0, types_1.hasManagerKey)(accountInfo))
return { items: [] };
const unstakeRequests = await fetchUnstakeRequests(config, address, accountInfo);
return { items: buildStakesForAccount(address, accountInfo, unstakeRequests) };
}
//# sourceMappingURL=getStakes.js.map