@ton.js/core
Version:
TonWeb - JavaScript API for TON blockchain
197 lines • 7.6 kB
JavaScript
;
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