UNPKG

ts-xdbchain-sdk

Version:

A TypeScript SDK for interacting with XDBCHAIN - a Stellar-based blockchain network

1,170 lines 65.9 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.XDBChainSDK = exports.OPERATION_TYPE = exports.ASSET_TYPE = exports.ACCOUNT_FLAGS = exports.XDBOfferError = exports.XDBAssetError = exports.XDBTransactionError = exports.XDBValidationError = exports.XDBNetworkError = exports.XDBChainError = void 0; exports.createXDBChainSDK = createXDBChainSDK; exports.createMainnetSDK = createMainnetSDK; exports.createFuturenetSDK = createFuturenetSDK; exports.xdbToStroops = xdbToStroops; exports.stroopsToXdb = stroopsToXdb; exports.isValidAmount = isValidAmount; exports.formatAmount = formatAmount; exports.generateNonce = generateNonce; exports.isValidMemo = isValidMemo; exports.calculateFee = calculateFee; exports.accountExists = accountExists; const stellar_sdk_1 = require("stellar-sdk"); class XDBChainError extends Error { constructor(message, code, details) { super(message); this.code = code; this.details = details; this.name = 'XDBChainError'; } } exports.XDBChainError = XDBChainError; class XDBNetworkError extends XDBChainError { constructor(message, details) { super(message, 'NETWORK_ERROR', details); this.name = 'XDBNetworkError'; } } exports.XDBNetworkError = XDBNetworkError; class XDBValidationError extends XDBChainError { constructor(message, details) { super(message, 'VALIDATION_ERROR', details); this.name = 'XDBValidationError'; } } exports.XDBValidationError = XDBValidationError; class XDBTransactionError extends XDBChainError { constructor(message, details) { super(message, 'TRANSACTION_ERROR', details); this.name = 'XDBTransactionError'; } } exports.XDBTransactionError = XDBTransactionError; class XDBAssetError extends XDBChainError { constructor(message, details) { super(message, 'ASSET_ERROR', details); this.name = 'XDBAssetError'; } } exports.XDBAssetError = XDBAssetError; class XDBOfferError extends XDBChainError { constructor(message, details) { super(message, 'OFFER_ERROR', details); this.name = 'XDBOfferError'; } } exports.XDBOfferError = XDBOfferError; exports.ACCOUNT_FLAGS = { AUTH_REQUIRED_FLAG: 0x1, AUTH_REVOCABLE_FLAG: 0x2, AUTH_IMMUTABLE_FLAG: 0x4, AUTH_CLAWBACK_ENABLED_FLAG: 0x8 }; exports.ASSET_TYPE = { NATIVE: 'native', CREDIT_ALPHANUM4: 'credit_alphanum4', CREDIT_ALPHANUM12: 'credit_alphanum12' }; exports.OPERATION_TYPE = { CREATE_ACCOUNT: 'create_account', PAYMENT: 'payment', PATH_PAYMENT_STRICT_RECEIVE: 'path_payment_strict_receive', PATH_PAYMENT_STRICT_SEND: 'path_payment_strict_send', MANAGE_SELL_OFFER: 'manage_sell_offer', MANAGE_BUY_OFFER: 'manage_buy_offer', CREATE_PASSIVE_SELL_OFFER: 'create_passive_sell_offer', SET_OPTIONS: 'set_options', CHANGE_TRUST: 'change_trust', ALLOW_TRUST: 'allow_trust', ACCOUNT_MERGE: 'account_merge', INFLATION: 'inflation', MANAGE_DATA: 'manage_data', BUMP_SEQUENCE: 'bump_sequence', CREATE_CLAIMABLE_BALANCE: 'create_claimable_balance', CLAIM_CLAIMABLE_BALANCE: 'claim_claimable_balance', BEGIN_SPONSORING_FUTURE_RESERVES: 'begin_sponsoring_future_reserves', END_SPONSORING_FUTURE_RESERVES: 'end_sponsoring_future_reserves', REVOKE_SPONSORSHIP: 'revoke_sponsorship', CLAWBACK: 'clawback', CLAWBACK_CLAIMABLE_BALANCE: 'clawback_claimable_balance', SET_TRUST_LINE_FLAGS: 'set_trust_line_flags' }; class XDBChainSDK { constructor(config) { this.config = { ...XDBChainSDK.DEFAULT_CONFIGS[config.network], ...config }; this.server = new stellar_sdk_1.Horizon.Server(this.config.horizonUrl, { allowHttp: this.config.allowHttp }); this.networkPassphrase = this.config.networkPassphrase; } async createWallet() { try { const keypair = stellar_sdk_1.Keypair.random(); const wallet = { publicKey: keypair.publicKey(), secretKey: keypair.secret(), network: this.config.network }; console.log('✅ Wallet created successfully:', wallet.publicKey); return wallet; } catch (error) { throw new XDBChainError(`Failed to create wallet: ${error}`); } } async loadWallet(secretKey) { try { if (!this.isValidSecretKey(secretKey)) { throw new XDBValidationError('Invalid secret key format'); } const keypair = stellar_sdk_1.Keypair.fromSecret(secretKey); const account = await this.server.loadAccount(keypair.publicKey()); return { publicKey: keypair.publicKey(), secretKey: secretKey, network: this.config.network, account: account }; } catch (error) { throw new XDBChainError(`Failed to load wallet: ${error}`); } } async createWalletFromSeed(seed) { try { const keypair = stellar_sdk_1.Keypair.fromRawEd25519Seed(typeof seed === 'string' ? Buffer.from(seed, 'hex') : seed); const wallet = { publicKey: keypair.publicKey(), secretKey: keypair.secret(), network: this.config.network }; return wallet; } catch (error) { throw new XDBChainError(`Failed to create wallet from seed: ${error}`); } } isValidAddress(address) { try { return stellar_sdk_1.StrKey.isValidEd25519PublicKey(address); } catch { return false; } } isValidSecretKey(secretKey) { try { return stellar_sdk_1.StrKey.isValidEd25519SecretSeed(secretKey); } catch { return false; } } generateKeypair() { return stellar_sdk_1.Keypair.random(); } keypairFromSecret(secretKey) { return stellar_sdk_1.Keypair.fromSecret(secretKey); } keypairFromPublicKey(publicKey) { return stellar_sdk_1.Keypair.fromPublicKey(publicKey); } async loadAccount(publicKey) { try { if (!this.isValidAddress(publicKey)) { throw new XDBValidationError('Invalid public key'); } return await this.server.loadAccount(publicKey); } catch (error) { throw new XDBChainError(`Failed to load account: ${error}`); } } async createAccount(source, destination, startingBalance = this.config.startingBalance) { try { if (!this.isValidSecretKey(source)) { throw new XDBValidationError('Invalid source secret key'); } if (!this.isValidAddress(destination)) { throw new XDBValidationError('Invalid destination address'); } const sourceKeypair = stellar_sdk_1.Keypair.fromSecret(source); const sourceAccount = await this.server.loadAccount(sourceKeypair.publicKey()); const transaction = new stellar_sdk_1.TransactionBuilder(sourceAccount, { fee: (await this.server.fetchBaseFee()).toString(), networkPassphrase: this.networkPassphrase }) .addOperation(stellar_sdk_1.Operation.createAccount({ destination: destination, startingBalance: startingBalance })) .setTimeout(this.config.timeout) .build(); transaction.sign(sourceKeypair); const result = await this.server.submitTransaction(transaction); console.log('✅ Account created successfully:', result.hash); return result; } catch (error) { throw new XDBTransactionError(`Failed to create account: ${error}`); } } async setAccountOptions(secretKey, options) { try { if (!this.isValidSecretKey(secretKey)) { throw new XDBValidationError('Invalid secret key'); } const keypair = stellar_sdk_1.Keypair.fromSecret(secretKey); const account = await this.server.loadAccount(keypair.publicKey()); const operation = {}; if (options.homeDomain !== undefined) operation.homeDomain = options.homeDomain; if (options.inflationDest !== undefined) operation.inflationDest = options.inflationDest; if (options.masterWeight !== undefined) operation.masterWeight = options.masterWeight; if (options.lowThreshold !== undefined) operation.lowThreshold = options.lowThreshold; if (options.medThreshold !== undefined) operation.medThreshold = options.medThreshold; if (options.highThreshold !== undefined) operation.highThreshold = options.highThreshold; if (options.setFlags !== undefined) operation.setFlags = options.setFlags; if (options.clearFlags !== undefined) operation.clearFlags = options.clearFlags; if (options.signer !== undefined) operation.signer = options.signer; const transaction = new stellar_sdk_1.TransactionBuilder(account, { fee: (await this.server.fetchBaseFee()).toString(), networkPassphrase: this.networkPassphrase }) .addOperation(stellar_sdk_1.Operation.setOptions(operation)) .setTimeout(this.config.timeout) .build(); transaction.sign(keypair); const result = await this.server.submitTransaction(transaction); console.log('✅ Account options set successfully:', result.hash); return result; } catch (error) { throw new XDBTransactionError(`Failed to set account options: ${error}`); } } async mergeAccount(sourceSecret, destination) { try { if (!this.isValidSecretKey(sourceSecret)) { throw new XDBValidationError('Invalid source secret key'); } if (!this.isValidAddress(destination)) { throw new XDBValidationError('Invalid destination address'); } const sourceKeypair = stellar_sdk_1.Keypair.fromSecret(sourceSecret); const sourceAccount = await this.server.loadAccount(sourceKeypair.publicKey()); const transaction = new stellar_sdk_1.TransactionBuilder(sourceAccount, { fee: (await this.server.fetchBaseFee()).toString(), networkPassphrase: this.networkPassphrase }) .addOperation(stellar_sdk_1.Operation.accountMerge({ destination: destination })) .setTimeout(this.config.timeout) .build(); transaction.sign(sourceKeypair); const result = await this.server.submitTransaction(transaction); console.log('✅ Account merged successfully:', result.hash); return result; } catch (error) { throw new XDBTransactionError(`Failed to merge account: ${error}`); } } async bumpSequence(secretKey, bumpTo) { try { if (!this.isValidSecretKey(secretKey)) { throw new XDBValidationError('Invalid secret key'); } const keypair = stellar_sdk_1.Keypair.fromSecret(secretKey); const account = await this.server.loadAccount(keypair.publicKey()); const transaction = new stellar_sdk_1.TransactionBuilder(account, { fee: (await this.server.fetchBaseFee()).toString(), networkPassphrase: this.networkPassphrase }) .addOperation(stellar_sdk_1.Operation.bumpSequence({ bumpTo: bumpTo })) .setTimeout(this.config.timeout) .build(); transaction.sign(keypair); const result = await this.server.submitTransaction(transaction); console.log('✅ Sequence bumped successfully:', result.hash); return result; } catch (error) { throw new XDBTransactionError(`Failed to bump sequence: ${error}`); } } async getBalances(publicKey) { try { if (!this.isValidAddress(publicKey)) { throw new XDBValidationError('Invalid public key'); } const account = await this.server.loadAccount(publicKey); return account.balances.map((balance) => ({ assetType: balance.asset_type, assetCode: balance.asset_code || 'XDB', assetIssuer: balance.asset_issuer || null, balance: balance.balance, limit: balance.limit || null, buyingLiabilities: balance.buying_liabilities, sellingLiabilities: balance.selling_liabilities, lastModifiedLedger: balance.last_modified_ledger, isAuthorized: balance.is_authorized, isAuthorizedToMaintainLiabilities: balance.is_authorized_to_maintain_liabilities })); } catch (error) { throw new XDBChainError(`Failed to get balances: ${error}`); } } async getXDBBalance(publicKey) { const balances = await this.getBalances(publicKey); const xdbBalance = balances.find(b => b.assetCode === 'XDB'); return xdbBalance?.balance || '0'; } watchBalances(publicKey, callback) { if (!this.isValidAddress(publicKey)) { throw new XDBValidationError('Invalid public key'); } const accountCallBuilder = this.server.accounts(); const closeHandler = accountCallBuilder .accountId(publicKey) .stream({ onmessage: (account) => { const balances = account.balances.map((balance) => ({ assetType: balance.asset_type, assetCode: balance.asset_code || 'XDB', assetIssuer: balance.asset_issuer || null, balance: balance.balance, limit: balance.limit || null, buyingLiabilities: balance.buying_liabilities, sellingLiabilities: balance.selling_liabilities, lastModifiedLedger: balance.last_modified_ledger, isAuthorized: balance.is_authorized, isAuthorizedToMaintainLiabilities: balance.is_authorized_to_maintain_liabilities })); callback(balances); }, onerror: (error) => { console.error('Balance stream error:', error); } }); return closeHandler; } async sendPayment(senderSecret, options) { try { if (!this.isValidSecretKey(senderSecret)) { throw new XDBValidationError('Invalid sender secret key'); } if (!this.isValidAddress(options.destination)) { throw new XDBValidationError('Invalid destination address'); } const senderKeypair = stellar_sdk_1.Keypair.fromSecret(senderSecret); const senderAccount = await this.server.loadAccount(senderKeypair.publicKey()); const asset = this.createAsset(options.asset); const transactionBuilder = new stellar_sdk_1.TransactionBuilder(senderAccount, { fee: (await this.server.fetchBaseFee()).toString(), networkPassphrase: this.networkPassphrase }); transactionBuilder.addOperation(stellar_sdk_1.Operation.payment({ destination: options.destination, asset: asset, amount: options.amount, source: options.source })); if (options.memo) { const memo = this.createMemo(options.memo, options.memoType); transactionBuilder.addMemo(memo); } const transaction = transactionBuilder.setTimeout(this.config.timeout).build(); transaction.sign(senderKeypair); const result = await this.server.submitTransaction(transaction); console.log('✅ Payment sent successfully:', result.hash); return result; } catch (error) { throw new XDBTransactionError(`Payment failed: ${error}`); } } async sendPathPaymentStrictReceive(senderSecret, options) { try { if (!this.isValidSecretKey(senderSecret)) { throw new XDBValidationError('Invalid sender secret key'); } if (!this.isValidAddress(options.destination)) { throw new XDBValidationError('Invalid destination address'); } const senderKeypair = stellar_sdk_1.Keypair.fromSecret(senderSecret); const senderAccount = await this.server.loadAccount(senderKeypair.publicKey()); const sendAsset = this.createAsset(options.sendAsset); const destAsset = this.createAsset(options.destAsset); const path = options.path ? options.path.map(asset => this.createAsset(asset)) : []; const transactionBuilder = new stellar_sdk_1.TransactionBuilder(senderAccount, { fee: (await this.server.fetchBaseFee()).toString(), networkPassphrase: this.networkPassphrase }); transactionBuilder.addOperation(stellar_sdk_1.Operation.pathPaymentStrictReceive({ sendAsset: sendAsset, sendMax: options.sendMax, destination: options.destination, destAsset: destAsset, destAmount: options.destAmount, path: path, source: options.source })); if (options.memo) { const memo = this.createMemo(options.memo, options.memoType); transactionBuilder.addMemo(memo); } const transaction = transactionBuilder.setTimeout(this.config.timeout).build(); transaction.sign(senderKeypair); const result = await this.server.submitTransaction(transaction); console.log('✅ Path payment sent successfully:', result.hash); return result; } catch (error) { throw new XDBTransactionError(`Path payment failed: ${error}`); } } async sendPathPaymentStrictSend(senderSecret, options) { try { if (!this.isValidSecretKey(senderSecret)) { throw new XDBValidationError('Invalid sender secret key'); } if (!this.isValidAddress(options.destination)) { throw new XDBValidationError('Invalid destination address'); } const senderKeypair = stellar_sdk_1.Keypair.fromSecret(senderSecret); const senderAccount = await this.server.loadAccount(senderKeypair.publicKey()); const sendAsset = this.createAsset(options.sendAsset); const destAsset = this.createAsset(options.destAsset); const path = options.path ? options.path.map(asset => this.createAsset(asset)) : []; const transactionBuilder = new stellar_sdk_1.TransactionBuilder(senderAccount, { fee: (await this.server.fetchBaseFee()).toString(), networkPassphrase: this.networkPassphrase }); transactionBuilder.addOperation(stellar_sdk_1.Operation.pathPaymentStrictSend({ sendAsset: sendAsset, sendAmount: options.sendMax, destination: options.destination, destAsset: destAsset, destMin: options.destAmount, path: path, source: options.source })); if (options.memo) { const memo = this.createMemo(options.memo, options.memoType); transactionBuilder.addMemo(memo); } const transaction = transactionBuilder.setTimeout(this.config.timeout).build(); transaction.sign(senderKeypair); const result = await this.server.submitTransaction(transaction); console.log('✅ Path payment (strict send) sent successfully:', result.hash); return result; } catch (error) { throw new XDBTransactionError(`Path payment (strict send) failed: ${error}`); } } async sendBatchPayments(senderSecret, payments) { try { if (!this.isValidSecretKey(senderSecret)) { throw new XDBValidationError('Invalid sender secret key'); } if (!payments.length) { throw new XDBValidationError('No payments provided'); } const senderKeypair = stellar_sdk_1.Keypair.fromSecret(senderSecret); const senderAccount = await this.server.loadAccount(senderKeypair.publicKey()); const transactionBuilder = new stellar_sdk_1.TransactionBuilder(senderAccount, { fee: (await this.server.fetchBaseFee()).toString(), networkPassphrase: this.networkPassphrase }); for (const payment of payments) { if (!this.isValidAddress(payment.destination)) { throw new XDBValidationError(`Invalid destination address: ${payment.destination}`); } const asset = this.createAsset(payment.asset); transactionBuilder.addOperation(stellar_sdk_1.Operation.payment({ destination: payment.destination, asset: asset, amount: payment.amount, source: payment.source })); } const transaction = transactionBuilder.setTimeout(this.config.timeout).build(); transaction.sign(senderKeypair); const result = await this.server.submitTransaction(transaction); console.log('✅ Batch payments sent successfully:', result.hash); return result; } catch (error) { throw new XDBTransactionError(`Batch payment failed: ${error}`); } } async addTrustline(walletSecret, options) { try { if (!this.isValidSecretKey(walletSecret)) { throw new XDBValidationError('Invalid wallet secret key'); } const keypair = stellar_sdk_1.Keypair.fromSecret(walletSecret); const account = await this.server.loadAccount(keypair.publicKey()); const asset = new stellar_sdk_1.Asset(options.assetCode, options.assetIssuer); const transaction = new stellar_sdk_1.TransactionBuilder(account, { fee: (await this.server.fetchBaseFee()).toString(), networkPassphrase: this.networkPassphrase }) .addOperation(stellar_sdk_1.Operation.changeTrust({ asset: asset, limit: options.limit, source: options.source })) .setTimeout(this.config.timeout) .build(); transaction.sign(keypair); const result = await this.server.submitTransaction(transaction); console.log('✅ Trustline added successfully:', result.hash); return result; } catch (error) { throw new XDBTransactionError(`Failed to add trustline: ${error}`); } } async removeTrustline(walletSecret, options) { return this.addTrustline(walletSecret, { ...options, limit: '0' }); } async getTrustlines(publicKey) { try { if (!this.isValidAddress(publicKey)) { throw new XDBValidationError('Invalid public key'); } const account = await this.server.loadAccount(publicKey); return account.balances.filter((balance) => balance.asset_type !== 'native'); } catch (error) { throw new XDBChainError(`Failed to get trustlines: ${error}`); } } async allowTrust(trustorSecret, trusteePublicKey, assetCode, authorize) { try { if (!this.isValidSecretKey(trustorSecret)) { throw new XDBValidationError('Invalid trustor secret key'); } if (!this.isValidAddress(trusteePublicKey)) { throw new XDBValidationError('Invalid trustee public key'); } const trustorKeypair = stellar_sdk_1.Keypair.fromSecret(trustorSecret); const trustorAccount = await this.server.loadAccount(trustorKeypair.publicKey()); const transaction = new stellar_sdk_1.TransactionBuilder(trustorAccount, { fee: (await this.server.fetchBaseFee()).toString(), networkPassphrase: this.networkPassphrase }) .addOperation(stellar_sdk_1.Operation.allowTrust({ trustor: trusteePublicKey, assetCode: assetCode, authorize: authorize })) .setTimeout(this.config.timeout) .build(); transaction.sign(trustorKeypair); const result = await this.server.submitTransaction(transaction); console.log('✅ Trust authorization updated successfully:', result.hash); return result; } catch (error) { throw new XDBTransactionError(`Failed to update trust authorization: ${error}`); } } createAssetObject(code, issuer) { if (code === 'XDB' || code === 'native') { const nativeAsset = stellar_sdk_1.Asset.native(); nativeAsset.code = 'XDB'; return nativeAsset; } if (!issuer) { throw new XDBAssetError('Asset issuer is required for non-native assets'); } return new stellar_sdk_1.Asset(code, issuer); } async issueAsset(issuerSecret, distributorPublicKey, assetCode, amount) { try { if (!this.isValidSecretKey(issuerSecret)) { throw new XDBValidationError('Invalid issuer secret key'); } if (!this.isValidAddress(distributorPublicKey)) { throw new XDBValidationError('Invalid distributor public key'); } const issuerKeypair = stellar_sdk_1.Keypair.fromSecret(issuerSecret); const issuerAccount = await this.server.loadAccount(issuerKeypair.publicKey()); const asset = new stellar_sdk_1.Asset(assetCode, issuerKeypair.publicKey()); const transaction = new stellar_sdk_1.TransactionBuilder(issuerAccount, { fee: (await this.server.fetchBaseFee()).toString(), networkPassphrase: this.networkPassphrase }) .addOperation(stellar_sdk_1.Operation.payment({ destination: distributorPublicKey, asset: asset, amount: amount })) .setTimeout(this.config.timeout) .build(); transaction.sign(issuerKeypair); const result = await this.server.submitTransaction(transaction); console.log('✅ Asset issued successfully:', result.hash); return result; } catch (error) { throw new XDBTransactionError(`Failed to issue asset: ${error}`); } } async createSellOffer(secretKey, options) { try { if (!this.isValidSecretKey(secretKey)) { throw new XDBValidationError('Invalid secret key'); } const keypair = stellar_sdk_1.Keypair.fromSecret(secretKey); const account = await this.server.loadAccount(keypair.publicKey()); const selling = this.createAsset(options.selling); const buying = this.createAsset(options.buying); const transaction = new stellar_sdk_1.TransactionBuilder(account, { fee: (await this.server.fetchBaseFee()).toString(), networkPassphrase: this.networkPassphrase }) .addOperation(stellar_sdk_1.Operation.manageSellOffer({ selling: selling, buying: buying, amount: options.amount, price: options.price, offerId: options.offerId || '0', source: options.source })) .setTimeout(this.config.timeout) .build(); transaction.sign(keypair); const result = await this.server.submitTransaction(transaction); console.log('✅ Sell offer created successfully:', result.hash); return result; } catch (error) { throw new XDBOfferError(`Failed to create sell offer: ${error}`); } } async createBuyOffer(secretKey, options) { try { if (!this.isValidSecretKey(secretKey)) { throw new XDBValidationError('Invalid secret key'); } const keypair = stellar_sdk_1.Keypair.fromSecret(secretKey); const account = await this.server.loadAccount(keypair.publicKey()); const selling = this.createAsset(options.selling); const buying = this.createAsset(options.buying); const transaction = new stellar_sdk_1.TransactionBuilder(account, { fee: (await this.server.fetchBaseFee()).toString(), networkPassphrase: this.networkPassphrase }) .addOperation(stellar_sdk_1.Operation.manageBuyOffer({ selling: selling, buying: buying, buyAmount: options.amount, price: options.price, offerId: options.offerId || '0', source: options.source })) .setTimeout(this.config.timeout) .build(); transaction.sign(keypair); const result = await this.server.submitTransaction(transaction); console.log('✅ Buy offer created successfully:', result.hash); return result; } catch (error) { throw new XDBOfferError(`Failed to create buy offer: ${error}`); } } async createPassiveSellOffer(secretKey, options) { try { if (!this.isValidSecretKey(secretKey)) { throw new XDBValidationError('Invalid secret key'); } const keypair = stellar_sdk_1.Keypair.fromSecret(secretKey); const account = await this.server.loadAccount(keypair.publicKey()); const selling = this.createAsset(options.selling); const buying = this.createAsset(options.buying); const transaction = new stellar_sdk_1.TransactionBuilder(account, { fee: (await this.server.fetchBaseFee()).toString(), networkPassphrase: this.networkPassphrase }) .addOperation(stellar_sdk_1.Operation.createPassiveSellOffer({ selling: selling, buying: buying, amount: options.amount, price: options.price, source: options.source })) .setTimeout(this.config.timeout) .build(); transaction.sign(keypair); const result = await this.server.submitTransaction(transaction); console.log('✅ Passive sell offer created successfully:', result.hash); return result; } catch (error) { throw new XDBOfferError(`Failed to create passive sell offer: ${error}`); } } async cancelOffer(secretKey, offerId, selling, buying) { try { if (!this.isValidSecretKey(secretKey)) { throw new XDBValidationError('Invalid secret key'); } const keypair = stellar_sdk_1.Keypair.fromSecret(secretKey); const account = await this.server.loadAccount(keypair.publicKey()); const sellingAsset = this.createAsset(selling); const buyingAsset = this.createAsset(buying); const transaction = new stellar_sdk_1.TransactionBuilder(account, { fee: (await this.server.fetchBaseFee()).toString(), networkPassphrase: this.networkPassphrase }) .addOperation(stellar_sdk_1.Operation.manageSellOffer({ selling: sellingAsset, buying: buyingAsset, amount: '0', price: '1', offerId: offerId })) .setTimeout(this.config.timeout) .build(); transaction.sign(keypair); const result = await this.server.submitTransaction(transaction); console.log('✅ Offer cancelled successfully:', result.hash); return result; } catch (error) { throw new XDBOfferError(`Failed to cancel offer: ${error}`); } } async manageData(secretKey, options) { try { if (!this.isValidSecretKey(secretKey)) { throw new XDBValidationError('Invalid secret key'); } const keypair = stellar_sdk_1.Keypair.fromSecret(secretKey); const account = await this.server.loadAccount(keypair.publicKey()); const transaction = new stellar_sdk_1.TransactionBuilder(account, { fee: (await this.server.fetchBaseFee()).toString(), networkPassphrase: this.networkPassphrase }) .addOperation(stellar_sdk_1.Operation.manageData({ name: options.name, value: options.value, source: options.source })) .setTimeout(this.config.timeout) .build(); transaction.sign(keypair); const result = await this.server.submitTransaction(transaction); console.log('✅ Data managed successfully:', result.hash); return result; } catch (error) { throw new XDBTransactionError(`Failed to manage data: ${error}`); } } async getTransactionHistory(publicKey, options = {}) { try { if (!this.isValidAddress(publicKey)) { throw new XDBValidationError('Invalid public key'); } const { limit = 10, order = 'desc', cursor, includeFailed = false } = options; let transactionBuilder = this.server .transactions() .forAccount(publicKey) .order(order) .limit(limit); if (cursor) { transactionBuilder = transactionBuilder.cursor(cursor); } if (includeFailed) { transactionBuilder = transactionBuilder.includeFailed(true); } const result = await transactionBuilder.call(); return result.records.map((tx) => ({ hash: tx.hash, ledger: tx.ledger_attr, createdAt: tx.created_at, fee: tx.fee_charged, operationCount: tx.operation_count, memo: tx.memo, memoType: tx.memo_type, successful: tx.successful, pagingToken: tx.paging_token, sourceAccount: tx.source_account, sourceAccountSequence: tx.source_account_sequence, feeAccount: tx.fee_account, feeCharged: tx.fee_charged, maxFee: tx.max_fee, timeBounds: tx.time_bounds })); } catch (error) { throw new XDBChainError(`Failed to get transaction history: ${error}`); } } async getTransactionsForLedger(ledgerSequence, options = {}) { try { const { limit = 10, order = 'desc', cursor, includeFailed = false } = options; let transactionBuilder = this.server .transactions() .forLedger(ledgerSequence) .order(order) .limit(limit); if (cursor) { transactionBuilder = transactionBuilder.cursor(cursor); } if (includeFailed) { transactionBuilder = transactionBuilder.includeFailed(true); } const result = await transactionBuilder.call(); return result.records.map((tx) => ({ hash: tx.hash, ledger: tx.ledger_attr, createdAt: tx.created_at, fee: tx.fee_charged, operationCount: tx.operation_count, memo: tx.memo, memoType: tx.memo_type, successful: tx.successful, pagingToken: tx.paging_token, sourceAccount: tx.source_account, sourceAccountSequence: tx.source_account_sequence, feeAccount: tx.fee_account, feeCharged: tx.fee_charged, maxFee: tx.max_fee, timeBounds: tx.time_bounds })); } catch (error) { throw new XDBChainError(`Failed to get transactions for ledger: ${error}`); } } watchTransactions(publicKey, callback) { if (!this.isValidAddress(publicKey)) { throw new XDBValidationError('Invalid public key'); } const closeHandler = this.server .transactions() .forAccount(publicKey) .cursor('now') .stream({ onmessage: (transaction) => { const xdbTransaction = { hash: transaction.hash, ledger: transaction.ledger_attr, createdAt: transaction.created_at, fee: transaction.fee_charged, operationCount: transaction.operation_count, memo: transaction.memo, memoType: transaction.memo_type, successful: transaction.successful, pagingToken: transaction.paging_token, sourceAccount: transaction.source_account, sourceAccountSequence: transaction.source_account_sequence, feeAccount: transaction.fee_account, feeCharged: transaction.fee_charged, maxFee: transaction.max_fee, timeBounds: transaction.time_bounds }; callback(xdbTransaction); }, onerror: (error) => { console.error('Transaction stream error:', error); } }); return closeHandler; } async getOperations(publicKey, options = {}) { try { if (!this.isValidAddress(publicKey)) { throw new XDBValidationError('Invalid public key'); } const { limit = 10, order = 'desc', cursor, includeFailed = false } = options; let operationBuilder = this.server .operations() .forAccount(publicKey) .order(order) .limit(limit); if (cursor) { operationBuilder = operationBuilder.cursor(cursor); } if (includeFailed) { operationBuilder = operationBuilder.includeFailed(true); } const result = await operationBuilder.call(); return result.records; } catch (error) { throw new XDBChainError(`Failed to get operations: ${error}`); } } async getOperationsForLedger(ledgerSequence, options = {}) { try { const { limit = 10, order = 'desc', cursor, includeFailed = false } = options; let operationBuilder = this.server .operations() .forLedger(ledgerSequence) .order(order) .limit(limit); if (cursor) { operationBuilder = operationBuilder.cursor(cursor); } if (includeFailed) { operationBuilder = operationBuilder.includeFailed(true); } const result = await operationBuilder.call(); return result.records; } catch (error) { throw new XDBChainError(`Failed to get operations for ledger: ${error}`); } } async getOperationsForTransaction(transactionHash, options = {}) { try { const { limit = 10, order = 'desc', cursor } = options; let operationBuilder = this.server .operations() .forTransaction(transactionHash) .order(order) .limit(limit); if (cursor) { operationBuilder = operationBuilder.cursor(cursor); } const result = await operationBuilder.call(); return result.records; } catch (error) { throw new XDBChainError(`Failed to get operations for transaction: ${error}`); } } async getPayments(publicKey, options = {}) { try { if (!this.isValidAddress(publicKey)) { throw new XDBValidationError('Invalid public key'); } const { limit = 10, order = 'desc', cursor, includeFailed = false } = options; let paymentBuilder = this.server .payments() .forAccount(publicKey) .order(order) .limit(limit); if (cursor) { paymentBuilder = paymentBuilder.cursor(cursor); } if (includeFailed) { paymentBuilder = paymentBuilder.includeFailed(true); } const result = await paymentBuilder.call(); return result.records.map((payment) => ({ id: payment.id, pagingToken: payment.paging_token, transactionSuccessful: payment.transaction_successful, sourceAccount: payment.source_account, type: payment.type, createdAt: payment.created_at, transactionHash: payment.transaction_hash, assetType: payment.asset_type, assetCode: payment.asset_code, assetIssuer: payment.asset_issuer, from: payment.from, to: payment.to, amount: payment.amount, memo: payment.memo, memoType: payment.memo_type })); } catch (error) { throw new XDBChainError(`Failed to get payments: ${error}`); } } watchPayments(publicKey, callback) { if (!this.isValidAddress(publicKey)) { throw new XDBValidationError('Invalid public key'); } const closeHandler = this.server .payments() .forAccount(publicKey) .cursor('now') .stream({ onmessage: (payment) => { const xdbPayment = { id: payment.id, pagingToken: payment.paging_token, transactionSuccessful: payment.transaction_successful, sourceAccount: payment.source_account, type: payment.type, createdAt: payment.created_at, transactionHash: payment.transaction_hash, assetType: payment.asset_type, assetCode: payment.asset_code, assetIssuer: payment.asset_issuer, from: payment.from, to: payment.to, amount: payment.amount, memo: payment.memo, memoType: payment.memo_type }; callback(xdbPayment); }, onerror: (error) => { console.error('Payment stream error:', error); } }); return closeHandler; } async getEffects(publicKey, options = {}) { try { if (!this.isValidAddress(publicKey)) { throw new XDBValidationError('Invalid public key'); } const { limit = 10, order = 'desc', cursor } = options; let effectBuilder = this.server .effects() .forAccount(publicKey) .order(order) .limit(limit); if (cursor) { effectBuilder = effectBuilder.cursor(cursor); } const result = await effectBuilder.call(); return result.records.map((effect) => ({ id: effect.id, type: effect.type, account: effect.account, createdAt: effect.created_at, operationId: effect.operation_id, details: effect })); } catch (error) { throw new XDBChainError(`Failed to get effects: ${error}`); } } async getEffectsForOperation(operationId, options = {}) { try { const { limit = 10, order = 'desc', cursor } = options; let effectBuilder = this.server .effects() .forOperation(operationId) .order(order) .limit(limit); if (cursor) { effectBuilder = effectBuilder.cursor(cursor); } const result = await effectBuilder.call(); return result.records.map((effect) => ({ id: effect.id, type: effect.type, account: effect.account, createdAt: effect.created_at, operationId: effect.operation_id, details: effect })); } catch (error) { throw new XDBChainError(`Failed to get effects for operation: ${error}`); } } async getTrades(publicKey, options = {}) { try { if (!this.isValidAddress(publicKey)) { throw new XDBValidationError('Invalid public key'); } const { limit = 10, order = 'desc', cursor } = options; let tradeBuilder = this.server .trades() .forAccount(publicKey) .order(order) .limit(limit); if (cursor) { tradeBuilder = tradeBuilder.cursor(cursor); } const result = await tradeBuilder.call(); return result.records.map((trade) => ({ id: trade.id, pagingToken: trade.paging_token, ledgerCloseTime: trade.ledger_close_time, offerIds: trade.offer_ids, baseAccount: trade.base_account, baseAmount: trade.base_amount, baseAssetType: trade.base_asset_type, baseAssetCode: trade.base_asset_code, baseAssetIssuer: trade.base_asset_issuer, counterAccount: trade.counter_account, counterAmount: trade.counter_amount, counterAssetType: trade.counter_asset_type, counterAssetCode: trade.counter_asset_code, counterAssetIssuer: trade.counter_asset_issuer, baseIsSeller: trade.base_is_seller, price: trade.price })); } catch (error) { throw new XDBChainError(`Failed to get trades: ${error}`); } } async getTradesForAssetPair(baseAsset, counterAsset, options = {}) { try { const { limit = 10, order = 'desc', cursor } = options; const base = this.createAsset(baseAsset); const counter = this.createAsset(counterAsset); let tradeBuilder = this.server .trades() .forAssetPair(base, counter) .order(order) .limit(limit); if (cursor) { tradeBuilder = tradeBuilder.cursor(cursor); } const result = await tradeBuilder.call(); return result.records.map((trade) => ({ id: trade.id, pagingToken: trade.paging_token, ledgerCloseTime: trade.ledger_close_time, offerIds: trade.offer_ids, baseAccount: trade.base_account, baseAmount: trade.base_amount, baseAssetType: trade.base_asset_type, baseAssetCode: trade.base_asset_code, baseAssetIssuer: trade.base_asset_issuer, counterAccount: trade.counter_account, counterAmount: trade.counter_amount, counterAssetType: trade.counter_asset_type, counterAssetCode: trade.counter_asset_code, counterAssetIssuer: trade.counter_asset_issuer, baseIsSeller: trade.base_is_seller, price: trade.price })); } catch (error) { throw new XDBChainError(`Failed to get trades for asset pair: ${error}`); } } async getOrderbook(selling, buying, limit = 10) { try { const sellingAsset = this.createAsset(selling); const buyingAsset = th