diff --git a/xsuite/src/data/TupleDecoder.ts b/xsuite/src/data/TupleDecoder.ts index 4d601b78..5efb6eeb 100644 --- a/xsuite/src/data/TupleDecoder.ts +++ b/xsuite/src/data/TupleDecoder.ts @@ -1,3 +1,4 @@ +import { Prettify } from "../helpers"; import { ByteReader } from "./ByteReader"; import { AbstractDecoder, Decoder } from "./Decoder"; @@ -25,8 +26,6 @@ export class TupleDecoder<T extends DecoderMap<any>> extends AbstractDecoder< export type DecoderMap<T> = Record<string, Decoder<T>>; -type DecoderMapToValueMap<T> = { +type DecoderMapToValueMap<T> = Prettify<{ [K in keyof T]: T[K] extends Decoder<infer U> ? U : never; -} & { - // Pretiffy type: https://twitter.com/mattpocockuk/status/1622730173446557697 -}; +}>; diff --git a/xsuite/src/helpers.ts b/xsuite/src/helpers.ts new file mode 100644 index 00000000..57b30c83 --- /dev/null +++ b/xsuite/src/helpers.ts @@ -0,0 +1,5 @@ +// Pretiffy type: https://twitter.com/mattpocockuk/status/1622730173446557697 +// eslint-disable-next-line @typescript-eslint/ban-types +export type Prettify<T> = { [K in keyof T]: T[K] } & {}; + +export type Optional<T, K extends keyof T> = Omit<T, K> & Partial<Pick<T, K>>; diff --git a/xsuite/src/proxy/proxy.ts b/xsuite/src/proxy/proxy.ts index 5ac0c03a..0760a0cf 100644 --- a/xsuite/src/proxy/proxy.ts +++ b/xsuite/src/proxy/proxy.ts @@ -241,7 +241,7 @@ export class Tx { value: (params.value ?? 0n).toString(), receiver: params.receiver.toString(), sender: params.sender.toString(), - gasPrice: params.gasPrice ?? 0, + gasPrice: params.gasPrice, gasLimit: params.gasLimit, data: params.data === undefined ? undefined : btoa(params.data), chainID: params.chainId, @@ -469,7 +469,7 @@ export type TxParams = { value?: number | bigint; receiver: Address; sender: Address; - gasPrice?: number; + gasPrice: number; gasLimit: number; data?: string; chainId: string; @@ -480,7 +480,7 @@ export type DeployContractTxParams = { nonce: number; value?: number | bigint; sender: Address; - gasPrice?: number; + gasPrice: number; gasLimit: number; code: string; codeMetadata: CodeMetadata; @@ -498,7 +498,7 @@ export type UpgradeContractTxParams = { value?: number | bigint; callee: Address; sender: Address; - gasPrice?: number; + gasPrice: number; gasLimit: number; code: string; codeMetadata: CodeMetadata; @@ -512,7 +512,7 @@ export type TransferTxParams = { value?: number | bigint; receiver: Address; sender: Address; - gasPrice?: number; + gasPrice: number; gasLimit: number; esdts?: { id: string; nonce?: number; amount: number | bigint }[]; chainId: string; @@ -524,7 +524,7 @@ export type CallContractTxParams = { value?: number | bigint; callee: Address; sender: Address; - gasPrice?: number; + gasPrice: number; gasLimit: number; funcName: string; funcArgs?: Hex[]; diff --git a/xsuite/src/world/sworld.ts b/xsuite/src/world/sworld.ts index 829459d7..a653afe1 100644 --- a/xsuite/src/world/sworld.ts +++ b/xsuite/src/world/sworld.ts @@ -13,7 +13,7 @@ export class SWorld extends World { proxy: SProxy; sysAcc: SContract; - constructor({ proxy, gasPrice }: { proxy: SProxy; gasPrice?: number }) { + constructor({ proxy, gasPrice }: { proxy: SProxy; gasPrice: number }) { super({ proxy, chainId: "S", gasPrice }); this.proxy = proxy; this.sysAcc = new SContract({ @@ -23,7 +23,7 @@ export class SWorld extends World { } static new({ proxyUrl, gasPrice }: { proxyUrl: string; gasPrice?: number }) { - return new SWorld({ proxy: new SProxy(proxyUrl), gasPrice }); + return new SWorld({ proxy: new SProxy(proxyUrl), gasPrice: gasPrice ?? 0 }); } static async start({ @@ -84,7 +84,7 @@ export class SWallet extends Wallet { signer: Signer; proxy: SProxy; chainId: string; - gasPrice?: number; + gasPrice: number; }) { super({ signer, proxy, chainId, gasPrice }); this.proxy = proxy; diff --git a/xsuite/src/world/world.ts b/xsuite/src/world/world.ts index 0501e441..c4edd86c 100644 --- a/xsuite/src/world/world.ts +++ b/xsuite/src/world/world.ts @@ -1,5 +1,6 @@ import { AddressEncodable } from "../data/AddressEncodable"; import { b64ToHexString } from "../data/utils"; +import { Optional, Prettify } from "../helpers"; import { CallContractTxParams, DeployContractTxParams, @@ -16,7 +17,7 @@ import { readFileHex } from "./utils"; export class World { proxy: Proxy; chainId: string; - gasPrice?: number; + gasPrice: number; constructor({ proxy, @@ -25,7 +26,7 @@ export class World { }: { proxy: Proxy; chainId: string; - gasPrice?: number; + gasPrice: number; }) { this.proxy = proxy; this.chainId = chainId; @@ -39,15 +40,15 @@ export class World { }: { proxyUrl: string; chainId: string; - gasPrice?: number; + gasPrice: number; }) { return new World({ proxy: new Proxy(proxyUrl), chainId, gasPrice }); } newWallet(signer: Signer) { return new Wallet({ - proxy: this.proxy, signer, + proxy: this.proxy, chainId: this.chainId, gasPrice: this.gasPrice, }); @@ -55,8 +56,8 @@ export class World { async newWalletFromFile(filePath: string) { return new Wallet({ - proxy: this.proxy, signer: await KeystoreSigner.fromFile(filePath), + proxy: this.proxy, chainId: this.chainId, gasPrice: this.gasPrice, }); @@ -64,8 +65,8 @@ export class World { newWalletFromFile_unsafe(filePath: string, password: string) { return new Wallet({ - proxy: this.proxy, signer: KeystoreSigner.fromFile_unsafe(filePath, password), + proxy: this.proxy, chainId: this.chainId, gasPrice: this.gasPrice, }); @@ -99,7 +100,7 @@ export class Wallet extends Signer { signer: Signer; proxy: Proxy; chainId: string; - gasPrice?: number; + gasPrice: number; constructor({ signer, @@ -110,11 +111,11 @@ export class Wallet extends Signer { signer: Signer; proxy: Proxy; chainId: string; - gasPrice?: number; + gasPrice: number; }) { super(signer.toTopBytes()); - this.proxy = proxy; this.signer = signer; + this.proxy = proxy; this.chainId = chainId; this.gasPrice = gasPrice; } @@ -143,18 +144,18 @@ export class Wallet extends Signer { return this.proxy.getAccountWithKvs(this); } - executeTx(txParams: Omit<TxParams, "sender" | "nonce" | "chainId">) { - return InteractionPromise.from(this.#executeTx(txParams)); + executeTx(params: ExecuteTxParams) { + return InteractionPromise.from(this.#executeTx(params)); } async #executeTx({ gasPrice, - ...txParams - }: Omit<TxParams, "sender" | "nonce" | "chainId">): Promise<TxResult> { + ...params + }: ExecuteTxParams): Promise<TxResult> { const nonce = await this.proxy.getAccountNonce(this); const tx = new Tx({ gasPrice: gasPrice ?? this.gasPrice, - ...txParams, + ...params, sender: this, nonce, chainId: this.chainId, @@ -179,18 +180,16 @@ export class Wallet extends Signer { return { tx: resTx }; } - deployContract( - txParams: Omit<DeployContractTxParams, "sender" | "nonce" | "chainId">, - ) { - return InteractionPromise.from(this.#deployContract(txParams)); + deployContract(params: DeployContractParams) { + return InteractionPromise.from(this.#deployContract(params)); } async #deployContract( - txParams: Omit<DeployContractTxParams, "sender" | "nonce" | "chainId">, + params: DeployContractParams, ): Promise<DeployContractTxResult> { - txParams.code = expandCode(txParams.code); + params.code = expandCode(params.code); const txResult = await this.#executeTx( - Tx.getParamsToDeployContract(txParams), + Tx.getParamsToDeployContract(params), ); const address = txResult.tx.logs.events.find( (e: any) => e.identifier === "SCDeploy", @@ -200,46 +199,38 @@ export class Wallet extends Signer { return { ...txResult, address, contract, returnData }; } - upgradeContract( - txParams: Omit<UpgradeContractTxParams, "sender" | "nonce" | "chainId">, - ) { - return InteractionPromise.from(this.#upgradeContract(txParams)); + upgradeContract(params: UpgradeContractParams) { + return InteractionPromise.from(this.#upgradeContract(params)); } async #upgradeContract( - txParams: Omit<UpgradeContractTxParams, "sender" | "nonce" | "chainId">, + params: UpgradeContractParams, ): Promise<CallContractTxResult> { - txParams.code = expandCode(txParams.code); + params.code = expandCode(params.code); const txResult = await this.#executeTx( - Tx.getParamsToUpgradeContract({ sender: this, ...txParams }), + Tx.getParamsToUpgradeContract({ sender: this, ...params }), ); const returnData = getTxReturnData(txResult.tx); return { ...txResult, returnData }; } - transfer(txParams: Omit<TransferTxParams, "sender" | "nonce" | "chainId">) { - return InteractionPromise.from(this.#transfer(txParams)); + transfer(params: TransferParams) { + return InteractionPromise.from(this.#transfer(params)); } - async #transfer( - txParams: Omit<TransferTxParams, "sender" | "nonce" | "chainId">, - ): Promise<TxResult> { - return this.#executeTx( - Tx.getParamsToTransfer({ sender: this, ...txParams }), - ); + #transfer(params: TransferParams): Promise<TxResult> { + return this.#executeTx(Tx.getParamsToTransfer({ sender: this, ...params })); } - callContract( - txParams: Omit<CallContractTxParams, "sender" | "nonce" | "chainId">, - ) { - return InteractionPromise.from(this.#callContract(txParams)); + callContract(params: CallContractParams) { + return InteractionPromise.from(this.#callContract(params)); } async #callContract( - txParams: Omit<CallContractTxParams, "sender" | "nonce" | "chainId">, + params: CallContractParams, ): Promise<CallContractTxResult> { const txResult = await this.#executeTx( - Tx.getParamsToCallContract({ sender: this, ...txParams }), + Tx.getParamsToCallContract({ sender: this, ...params }), ); const returnData = getTxReturnData(txResult.tx); return { ...txResult, returnData }; @@ -401,6 +392,35 @@ export const expandCode = (code: string) => { return code; }; +type ExecuteTxParams = Prettify< + Optional<Omit<TxParams, "sender" | "nonce" | "chainId">, "gasPrice"> +>; + +type DeployContractParams = Prettify< + Optional< + Omit<DeployContractTxParams, "sender" | "nonce" | "chainId">, + "gasPrice" + > +>; + +type UpgradeContractParams = Prettify< + Optional< + Omit<UpgradeContractTxParams, "sender" | "nonce" | "chainId">, + "gasPrice" + > +>; + +type TransferParams = Prettify< + Optional<Omit<TransferTxParams, "sender" | "nonce" | "chainId">, "gasPrice"> +>; + +type CallContractParams = Prettify< + Optional< + Omit<CallContractTxParams, "sender" | "nonce" | "chainId">, + "gasPrice" + > +>; + type QueryResult = { query: any; returnData: string[];