UNPKG

@ton.js/core

Version:

TonWeb - JavaScript API for TON blockchain

197 lines 7.6 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.Contract = void 0; const cell_1 = require("../boc/cell"); const base64_1 = require("../utils/base64"); const common_1 = require("../utils/common"); const address_1 = require("../utils/address"); class Contract { constructor(provider, options = {}) { var _a; this.provider = provider; this.options = options; this.methods = {}; if (options.address) { this.address = new address_1.Address(options.address); } if (!options.wc) { options.wc = (((_a = this.address) === null || _a === void 0 ? void 0 : _a.wc) || 0); } } static createStateInit(code, data, library, splitDepth, ticktock) { // _ split_depth:(Maybe (## 5)) special:(Maybe TickTock) // code:(Maybe ^Cell) data:(Maybe ^Cell) // library:(Maybe ^Cell) = StateInit; if (library) { throw new Error('Library in state init is not implemented'); } if (splitDepth) { throw new Error('Split depth in state init is not implemented'); } if (ticktock) { throw new Error('Ticktock in state init is not implemented'); } const stateInit = new cell_1.Cell(); stateInit.bits.writeBitArray([ Boolean(splitDepth), Boolean(ticktock), Boolean(code), Boolean(data), Boolean(library), ]); if (code) { stateInit.refs.push(code); } if (data) { stateInit.refs.push(data); } if (library) { stateInit.refs.push(library); } return stateInit; } static createInternalMessageHeader(dest, nanograms = 0, ihrDisabled = true, bounce, bounced = false, src, currencyCollection, ihrFees = 0, fwdFees = 0, // @todo: do we really need BN for timestamps? createdLt = 0, createdAt = 0) { // extra_currencies$_ dict:(HashmapE 32 (VarUInteger 32)) // = ExtraCurrencyCollection; // currencies$_ grams:Grams other:ExtraCurrencyCollection // = CurrencyCollection; //int_msg_info$0 ihr_disabled:Bool bounce:Bool //src:MsgAddressInt dest:MsgAddressInt //value:CurrencyCollection ihr_fee:Grams fwd_fee:Grams //created_lt:uint64 created_at:uint32 = CommonMsgInfo; const destAddress = new address_1.Address(dest); const message = new cell_1.Cell(); message.bits.writeBit(false); message.bits.writeBit(ihrDisabled); message.bits.writeBit((bounce !== null && bounce !== void 0 ? bounce : destAddress.isBounceable)); message.bits.writeBit(bounced); message.bits.writeAddress(src ? new address_1.Address(src) : undefined); message.bits.writeAddress(destAddress); message.bits.writeGrams(nanograms); if (currencyCollection) { throw new Error('Currency collections are not implemented yet'); } message.bits.writeBit(Boolean(currencyCollection)); message.bits.writeGrams(ihrFees); message.bits.writeGrams(fwdFees); message.bits.writeUint(createdLt, 64); message.bits.writeUint(createdAt, 32); return message; } static createExternalMessageHeader(dest, src, importFee = 0) { //ext_in_msg_info$10 src:MsgAddressExt dest:MsgAddressInt //import_fee:Grams = CommonMsgInfo; const message = new cell_1.Cell(); message.bits.writeUint(2, 2); message.bits.writeAddress(src ? new address_1.Address(src) : undefined); message.bits.writeAddress(new address_1.Address(dest)); message.bits.writeGrams(importFee); return message; } /** * Creates CommonMsgInfo cell that contains specified * header, stateInit and body. */ static createCommonMsgInfo(header, stateInit, body) { // tblkch.pdf, page 57 const commonMsgInfo = new cell_1.Cell(); commonMsgInfo.writeCell(header); if (stateInit) { commonMsgInfo.bits.writeBit(true); // -1: need at least one bit for body // @todo: we also should check for free refs here if (commonMsgInfo.bits.getFreeBits() - 1 >= stateInit.bits.getUsedBits()) { commonMsgInfo.bits.writeBit(false); commonMsgInfo.writeCell(stateInit); } else { commonMsgInfo.bits.writeBit(true); commonMsgInfo.refs.push(stateInit); } } else { commonMsgInfo.bits.writeBit(false); } // @todo: we also should check for free refs here if (body) { if (commonMsgInfo.bits.getFreeBits() >= body.bits.getUsedBits()) { commonMsgInfo.bits.writeBit(false); commonMsgInfo.writeCell(body); } else { commonMsgInfo.bits.writeBit(true); commonMsgInfo.refs.push(body); } } else { commonMsgInfo.bits.writeBit(false); } return commonMsgInfo; } static createMethod(provider, queryPromise) { return { getQuery: async () => { return (await queryPromise).message; }, send: async () => { const query = await queryPromise; const boc = (0, base64_1.bytesToBase64)(await query.message.toBoc(false)); return provider.sendBoc(boc); }, estimateFee: async () => { const query = await queryPromise; const serialized = (query.code ? // deploy { address: query.address.toString(true, true, false), body: (0, base64_1.bytesToBase64)(await query.body.toBoc(false)), init_code: (0, base64_1.bytesToBase64)(await query.code.toBoc(false)), init_data: (0, base64_1.bytesToBase64)(await query.data.toBoc(false)), } : { address: query.address.toString(true, true, true), body: (0, base64_1.bytesToBase64)(await query.body.toBoc(false)), }); return provider.getEstimateFee(serialized); } }; } async getAddress() { if (!this.address) { this.address = (await this.createStateInit()).address; } return this.address; } async createStateInit() { const code = this.createCodeCell(); const data = this.createDataCell(); const stateInit = Contract.createStateInit(code, data); const stateInitHash = await stateInit.hash(); const address = new address_1.Address(this.options.wc + ':' + (0, common_1.bytesToHex)(stateInitHash)); return { stateInit, address, code, data, }; } /** * Return cell that contains contract data. */ createDataCell() { // Should be overridden by child classes return new cell_1.Cell(); } /** * Returns cell that contains contact code. */ createCodeCell() { if (!this.options.code) { throw new Error(`Can't create code cell, code option ` + `must be specified when creating a contract`); } return this.options.code; } } exports.Contract = Contract; //# sourceMappingURL=contract.js.map