UNPKG

@ton/ton

Version:

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

193 lines (192 loc) 9.26 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.ElectorContract = void 0; const core_1 = require("@ton/core"); const FrozenDictValue = { serialize(src, builder) { throw Error("not implemented"); }, parse(src) { const address = new core_1.Address(-1, src.loadBuffer(32)); const weight = src.loadUintBig(64); const stake = src.loadCoins(); return { address, weight, stake }; } }; const EntitiesDictValue = { serialize(src, builder) { throw Error("not implemented"); }, parse(src) { const stake = src.loadCoins(); // skip time and maxFactor src.skip(64); const address = new core_1.Address(-1, src.loadBuffer(32)); const adnl = src.loadBuffer(32); return { stake, address, adnl }; } }; class ElectorContract { //readonly source: ContractSource = new UnknownContractSource('org.ton.elector', -1, 'Elector Contract'); static create() { return new ElectorContract(); } constructor() { // Please note that we are NOT loading address from config to avoid mistake and send validator money to a wrong contract this.address = core_1.Address.parseRaw('-1:3333333333333333333333333333333333333333333333333333333333333333'); } async getReturnedStake(provider, address) { if (address.workChain !== -1) { throw Error('Only masterchain addresses could have stake'); } const res = await provider.get('compute_returned_stake', [{ type: 'int', value: BigInt('0x' + address.hash.toString('hex')) }]); return res.stack.readBigNumber(); } async getPastElectionsList(provider) { const res = await provider.get('past_elections_list', []); const electionsListRaw = new core_1.TupleReader(res.stack.readLispList()); const elections = []; while (electionsListRaw.remaining > 0) { const electionsListEntry = electionsListRaw.readTuple(); const id = electionsListEntry.readNumber(); const unfreezeAt = electionsListEntry.readNumber(); electionsListEntry.pop(); // Ignore vset_hash const stakeHeld = electionsListEntry.readNumber(); elections.push({ id, unfreezeAt, stakeHeld }); } return elections; } async getPastElections(provider) { const res = await provider.get('past_elections', []); const electionsRaw = new core_1.TupleReader(res.stack.readLispList()); const elections = []; while (electionsRaw.remaining > 0) { const electionsEntry = electionsRaw.readTuple(); const id = electionsEntry.readNumber(); const unfreezeAt = electionsEntry.readNumber(); const stakeHeld = electionsEntry.readNumber(); electionsEntry.pop(); // Ignore vset_hash const frozenDict = electionsEntry.readCell(); const totalStake = electionsEntry.readBigNumber(); const bonuses = electionsEntry.readBigNumber(); let frozen = new Map(); const frozenData = frozenDict.beginParse().loadDictDirect(core_1.Dictionary.Keys.Buffer(32), FrozenDictValue); for (const [key, value] of frozenData) { frozen.set(BigInt("0x" + key.toString("hex")).toString(10), { address: value["address"], weight: value["weight"], stake: value["stake"] }); } elections.push({ id, unfreezeAt, stakeHeld, totalStake, bonuses, frozen }); } return elections; } async getElectionEntities(provider) { // // NOTE: this method doesn't call get method since for some reason it doesn't work // const account = await provider.getState(); if (account.state.type !== 'active') { throw Error('Unexpected error'); } const cell = core_1.Cell.fromBoc(account.state.data)[0]; const cs = cell.beginParse(); if (!cs.loadBit()) { return null; } // (es~load_uint(32), es~load_uint(32), es~load_grams(), es~load_grams(), es~load_dict(), es~load_int(1), es~load_int(1)); const sc = cs.loadRef().beginParse(); const startWorkTime = sc.loadUint(32); const endElectionsTime = sc.loadUint(32); const minStake = sc.loadCoins(); const allStakes = sc.loadCoins(); // var (stake, time, max_factor, addr, adnl_addr) = (cs~load_grams(), cs~load_uint(32), cs~load_uint(32), cs~load_uint(256), cs~load_uint(256)); const entitiesData = sc.loadDict(core_1.Dictionary.Keys.Buffer(32), EntitiesDictValue); let entities = []; // const failed = sc.loadBit(); // const finished = sc.loadBit(); if (entitiesData) { for (const [key, value] of entitiesData) { entities.push({ pubkey: key, stake: value["stake"], address: value["address"], adnl: value["adnl"] }); } } return { minStake, allStakes, endElectionsTime, startWorkTime, entities }; } // possible code for fetching data via get method if it is possible to set gas limit by request // async getElectionEntities(block: number) { // const res = await this.client.runMethod(block, this.address, 'participant_list_extended'); // if (res.exitCode !== 0 && res.exitCode !== 1) { // throw Error('Exit code: ' + res.exitCode); // } // let tuple = new TupleReader(res.result); // const startWorkTime = tuple.readNumber(); // const endElectionsTime = tuple.readNumber(); // const minStake = tuple.readBigNumber(); // const allStakes = tuple.readBigNumber(); // let entriesTuple = tuple.readTuple(); // const entriesRaw = new TupleReader(entriesTuple.readLispList()); // let entities: { pubkey: Buffer, stake: bigint, address: Address, adnl: Buffer }[] = []; // while (entriesRaw.remaining > 0) { // const electionsEntry = entriesRaw.readTuple(); // const pubkey = electionsEntry.readBuffer(); // const stake = electionsEntry.readBigNumber(); // const address = electionsEntry.readAddress(); // const adnl = electionsEntry.readBuffer(); // entities.push({ pubkey, stake, address, adnl }); // } // return { minStake, allStakes, endElectionsTime, startWorkTime, entities }; // } async getActiveElectionId(provider) { const res = await provider.get('active_election_id', []); const electionId = res.stack.readNumber(); return electionId > 0 ? electionId : null; } async getComplaints(provider, electionId) { const b = new core_1.TupleBuilder(); b.writeNumber(electionId); const res = await provider.get('list_complaints', b.build()); if (res.stack.peek().type === 'null') { return []; } //let tuple = new TupleReader(res.result); const complaintsRaw = new core_1.TupleReader(res.stack.readLispList()); const results = []; while (complaintsRaw.remaining > 0) { const complaintsEntry = complaintsRaw.readTuple(); const id = complaintsEntry.readBigNumber(); const completeUnpackedComplaint = complaintsEntry.readTuple(); const unpackedComplaints = completeUnpackedComplaint.readTuple(); const publicKey = Buffer.from(unpackedComplaints.readBigNumber().toString(16), 'hex'); // prod_info#34 utime:uint32 mc_blk_ref:ExtBlkRef state_proof:^(MERKLE_PROOF Block) // prod_proof:^(MERKLE_PROOF ShardState) = ProducerInfo; // no_blk_gen from_utime:uint32 prod_info:^ProducerInfo = ComplaintDescr; // no_blk_gen_diff prod_info_old:^ProducerInfo prod_info_new:^ProducerInfo = ComplaintDescr; const description = unpackedComplaints.readCell(); const createdAt = unpackedComplaints.readNumber(); const severity = unpackedComplaints.readNumber(); const rewardAddress = new core_1.Address(-1, Buffer.from(unpackedComplaints.readBigNumber().toString(16), 'hex')); const paid = unpackedComplaints.readBigNumber(); const suggestedFine = unpackedComplaints.readBigNumber(); const suggestedFinePart = unpackedComplaints.readBigNumber(); const votes = []; const votersListRaw = new core_1.TupleReader(completeUnpackedComplaint.readLispList()); while (votersListRaw.remaining > 0) { votes.push(votersListRaw.readNumber()); } const vsetId = completeUnpackedComplaint.readBigNumber(); const remainingWeight = completeUnpackedComplaint.readBigNumber(); results.push({ id, publicKey, createdAt, severity, paid, suggestedFine, suggestedFinePart, rewardAddress, votes, remainingWeight, vsetId }); } return results; } } exports.ElectorContract = ElectorContract;