@ton/ton
Version:
[](https://www.npmjs.com/package/ton)
105 lines (104 loc) • 4.14 kB
JavaScript
;
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;
}