UNPKG

@ledgerhq/coin-stellar

Version:
137 lines 5.64 kB
"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.envelopeFromAnyXDR = exports.createApi = void 0; const config_1 = __importDefault(require("../config")); const logic_1 = require("../logic"); const errors_1 = require("@ledgerhq/errors"); const logs_1 = require("@ledgerhq/logs"); const stellar_sdk_1 = require("@stellar/stellar-sdk"); function createApi(config) { config_1.default.setCoinConfig(() => ({ ...config, status: { type: "active" } })); return { broadcast: logic_1.broadcast, combine: compose, craftTransaction: craft, estimateFees: estimate, getBalance: logic_1.getBalance, lastBlock: logic_1.lastBlock, listOperations: operations, getBlock(_height) { throw new Error("getBlock is not supported"); }, getBlockInfo(_height) { throw new Error("getBlockInfo is not supported"); }, }; } exports.createApi = createApi; async function craft(transactionIntent, customFees) { const fees = customFees !== undefined ? customFees : await (0, logic_1.estimateFees)(); // NOTE: check how many memos, throw if more than one? // if (transactionIntent.memos && transactionIntent.memos.length > 1) { // throw new Error("Stellar only supports one memo per transaction."); // } const memo = "memo" in transactionIntent ? transactionIntent.memo : undefined; const hasMemoValue = memo && memo.type !== "NO_MEMO"; const tx = await (0, logic_1.craftTransaction)({ address: transactionIntent.sender }, { type: transactionIntent.type, recipient: transactionIntent.recipient, amount: transactionIntent.amount, fee: fees, ...(transactionIntent.asset.type === "token" ? { assetCode: transactionIntent.asset.assetCode, assetIssuer: transactionIntent.asset.assetIssuer, } : {}), memoType: memo?.type, ...(hasMemoValue ? { memoValue: memo.value } : {}), }); // Note: the API returns the signature base, not the full XDR, see BACK-8727 for more context return tx.signatureBase; } function compose(tx, signature, pubkey) { if (!pubkey) { throw new Error("Missing pubkey"); } // note: accept here `TransactionEnvelope` or `TransactionSignaturePayload`, see BACK-8727 for more context return (0, logic_1.combine)(envelopeFromAnyXDR(tx, "base64"), signature, pubkey); } async function estimate() { const value = await (0, logic_1.estimateFees)(); return { value }; } async function operations(address, { minHeight }) { return operationsFromHeight(address, minHeight); } async function operationsFromHeight(address, minHeight) { const state = { pageSize: 200, heightLimit: minHeight, continueIterations: true, accumulator: [], }; // unfortunately, the stellar API does not support an option to filter by min height // so the only strategy to get ALL operations is to iterate over all of them in descending order // until we reach the desired minHeight while (state.continueIterations) { const options = { limit: state.pageSize, order: "desc", minHeight }; if (state.apiNextCursor) { options.cursor = state.apiNextCursor; } try { const [operations, nextCursor] = await (0, logic_1.listOperations)(address, options); state.accumulator.push(...operations); state.apiNextCursor = nextCursor; state.continueIterations = nextCursor !== ""; } catch (e) { if (e instanceof errors_1.LedgerAPI4xx && e.status === 429) { (0, logs_1.log)("coin:stellar", "(api/operations): TooManyRequests, retrying in 4s"); await new Promise(resolve => setTimeout(resolve, 4000)); } else { throw e; } } } return [state.accumulator, state.apiNextCursor ? state.apiNextCursor : ""]; } /** * Deserialize a transaction envelope, also accepting transaction signature payload form. * * @param input serialized `TransactionEnvelope` or `TransactionSignaturePayload` * @param format serialization encoding */ function envelopeFromAnyXDR(input, format) { try { return stellar_sdk_1.xdr.TransactionEnvelope.fromXDR(input, format); } catch (envelopeError) { try { return signatureBaseToEnvelope(stellar_sdk_1.xdr.TransactionSignaturePayload.fromXDR(input, format)); } catch (signatureBaseError) { throw new Error(`Failed decoding transaction as an envelope (${envelopeError}) or as a signature base: (${signatureBaseError})`); } } } exports.envelopeFromAnyXDR = envelopeFromAnyXDR; /** * Convert a `TransactionSignaturePayload` into a `TransactionEnvelope`. * * @param signatureBase deserialized `TransactionSignaturePayload` */ function signatureBaseToEnvelope(signatureBase) { const tx = signatureBase.taggedTransaction().value(); if (tx instanceof stellar_sdk_1.xdr.Transaction) { return stellar_sdk_1.xdr.TransactionEnvelope.envelopeTypeTx(new stellar_sdk_1.xdr.TransactionV1Envelope({ tx, signatures: [] })); } else { return stellar_sdk_1.xdr.TransactionEnvelope.envelopeTypeTxFeeBump(new stellar_sdk_1.xdr.FeeBumpTransactionEnvelope({ tx, signatures: [] })); } } //# sourceMappingURL=index.js.map