UNPKG

@ledgerhq/coin-ton

Version:
118 lines 4.53 kB
"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.buildOptimisticOperation = exports.buildSignOperation = void 0; const index_1 = require("@ledgerhq/coin-framework/account/index"); const core_1 = require("@ton/core"); const ton_1 = require("@ton/ton"); const bignumber_js_1 = __importDefault(require("bignumber.js")); const rxjs_1 = require("rxjs"); const api_1 = require("./bridge/bridgeHelpers/api"); const constants_1 = require("./constants"); const utils_1 = require("./utils"); const packTransaction = (account, needsInit, signature) => { const { address } = core_1.Address.parseFriendly(account.freshAddress); let init = null; if (needsInit) { if (account.xpub?.length !== 64) throw Error("[ton] xpub can't be found"); const wallet = ton_1.WalletContractV4.create({ workchain: 0, publicKey: Buffer.from(account.xpub, "hex"), }); init = wallet.init; } const ext = (0, core_1.external)({ to: address, init, body: signature }); return (0, core_1.beginCell)().store((0, core_1.storeMessage)(ext)).endCell().toBoc().toString("base64"); }; /** * Sign Transaction with Ledger hardware */ const buildSignOperation = (signerContext) => ({ account, transaction, deviceId, }) => new rxjs_1.Observable(o => { let cancelled = false; async function main() { const address = account.freshAddress; const accountInfo = await (0, api_1.fetchAccountInfo)(address); const tonTx = (0, utils_1.buildTonTransaction)(transaction, accountInfo.seqno, account); const ledgerPath = (0, utils_1.getLedgerTonPath)(account.freshAddressPath); o.next({ type: "device-signature-requested" }); const sig = await signerContext(deviceId, signer => signer.signTransaction(ledgerPath, tonTx)); if (cancelled) return; o.next({ type: "device-signature-granted" }); if (!sig) { throw new Error("No signature"); } const signature = packTransaction(account, accountInfo.status === "uninit", sig); const operation = (0, exports.buildOptimisticOperation)(account, transaction); o.next({ type: "signed", signedOperation: { operation, signature, }, }); } main().then(() => o.complete(), e => o.error(e)); return () => { cancelled = true; }; }); exports.buildSignOperation = buildSignOperation; const buildOptimisticOperation = (account, transaction) => { const { recipient, amount, fees, comment, useAllAmount, subAccountId } = transaction; const { id: accountId } = account; const subAccount = (0, index_1.findSubAccountById)(account, subAccountId ?? ""); const tokenTransfer = Boolean(subAccount && (0, index_1.isTokenAccount)(subAccount)); const value = tokenTransfer ? (0, bignumber_js_1.default)((0, core_1.toNano)(constants_1.TOKEN_TRANSFER_MAX_FEE).toString()) : amount.plus(fees); const op = { id: "", hash: "", type: "OUT", senders: [account.freshAddress], recipients: [recipient], accountId, value, fee: fees, blockHash: null, blockHeight: null, date: new Date(), extra: { // we don't know yet, will be patched in final operation lt: "", explorerHash: "", comment, }, }; if (tokenTransfer && subAccount) { op.subOperations = [ { id: "", hash: "", type: "OUT", value: useAllAmount ? subAccount.balance : amount, fee: fees, blockHash: null, blockHeight: null, senders: [account.freshAddress], recipients: [recipient], accountId: subAccount.id, date: new Date(), extra: { lt: "", explorerHash: "", comment, }, contract: subAccount.token.contractAddress, }, ]; } return op; }; exports.buildOptimisticOperation = buildOptimisticOperation; exports.default = exports.buildSignOperation; //# sourceMappingURL=signOperation.js.map