UNPKG

@ton/ton

Version:

[![Version npm](https://img.shields.io/npm/v/ton.svg?logo=npm)](https://www.npmjs.com/package/ton)

105 lines (104 loc) 4.14 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.computeStorageFees = computeStorageFees; exports.computeFwdFees = computeFwdFees; exports.computeGasPrices = computeGasPrices; exports.computeExternalMessageFees = computeExternalMessageFees; exports.computeMessageForwardFees = computeMessageForwardFees; const core_1 = require("@ton/core"); // // Source: https://github.com/ton-foundation/ton/blob/ae5c0720143e231c32c3d2034cfe4e533a16d969/crypto/block/transaction.cpp#L425 // function computeStorageFees(data) { const { lastPaid, now, storagePrices, storageStat, special, masterchain } = data; if (now <= lastPaid || storagePrices.length === 0 || now < storagePrices[0].utime_since || special) { return BigInt(0); } let upto = Math.max(lastPaid, storagePrices[0].utime_since); let total = BigInt(0); for (let i = 0; i < storagePrices.length && upto < now; i++) { let valid_until = (i < storagePrices.length - 1 ? Math.min(now, storagePrices[i + 1].utime_since) : now); let payment = BigInt(0); if (upto < valid_until) { let delta = valid_until - upto; payment += (BigInt(storageStat.cells) * (masterchain ? storagePrices[i].mc_cell_price_ps : storagePrices[i].cell_price_ps)); payment += (BigInt(storageStat.bits) * (masterchain ? storagePrices[i].mc_bit_price_ps : storagePrices[i].bit_price_ps)); payment = payment * BigInt(delta); } upto = valid_until; total += payment; } return shr16ceil(total); } // // Source: https://github.com/ton-foundation/ton/blob/ae5c0720143e231c32c3d2034cfe4e533a16d969/crypto/block/transaction.cpp#L1218 // function computeFwdFees(msgPrices, cells, bits) { return msgPrices.lumpPrice + (shr16ceil(msgPrices.bitPrice * bits + (msgPrices.cellPrice * cells))); } // // Source: https://github.com/ton-foundation/ton/blob/ae5c0720143e231c32c3d2034cfe4e533a16d969/crypto/block/transaction.cpp#L761 // function computeGasPrices(gasUsed, prices) { if (gasUsed <= prices.flatLimit) { return prices.flatPrice; } else { // td::rshift(gas_price256 * (gas_used - cfg.flat_gas_limit), 16, 1) + cfg.flat_gas_price return prices.flatPrice + ((prices.price * (gasUsed - prices.flatLimit)) >> 16n); } } // // Source: https://github.com/ton-foundation/ton/blob/ae5c0720143e231c32c3d2034cfe4e533a16d969/crypto/block/transaction.cpp#L530 // function computeExternalMessageFees(msgPrices, cell) { // Collect stats let storageStats = collectCellStats(cell); storageStats.bits -= cell.bits.length; storageStats.cells -= 1; return computeFwdFees(msgPrices, BigInt(storageStats.cells), BigInt(storageStats.bits)); } function computeMessageForwardFees(msgPrices, cell) { let msg = (0, core_1.loadMessageRelaxed)(cell.beginParse()); let storageStats = { bits: 0, cells: 0 }; // Init if (msg.init) { const rawBuilder = new core_1.Cell().asBuilder(); (0, core_1.storeStateInit)(msg.init)(rawBuilder); const raw = rawBuilder.endCell(); let c = collectCellStats(raw); c.bits -= raw.bits.length; c.cells -= 1; storageStats.bits += c.bits; storageStats.cells += c.cells; } // Body let bc = collectCellStats(msg.body); bc.bits -= msg.body.bits.length; bc.cells -= 1; storageStats.bits += bc.bits; storageStats.cells += bc.cells; // NOTE: Extra currencies are ignored for now let fees = computeFwdFees(msgPrices, BigInt(storageStats.cells), BigInt(storageStats.bits)); let res = (fees * BigInt(msgPrices.firstFrac)) >> 16n; let remaining = fees - res; return { fees: res, remaining }; } function collectCellStats(cell) { let bits = cell.bits.length; let cells = 1; for (let ref of cell.refs) { let r = collectCellStats(ref); cells += r.cells; bits += r.bits; } return { bits, cells }; } function shr16ceil(src) { let rem = src % 65536n; let res = src >> 16n; if (rem !== 0n) { res += 1n; } return res; }