UNPKG

@ton.js/core

Version:

TonWeb - JavaScript API for TON blockchain

174 lines 6.81 kB
"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.WalletContract = void 0; const bn_js_1 = __importDefault(require("bn.js")); const tweetnacl_1 = __importDefault(require("tweetnacl")); const contract_1 = require("../contract"); const cell_1 = require("../../boc/cell"); const address_1 = require("../../utils/address"); /** * Abstract standard wallet class. */ class WalletContract extends contract_1.Contract { constructor(provider, options) { if (!options.publicKey && !options.address) { throw new Error(`Missing "publicKey" or "address" options`); } super(provider, options); this.methods = { transfer: (params) => contract_1.Contract.createMethod(provider, this.createTransferMessage(params.secretKey, params.toAddress, params.amount, params.seqno, params.payload, params.sendMode, !Boolean(params.secretKey), params.stateInit)), seqno: () => ({ // @todo: we do we have sub-method here? // should we rename `seqno` to `getSeqno` // and return the result directly? call: async () => { const address = await this.getAddress(); let seqno; try { seqno = (await provider.call2(address.toString(), 'seqno')).toNumber(); } catch (error) { // Ignoring the error // @todo: it doesn't look like a // good idea to silently ignore // the errors } return seqno; } }) }; } /** * Returns name of the contract. */ getName() { // This method should be implemented in the subclasses throw new Error('Not implemented'); } /** * Creates external message for contract initialization. */ async createInitExternalMessage(secretKey) { // @todo: we should return ExternalMessage instead of Query // but we will need to add `signature` to the result if (!this.options.publicKey) { const keyPair = tweetnacl_1.default.sign.keyPair.fromSecretKey(secretKey); this.options.publicKey = keyPair.publicKey; } const { stateInit, address, code, data, } = await this.createStateInit(); const signingMessage = this.createSigningMessage(); const signature = tweetnacl_1.default.sign.detached(await signingMessage.hash(), secretKey); const body = new cell_1.Cell(); body.bits.writeBytes(signature); body.writeCell(signingMessage); const header = contract_1.Contract.createExternalMessageHeader(address); const externalMessage = contract_1.Contract.createCommonMsgInfo(header, stateInit, body); return { address, message: externalMessage, body, signingMessage, stateInit, code, data, }; } async createTransferMessage( /** * `nacl.KeyPair.secretKey` * @todo: improve the description */ secretKey, address, nanograms, seqno, payload, sendMode = 3, dummySignature = false, stateInit) { const payloadCell = this.serializePayload(payload); const orderHeader = contract_1.Contract.createInternalMessageHeader(new address_1.Address(address), new bn_js_1.default(nanograms)); const order = contract_1.Contract.createCommonMsgInfo(orderHeader, stateInit, payloadCell); const signingMessage = this.createSigningMessage(seqno); signingMessage.bits.writeUint8(sendMode); signingMessage.refs.push(order); return this.createExternalMessage(signingMessage, secretKey, seqno, dummySignature); } deploy(secretKey) { return contract_1.Contract.createMethod(this.provider, this.createInitExternalMessage(secretKey)); } /** * Returns cell that contains wallet data. */ createDataCell() { // 4 byte seqno, 32 byte publicKey const cell = new cell_1.Cell(); cell.bits.writeUint(0, 32); // seqno cell.bits.writeBytes(this.options.publicKey); return cell; } createSigningMessage(seqno) { seqno = (seqno || 0); const cell = new cell_1.Cell(); cell.bits.writeUint(seqno, 32); return cell; } async createExternalMessage(signingMessage, /** * `nacl.KeyPair.secretKey` * @todo: improve the description */ secretKey, seqno, dummySignature = false) { const signature = (dummySignature ? new Uint8Array(64) : tweetnacl_1.default.sign.detached(await signingMessage.hash(), secretKey)); const body = new cell_1.Cell(); body.bits.writeBytes(signature); body.writeCell(signingMessage); let stateInit; let code; let data; if (seqno === 0) { if (!this.options.publicKey) { const keyPair = (tweetnacl_1.default.sign.keyPair .fromSecretKey(secretKey)); this.options.publicKey = keyPair.publicKey; } const deploy = await this.createStateInit(); stateInit = deploy.stateInit; code = deploy.code; data = deploy.data; } const selfAddress = await this.getAddress(); const header = contract_1.Contract.createExternalMessageHeader(selfAddress); const resultMessage = contract_1.Contract.createCommonMsgInfo(header, stateInit, body); return { address: selfAddress, signature, // old wallet_send_generate_external_message message: resultMessage, body, signingMessage, stateInit, code, data, }; } serializePayload(payload) { if (!payload) { return new cell_1.Cell(); } if (payload instanceof cell_1.Cell) { return payload; } let payloadCell = new cell_1.Cell(); // @todo: throw more meaningful error // on cell bytes overflow if (typeof payload === 'string') { payloadCell.bits.writeUint(0, 32); payloadCell.bits.writeString(payload); } else { payloadCell.bits.writeBytes(payload); } return payloadCell; } } exports.WalletContract = WalletContract; //# sourceMappingURL=wallet-contract.js.map