UNPKG

@cityofzion/neon-api

Version:

Neon-API module: High level API for neon-js

117 lines 4.73 kB
import { rpc, sc, u } from "@cityofzion/neon-core"; import { getTokenInfos } from "./api"; import { getCandidates } from "./api/getCandidates"; import { TransactionBuilder, TransactionValidator, ValidationAttributes, } from "./transaction"; export class NetworkFacade { static async fromConfig(config) { const i = new NetworkFacade(config); await i.initialize(); return i; } constructor(config) { this.magicNumber = 0; this.client = typeof config.node === "string" ? new rpc.NeoServerRpcClient(config.node) : config.node; } async initialize() { const response = await this.client.getVersion(); this.magicNumber = response.protocol.network; } getRpcNode() { return this.client; } /** * Constructs and executes a transaction of multiple token transfers * @param intents - Token transfers * @param config - Configuration */ async transferToken(intents, config) { const client = this.getRpcNode(); const txBuilder = new TransactionBuilder(); for (const intent of intents) { if (intent.decimalAmt) { const [tokenInfo] = await getTokenInfos([intent.contractHash], client); const amt = u.BigInteger.fromDecimal(intent.decimalAmt, tokenInfo.decimals); txBuilder.addNep17Transfer(intent.from, intent.to, intent.contractHash, amt); } else if (intent.integerAmt) { txBuilder.addNep17Transfer(intent.from, intent.to, intent.contractHash, intent.integerAmt); } else { throw new Error("no amount specified!"); } } const txn = txBuilder.build(); const validateResult = await this.validate(txn); if (!validateResult.valid) { throw new Error("Unable to validate transaction"); } const signedTxn = await this.sign(txn, config); const sendResult = await this.getRpcNode().sendRawTransaction(signedTxn); return sendResult; } /** * Claims all the gas available for the specified account. Do note that GAS is automatically claimed when you perform a transaction involving NEO. * @param acct - The account to claim gas on * @param config - Configuration */ async claimGas(acct, config) { const txn = TransactionBuilder.newBuilder().addGasClaim(acct).build(); const validateResult = await this.validate(txn); if (!validateResult.valid) { throw new Error("Unable to validate transaction"); } const signedTxn = await this.sign(txn, config); const sendResult = await this.getRpcNode().sendRawTransaction(signedTxn); return sendResult; } /** * Convenience method for getting list of candidates. */ async getCandidates() { return getCandidates(this.getRpcNode()); } async vote(acct, candidatePublicKey, config) { const txn = TransactionBuilder.newBuilder() .addVote(acct, candidatePublicKey) .build(); const validateResult = await this.validate(txn); if (!validateResult.valid) { throw new Error("Unable to validate transaction"); } const signedTxn = await this.sign(txn, config); const sendResult = await this.getRpcNode().sendRawTransaction(signedTxn); return sendResult; } /** * Performs validation of all attributes on the given transaction. * @param txn - Transaction to validate */ async validate(txn) { const validator = new TransactionValidator(this.getRpcNode(), txn); return await validator.validate(ValidationAttributes.All, ValidationAttributes.All); } /** * Signs a transaction according to the signing configuration. The input transaction is modified with the signatures and returned. * @param txn - Transaction to sign * @param config - Configuration * @returns */ async sign(txn, config) { for (const [idx, w] of txn.witnesses.entries()) { const signature = await config.signingCallback(txn, { network: this.magicNumber, witnessIndex: idx, }); const invocationScript = new sc.OpToken(sc.OpCode.PUSHDATA1, signature).toScript(); w.invocationScript = u.HexString.fromHex(invocationScript); } return txn; } async invoke(contractCall) { return this.getRpcNode().invokeFunction(contractCall.scriptHash, contractCall.operation, contractCall.args); } } //# sourceMappingURL=NetworkFacade.js.map