import { ContractMethod, AbiFunctionName, AbiFunctionInputs, DecodedAbiFunctionOutputs, Address, Contract, ProviderRpcClient, MergeInputObjectsArray, } from "everscale-inpage-provider"; import { Deployer } from "./deployer"; import { ConstructorParams, TransactionWithOutput, Transfer } from "../../types"; import { toNano, errorExtractor } from "../../utils"; import { DeployParams } from "./index"; import { logger } from "../logger"; export const accountAbiBase = { functions: [ { name: "sendTransaction", inputs: [ { name: "dest", type: "address" }, { name: "value", type: "uint128" }, { name: "bounce", type: "bool" }, { name: "flags", type: "uint8" }, { name: "payload", type: "cell" }, ], outputs: [], }, ], } as const; export class Account { constructor(readonly accountContract: Contract, readonly publicKey: string) {} public static getAccount( accountAddress: Address, ever: ProviderRpcClient, publicKey: string, abi: Abi, ): Account { return new Account(new ever.Contract(abi, accountAddress), publicKey); } private static async deployNewAccount( deployer: Deployer, publicKey: string, value: string, abi: Abi, deployParams: DeployParams, constructorParams: ConstructorParams, ): Promise<{ account: Account; tx: TransactionWithOutput }> { const { contract, tx } = await deployer.deployContract(abi, deployParams, constructorParams, value); return { account: new Account(contract, publicKey), tx }; } get address(): Address { return this.accountContract.address; } public runTarget = async ( config: { contract: Contract; value?: string; bounce?: boolean; flags?: number; }, producer?: ( targetContract: Contract, ) => ContractMethod< AbiFunctionInputs>, DecodedAbiFunctionOutputs> >, ) => { return errorExtractor( (this.accountContract as unknown as Contract).methods .sendTransaction({ value: config.value || toNano(2), bounce: !!config.bounce, dest: config.contract.address, payload: producer ? await producer(config.contract).encodeInternal() : "", flags: config.flags || 0, }) .sendExternal({ publicKey: this.publicKey }), ); }; public transfer = ({ recipient, value, bounce = false, flags = 0, payload = "" }: Transfer) => errorExtractor( (this.accountContract as unknown as Contract).methods .sendTransaction({ value, bounce, flags, dest: recipient, payload, }) .sendExternal({ publicKey: this.publicKey }), ); } export type DeployNewAccountParams = Abi extends { data: infer D } ? { tvc?: string; workchain?: number; publicKey: string; initParams: MergeInputObjectsArray; constructorParams: ConstructorParams; value: string; } : never; /** * @deprecated since version 2.2.0 * use locklift.factory.accounts instead */ export class AccountFactory { constructor( private readonly deployer: Deployer, private readonly ever: ProviderRpcClient, private readonly abi: Abi, private readonly tvc: string, ) { logger.deprecated({ methodName: "AccountFactory", instruction: "use locklift.factory.accounts instead" }); } getAccount = (accountAddress: Address, publicKey: string): Account => Account.getAccount(accountAddress, this.ever, publicKey, this.abi); public deployNewAccount = async ( args: DeployNewAccountParams, ): Promise<{ account: Account; tx: TransactionWithOutput }> => { return Account["deployNewAccount"]( this.deployer, args.publicKey, args.value, this.abi, { tvc: args.tvc || this.tvc, publicKey: args.publicKey, initParams: args.initParams, workchain: args.workchain, } as DeployParams, args.constructorParams, ); }; }