UNPKG

@ledgerhq/coin-algorand

Version:
91 lines (76 loc) 2.62 kB
import { encode as msgpackEncode } from "algo-msgpack-with-bigint"; import type { EncodedSignedTransaction as AlgoSignedTransactionPayload, Transaction as AlgoTransaction, EncodedTransaction as AlgoTransactionPayload, } from "algosdk"; import { makeAssetTransferTxnWithSuggestedParams, makePaymentTxnWithSuggestedParams, } from "algosdk"; import algorandAPI from "./api"; import { extractTokenId } from "./tokens"; import type { AlgorandAccount, Transaction } from "./types"; export const buildTransactionPayload = async ( account: AlgorandAccount, transaction: Transaction, ): Promise<AlgoTransactionPayload> => { const { amount, recipient, mode, memo, assetId, subAccountId } = transaction; const subAccount = subAccountId ? account.subAccounts && account.subAccounts.find(t => t.id === subAccountId) : null; const note = memo ? new TextEncoder().encode(memo) : undefined; const params = await algorandAPI.getTransactionParams(); let algoTxn: AlgoTransaction; if (subAccount || (assetId && mode === "optIn")) { const targetAssetId = subAccount && subAccount.type === "TokenAccount" ? extractTokenId(subAccount.token.id) : assetId ? extractTokenId(assetId) : ""; if (!targetAssetId) { throw new Error("Token Asset Id not found"); } algoTxn = makeAssetTransferTxnWithSuggestedParams( account.freshAddress, recipient, undefined, undefined, amount.toNumber(), note, Number(targetAssetId), params, undefined, ); } else { algoTxn = makePaymentTxnWithSuggestedParams( account.freshAddress, recipient, amount.toNumber(), undefined, note, params, ); } // Bit of safety: set tx validity to the next 1000 blocks algoTxn.firstRound = params.lastRound; algoTxn.lastRound = params.lastRound + 1000; // Flaw in the SDK: payload isn't sorted, but it needs to be for msgPack encoding const sorted = Object.fromEntries( Object.entries(algoTxn.get_obj_for_encoding()).sort(), ) as AlgoTransactionPayload; return sorted; }; export const encodeToSign = (payload: AlgoTransactionPayload): string => { const msgPackEncoded = msgpackEncode(payload); return Buffer.from(msgPackEncoded).toString("hex"); }; export const encodeToBroadcast = (payload: AlgoTransactionPayload, signature: Buffer): Buffer => { const signedPayload: AlgoSignedTransactionPayload = { sig: signature, txn: payload, }; const msgPackEncoded = msgpackEncode(signedPayload); return Buffer.from(msgPackEncoded); };