@ledgerhq/coin-ton
Version:
118 lines • 4.53 kB
JavaScript
;
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