/** * Contract module - routines to interact with the æternity contract * * High level documentation of the contracts are available at * https://github.com/aeternity/protocol/tree/master/contracts and */ import { Encoder as Calldata } from '@aeternity/aepp-calldata'; import { Tag, AensName } from '../tx/builder/constants.js'; import { BuildTxOptions } from '../tx/builder/index.js'; import { Encoded } from '../utils/encoder.js'; import { ContractCallObject as NodeContractCallObject, Event as NodeEvent } from '../apis/node/index.js'; import CompilerBase, { Aci } from './compiler/Base.js'; import Node from '../Node.js'; import { txDryRun } from '../chain.js'; import { sendTransaction, SendTransactionOptions } from '../send-transaction.js'; import { TxUnpacked } from '../tx/builder/schema.generated.js'; import { Optional } from '../utils/other.js'; interface Event extends NodeEvent { address: Encoded.ContractAddress; data: Encoded.ContractBytearray; } export interface ContractCallObject extends NodeContractCallObject { returnValue: Encoded.ContractBytearray; log: Event[]; } interface DecodedEvent { name: string; args: unknown[]; contract: { name: string; address: Encoded.ContractAddress; }; } type TxData = Awaited>; interface SendAndProcessReturnType { result?: ContractCallObject; hash: TxData['hash']; tx: TxUnpacked & { tag: Tag.SignedTx | Tag.ContractCallTx | Tag.ContractCreateTx; }; txData: TxData; rawTx: Encoded.Transaction; } /** * @category contract */ export interface ContractMethodsBase { [key: string]: (...args: any[]) => any; } type MethodsToContractApi = { [Name in keyof M]: M[Name] extends (...args: infer Args) => infer Ret ? (...args: [ ...Args, ...([] | [ Name extends 'init' ? Parameters['$deploy']>[1] : Parameters['$call']>[2] ]) ]) => Promise['$call']>>, 'decodedResult'> & { decodedResult: Ret; }> : never; }; /** * @category contract */ type ContractWithMethods = Contract & MethodsToContractApi; type MethodNames = (keyof M & string) | 'init'; type MethodParameters> = Fn extends 'init' ? M extends { init: any; } ? Parameters : [] : Parameters; interface GetContractNameByEventOptions { contractAddressToName?: { [key: Encoded.ContractAddress]: string; }; } interface GetCallResultByHashReturnType> { decodedResult: ReturnType; decodedEvents?: ReturnType['$decodeEvents']>; } /** * Generate contract ACI object with predefined js methods for contract usage - can be used for * creating a reference to already deployed contracts * @category contract * @param options - Options object * @returns JS Contract API * @example * ```js * const contractIns = await Contract.initialize({ ...aeSdk.getContext(), sourceCode }) * await contractIns.$deploy([321]) or await contractIns.init(321) * const callResult = await contractIns.$call('setState', [123]) * const staticCallResult = await contractIns.$call('setState', [123], { callStatic: true }) * ``` * Also you can call contract like: `await contractIns.setState(123, options)` * Then sdk decide to make on-chain or static call (dry-run API) transaction based on function is * stateful or not */ declare class Contract { #private; /** * Compile contract * @returns bytecode */ $compile(): Promise; $getCallResultByTxHash>(hash: Encoded.TxHash, fnName: Fn, options?: Parameters['$decodeEvents']>[1]): Promise & { result: ContractCallObject; }>; _estimateGas>(name: Fn, params: MethodParameters, options?: Omit['$call']>[2], 'callStatic'>): Promise; /** * Deploy contract * @param params - Contract init function arguments array * @param options - Options * @returns deploy info */ $deploy(params: MethodParameters, options?: Parameters['$call']>[2] & Partial>): Promise & { transaction?: Encoded.TxHash; owner?: Encoded.AccountAddress; address?: Encoded.ContractAddress; decodedEvents?: ReturnType['$decodeEvents']>; }>; /** * Call contract function * @param fn - Function name * @param params - Array of function arguments * @param options - Array of function arguments * @returns CallResult */ $call>(fn: Fn, params: MethodParameters, options?: Partial> & Parameters['$decodeEvents']>[1] & Optional & Omit[2], 'onNode'> & { callStatic?: boolean; }): Promise>>; /** * Decode Events * @param events - Array of encoded events (callRes.result.log) * @param options - Options * @returns DecodedEvents */ $decodeEvents(events: Event[], { omitUnknown, ...opt }?: { omitUnknown?: boolean; } & GetContractNameByEventOptions): DecodedEvent[]; static initialize({ onCompiler, onNode, bytecode, aci, address, sourceCodePath, sourceCode, fileSystem, validateBytecode, ...otherOptions }: Omit[0], 'aci' | 'address'> & { validateBytecode?: boolean; aci?: Aci; address?: Encoded.ContractAddress | AensName; }): Promise>; _aci: Aci; _name: string; _calldata: Calldata; $options: Omit[0], 'aci'>; /** * @param options - Options */ constructor({ aci, ...otherOptions }: { onCompiler?: CompilerBase; onNode: Node; bytecode?: Encoded.ContractBytearray; aci: Aci; address?: Encoded.ContractAddress; /** * Supported only in Ceres */ name?: AensName; sourceCodePath?: Parameters[0]; sourceCode?: Parameters[0]; fileSystem?: Parameters[1]; } & Parameters['$deploy']>[1]); } interface ContractWithMethodsClass { new (options: ConstructorParameters[0]): ContractWithMethods; initialize: (typeof Contract)['initialize']; } /** * @category contract */ declare const ContractWithMethods: ContractWithMethodsClass; export default ContractWithMethods;