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

161 lines (160 loc) 7.14 kB
"use strict"; var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { if (k2 === undefined) k2 = k; var desc = Object.getOwnPropertyDescriptor(m, k); if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { desc = { enumerable: true, get: function() { return m[k]; } }; } Object.defineProperty(o, k2, desc); }) : (function(o, m, k, k2) { if (k2 === undefined) k2 = k; o[k2] = m[k]; })); var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { Object.defineProperty(o, "default", { enumerable: true, value: v }); }) : function(o, v) { o["default"] = v; }); var __importStar = (this && this.__importStar) || (function () { var ownKeys = function(o) { ownKeys = Object.getOwnPropertyNames || function (o) { var ar = []; for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k; return ar; }; return ownKeys(o); }; return function (mod) { if (mod && mod.__esModule) return mod; var result = {}; if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]); __setModuleDefault(result, mod); return result; }; })(); var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.getIdentityFromPrivateKey = exports.getIdentityFromSeed = void 0; exports.isNotEmptyOrError = isNotEmptyOrError; exports.createHostAgentAndIdentityFromSeed = createHostAgentAndIdentityFromSeed; exports.createHostAgentAndIdentityFromPrivateKey = createHostAgentAndIdentityFromPrivateKey; const cross_fetch_1 = __importDefault(require("cross-fetch")); const agent_1 = require("@dfinity/agent"); const bip39 = __importStar(require("bip39")); const hdkey_1 = __importDefault(require("hdkey")); const secp256k1_1 = require("secp256k1"); const identity_secp256k1_1 = require("@dfinity/identity-secp256k1"); // Define the BIP44 derivation path for ICP. const DERIVATION_PATH = "m/44'/223'/0'/0"; /** * Checks if a value is not empty or throws an error. * @param value - The value to check. * @param errorMessage - The error message to throw if the value is empty. * @throws {Error} - Throws an error with the specified message if the value is empty. */ function isNotEmptyOrError(variable, message = undefined) { let error_msg; if (message === undefined) { error_msg = 'Variable is empty.'; } else { error_msg = message; } if (Array.isArray(variable)) { if (variable.length < 1) { throw new Error(error_msg); } } else { if (variable === undefined || variable === '' || variable === null) { throw new Error(error_msg); } } } /** * Generates a Secp256k1KeyIdentity from a seed phrase and an optional index. * @param {string} mnemonic - The mnemonic seed phrase. * @param {number} [index=0] - The index to use in the derivation path (default is 0). * @returns {Secp256k1KeyIdentity} - The generated Secp256k1KeyIdentity. */ const getIdentityFromSeed = (mnemonic, index = 0) => { if (!mnemonic || mnemonic.trim() === '') { throw new Error('Mnemonic seed phrase cannot be empty'); } if (!bip39.validateMnemonic(mnemonic)) { throw new Error('Invalid mnemonic seed phrase'); } const seed = bip39.mnemonicToSeedSync(mnemonic); const masterKey = hdkey_1.default.fromMasterSeed(seed); // Derive the private and public keys using the BIP44 derivation path. const { privateKey } = masterKey.derive(`${DERIVATION_PATH}/${index}`); const publicKey = (0, secp256k1_1.publicKeyCreate)(privateKey, false); return identity_secp256k1_1.Secp256k1KeyIdentity.fromKeyPair(publicKey, privateKey); }; exports.getIdentityFromSeed = getIdentityFromSeed; /** * Generates a Secp256k1KeyIdentity from a private key in various formats. * @param {string} privateKey - The private key as hex string or EC PEM format. * @returns {Secp256k1KeyIdentity} - The generated Secp256k1KeyIdentity. */ const getIdentityFromPrivateKey = (privateKey) => { if (!privateKey || typeof privateKey !== 'string') { throw new Error('Private key cannot be empty'); } try { // Check if it's a PEM format if (privateKey.includes('-----BEGIN') && privateKey.includes('-----END')) { // For PEM format, try to parse using the Secp256k1KeyIdentity.fromPem method try { return identity_secp256k1_1.Secp256k1KeyIdentity.fromPem(privateKey); } catch (pemError) { throw new Error(`Failed to parse PEM private key: ${pemError.message}. Make sure it's a valid EC (secp256k1) private key in PEM format.`); } } // Handle hex format (with or without 0x prefix) const cleanPrivateKey = privateKey.replace(/^0x/, '').replace(/\s/g, ''); if (cleanPrivateKey.length !== 64) { throw new Error('Private key must be 64 hex characters (32 bytes) for secp256k1'); } const privateKeyBuffer = Buffer.from(cleanPrivateKey, 'hex'); const publicKey = (0, secp256k1_1.publicKeyCreate)(privateKeyBuffer, false); return identity_secp256k1_1.Secp256k1KeyIdentity.fromKeyPair(publicKey, privateKeyBuffer); } catch (error) { throw new Error(`Invalid private key format: ${error.message}`); } }; exports.getIdentityFromPrivateKey = getIdentityFromPrivateKey; /** * Creates an HttpAgent with a Secp256k1KeyIdentity from a given seed phrase. * @param {string} seedPhrase - The seed phrase to generate the identity. * @param {string} [host="https://ic0.app"] - The host URL for the HttpAgent (default is the IC mainnet URL). * @returns {HttpAgent} - The initialized HttpAgent with the generated identity. */ function createHostAgentAndIdentityFromSeed(seedPhrase, host = 'https://ic0.app') { const identity = (0, exports.getIdentityFromSeed)(seedPhrase); // Initialize and return the HttpAgent with the generated identity. return new agent_1.HttpAgent({ host, identity, fetch: cross_fetch_1.default, }); } /** * Creates an HttpAgent with a Secp256k1KeyIdentity from a private key. * @param {string} privateKey - The private key in EC PEM format or as a hex string. * @param {string} [host="https://ic0.app"] - The host URL for the HttpAgent (default is the IC mainnet URL). * @returns {HttpAgent} - The initialized HttpAgent with the generated identity. */ function createHostAgentAndIdentityFromPrivateKey(privateKey, host = 'https://ic0.app') { const identity = (0, exports.getIdentityFromPrivateKey)(privateKey); // Initialize and return the HttpAgent with the generated identity. return new agent_1.HttpAgent({ host, identity, fetch: cross_fetch_1.default, }); }