UNPKG

@jagad/icsi

Version:

Internet Computer Subaccount Indexer Library - TypeScript SDK for ICP multi-token subaccount management, transaction tracking, and automated sweeping with webhook support

243 lines (242 loc) 12.3 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.refund = refund; exports.setUserVaultInterval = setUserVaultInterval; exports.sweep = sweep; exports.sweepByTokenType = sweepByTokenType; exports.addSubaccount = addSubaccount; exports.addSubaccountForToken = addSubaccountForToken; exports.clearTransactions = clearTransactions; exports.setWebhookUrl = setWebhookUrl; exports.registerToken = registerToken; exports.sweepSubaccountId = sweepSubaccountId; exports.convertToIcrcAccount = convertToIcrcAccount; exports.validateIcrcAccount = validateIcrcAccount; exports.singleSweep = singleSweep; exports.setSweepFailed = setSweepFailed; const agent_1 = require("@dfinity/agent"); const utils_1 = require("./utils"); const userVault_did_1 = require("./userVault.did"); /** * Creates an actor for interacting with a user vault canister. * @param {HttpAgent} agent - The HTTP agent used for the call. * @param {string} userVaultCanisterId - The canister ID of the user vault. * @returns {_SERVICE} - The actor instance. */ function createUserVaultActor(agent, userVaultCanisterId) { (0, utils_1.isNotEmptyOrError)(userVaultCanisterId, 'User Vault Canister ID is undefined.'); return agent_1.Actor.createActor(userVault_did_1.idlFactory, { agent, canisterId: userVaultCanisterId, }); } /** * Calls the refund function on a canister with a specific amount. * @param {HttpAgent} agent - The HTTP agent used for the call. * @param {string} userVaultCanisterId - The canister ID of the user vault. * @param {bigint} amount - The amount to refund. * @returns {Promise<string>} - The result of the refund operation. */ async function refund(agent, userVaultCanisterId, amount) { const actor = createUserVaultActor(agent, userVaultCanisterId); return await actor.refund(amount); } /** * Calls the set_interval function on a canister with a specific interval. * @param {HttpAgent} agent - The HTTP agent used for the call. * @param {string} userVaultCanisterId - The canister ID of the user vault. * @param {bigint} interval - The interval to set. * @returns {Promise<bigint>} - The set interval value. */ async function setUserVaultInterval(agent, userVaultCanisterId, interval) { const actor = createUserVaultActor(agent, userVaultCanisterId); return await actor.set_interval(interval); } /** * Calls the sweep function on a canister. * @param {HttpAgent} agent - The HTTP agent used for the call. * @param {string} userVaultCanisterId - The canister ID of the user vault. * @returns {Promise<string[]>} - The result of the sweep operation. */ async function sweep(agent, userVaultCanisterId) { const actor = createUserVaultActor(agent, userVaultCanisterId); return await actor.sweep(); } /** * Sweeps all subaccounts for a specific token type. * @param {HttpAgent} agent - The HTTP agent used for the call. * @param {string} userVaultCanisterId - The canister ID of the user vault. * @param {TokenType} tokenType - The token type to sweep (ICP, CKUSDC, CKUSDT, or CKBTC). * @returns {Promise<string[]>} - The result of the sweep operation. */ async function sweepByTokenType(agent, userVaultCanisterId, tokenType) { const actor = createUserVaultActor(agent, userVaultCanisterId); return await actor.sweep_by_token_type(tokenType); } /** * Calls the add_subaccount function on a canister to add a generic subaccount for ICP. * @param {HttpAgent} agent - The HTTP agent used for the call. * @param {string} userVaultCanisterId - The canister ID of the user vault. * @returns {Promise<string>} - The result of the add_subaccount operation. */ async function addSubaccount(agent, userVaultCanisterId) { const actor = createUserVaultActor(agent, userVaultCanisterId); return await actor.add_subaccount([{ ICP: null }]); } /** * Adds a new subaccount for a specific token type (ICP, CKUSDC, CKUSDT, or CKBTC). * @param {HttpAgent} agent - The HTTP agent used for the call. * @param {string} userVaultCanisterId - The canister ID of the user vault. * @param {TokenType} tokenType - The token type to create a subaccount for. * @param {Object} tokenCanisterIds - The canister IDs for the different token types. * @param {string} [tokenCanisterIds.ckusdcCanisterId="xevnm-gaaaa-aaaar-qafnq-cai"] - The canister ID for CKUSDC token. * @param {string} [tokenCanisterIds.ckusdtCanisterId="vgmay-piaaa-aaaar-qafoq-cai"] - The canister ID for CKUSDT token. * @param {string} [tokenCanisterIds.ckbtcCanisterId="mxzaz-hqaaa-aaaar-qaada-cai"] - The canister ID for CKBTC token. * @param {string} [tokenCanisterIds.icpLedgerCanisterId="ryjl3-tyaaa-aaaaa-aaaba-cai"] - The canister ID for ICP ledger. * @returns {Promise<AddAccountResult>} - The result of the add_subaccount operation. */ async function addSubaccountForToken(agent, userVaultCanisterId, tokenType, tokenCanisterIds = {}) { const actor = createUserVaultActor(agent, userVaultCanisterId); // Check if the token is already registered const registeredTokens = await actor.get_registered_tokens(); if ('Err' in registeredTokens) { throw new Error(`Failed to get registered tokens: ${registeredTokens.Err}`); } // Get the canister ID for the token type let canisterId; switch (true) { case 'CKUSDC' in tokenType: canisterId = tokenCanisterIds.ckusdcCanisterId || 'xevnm-gaaaa-aaaar-qafnq-cai'; break; case 'CKUSDT' in tokenType: canisterId = tokenCanisterIds.ckusdtCanisterId || 'vgmay-piaaa-aaaar-qafoq-cai'; break; case 'CKBTC' in tokenType: canisterId = tokenCanisterIds.ckbtcCanisterId || 'mxzaz-hqaaa-aaaar-qaada-cai'; break; case 'ICP' in tokenType: canisterId = tokenCanisterIds.icpLedgerCanisterId || 'ryjl3-tyaaa-aaaaa-aaaba-cai'; break; default: throw new Error(`Unsupported token type: ${JSON.stringify(tokenType)}`); } // Check if the token type is already registered const isTokenRegistered = registeredTokens.Ok.some(([regTokenType, _]) => ('CKUSDC' in tokenType && 'CKUSDC' in regTokenType) || ('CKUSDT' in tokenType && 'CKUSDT' in regTokenType) || ('CKBTC' in tokenType && 'CKBTC' in regTokenType) || ('ICP' in tokenType && 'ICP' in regTokenType)); // Register the token if not already registered if (!isTokenRegistered) { const registerResult = await actor.register_token(tokenType, canisterId); if ('Err' in registerResult) { throw new Error(`Failed to register token: ${registerResult.Err.message}`); } } // Add a subaccount for the token type return await actor.add_subaccount([tokenType]); } /** * Calls the clear_transactions function on a canister. * @param {HttpAgent} agent - The HTTP agent used for the call. * @param {string} userVaultCanisterId - The canister ID of the user vault. * @param {bigint} [index] - The optional index to start clearing from. * @param {object} [timestamp] - The optional timestamp to clear up to. * @param {bigint} [timestamp.timestamp_nanos] - The timestamp in nanoseconds. * @returns {Promise<any[]>} - The result of the clear transactions operation. */ async function clearTransactions(agent, userVaultCanisterId, index, timestamp) { const actor = createUserVaultActor(agent, userVaultCanisterId); return await actor.clear_transactions(index ? [index] : [], timestamp ? [timestamp] : []); } /** * Sets a new webhook URL for the user's vault. * @param {HttpAgent} agent - The HTTP agent used for the call. * @param {string} userVaultCanisterId - The canister ID of the user vault. * @param {string} url - The new webhook URL to be set. * @returns {Promise<void>} - A promise that resolves when the webhook URL is successfully set. * @throws {Error} - Throws an error if the User Vault Canister ID is undefined. */ async function setWebhookUrl(agent, userVaultCanisterId, url) { const actor = createUserVaultActor(agent, userVaultCanisterId); return await actor.set_webhook_url(url); } /** * Registers a new token type with the user vault canister. * @param {HttpAgent} agent - The HTTP agent used for the call. * @param {string} userVaultCanisterId - The canister ID of the user vault. * @param {TokenType} tokenType - The token type to register (ICP, CKUSDC, CKUSDT, or CKBTC). * @param {string} canisterId - The canister ID for the token ledger. * @returns {Promise<any>} - A promise that resolves with the result of the register operation. */ async function registerToken(agent, userVaultCanisterId, tokenType, canisterId) { const actor = createUserVaultActor(agent, userVaultCanisterId); return await actor.register_token(tokenType, canisterId); } /** * Sweeps a specific amount from a given subaccount for a specific token type. * @param {HttpAgent} agent - The HTTP agent used for the call. * @param {string} userVaultCanisterId - The canister ID of the user vault. * @param {string} subaccountId - The ID of the subaccount to sweep from. * @param {number} amount - The amount to sweep. * @param {TokenType} [tokenType] - The token type to sweep (ICP, CKUSDC, CKUSDT, or CKBTC). Defaults to ICP if not provided. * @returns {Promise<any>} - A promise that resolves with the result of the sweep operation. * @throws {Error} - Throws an error if the User Vault Canister ID is undefined. */ async function sweepSubaccountId(agent, userVaultCanisterId, subaccountId, amount, tokenType) { const actor = createUserVaultActor(agent, userVaultCanisterId); // Ensure amount is explicitly a float by using parseFloat const floatAmount = parseFloat(amount.toString()); return await actor.sweep_subaccount(subaccountId, floatAmount, tokenType ? [tokenType] : []); } /** * Converts a subaccount ID to an ICRC account. * @param {HttpAgent} agent - The HTTP agent used for the call. * @param {string} userVaultCanisterId - The canister ID of the user vault. * @param {string} subaccountId - The ID of the subaccount to convert. * @returns {Promise<AddAccountResult>} - A promise that resolves with the result of the conversion. */ async function convertToIcrcAccount(agent, userVaultCanisterId, subaccountId) { const actor = createUserVaultActor(agent, userVaultCanisterId); return await actor.convert_to_icrc_account(subaccountId); } /** * Validates if a string is a valid ICRC account. * @param {HttpAgent} agent - The HTTP agent used for the call. * @param {string} userVaultCanisterId - The canister ID of the user vault. * @param {string} account - The account string to validate. * @returns {Promise<boolean>} - A promise that resolves with the validation result. */ async function validateIcrcAccount(agent, userVaultCanisterId, account) { const actor = createUserVaultActor(agent, userVaultCanisterId); const result = await actor.validate_icrc_account(account); if ('Err' in result) { throw new Error(`Failed to validate ICRC account: ${result.Err.message}`); } return result.Ok; } /** * Performs a single sweep for a specific transaction. * @param {HttpAgent} agent - The HTTP agent used for the call. * @param {string} userVaultCanisterId - The canister ID of the user vault. * @param {string} txHash - The transaction hash to sweep. * @returns {Promise<string[]>} - A promise that resolves with the result of the sweep operation. */ async function singleSweep(agent, userVaultCanisterId, txHash) { const actor = createUserVaultActor(agent, userVaultCanisterId); return await actor.single_sweep(txHash); } /** * Sets a transaction's sweep status to failed. * @param {HttpAgent} agent - The HTTP agent used for the call. * @param {string} userVaultCanisterId - The canister ID of the user vault. * @param {string} txHash - The transaction hash to mark as failed. * @returns {Promise<string[]>} - A promise that resolves with the result of the operation. */ async function setSweepFailed(agent, userVaultCanisterId, txHash) { const actor = createUserVaultActor(agent, userVaultCanisterId); return await actor.set_sweep_failed(txHash); }