UNPKG

laksa-core-contract

Version:

Contract instance for laksa

115 lines (108 loc) 3.44 kB
import { getAddress, AddressType } from 'laksa-core-crypto' import { Core, assertObject } from 'laksa-shared' import { Contract } from './contract' import { TestScilla } from './testScilla' import { ContractStatus, getAddressForContract } from './util' /** * @class Contracts * @param {Messenger} messenger - Messenger instance * @param {Wallet} signer - Wallet instance * @return {Contracts} Contract factory */ class Contracts extends Core { constructor(messenger, signer) { super() /** * @var {Messeger} messenger * @memberof Contracts.prototype * @description Messenger instance */ this.messenger = messenger /** * @var {Wallet} signer * @memberof Contracts.prototype * @description Wallet instance */ this.signer = signer } /** * @function getAddressForContract * @memberof Contracts * @description get Contract address from Transaction * @param {Transaction} tx - Transaction instance * @return {String} Contract address */ getAddressForContract(tx) { // always subtract 1 from the tx nonce, as contract addresses are computed // based on the nonce in the global state. return getAddress(getAddressForContract(tx), undefined, AddressType.checkSum) } /** * @function new * @memberof Contracts * @description Create a Contract * @param {String} code - Code string * @param {Array<Object>} init - init params * @return {Contract} Contract instance */ new(code, init) { const newContract = new Contract( { code, init }, { messenger: this.messenger, signer: this.signer }, ContractStatus.INITIALISED ) return newContract } /** * @function at * @memberof Contracts * @description get a Contract from factory and give it Messenger and Wallet as members * @param {Contract} contract - Contract instance * @return {Contract} Contract instance */ @assertObject({ ContractAddress: ['isAddress', 'optional'], code: ['isString', 'optional'], init: ['isArray', 'optional'], status: ['isString', 'optional'] }) at(contract) { return new Contract( { ...contract }, { messenger: this.messenger, signer: this.signer }, contract.status ) } /** * @function testContract * @memberof Contracts * @description test Contract code and init params, usable before deploying * @param {String} code - Code string * @param {Array<Object>} init - init params * @return {Boolean} test result boolean */ async testContract(code, init) { const contract = new TestScilla( { code, init }, { messenger: this.messenger, signer: this.signer }, ContractStatus.INITIALISED ) const result = await contract // decode ABI from code first .decodeABI({ code }) // we set the init params to decoded ABI .then(decoded => decoded.setInitParamsValues(decoded.abi.getInitParams(), init)) // we get the current block number from node, and set it to params .then(inited => inited.setBlockNumber()) // but we have to give it a test .then(ready => ready.testCall(2000)) // now we change the status to wait for sign .then(state => { return state.status === ContractStatus.TESTED ? { abi: state.abi, init: state.init, status: state.status } : false }) return result } } export { Contracts }