@ledgerhq/coin-multiversx
Version:
Ledger MultiversX Coin integration
133 lines • 5.7 kB
JavaScript
"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const state_1 = require("@ledgerhq/cryptoassets/state");
const bignumber_js_1 = __importDefault(require("bignumber.js"));
const index_1 = require("@ledgerhq/coin-framework/account/index");
const jsHelpers_1 = require("@ledgerhq/coin-framework/bridge/jsHelpers");
const api_1 = require("./api");
const logic_1 = require("./logic");
async function buildMultiversXESDTTokenAccount({ parentAccountId, accountAddress, token, balance, }) {
const tokenAccountId = (0, index_1.encodeTokenAccountId)(parentAccountId, token);
const tokenIdentifierHex = (0, logic_1.extractTokenId)(token.id);
const tokenIdentifier = Buffer.from(tokenIdentifierHex, "hex").toString();
const operations = await (0, api_1.getESDTOperations)(tokenAccountId, accountAddress, tokenIdentifier, 0);
const tokenAccount = {
type: "TokenAccount",
id: tokenAccountId,
parentId: parentAccountId,
token,
operationsCount: operations.length,
operations,
pendingOperations: [],
balance,
spendableBalance: balance,
swapHistory: [],
creationDate: operations.length > 0 ? operations[operations.length - 1].date : new Date(),
balanceHistoryCache: index_1.emptyHistoryCache, // calculated in the jsHelpers
};
return tokenAccount;
}
function buildExistingAccountMaps(existingAccount, blacklistedTokenIds) {
const existingAccountByTicker = {};
const existingAccountTickers = [];
if (!existingAccount?.subAccounts) {
return { existingAccountByTicker, existingAccountTickers };
}
for (const existingSubAccount of existingAccount.subAccounts) {
if (existingSubAccount.type !== "TokenAccount")
continue;
const { ticker, id } = existingSubAccount.token;
if (!blacklistedTokenIds.includes(id)) {
existingAccountTickers.push(ticker);
existingAccountByTicker[ticker] = existingSubAccount;
}
}
return { existingAccountByTicker, existingAccountTickers };
}
async function syncESDTTokenAccountOperations(tokenAccount, address) {
const oldOperations = tokenAccount?.operations || [];
const startAt = oldOperations.length ? Math.floor(oldOperations[0].date.valueOf() / 1000) : 0;
const tokenIdentifierHex = (0, logic_1.extractTokenId)(tokenAccount.token.id);
const tokenIdentifier = Buffer.from(tokenIdentifierHex, "hex").toString();
const newOperations = await (0, api_1.getESDTOperations)(tokenAccount.id, address, tokenIdentifier, startAt);
const operations = (0, jsHelpers_1.mergeOps)(oldOperations, newOperations);
if (operations === oldOperations)
return tokenAccount;
return {
...tokenAccount,
operations,
operationsCount: operations.length,
};
}
async function updateTokenAccountBalance(tokenAccount, newBalance) {
if (newBalance.eq(tokenAccount.balance)) {
return tokenAccount;
}
return {
...tokenAccount,
balance: newBalance,
spendableBalance: newBalance,
};
}
async function processESDT({ esdt, accountId, accountAddress, existingAccountByTicker, existingAccountTickers, blacklistedTokenIds, }) {
const esdtIdentifierHex = Buffer.from(esdt.identifier).toString("hex");
const token = await (0, state_1.getCryptoAssetsStore)().findTokenById((0, logic_1.addPrefixToken)(esdtIdentifierHex));
if (!token || blacklistedTokenIds.includes(token.id)) {
return null;
}
const existingTokenAccount = existingAccountByTicker[token.ticker];
const balance = new bignumber_js_1.default(esdt.balance);
let tokenAccount;
if (existingTokenAccount) {
const syncedTokenAccount = await syncESDTTokenAccountOperations(existingTokenAccount, accountAddress);
tokenAccount = await updateTokenAccountBalance(syncedTokenAccount, balance);
}
else {
tokenAccount = await buildMultiversXESDTTokenAccount({
parentAccountId: accountId,
accountAddress,
token,
balance,
});
}
existingAccountTickers.push(token.ticker);
existingAccountByTicker[token.ticker] = tokenAccount;
return tokenAccount;
}
async function MultiversXBuildESDTTokenAccounts({ accountId, accountAddress, existingAccount, syncConfig, }) {
const { blacklistedTokenIds = [] } = syncConfig;
const tokenAccounts = [];
const { existingAccountByTicker, existingAccountTickers } = buildExistingAccountMaps(existingAccount, blacklistedTokenIds);
const accountESDTs = await (0, api_1.getAccountESDTTokens)(accountAddress);
for (const esdt of accountESDTs) {
const tokenAccount = await processESDT({
esdt,
accountId,
accountAddress,
existingAccountByTicker,
existingAccountTickers,
blacklistedTokenIds,
});
if (tokenAccount) {
tokenAccounts.push(tokenAccount);
}
}
// Preserve order of tokenAccounts from the existing token accounts
tokenAccounts.sort((a, b) => {
const i = existingAccountTickers.indexOf(a.token.ticker);
const j = existingAccountTickers.indexOf(b.token.ticker);
if (i === j)
return 0;
if (i < 0)
return 1;
if (j < 0)
return -1;
return i - j;
});
return tokenAccounts;
}
exports.default = MultiversXBuildESDTTokenAccounts;
//# sourceMappingURL=buildSubAccounts.js.map