UNPKG

ts-xdbchain-sdk

Version:

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

1,574 lines 64 kB
import { Horizon, Keypair, Asset, TransactionBuilder, Operation, Memo, Claimant, StrKey } from 'stellar-sdk';
export class XDBChainError extends Error {
    constructor(message, code, details) {
        super(message);
        this.code = code;
        this.details = details;
        this.name = 'XDBChainError';
    }
}
export class XDBNetworkError extends XDBChainError {
    constructor(message, details) {
        super(message, 'NETWORK_ERROR', details);
        this.name = 'XDBNetworkError';
    }
}
export class XDBValidationError extends XDBChainError {
    constructor(message, details) {
        super(message, 'VALIDATION_ERROR', details);
        this.name = 'XDBValidationError';
    }
}
export class XDBTransactionError extends XDBChainError {
    constructor(message, details) {
        super(message, 'TRANSACTION_ERROR', details);
        this.name = 'XDBTransactionError';
    }
}
export class XDBAssetError extends XDBChainError {
    constructor(message, details) {
        super(message, 'ASSET_ERROR', details);
        this.name = 'XDBAssetError';
    }
}
export class XDBOfferError extends XDBChainError {
    constructor(message, details) {
        super(message, 'OFFER_ERROR', details);
        this.name = 'XDBOfferError';
    }
}
export const ACCOUNT_FLAGS = {
    AUTH_REQUIRED_FLAG: 0x1,
    AUTH_REVOCABLE_FLAG: 0x2,
    AUTH_IMMUTABLE_FLAG: 0x4,
    AUTH_CLAWBACK_ENABLED_FLAG: 0x8
};
export const ASSET_TYPE = {
    NATIVE: 'native',
    CREDIT_ALPHANUM4: 'credit_alphanum4',
    CREDIT_ALPHANUM12: 'credit_alphanum12'
};
export const 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'
};
export class XDBChainSDK {
    constructor(config) {
        this.config = {
            ...XDBChainSDK.DEFAULT_CONFIGS[config.network],
            ...config
        };
        this.server = new Horizon.Server(this.config.horizonUrl, {
            allowHttp: this.config.allowHttp
        });
        this.networkPassphrase = this.config.networkPassphrase;
    }
    async createWallet() {
        try {
            const keypair = 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 = 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 = 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 StrKey.isValidEd25519PublicKey(address);
        }
        catch {
            return false;
        }
    }
    isValidSecretKey(secretKey) {
        try {
            return StrKey.isValidEd25519SecretSeed(secretKey);
        }
        catch {
            return false;
        }
    }
    generateKeypair() {
        return Keypair.random();
    }
    keypairFromSecret(secretKey) {
        return Keypair.fromSecret(secretKey);
    }
    keypairFromPublicKey(publicKey) {
        return 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 = Keypair.fromSecret(source);
            const sourceAccount = await this.server.loadAccount(sourceKeypair.publicKey());
            const transaction = new TransactionBuilder(sourceAccount, {
                fee: (await this.server.fetchBaseFee()).toString(),
                networkPassphrase: this.networkPassphrase
            })
                .addOperation(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 = 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 TransactionBuilder(account, {
                fee: (await this.server.fetchBaseFee()).toString(),
                networkPassphrase: this.networkPassphrase
            })
                .addOperation(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 = Keypair.fromSecret(sourceSecret);
            const sourceAccount = await this.server.loadAccount(sourceKeypair.publicKey());
            const transaction = new TransactionBuilder(sourceAccount, {
                fee: (await this.server.fetchBaseFee()).toString(),
                networkPassphrase: this.networkPassphrase
            })
                .addOperation(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 = Keypair.fromSecret(secretKey);
            const account = await this.server.loadAccount(keypair.publicKey());
            const transaction = new TransactionBuilder(account, {
                fee: (await this.server.fetchBaseFee()).toString(),
                networkPassphrase: this.networkPassphrase
            })
                .addOperation(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 = Keypair.fromSecret(senderSecret);
            const senderAccount = await this.server.loadAccount(senderKeypair.publicKey());
            const asset = this.createAsset(options.asset);
            const transactionBuilder = new TransactionBuilder(senderAccount, {
                fee: (await this.server.fetchBaseFee()).toString(),
                networkPassphrase: this.networkPassphrase
            });
            transactionBuilder.addOperation(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 = 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 TransactionBuilder(senderAccount, {
                fee: (await this.server.fetchBaseFee()).toString(),
                networkPassphrase: this.networkPassphrase
            });
            transactionBuilder.addOperation(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 = 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 TransactionBuilder(senderAccount, {
                fee: (await this.server.fetchBaseFee()).toString(),
                networkPassphrase: this.networkPassphrase
            });
            transactionBuilder.addOperation(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 = Keypair.fromSecret(senderSecret);
            const senderAccount = await this.server.loadAccount(senderKeypair.publicKey());
            const transactionBuilder = new 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(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 = Keypair.fromSecret(walletSecret);
            const account = await this.server.loadAccount(keypair.publicKey());
            const asset = new Asset(options.assetCode, options.assetIssuer);
            const transaction = new TransactionBuilder(account, {
                fee: (await this.server.fetchBaseFee()).toString(),
                networkPassphrase: this.networkPassphrase
            })
                .addOperation(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 = Keypair.fromSecret(trustorSecret);
            const trustorAccount = await this.server.loadAccount(trustorKeypair.publicKey());
            const transaction = new TransactionBuilder(trustorAccount, {
                fee: (await this.server.fetchBaseFee()).toString(),
                networkPassphrase: this.networkPassphrase
            })
                .addOperation(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 = Asset.native();
            nativeAsset.code = 'XDB';
            return nativeAsset;
        }
        if (!issuer) {
            throw new XDBAssetError('Asset issuer is required for non-native assets');
        }
        return new 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 = Keypair.fromSecret(issuerSecret);
            const issuerAccount = await this.server.loadAccount(issuerKeypair.publicKey());
            const asset = new Asset(assetCode, issuerKeypair.publicKey());
            const transaction = new TransactionBuilder(issuerAccount, {
                fee: (await this.server.fetchBaseFee()).toString(),
                networkPassphrase: this.networkPassphrase
            })
                .addOperation(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 = 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 TransactionBuilder(account, {
                fee: (await this.server.fetchBaseFee()).toString(),
                networkPassphrase: this.networkPassphrase
            })
                .addOperation(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 = 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 TransactionBuilder(account, {
                fee: (await this.server.fetchBaseFee()).toString(),
                networkPassphrase: this.networkPassphrase
            })
                .addOperation(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 = 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 TransactionBuilder(account, {
                fee: (await this.server.fetchBaseFee()).toString(),
                networkPassphrase: this.networkPassphrase
            })
                .addOperation(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 = Keypair.fromSecret(secretKey);
            const account = await this.server.loadAccount(keypair.publicKey());
            const sellingAsset = this.createAsset(selling);
            const buyingAsset = this.createAsset(buying);
            const transaction = new TransactionBuilder(account, {
                fee: (await this.server.fetchBaseFee()).toString(),
                networkPassphrase: this.networkPassphrase
            })
                .addOperation(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 = Keypair.fromSecret(secretKey);
            const account = await this.server.loadAccount(keypair.publicKey());
            const transaction = new TransactionBuilder(account, {
                fee: (await this.server.fetchBaseFee()).toString(),
                networkPassphrase: this.networkPassphrase
            })
                .addOperation(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 = this.createAsset(buying);
            const result = await this.server
                .orderbook(sellingAsset, buyingAsset)
                .limit(limit)
                .call();
            return {
                bids: result.bids.map((bid) => ({
                    price: bid.price,
                    amount: bid.amount
                })),
                asks: result.asks.map((ask) => ({
                    price: ask.price,
                    amount: ask.amount
                })),
                base: selling,
                counter: buying
            };
        }
        catch (error) {
            throw new XDBChainError(`Failed to get orderbook: ${error}`);
        }
    }
    async getOffers(publicKey, options = {}) {
        try {
            if (!this.isValidAddress(publicKey)) {
                throw new XDBValidationError('Invalid public key');
            }
            const { limit = 10, order = 'desc', cursor } = options;
            let offerBuilder = this.server
                .offers()
                .forAccount(publicKey)
                .order(order)
                .limit(limit);
            if (cursor) {
                offerBuilder = offerBuilder.cursor(cursor);
            }
            const result = await offerBuilder.call();
            return result.records.map((offer) => ({
                id: offer.id,
                pagingToken: offer.paging_token,
                seller: offer.seller,
                selling: {
                    code: offer.selling.asset_code || 'XDB',
                    issuer: offer.selling.asset_issuer,
                    type: offer.selling.asset_type
                },
                buying: {
                    code: offer.buying.asset_code || 'XDB',
                    issuer: offer.buying.asset_issuer,
                    type: offer.buying.asset_type
                },
                amount: offer.amount,
                price: offer.price,
                lastModifiedLedger: offer.last_modified_ledger,
                lastModifiedTime: offer.last_modified_time
            }));
        }
        catch (error) {
            throw new XDBChainError(`Failed to get offers: ${error}`);
        }
    }
    async getLedger(sequence) {
        try {
            const result = await this.server.ledgers().ledger(sequence).call();
            return {
                id: result.id,
                pagingToken: result.paging_token,
                hash: result.hash,
                sequence: result.sequence,
                transactionCount: result.successful_transaction_count || result.transaction_count || 0,
                operationCount: result.operation_count,
                closedAt: result.closed_at,
                totalCoins: result.total_coins,
                feePool: result.fee_pool,
                baseFee: result.base_fee_in_stroops || result.base_fee || 100,
                baseReserve: result.base_reserve_in_stroops || result.base_reserve || '0',
                maxTxSetSize: result.max_tx_set_size,
                protocolVersion: result.protocol_version,
                headerXdr: result.header_xdr
            };
        }
        catch (error) {
            throw new XDBChainError(`Failed to get ledger: ${error}`);
        }
    }
    async getLedgers(options = {}) {
        try {
            const { limit = 10, order = 'desc', cursor } = options;
            let ledgerBuilder = this.server
                .ledgers()
                .order(order)
                .limit(limit);
            if (cursor) {
                ledgerBuilder = ledgerBuilder.cursor(cursor);
            }
            const result = await ledgerBuilder.call();
            return result.records.map((ledger) => ({
                id: ledger.id,
                pagingToken: ledger.paging_token,
                hash: ledger.hash,
                sequence: ledger.sequence,
                transactionCount: ledger.successful_transaction_count || 0,
                operationCount: ledger.operation_count,
                closedAt: ledger.closed_at,
                totalCoins: ledger.total_coins,
                feePool: ledger.fee_pool,
                baseFee: ledger.base_fee_in_stroops,
                baseReserve: ledger.base_reserve_in_stroops,
                maxTxSetSize: ledger.max_tx_set_size,
                protocolVersion: ledger.protocol_version,
                headerXdr: ledger.header_xdr
            }));
        }
        catch (error) {
            throw new XDBChainError(`Failed to get ledgers: ${error}`);
        }
    }
    async createClaimableBalance(senderSecret, claimantPublicKey, amount, asset) {
        try {
            if (!this.isValidSecretKey(senderSecret)) {
                throw new XDBValidationError('Invalid sender secret key');
            }
            if (!this.isValidAddress(claimantPublicKey)) {
                throw new XDBValidationError('Invalid claimant public key');
            }
            const senderKeypair = Keypair.fromSecret(senderSecret);
            const senderAccount = await this.server.loadAccount(senderKeypair.publicKey());
            const assetObj = this.createAsset(asset);
            const claimant = new Claimant(claimantPublicKey);
            const transaction = new TransactionBuilder(senderAccount, {
                fee: (await this.server.fetchBaseFee()).toString(),
                networkPassphrase: this.networkPassphrase
            })
                .addOperation(Operation.createClaimableBalance({
                asset: assetObj,
                amount: amount,
                claimants: [claimant]
            }))
                .setTimeout(this.config.timeout)
                .build();
            transaction.sign(senderKeypair);
            const result = await this.server.submitTransaction(transaction);
            console.log('✅ Claimable balance created successfully:', result.hash);
            return result;
        }
        catch (error) {
            throw new XDBTransactionError(`Failed to create claimable balance: ${error}`);
        }
    }
    async claimBalance(claimantSecret, balanceId) {
        try {
            if (!this.isValidSecretKey(claimantSecret)) {
                throw new XDBValidationError('Invalid claimant secret key');
            }
            const claimantKeypair = Keypair.fromSecret(claimantSecret);
            const claimantAccount = await this.server.loadAccount(claimantKeypair.publicKey());
            const transaction = new TransactionBuilder(claimantAccount, {
                fee: (await this.server.fetchBaseFee()).toString(),
                networkPassphrase: this.networkPassphrase
            })
                .addOperation(Operation.claimClaimableBalance({
                balanceId: balanceId
            }))
                .setTimeout(this.config.timeout)
                .build();
            transaction.sign(claimantKeypair);
            const result = await this.server.submitTransaction(transaction);
            console.log('✅ Balance claimed successfully:', result.hash);
            return result;
        }
        catch (error) {
            throw new XDBTransactionError(`Failed to claim balance: ${error}`);
        }
    }
    async getClaimableBalances(publicKey) {
        try {
            if (!this.isValidAddress(publicKey)) {
                throw new XDBValidationError('Invalid public key');
            }
            const result = await this.server.claimableBalances().claimant(publicKey).call();
            return result.records.map((cb) => ({
                id: cb.id,
                assetCode: cb.asset === 'native' ? 'XDB' : cb.asset.split(':')[0],
                assetIssuer: cb.asset === 'native' ? null : cb.asset.split(':')[1],
                amount: cb.amount,
                claimants: cb.claimants.map((claimant) => ({
                    destination: claimant.destination,
                    predicate: claimant.predicate
                })),
                sponsor: cb.sponsor,
                flags: cb.flags,
                lastModifiedLedger: cb.last_modified_ledger,
                lastModifiedTime: cb.last_modified_time
            }));
        }
        catch (error) {
            throw new XDBChainError(`Failed to get claimable balances: ${error}`);
        }
    }
    async getNetworkInfo() {
        try {
            const response = await this.server.ledgers().order('desc').limit(1).call();
            return response;
        }
        catch (error) {
            throw new XDBNetworkError(`Failed to get network info: ${error}`);
        }
    }
    async getBaseFee() {
        try {
            return await this.server.fetchBaseFee();
        }
        catch (error) {
            throw new XDBNetworkError(`Failed to get base fee: ${error}`);
        }
    }
    async getFeeStats() {
        try {
            return await this.server.feeStats();
        }
        catch (error) {
            throw new XDBNetworkError(`Failed to get fee stats: ${error}`);
        }
    }
    async fundTestnetAccount(publicKey) {
        try {
            if (!this.isValidAddress(publicKey)) {
                throw new XDBValidationError('Invalid public key');
            }
            const response = await fetch(`https://friendbot.futurenet.xdbchain.com?addr=${encodeURIComponent(publicKey)}`);
            if (response.ok) {
                console.log('✅ Futurenet account funded successfully');
                return true;
            }
            else {
                throw new Error(`Funding failed with status: ${response.status}`);
            }
        }
        catch (error) {
            throw new XDBNetworkError(`Failed to fund testnet account: ${error}`);
        }
    }
    async estimateFee(operationCount = 1) {
        try {
            const baseFee = await this.getBaseFee();
            return baseFee * operationCount;
        }
        catch (error) {
            throw new XDBNetworkError(`Failed to estimate fee: ${error}`);
        }
    }
    async getPaymentPaths(sourcePublicKey, destination, amount) {
        try {
            const destinationAsset = this.createAsset(destination);
            return await this.server
                .strictReceivePaths(sourcePublicKey, destinationAsset, amount)
                .call();
        }
        catch (error) {
            throw new XDBChainError(`Failed to get payment paths: ${error}`);
        }
    }
    async getStrictReceivePaths(sourceAccount, destination, amount) {
        try {
            const destinationAsset = this.createAsset(destination);
            return await this.server
                .strictReceivePaths(sourceAccount, destinationAsset, amount)
                .call();
        }
        catch (error) {
            throw new XDBChainError(`Failed to get strict receive paths: ${error}`);
        }
    }
    async getStrictSendPaths(sourceAsset, destinationAssets, amount) {
        try {
            const source = this.createAsset(sourceAsset);
            const destinations = destinationAssets.map(asset => this.createAsset(asset));
            return await this.server
                .strictSendPaths(source, amount, destinations)
                .call();
        }
        catch (error) {
            throw new XDBChainError(`Failed to get strict send paths: ${error}`);
        }
    }
    signTransaction(transaction, signers) {
        try {
            for (const signer of signers) {
                transaction.sign(signer);
            }
            return transaction;
        }
        catch (error) {
            throw new XDBTransactionError(`Failed to sign transaction: ${error}`);
        }
    }
    async createMultiSigTransaction(sourceAccount, operations, signers) {
        try {
            const transactionBuilder = new TransactionBuilder(sourceAccount, {
                fee: (await this.server.fetchBaseFee()).toString(),
                networkPassphrase: this.networkPassphrase
            });
            for (const operation of operations) {
                transactionBuilder.addOperation(operation);
            }
            const transaction = transactionBuilder.setTimeout(this.config.timeout).build();
            return this.signTransaction(transaction, signers);
        }
        catch (error) {
            throw new XDBTransactionError(`Failed to create multi-sig transaction: ${error}`);
        }
    }
    createAsset(asset) {
        if (!asset || asset.code === 'XDB' || asset.code === 'native') {
            return Asset.native();
        }
        if (!asset.issuer) {
            throw new XDBValidationError('Asset issuer is required for non-native assets');
        }
        return new Asset(asset.code, asset.issuer);
    }
    createMemo(memo, memoType = 'text') {
        switch (memoType) {
            case 'text':
                return Memo.text(memo);
            case 'id':
                return Memo.id(memo);
            case 'hash':
                return Memo.hash(memo);
            case 'return':
                return Memo.return(memo);
            default:
                return Memo.text(memo);
        }
    }
    getServer() {
        return this.server;
    }
    getNetworkPassphrase() {
        return this.networkPassphrase;
    }
    getConfig() {
        return { ...this.config };
    }
    async submitTransaction(transaction) {
        try {
            return await this.server.submitTransaction(transaction);
        }
        catch (error) {
            throw new XDBTransactionError(`Failed to submit transaction: ${error}`);
        }
    }
    fromXDR(xdr) {
        try {
            return TransactionBuilder.fromXDR(xdr, this.networkPassphrase);
        }
        catch (error) {
            throw new XDBValidationError(`Failed to parse XDR: ${error}`);
        }
    }
}
XDBChainSDK.DEFAULT_CONFIGS = {
    mainnet: {
        network: 'mainnet',
        horizonUrl: 'https://horizon.livenet.xdbchain.com/',
        networkPassphrase: 'LiveNet Global XDBChain Network ; November 2023',
        startingBalance: '30',
        timeout: 30000,
        allowHttp: false
    },
    futurenet: {
        network: 'futurenet',
        horizonUrl: 'https://horizon.futurenet.xdbchain.com/',
        networkPassphrase: 'Future XDBChain Network ; November 2023',
        startingBalance: '30',
        timeout: 30000,
        allowHttp: false
    }
};
export function createXDBChainSDK(config) {
    return new XDBChainSDK(config);
}
export function createMainnetSDK() {
    return new XDBChainSDK({ network: 'mainnet' });
}
export function createFuturenetSDK() {
    return new XDBChainSDK({ network: 'futurenet' });
}
export function xdbToStroops(amount) {
    return (parseFloat(amount.toString()) * 10000000).toFixed(0);
}
export function stroopsToXdb(stroops) {
    return (parseFloat(stroops.toString()) / 10000000).toFixed(7);
}
export function isValidAmount(amount) {
    const num = parseFloat(amount);
    return !isNaN(num) && num > 0 && num <= 922337203685.4775807;
}
export function formatAmount(amount, decimals = 7) {
    const num = parseFloat(amount);
    return num.toFixed(decimals);
}
export function generateNonce() {
    return Math.random().toString(36).substring(2, 15);
}
export function isValidMemo(memo, type = 'text') {
    if (type === 'text') {
        return memo.length <= 28;
    }
    return true;
}
export function calculateFee(operationCount, baseFee) {
    return operationCount * baseFee;
}
export async function accountExists(server, publicKey) {
    try {
        await server.loadAccount(publicKey);
        return true;
    }
    catch {
        return false;
    }
}
export default XDBChainSDK;
//# sourceMappingURL=index.js.map