UNPKG

@factorial-finance/blueprint-node

Version:

blueprint-node-plugin

168 lines (167 loc) 6.64 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.BlockchainService = void 0; const sandbox_1 = require("@ton/sandbox"); const ton_1 = require("@ton/ton"); const core_1 = require("@ton/core"); const library_cell_1 = require("../constants/library-cell"); const test_wallets_1 = require("../constants/test-wallets"); const networks_1 = require("../constants/networks"); const utils_1 = require("../utils"); const defaults_1 = require("../constants/defaults"); class BlockchainService { constructor(fork) { this.blockchain = null; this.txs = new Map(); if (fork) { const networkConfig = networks_1.NETWORK_CONFIGS[fork]; this.fork = fork; this.endpoint = networkConfig.endpoint; } } async initialize() { if (process.env.NODE_ENV !== 'test') { console.clear(); } utils_1.Logger.info('🔄 Initializing TON Sandbox Blockchain...'); try { this.blockchain = await this.createBlockchain(); await this.initializeTestWallets(); this.setupLibraries(); } catch (error) { throw new utils_1.ValidationError(`Failed to initialize blockchain: ${error instanceof Error ? error.message : String(error)}`); } } async createBlockchain() { const params = this.endpoint ? { storage: new sandbox_1.RemoteBlockchainStorage((0, sandbox_1.wrapTonClient4ForRemote)(new ton_1.TonClient4({ endpoint: this.endpoint }))) } : undefined; return await sandbox_1.Blockchain.create(params); } async initializeTestWallets() { const walletInitPromises = test_wallets_1.testWallets.subWallets.map(async (wallet) => { await this.setBalance(core_1.Address.parse(wallet.address), defaults_1.DEFAULTS.INITIAL_TON_AMOUNT); }); await Promise.all(walletInitPromises); } setupLibraries() { if (this.fork === "mainnet" || this.fork === "testnet") { this.blockchain.libs = core_1.Cell.fromBase64(library_cell_1.MAINNET_LIBRARY_CELL); } } ensureBlockchainInitialized() { if (!this.blockchain) { throw new utils_1.ValidationError('Blockchain service not initialized. Call initialize() first.'); } } async setBalance(address, balance) { this.ensureBlockchainInitialized(); const contract = await this.blockchain.getContract(address); contract.balance = balance; } async increaseBalance(address, amount) { this.ensureBlockchainInitialized(); const contract = await this.blockchain.getContract(address); contract.balance += amount; } async setAccountCode(address, code) { this.ensureBlockchainInitialized(); const contract = await this.blockchain.getContract(address); if (contract.accountState?.type !== "active" || !contract.accountState.state.code) { throw new utils_1.ContractError("Account is not active"); } const newShardAccount = (0, sandbox_1.createShardAccount)({ address: address, code: code, data: contract.accountState.state.data, balance: contract.balance, }); this.blockchain.setShardAccount(address, newShardAccount); } async setAccountData(address, data) { this.ensureBlockchainInitialized(); const contract = await this.blockchain.getContract(address); if (contract.accountState?.type !== "active" || !contract.accountState.state.data) { throw new utils_1.ContractError("Account is not active"); } const newShardAccount = (0, sandbox_1.createShardAccount)({ address: address, code: contract.accountState.state.code, data: data, balance: contract.balance, }); this.blockchain.setShardAccount(address, newShardAccount); } async addLibrary(library) { this.ensureBlockchainInitialized(); const libs = this.getCurrentLibraries(); libs.set(BigInt("0x" + library.hash().toString('hex')), library); this.setLibraries((0, core_1.beginCell)().storeDictDirect(libs).endCell()); } getCurrentLibraries() { this.ensureBlockchainInitialized(); if (this.blockchain.libs) { try { return this.blockchain.libs .beginParse() .loadDictDirect(core_1.Dictionary.Keys.BigUint(256), core_1.Dictionary.Values.Cell()); } catch (error) { } } return core_1.Dictionary.empty(core_1.Dictionary.Keys.BigUint(256), core_1.Dictionary.Values.Cell()); } async setLibraries(libraries) { this.ensureBlockchainInitialized(); this.blockchain.libs = libraries; } async getLibraries() { this.ensureBlockchainInitialized(); return this.getCurrentLibraries(); } async sendBoc(boc) { this.ensureBlockchainInitialized(); const cell = core_1.Cell.fromBase64(boc); const result = await this.blockchain.sendMessage(cell); this.addTransactions(result.transactions); return result.transactions; } async getContract(address) { this.ensureBlockchainInitialized(); const contract = await this.blockchain.getContract(address); return contract; } async runGetMethod(address, method, stack) { this.ensureBlockchainInitialized(); const result = await this.blockchain.runGetMethod(address, method, stack); return result; } getBlockchain() { this.ensureBlockchainInitialized(); return this.blockchain; } addTransactions(transactions) { for (const tx of transactions) { const existingTxs = this.txs.get(tx.address) || []; existingTxs.push(tx); this.txs.set(tx.address, existingTxs); } } getTransactions(address) { return this.txs.get((0, utils_1.addrToBigInt)(address)) || []; } getCurrentTime() { return this.blockchain?.now || Math.floor(Date.now() / 1000); } async getCodeHash(address) { this.ensureBlockchainInitialized(); const contract = await this.getContract(address); if (contract.accountState?.type === 'active' && contract.accountState.state.code) { return contract.accountState.state.code.hash().toString('hex'); } return null; } } exports.BlockchainService = BlockchainService;