diff --git a/.changeset/curvy-melons-itch.md b/.changeset/curvy-melons-itch.md new file mode 100644 index 00000000000..f50b1138dba --- /dev/null +++ b/.changeset/curvy-melons-itch.md @@ -0,0 +1,5 @@ +--- +"@fuel-ts/account": patch +--- + +feat: return deep clone on transaction request `from` method diff --git a/packages/account/src/providers/transaction-request/blob-transaction-request.ts b/packages/account/src/providers/transaction-request/blob-transaction-request.ts index 4008a8766bf..1eb53255796 100644 --- a/packages/account/src/providers/transaction-request/blob-transaction-request.ts +++ b/packages/account/src/providers/transaction-request/blob-transaction-request.ts @@ -1,5 +1,6 @@ import type { BN } from '@fuel-ts/math'; import type { TransactionBlob } from '@fuel-ts/transactions'; +import { clone } from 'ramda'; import type { GasCosts } from '../provider'; import { calculateMetadataGasForTxBlob } from '../utils'; @@ -17,10 +18,7 @@ export interface BlobTransactionRequestLike extends BaseTransactionRequestLike { export class BlobTransactionRequest extends BaseTransactionRequest { static from(obj: BlobTransactionRequestLike) { - if (obj instanceof this) { - return obj; - } - return new this(obj); + return new this(clone(obj)); } /** Type of the transaction */ diff --git a/packages/account/src/providers/transaction-request/create-transaction-request.ts b/packages/account/src/providers/transaction-request/create-transaction-request.ts index 1c7c1d3a376..16f9a648367 100644 --- a/packages/account/src/providers/transaction-request/create-transaction-request.ts +++ b/packages/account/src/providers/transaction-request/create-transaction-request.ts @@ -4,6 +4,7 @@ import { bn, type BN } from '@fuel-ts/math'; import type { TransactionCreate } from '@fuel-ts/transactions'; import { TransactionType, OutputType } from '@fuel-ts/transactions'; import { arrayify, hexlify } from '@fuel-ts/utils'; +import { clone } from 'ramda'; import type { GqlGasCosts } from '../__generated__/operations'; import { calculateMetadataGasForTxCreate } from '../utils/gas'; @@ -32,10 +33,7 @@ export interface CreateTransactionRequestLike extends BaseTransactionRequestLike */ export class CreateTransactionRequest extends BaseTransactionRequest { static from(obj: CreateTransactionRequestLike) { - if (obj instanceof this) { - return obj; - } - return new this(obj); + return new this(clone(obj)); } /** Type of the transaction */ diff --git a/packages/account/src/providers/transaction-request/script-transaction-request.ts b/packages/account/src/providers/transaction-request/script-transaction-request.ts index 9261ec26b1f..8a1ecc7c4ef 100644 --- a/packages/account/src/providers/transaction-request/script-transaction-request.ts +++ b/packages/account/src/providers/transaction-request/script-transaction-request.ts @@ -8,6 +8,7 @@ import type { BN, BigNumberish } from '@fuel-ts/math'; import type { TransactionScript } from '@fuel-ts/transactions'; import { InputType, OutputType, TransactionType } from '@fuel-ts/transactions'; import { arrayify, hexlify } from '@fuel-ts/utils'; +import { clone } from 'ramda'; import type { ChainInfo, GasCosts } from '../provider'; import { calculateMetadataGasForTxScript, getMaxGas } from '../utils/gas'; @@ -39,10 +40,7 @@ export interface ScriptTransactionRequestLike extends BaseTransactionRequestLike */ export class ScriptTransactionRequest extends BaseTransactionRequest { static from(obj: ScriptTransactionRequestLike) { - if (obj instanceof this) { - return obj; - } - return new this(obj); + return new this(clone(obj)); } /** Type of the transaction */ diff --git a/packages/account/src/providers/transaction-request/utils.test.ts b/packages/account/src/providers/transaction-request/utils.test.ts index 35c89e49715..f677b333cbc 100644 --- a/packages/account/src/providers/transaction-request/utils.test.ts +++ b/packages/account/src/providers/transaction-request/utils.test.ts @@ -1,3 +1,6 @@ +import { bn } from '@fuel-ts/math'; +import { InputType } from '@fuel-ts/transactions'; + import { BlobTransactionRequest } from './blob-transaction-request'; import { CreateTransactionRequest } from './create-transaction-request'; import { ScriptTransactionRequest } from './script-transaction-request'; @@ -42,3 +45,88 @@ describe('isTransactionTypeBlob', () => { expect(isTransactionTypeCreate(request)).toBe(false); }); }); + +describe('transactionRequestify', () => { + it('from method should return a cloned script transaction request', () => { + const baseRequest = new ScriptTransactionRequest(); + const newRequest = ScriptTransactionRequest.from(baseRequest); + newRequest.inputs.push({ + amount: bn(1), + id: '0x', + owner: '0x', + txPointer: '0x', + witnessIndex: 0, + type: InputType.Coin, + assetId: '0x', + }); + baseRequest.inputs.push({ + amount: bn(10), + id: '0x123', + owner: '0x456', + txPointer: '0x789', + witnessIndex: 1, + type: InputType.Coin, + assetId: '0xabc', + }); + expect(newRequest).to.not.equal(baseRequest); + expect(newRequest.inputs).to.not.equal(baseRequest.inputs); + expect(newRequest.inputs).toHaveLength(1); + expect(baseRequest.inputs).toHaveLength(1); + }); + + it('from method should return a cloned create transaction request', () => { + const baseRequest = new CreateTransactionRequest({}); + const newRequest = CreateTransactionRequest.from(baseRequest); + newRequest.inputs.push({ + amount: bn(1), + id: '0x', + owner: '0x', + txPointer: '0x', + witnessIndex: 0, + type: InputType.Coin, + assetId: '0x', + }); + baseRequest.inputs.push({ + amount: bn(10), + id: '0x123', + owner: '0x456', + txPointer: '0x789', + witnessIndex: 1, + type: InputType.Coin, + assetId: '0xabc', + }); + + expect(newRequest).to.not.equal(baseRequest); + expect(newRequest.inputs).to.not.equal(baseRequest.inputs); + expect(newRequest.inputs).toHaveLength(1); + expect(baseRequest.inputs).toHaveLength(1); + }); + + it('from method should return a cloned blob transaction request', () => { + const baseRequest = new BlobTransactionRequest({ blobId: '0x' }); + const newRequest = BlobTransactionRequest.from(baseRequest); + newRequest.inputs.push({ + amount: bn(1), + id: '0x', + owner: '0x', + txPointer: '0x', + witnessIndex: 0, + type: InputType.Coin, + assetId: '0x', + }); + baseRequest.inputs.push({ + amount: bn(10), + id: '0x123', + owner: '0x456', + txPointer: '0x789', + witnessIndex: 1, + type: InputType.Coin, + assetId: '0xabc', + }); + + expect(newRequest).to.not.equal(baseRequest); + expect(newRequest.inputs).to.not.equal(baseRequest.inputs); + expect(newRequest.inputs).toHaveLength(1); + expect(baseRequest.inputs).toHaveLength(1); + }); +});