diff --git a/.changeset/shaggy-donkeys-exist.md b/.changeset/shaggy-donkeys-exist.md new file mode 100644 index 00000000000..f9de0b7e9bd --- /dev/null +++ b/.changeset/shaggy-donkeys-exist.md @@ -0,0 +1,5 @@ +--- +"@fuel-ts/transactions": minor +--- + +chore!: remove receipt coders diff --git a/packages/account/src/providers/utils/receipts.test.ts b/packages/account/src/providers/utils/receipts.test.ts index 5da13b10377..a4442148e52 100644 --- a/packages/account/src/providers/utils/receipts.test.ts +++ b/packages/account/src/providers/utils/receipts.test.ts @@ -14,7 +14,7 @@ import type { ReceiptTransfer, ReceiptTransferOut, } from '@fuel-ts/transactions'; -import { ReceiptBurnCoder, ReceiptMessageOutCoder, ReceiptType } from '@fuel-ts/transactions'; +import { getMintedAssetId, getMessageId, ReceiptType } from '@fuel-ts/transactions'; import { arrayify } from '@fuel-ts/utils'; import { @@ -222,7 +222,7 @@ describe('assembleReceiptByType', () => { const digest = MOCK_GQL_RECEIPT_FRAGMENT.digest; const len = Number(MOCK_GQL_RECEIPT_FRAGMENT.len); - const messageId = ReceiptMessageOutCoder.getMessageId({ + const messageId = getMessageId({ sender, recipient, nonce, @@ -244,7 +244,7 @@ describe('assembleReceiptByType', () => { it('should return a ReceiptMint when GqlReceiptType.Mint is provided', () => { const contractId = MOCK_GQL_RECEIPT_FRAGMENT.id || ''; const subId = MOCK_GQL_RECEIPT_FRAGMENT.subId || ''; - const assetId = ReceiptBurnCoder.getAssetId(contractId, subId); + const assetId = getMintedAssetId(contractId, subId); const receipt = assembleReceiptByType({ ...MOCK_GQL_RECEIPT_FRAGMENT, @@ -263,7 +263,7 @@ describe('assembleReceiptByType', () => { it('should return a ReceiptBurn when GqlReceiptType.Burn is provided', () => { const contractId = MOCK_GQL_RECEIPT_FRAGMENT.id || ''; const subId = MOCK_GQL_RECEIPT_FRAGMENT.subId || ''; - const assetId = ReceiptBurnCoder.getAssetId(contractId, subId); + const assetId = getMintedAssetId(contractId, subId); const receipt = assembleReceiptByType({ ...MOCK_GQL_RECEIPT_FRAGMENT, diff --git a/packages/transactions/src/coders/receipt.test.ts b/packages/transactions/src/coders/receipt.test.ts deleted file mode 100644 index 7199104f06e..00000000000 --- a/packages/transactions/src/coders/receipt.test.ts +++ /dev/null @@ -1,309 +0,0 @@ -import { sha256 } from '@fuel-ts/hasher'; -import { bn } from '@fuel-ts/math'; -import { arrayify, hexlify, concat } from '@fuel-ts/utils'; - -import type { Receipt } from './receipt'; -import { ReceiptCoder, ReceiptMessageOutCoder, ReceiptType } from './receipt'; - -const B256 = '0xd5579c46dfcc7f18207013e65b44e4cb4e2c2298f4ac457ba8f82743f31e930b'; -const B256_ALT1 = '0x750f560d912ec02d826af8ba3be90a9481fb6d3bc6b4e7f01a89f245cf0a7059'; -const B256_ALT2 = '0x68b401b682ba0c9018150cca596358a6b98576337ea10b9cfb0d02441b3bc61a'; -const B256_ALT3 = '0xeb03488970d05ea240c788a0ea2e07176cc5317b7c7c89f26ac5282bbcd445bd'; -const B256_ALT4 = '0x2f6d40e3ac1a172fb9445f9843440a0fc383bea238a7a35a77a3c73d36902992'; - -/** - * @group node - * @group browser - */ -describe('ReceiptCoder', () => { - it('Can encode Call', () => { - const receipt: Receipt = { - type: ReceiptType.Call, - id: B256, - from: B256, - to: B256, - amount: bn(0), - assetId: B256, - gas: bn(0), - param1: bn(0), - param2: bn(0), - pc: bn(0), - is: bn(0), - }; - - const encoded = hexlify(new ReceiptCoder().encode(receipt)); - - expect(encoded).toEqual( - '0x0000000000000000d5579c46dfcc7f18207013e65b44e4cb4e2c2298f4ac457ba8f82743f31e930bd5579c46dfcc7f18207013e65b44e4cb4e2c2298f4ac457ba8f82743f31e930b0000000000000000d5579c46dfcc7f18207013e65b44e4cb4e2c2298f4ac457ba8f82743f31e930b00000000000000000000000000000000000000000000000000000000000000000000000000000000' - ); - - const [decoded, offset] = new ReceiptCoder().decode(arrayify(encoded), 0); - - expect(offset).toEqual((encoded.length - 2) / 2); - expect(JSON.stringify(decoded)).toEqual(JSON.stringify(receipt)); - }); - - it('Can encode Return', () => { - const receipt: Receipt = { - type: ReceiptType.Return, - id: B256, - val: bn(0), - pc: bn(0), - is: bn(0), - }; - - const encoded = hexlify(new ReceiptCoder().encode(receipt)); - - expect(encoded).toEqual( - '0x0000000000000001d5579c46dfcc7f18207013e65b44e4cb4e2c2298f4ac457ba8f82743f31e930b000000000000000000000000000000000000000000000000' - ); - - const [decoded, offset] = new ReceiptCoder().decode(arrayify(encoded), 0); - - expect(offset).toEqual((encoded.length - 2) / 2); - expect(JSON.stringify(decoded)).toEqual(JSON.stringify(receipt)); - }); - - it('Can encode ReturnData', () => { - const receipt: Receipt = { - type: ReceiptType.ReturnData, - id: B256, - ptr: bn(0), - len: bn(0), - digest: B256, - pc: bn(0), - is: bn(0), - data: '0x', - }; - - const encoded = hexlify(new ReceiptCoder().encode(receipt)); - - expect(encoded).toEqual( - '0x0000000000000002d5579c46dfcc7f18207013e65b44e4cb4e2c2298f4ac457ba8f82743f31e930b00000000000000000000000000000000d5579c46dfcc7f18207013e65b44e4cb4e2c2298f4ac457ba8f82743f31e930b00000000000000000000000000000000' - ); - - const [decoded, offset] = new ReceiptCoder().decode(arrayify(encoded), 0); - - expect(offset).toEqual((encoded.length - 2) / 2); - expect(JSON.stringify(decoded)).toEqual(JSON.stringify(receipt)); - }); - - it('Can encode Panic', () => { - const receipt: Receipt = { - type: ReceiptType.Panic, - id: B256, - reason: bn(0), - pc: bn(0), - is: bn(0), - contractId: B256, - }; - - const encoded = hexlify(new ReceiptCoder().encode(receipt)); - - expect(encoded).toEqual( - '0x0000000000000003d5579c46dfcc7f18207013e65b44e4cb4e2c2298f4ac457ba8f82743f31e930b000000000000000000000000000000000000000000000000d5579c46dfcc7f18207013e65b44e4cb4e2c2298f4ac457ba8f82743f31e930b' - ); - - const [decoded, offset] = new ReceiptCoder().decode(arrayify(encoded), 0); - - expect(offset).toEqual((encoded.length - 2) / 2); - expect(JSON.stringify(decoded)).toEqual(JSON.stringify(receipt)); - }); - - it('Can encode Revert', () => { - const receipt: Receipt = { - type: ReceiptType.Revert, - id: B256, - val: bn(0), - pc: bn(0), - is: bn(0), - }; - - const encoded = hexlify(new ReceiptCoder().encode(receipt)); - - expect(encoded).toEqual( - '0x0000000000000004d5579c46dfcc7f18207013e65b44e4cb4e2c2298f4ac457ba8f82743f31e930b000000000000000000000000000000000000000000000000' - ); - - const [decoded, offset] = new ReceiptCoder().decode(arrayify(encoded), 0); - - expect(offset).toEqual((encoded.length - 2) / 2); - expect(JSON.stringify(decoded)).toEqual(JSON.stringify(receipt)); - }); - - it('Can encode Log', () => { - const receipt: Receipt = { - type: ReceiptType.Log, - id: B256, - ra: bn(0), - rb: bn(0), - rc: bn(0), - rd: bn(0), - val0: bn(0), - val1: bn(0), - val2: bn(0), - val3: bn(0), - pc: bn(0), - is: bn(0), - }; - - const encoded = hexlify(new ReceiptCoder().encode(receipt)); - - expect(encoded).toEqual( - '0x0000000000000005d5579c46dfcc7f18207013e65b44e4cb4e2c2298f4ac457ba8f82743f31e930b000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000' - ); - - const [decoded, offset] = new ReceiptCoder().decode(arrayify(encoded), 0); - - expect(offset).toEqual((encoded.length - 2) / 2); - expect(JSON.stringify(decoded)).toEqual(JSON.stringify(receipt)); - }); - - it('Can encode LogData', () => { - const receipt: Receipt = { - type: ReceiptType.LogData, - id: B256, - ra: bn(0), - rb: bn(0), - val0: bn(0), - val1: bn(0), - ptr: bn(0), - len: bn(0), - digest: B256, - pc: bn(0), - is: bn(0), - data: '0x', - }; - - const encoded = hexlify(new ReceiptCoder().encode(receipt)); - - expect(encoded).toEqual( - '0x0000000000000006d5579c46dfcc7f18207013e65b44e4cb4e2c2298f4ac457ba8f82743f31e930b0000000000000000000000000000000000000000000000000000000000000000d5579c46dfcc7f18207013e65b44e4cb4e2c2298f4ac457ba8f82743f31e930b00000000000000000000000000000000' - ); - - const [decoded, offset] = new ReceiptCoder().decode(arrayify(encoded), 0); - - expect(offset).toEqual((encoded.length - 2) / 2); - expect(JSON.stringify(decoded)).toEqual(JSON.stringify(receipt)); - }); - - it('Can encode Transfer', () => { - const receipt: Receipt = { - type: ReceiptType.Transfer, - id: B256, - from: B256, - to: B256, - amount: bn(0), - assetId: B256, - pc: bn(0), - is: bn(0), - }; - - const encoded = hexlify(new ReceiptCoder().encode(receipt)); - - expect(encoded).toEqual( - '0x0000000000000007d5579c46dfcc7f18207013e65b44e4cb4e2c2298f4ac457ba8f82743f31e930bd5579c46dfcc7f18207013e65b44e4cb4e2c2298f4ac457ba8f82743f31e930b0000000000000000d5579c46dfcc7f18207013e65b44e4cb4e2c2298f4ac457ba8f82743f31e930b00000000000000000000000000000000' - ); - - const [decoded, offset] = new ReceiptCoder().decode(arrayify(encoded), 0); - - expect(offset).toEqual((encoded.length - 2) / 2); - expect(JSON.stringify(decoded)).toEqual(JSON.stringify(receipt)); - }); - - it('Can encode TransferOut', () => { - const receipt: Receipt = { - type: ReceiptType.TransferOut, - id: B256, - from: B256, - to: B256, - amount: bn(0), - assetId: B256, - pc: bn(0), - is: bn(0), - }; - - const encoded = hexlify(new ReceiptCoder().encode(receipt)); - - expect(encoded).toEqual( - '0x0000000000000008d5579c46dfcc7f18207013e65b44e4cb4e2c2298f4ac457ba8f82743f31e930bd5579c46dfcc7f18207013e65b44e4cb4e2c2298f4ac457ba8f82743f31e930b0000000000000000d5579c46dfcc7f18207013e65b44e4cb4e2c2298f4ac457ba8f82743f31e930b00000000000000000000000000000000' - ); - - const [decoded, offset] = new ReceiptCoder().decode(arrayify(encoded), 0); - - expect(offset).toEqual((encoded.length - 2) / 2); - expect(JSON.stringify(decoded)).toEqual(JSON.stringify(receipt)); - }); - - it('Can encode MessageOut', () => { - const receipt: Receipt = { - type: ReceiptType.MessageOut, - messageId: '', - sender: B256_ALT1, - recipient: B256_ALT2, - amount: bn(4000), - nonce: B256_ALT3, - len: 12, - digest: B256_ALT4, - data: Uint8Array.from([1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]), - }; - receipt.messageId = ReceiptMessageOutCoder.getMessageId(receipt); - - const encoded = hexlify(new ReceiptCoder().encode(receipt)); - - expect(encoded).toEqual( - '0x000000000000000a750f560d912ec02d826af8ba3be90a9481fb6d3bc6b4e7f01a89f245cf0a705968b401b682ba0c9018150cca596358a6b98576337ea10b9cfb0d02441b3bc61a0000000000000fa0eb03488970d05ea240c788a0ea2e07176cc5317b7c7c89f26ac5282bbcd445bd000000000000000c2f6d40e3ac1a172fb9445f9843440a0fc383bea238a7a35a77a3c73d369029920102030405060708090a0b0c00000000' - ); - - expect(arrayify(encoded).length).toEqual((encoded.length - 2) / 2); - - const [decoded] = new ReceiptCoder().decode(arrayify(encoded), 0); - expect(JSON.stringify(decoded)).toEqual(JSON.stringify(receipt)); - }); - - it('Can encode Mint', () => { - const receipt: Receipt = { - type: ReceiptType.Mint, - subId: B256_ALT3, - contractId: B256_ALT1, - val: bn(4000), - pc: bn(30), - is: bn(20), - assetId: sha256(concat([B256_ALT1, B256_ALT3])), - }; - - const encoded = hexlify(new ReceiptCoder().encode(receipt)); - - expect(encoded).toEqual( - '0x000000000000000beb03488970d05ea240c788a0ea2e07176cc5317b7c7c89f26ac5282bbcd445bd750f560d912ec02d826af8ba3be90a9481fb6d3bc6b4e7f01a89f245cf0a70590000000000000fa0000000000000001e0000000000000014' - ); - - expect(arrayify(encoded).length).toEqual((encoded.length - 2) / 2); - - const [decoded] = new ReceiptCoder().decode(arrayify(encoded), 0); - expect(JSON.stringify(decoded)).toEqual(JSON.stringify(receipt)); - }); - - it('Can encode Burn', () => { - const receipt: Receipt = { - type: ReceiptType.Burn, - subId: B256_ALT1, - contractId: B256_ALT3, - val: bn(300), - pc: bn(90), - is: bn(10), - assetId: sha256(concat([B256_ALT3, B256_ALT1])), - }; - - const encoded = hexlify(new ReceiptCoder().encode(receipt)); - - expect(encoded).toEqual( - '0x000000000000000c750f560d912ec02d826af8ba3be90a9481fb6d3bc6b4e7f01a89f245cf0a7059eb03488970d05ea240c788a0ea2e07176cc5317b7c7c89f26ac5282bbcd445bd000000000000012c000000000000005a000000000000000a' - ); - - expect(arrayify(encoded).length).toEqual((encoded.length - 2) / 2); - - const [decoded] = new ReceiptCoder().decode(arrayify(encoded), 0); - expect(JSON.stringify(decoded)).toEqual(JSON.stringify(receipt)); - }); -}); diff --git a/packages/transactions/src/coders/receipt.ts b/packages/transactions/src/coders/receipt.ts deleted file mode 100644 index 722cc1ad92c..00000000000 --- a/packages/transactions/src/coders/receipt.ts +++ /dev/null @@ -1,1196 +0,0 @@ -/* eslint-disable max-classes-per-file */ -import { Coder, BigNumberCoder, B256Coder, NumberCoder } from '@fuel-ts/abi-coder'; -import { ErrorCode, FuelError } from '@fuel-ts/errors'; -import { sha256 } from '@fuel-ts/hasher'; -import type { AssetId } from '@fuel-ts/interfaces'; -import type { BN } from '@fuel-ts/math'; -import { arrayify, concat } from '@fuel-ts/utils'; - -import { ByteArrayCoder } from './byte-array'; - -export enum ReceiptType /* u8 */ { - Call = 0, - Return = 1, - ReturnData = 2, - Panic = 3, - Revert = 4, - Log = 5, - LogData = 6, - Transfer = 7, - TransferOut = 8, - ScriptResult = 9, - MessageOut = 10, - Mint = 11, - Burn = 12, -} - -export type ReceiptCall = { - type: ReceiptType.Call; - /** - * @deprecated This property is deprecated and it will be removed soon. Use property `id` instead. - */ - from: string; - /** Contract ID of current context if in an internal context, zero otherwise (b256) */ - id: string; - /** Contract ID of called contract (b256) */ - to: string; - /** Amount of coins to forward, i.e. $rB (u64) */ - amount: BN; - /** Asset ID of coins to forward, i.e. MEM[$rC, 32] (b256) */ - assetId: string; - /** Gas to forward, i.e. $rD (u64) */ - gas: BN; - /** First parameter (u64) */ - param1: BN; - /** Second parameter (u64) */ - param2: BN; - /** Value of register $pc (u64) */ - pc: BN; - /** Value of register $is (u64) */ - is: BN; -}; - -/** - * @deprecated Receipt Coders are deprecated and will be removed in future versions - * because decoding receipts is no longer necessary. No replacement is required as - * this functionality is obsolete. - */ -export class ReceiptCallCoder extends Coder { - constructor() { - super('ReceiptCall', 'struct ReceiptCall', 0); - } - - encode(value: ReceiptCall): Uint8Array { - const parts: Uint8Array[] = []; - - parts.push(new B256Coder().encode(value.from)); - parts.push(new B256Coder().encode(value.to)); - parts.push(new BigNumberCoder('u64').encode(value.amount)); - parts.push(new B256Coder().encode(value.assetId)); - parts.push(new BigNumberCoder('u64').encode(value.gas)); - parts.push(new BigNumberCoder('u64').encode(value.param1)); - parts.push(new BigNumberCoder('u64').encode(value.param2)); - parts.push(new BigNumberCoder('u64').encode(value.pc)); - parts.push(new BigNumberCoder('u64').encode(value.is)); - - return concat(parts); - } - - decode(data: Uint8Array, offset: number): [ReceiptCall, number] { - let decoded; - let o = offset; - - [decoded, o] = new B256Coder().decode(data, o); - const id = decoded; - [decoded, o] = new B256Coder().decode(data, o); - const to = decoded; - [decoded, o] = new BigNumberCoder('u64').decode(data, o); - const amount = decoded; - [decoded, o] = new B256Coder().decode(data, o); - const assetId = decoded; - [decoded, o] = new BigNumberCoder('u64').decode(data, o); - const gas = decoded; - [decoded, o] = new BigNumberCoder('u64').decode(data, o); - const param1 = decoded; - [decoded, o] = new BigNumberCoder('u64').decode(data, o); - const param2 = decoded; - [decoded, o] = new BigNumberCoder('u64').decode(data, o); - const pc = decoded; - [decoded, o] = new BigNumberCoder('u64').decode(data, o); - const is = decoded; - - return [ - { - type: ReceiptType.Call, - id, - from: id, - to, - amount, - assetId, - gas, - param1, - param2, - pc, - is, - }, - o, - ]; - } -} - -export type ReceiptReturn = { - type: ReceiptType.Return; - /** Contract ID of current context if in an internal context, zero otherwise (b256) */ - id: string; - /** Value of register $rA (u64) */ - val: BN; - /** Value of register $pc (u64) */ - pc: BN; - /** Value of register $is (u64) */ - is: BN; -}; - -/** - * @deprecated Receipt Coders are deprecated and will be removed in future versions - * because decoding receipts is no longer necessary. No replacement is required as - * this functionality is obsolete. - */ -export class ReceiptReturnCoder extends Coder { - constructor() { - super('ReceiptReturn', 'struct ReceiptReturn', 0); - } - - encode(value: ReceiptReturn): Uint8Array { - const parts: Uint8Array[] = []; - - parts.push(new B256Coder().encode(value.id)); - parts.push(new BigNumberCoder('u64').encode(value.val)); - parts.push(new BigNumberCoder('u64').encode(value.pc)); - parts.push(new BigNumberCoder('u64').encode(value.is)); - - return concat(parts); - } - - decode(data: Uint8Array, offset: number): [ReceiptReturn, number] { - let decoded; - let o = offset; - - [decoded, o] = new B256Coder().decode(data, o); - const id = decoded; - [decoded, o] = new BigNumberCoder('u64').decode(data, o); - const val = decoded; - [decoded, o] = new BigNumberCoder('u64').decode(data, o); - const pc = decoded; - [decoded, o] = new BigNumberCoder('u64').decode(data, o); - const is = decoded; - - return [ - { - type: ReceiptType.Return, - id, - val, - pc, - is, - }, - o, - ]; - } -} - -export type ReceiptReturnData = { - type: ReceiptType.ReturnData; - /** Contract ID of current context if in an internal context, zero otherwise (b256) */ - id: string; - /** Value of register $rA (u64) */ - ptr: BN; - /** Value of register $rB (u64) */ - len: BN; - /** Hash of MEM[$rA, $rB] (b256) */ - digest: string; - /** Value of register $pc (u64) */ - pc: BN; - /** Value of the memory range MEM[$rA, $rB]. */ - data: string; - /** Value of register $is (u64) */ - is: BN; -}; - -/** - * @deprecated Receipt Coders are deprecated and will be removed in future versions - * because decoding receipts is no longer necessary. No replacement is required as - * this functionality is obsolete. - */ -export class ReceiptReturnDataCoder extends Coder { - constructor() { - super('ReceiptReturnData', 'struct ReceiptReturnData', 0); - } - - encode(value: ReceiptReturnData): Uint8Array { - const parts: Uint8Array[] = []; - - parts.push(new B256Coder().encode(value.id)); - parts.push(new BigNumberCoder('u64').encode(value.ptr)); - parts.push(new BigNumberCoder('u64').encode(value.len)); - parts.push(new B256Coder().encode(value.digest)); - parts.push(new BigNumberCoder('u64').encode(value.pc)); - parts.push(new BigNumberCoder('u64').encode(value.is)); - parts.push(new ByteArrayCoder(value.len.toNumber()).encode(value.data)); - - return concat(parts); - } - - decode(data: Uint8Array, offset: number): [ReceiptReturnData, number] { - let decoded; - let o = offset; - - [decoded, o] = new B256Coder().decode(data, o); - const id = decoded; - [decoded, o] = new BigNumberCoder('u64').decode(data, o); - const ptr = decoded; - [decoded, o] = new BigNumberCoder('u64').decode(data, o); - const len = decoded; - [decoded, o] = new B256Coder().decode(data, o); - const digest = decoded; - [decoded, o] = new BigNumberCoder('u64').decode(data, o); - const pc = decoded; - [decoded, o] = new BigNumberCoder('u64').decode(data, o); - const is = decoded; - [decoded, o] = new ByteArrayCoder(len.toNumber()).decode(data, o); - const returnData = decoded; - - return [ - { - type: ReceiptType.ReturnData, - id, - ptr, - len, - digest, - pc, - is, - data: returnData, - }, - o, - ]; - } -} - -export type ReceiptPanic = { - type: ReceiptType.Panic; - /** Contract ID of current context if in an internal context, zero otherwise (b256) */ - id: string; - /** Panic reason (u64) */ - reason: BN; - /** Value of register $pc (u64) */ - pc: BN; - /** Value of register $is (u64) */ - is: BN; - /** Value of optional contract ID */ - contractId: string; -}; - -/** - * @deprecated Receipt Coders are deprecated and will be removed in future versions - * because decoding receipts is no longer necessary. No replacement is required as - * this functionality is obsolete. - */ -export class ReceiptPanicCoder extends Coder { - constructor() { - super('ReceiptPanic', 'struct ReceiptPanic', 0); - } - - encode(value: ReceiptPanic): Uint8Array { - const parts: Uint8Array[] = []; - - parts.push(new B256Coder().encode(value.id)); - parts.push(new BigNumberCoder('u64').encode(value.reason)); - parts.push(new BigNumberCoder('u64').encode(value.pc)); - parts.push(new BigNumberCoder('u64').encode(value.is)); - parts.push(new B256Coder().encode(value.contractId)); - - return concat(parts); - } - - decode(data: Uint8Array, offset: number): [ReceiptPanic, number] { - let decoded; - let o = offset; - - [decoded, o] = new B256Coder().decode(data, o); - const id = decoded; - [decoded, o] = new BigNumberCoder('u64').decode(data, o); - const reason = decoded; - [decoded, o] = new BigNumberCoder('u64').decode(data, o); - const pc = decoded; - [decoded, o] = new BigNumberCoder('u64').decode(data, o); - const is = decoded; - [decoded, o] = new B256Coder().decode(data, o); - const contractId = decoded; - - return [ - { - type: ReceiptType.Panic, - id, - reason, - pc, - is, - contractId, - }, - o, - ]; - } -} - -export type ReceiptRevert = { - type: ReceiptType.Revert; - /** Contract ID of current context if in an internal context, zero otherwise (b256) */ - id: string; - /** Value of register $rA (u64) */ - val: BN; - /** Value of register $pc (u64) */ - pc: BN; - /** Value of register $is (u64) */ - is: BN; -}; - -/** - * @deprecated Receipt Coders are deprecated and will be removed in future versions - * because decoding receipts is no longer necessary. No replacement is required as - * this functionality is obsolete. - */ -export class ReceiptRevertCoder extends Coder { - constructor() { - super('ReceiptRevert', 'struct ReceiptRevert', 0); - } - - encode(value: ReceiptRevert): Uint8Array { - const parts: Uint8Array[] = []; - - parts.push(new B256Coder().encode(value.id)); - parts.push(new BigNumberCoder('u64').encode(value.val)); - parts.push(new BigNumberCoder('u64').encode(value.pc)); - parts.push(new BigNumberCoder('u64').encode(value.is)); - - return concat(parts); - } - - decode(data: Uint8Array, offset: number): [ReceiptRevert, number] { - let decoded; - let o = offset; - - [decoded, o] = new B256Coder().decode(data, o); - const id = decoded; - [decoded, o] = new BigNumberCoder('u64').decode(data, o); - const val = decoded; - [decoded, o] = new BigNumberCoder('u64').decode(data, o); - const pc = decoded; - [decoded, o] = new BigNumberCoder('u64').decode(data, o); - const is = decoded; - - return [ - { - type: ReceiptType.Revert, - id, - val, - pc, - is, - }, - o, - ]; - } -} - -export type ReceiptLog = { - type: ReceiptType.Log; - /** Contract ID of current context if in an internal context, zero otherwise (b256) */ - id: string; - /** - * @deprecated This property is deprecated and it will be removed soon. Use property `ra` instead. - */ - val0: BN; - /** Value of register $rA (u64) */ - ra: BN; - /** - * @deprecated This property is deprecated and it will be removed soon. Use property `rb` instead. - */ - val1: BN; - /** Value of register $rB (u64) */ - rb: BN; - /** - * @deprecated This property is deprecated and it will be removed soon. Use property `rc` instead. - */ - val2: BN; - /** Value of register $rC (u64) */ - rc: BN; - /** - * @deprecated This property is deprecated and it will be removed soon. Use property `rd` instead. - */ - val3: BN; - /** Value of register $rD (u64) */ - rd: BN; - /** Value of register $pc (u64) */ - pc: BN; - /** Value of register $is (u64) */ - is: BN; -}; - -/** - * @deprecated Receipt Coders are deprecated and will be removed in future versions - * because decoding receipts is no longer necessary. No replacement is required as - * this functionality is obsolete. - */ -export class ReceiptLogCoder extends Coder { - constructor() { - super('ReceiptLog', 'struct ReceiptLog', 0); - } - - encode(value: ReceiptLog): Uint8Array { - const parts: Uint8Array[] = []; - - parts.push(new B256Coder().encode(value.id)); - parts.push(new BigNumberCoder('u64').encode(value.val0)); - parts.push(new BigNumberCoder('u64').encode(value.val1)); - parts.push(new BigNumberCoder('u64').encode(value.val2)); - parts.push(new BigNumberCoder('u64').encode(value.val3)); - parts.push(new BigNumberCoder('u64').encode(value.pc)); - parts.push(new BigNumberCoder('u64').encode(value.is)); - - return concat(parts); - } - - decode(data: Uint8Array, offset: number): [ReceiptLog, number] { - let decoded; - let o = offset; - - [decoded, o] = new B256Coder().decode(data, o); - const id = decoded; - [decoded, o] = new BigNumberCoder('u64').decode(data, o); - const ra = decoded; - [decoded, o] = new BigNumberCoder('u64').decode(data, o); - const rb = decoded; - [decoded, o] = new BigNumberCoder('u64').decode(data, o); - const rc = decoded; - [decoded, o] = new BigNumberCoder('u64').decode(data, o); - const rd = decoded; - [decoded, o] = new BigNumberCoder('u64').decode(data, o); - const pc = decoded; - [decoded, o] = new BigNumberCoder('u64').decode(data, o); - const is = decoded; - - return [ - { - type: ReceiptType.Log, - id, - ra, - rb, - rc, - rd, - val0: ra, - val1: rb, - val2: rc, - val3: rd, - pc, - is, - }, - o, - ]; - } -} - -export type ReceiptLogData = { - type: ReceiptType.LogData; - /** Contract ID of current context if in an internal context, zero otherwise (b256) */ - id: string; - /** Value of register $rA (u64) */ - ra: BN; - /** - * @deprecated This property is deprecated and it will be removed soon. Use property `ra` instead. - */ - val0: BN; - /** Value of register $rB (u64) */ - rb: BN; - /** - * @deprecated This property is deprecated and it will be removed soon. Use property `rb` instead. - */ - val1: BN; - /** Value of register $rC (u64) */ - ptr: BN; - /** Value of register $rD (u64) */ - len: BN; - /** Hash of MEM[$rC, $rD] (b256) */ - digest: string; - /** Value of the memory range MEM[$rC, $rD]. */ - data: string; - /** Value of register $pc (u64) */ - pc: BN; - /** Value of register $is (u64) */ - is: BN; -}; - -/** - * @deprecated Receipt Coders are deprecated and will be removed in future versions - * because decoding receipts is no longer necessary. No replacement is required as - * this functionality is obsolete. - */ -export class ReceiptLogDataCoder extends Coder { - constructor() { - super('ReceiptLogData', 'struct ReceiptLogData', 0); - } - - encode(value: ReceiptLogData): Uint8Array { - const parts: Uint8Array[] = []; - - parts.push(new B256Coder().encode(value.id)); - parts.push(new BigNumberCoder('u64').encode(value.val0)); - parts.push(new BigNumberCoder('u64').encode(value.val1)); - parts.push(new BigNumberCoder('u64').encode(value.ptr)); - parts.push(new BigNumberCoder('u64').encode(value.len)); - parts.push(new B256Coder().encode(value.digest)); - parts.push(new BigNumberCoder('u64').encode(value.pc)); - parts.push(new BigNumberCoder('u64').encode(value.is)); - parts.push(new ByteArrayCoder(value.len.toNumber()).encode(value.data)); - - return concat(parts); - } - - decode(data: Uint8Array, offset: number): [ReceiptLogData, number] { - let decoded; - let o = offset; - - [decoded, o] = new B256Coder().decode(data, o); - const id = decoded; - [decoded, o] = new BigNumberCoder('u64').decode(data, o); - const ra = decoded; - [decoded, o] = new BigNumberCoder('u64').decode(data, o); - const rb = decoded; - [decoded, o] = new BigNumberCoder('u64').decode(data, o); - const ptr = decoded; - [decoded, o] = new BigNumberCoder('u64').decode(data, o); - const len = decoded; - [decoded, o] = new B256Coder().decode(data, o); - const digest = decoded; - [decoded, o] = new BigNumberCoder('u64').decode(data, o); - const pc = decoded; - [decoded, o] = new BigNumberCoder('u64').decode(data, o); - const is = decoded; - [decoded, o] = new ByteArrayCoder(len.toNumber()).decode(data, o); - const logData = decoded; - - return [ - { - type: ReceiptType.LogData, - id, - ra, - rb, - val0: ra, - val1: rb, - ptr, - len, - digest, - pc, - is, - data: logData, - }, - o, - ]; - } -} - -export type ReceiptTransfer = { - type: ReceiptType.Transfer; - /** - * @deprecated This property is deprecated and it will be removed soon. Use property `id` instead. - */ - from: string; - /** Contract ID of current context if in an internal context, zero otherwise (b256) */ - id: string; - /** Contract ID of contract to transfer coins to (b256) */ - to: string; - /** Amount of coins transferred (u64) */ - amount: BN; - /** Asset ID of coins transferred (b256) */ - assetId: string; - /** Value of register $pc (u64) */ - pc: BN; - /** Value of register $is (u64) */ - is: BN; -}; - -/** - * @deprecated Receipt Coders are deprecated and will be removed in future versions - * because decoding receipts is no longer necessary. No replacement is required as - * this functionality is obsolete. - */ -export class ReceiptTransferCoder extends Coder { - constructor() { - super('ReceiptTransfer', 'struct ReceiptTransfer', 0); - } - - encode(value: ReceiptTransfer): Uint8Array { - const parts: Uint8Array[] = []; - - parts.push(new B256Coder().encode(value.from)); - parts.push(new B256Coder().encode(value.to)); - parts.push(new BigNumberCoder('u64').encode(value.amount)); - parts.push(new B256Coder().encode(value.assetId)); - parts.push(new BigNumberCoder('u64').encode(value.pc)); - parts.push(new BigNumberCoder('u64').encode(value.is)); - - return concat(parts); - } - - decode(data: Uint8Array, offset: number): [ReceiptTransfer, number] { - let decoded; - let o = offset; - - [decoded, o] = new B256Coder().decode(data, o); - const id = decoded; - [decoded, o] = new B256Coder().decode(data, o); - const to = decoded; - [decoded, o] = new BigNumberCoder('u64').decode(data, o); - const amount = decoded; - [decoded, o] = new B256Coder().decode(data, o); - const assetId = decoded; - [decoded, o] = new BigNumberCoder('u64').decode(data, o); - const pc = decoded; - [decoded, o] = new BigNumberCoder('u64').decode(data, o); - const is = decoded; - - return [ - { - type: ReceiptType.Transfer, - id, - from: id, - to, - amount, - assetId, - pc, - is, - }, - o, - ]; - } -} - -export type ReceiptTransferOut = { - type: ReceiptType.TransferOut; - /** - * @deprecated This property is deprecated and it will be removed soon. Use property `id` instead. - */ - from: string; - /** Contract ID of current context if in an internal context, zero otherwise (b256) */ - id: string; - /** Address to transfer coins to (b256) */ - to: string; - /** Amount of coins transferred (u64) */ - amount: BN; - /** Asset ID of coins transferred (b256) */ - assetId: string; - /** Value of register $pc (u64) */ - pc: BN; - /** Value of register $is (u64) */ - is: BN; -}; - -/** - * @deprecated Receipt Coders are deprecated and will be removed in future versions - * because decoding receipts is no longer necessary. No replacement is required as - * this functionality is obsolete. - */ -export class ReceiptTransferOutCoder extends Coder { - constructor() { - super('ReceiptTransferOut', 'struct ReceiptTransferOut', 0); - } - - encode(value: ReceiptTransferOut): Uint8Array { - const parts: Uint8Array[] = []; - - parts.push(new B256Coder().encode(value.from)); - parts.push(new B256Coder().encode(value.to)); - parts.push(new BigNumberCoder('u64').encode(value.amount)); - parts.push(new B256Coder().encode(value.assetId)); - parts.push(new BigNumberCoder('u64').encode(value.pc)); - parts.push(new BigNumberCoder('u64').encode(value.is)); - - return concat(parts); - } - - decode(data: Uint8Array, offset: number): [ReceiptTransferOut, number] { - let decoded; - let o = offset; - - [decoded, o] = new B256Coder().decode(data, o); - const id = decoded; - [decoded, o] = new B256Coder().decode(data, o); - const to = decoded; - [decoded, o] = new BigNumberCoder('u64').decode(data, o); - const amount = decoded; - [decoded, o] = new B256Coder().decode(data, o); - const assetId = decoded; - [decoded, o] = new BigNumberCoder('u64').decode(data, o); - const pc = decoded; - [decoded, o] = new BigNumberCoder('u64').decode(data, o); - const is = decoded; - - return [ - { - type: ReceiptType.TransferOut, - id, - from: id, - to, - amount, - assetId, - pc, - is, - }, - o, - ]; - } -} - -export type ReceiptScriptResult = { - type: ReceiptType.ScriptResult; - /** Result variant with embedded `PanicReason` in first 8 bits and `instr` (u64) */ - result: BN; - /** Gas consumed by the script (u64) */ - gasUsed: BN; -}; - -/** - * @deprecated Receipt Coders are deprecated and will be removed in future versions - * because decoding receipts is no longer necessary. No replacement is required as - * this functionality is obsolete. - */ -export class ReceiptScriptResultCoder extends Coder { - constructor() { - super('ReceiptScriptResult', 'struct ReceiptScriptResult', 0); - } - - encode(value: ReceiptScriptResult): Uint8Array { - const parts: Uint8Array[] = []; - - parts.push(new BigNumberCoder('u64').encode(value.result)); - parts.push(new BigNumberCoder('u64').encode(value.gasUsed)); - - return concat(parts); - } - - decode(data: Uint8Array, offset: number): [ReceiptScriptResult, number] { - let decoded; - let o = offset; - - [decoded, o] = new BigNumberCoder('u64').decode(data, o); - const result = decoded; - [decoded, o] = new BigNumberCoder('u64').decode(data, o); - const gasUsed = decoded; - - return [ - { - type: ReceiptType.ScriptResult, - result, - gasUsed, - }, - o, - ]; - } -} - -export type ReceiptMessageOut = { - type: ReceiptType.MessageOut; - /** Hexadecimal string representation of the 256-bit (32-byte) message ID */ - messageId: string; - /** Hexadecimal string representation of the 256-bit (32-byte) address of the message sender: MEM[$fp, 32] */ - sender: string; - /** Hexadecimal string representation of the 256-bit (32-byte) address of the message recipient: MEM[$rA, 32] */ - recipient: string; - /** Hexadecimal string representation of a 64-bit unsigned integer; value of register $rD */ - amount: BN; - /** Hexadecimal string representation of the 256-bit (32-byte) message nonce */ - nonce: string; - /** Decimal string representation of a 16-bit unsigned integer; value of register $rC. */ - len: number; - /** Hexadecimal string representation of 256-bit (32-byte), hash of MEM[$rA + 32, $rB] */ - digest: string; - /** Hexadecimal string representation of the value of the memory range MEM[$rA + 32, $rB] */ - data: Uint8Array; -}; - -/** - * @deprecated Receipt Coders are deprecated and will be removed in future versions - * because decoding receipts is no longer necessary. No replacement is required as - * this functionality is obsolete. - */ -export class ReceiptMessageOutCoder extends Coder { - constructor() { - super('ReceiptMessageOut', 'struct ReceiptMessageOut', 0); - } - - /** - * @deprecated `ReceiptMessageOutCoder.getMessageId` is deprecated and will be removed in future versions. - * Use the static method `InputMessageCoder.getMessageId` instead. - */ - static getMessageId( - value: Pick - ): string { - const parts: Uint8Array[] = []; - - parts.push(new ByteArrayCoder(32).encode(value.sender)); - parts.push(new ByteArrayCoder(32).encode(value.recipient)); - parts.push(new ByteArrayCoder(32).encode(value.nonce)); - parts.push(new BigNumberCoder('u64').encode(value.amount)); - parts.push(arrayify(value.data || '0x')); - - return sha256(concat(parts)); - } - - encode(value: Omit): Uint8Array { - const parts: Uint8Array[] = []; - - parts.push(new B256Coder().encode(value.sender)); - parts.push(new B256Coder().encode(value.recipient)); - parts.push(new BigNumberCoder('u64').encode(value.amount)); - parts.push(new B256Coder().encode(value.nonce)); - parts.push(new NumberCoder('u16', { padToWordSize: true }).encode(value.data.length)); - parts.push(new B256Coder().encode(value.digest)); - parts.push(new ByteArrayCoder(value.data.length).encode(value.data)); - - return concat(parts); - } - - decode(data: Uint8Array, offset: number): [ReceiptMessageOut, number] { - let decoded; - let o = offset; - - [decoded, o] = new B256Coder().decode(data, o); - const sender = decoded; - [decoded, o] = new B256Coder().decode(data, o); - const recipient = decoded; - [decoded, o] = new BigNumberCoder('u64').decode(data, o); - const amount = decoded; - [decoded, o] = new B256Coder().decode(data, o); - const nonce = decoded; - [decoded, o] = new NumberCoder('u16', { padToWordSize: true }).decode(data, o); - const len = decoded; - [decoded, o] = new B256Coder().decode(data, o); - const digest = decoded; - [decoded, o] = new ByteArrayCoder(len).decode(data, o); - const messageData = arrayify(decoded); - - const receiptMessageOut: ReceiptMessageOut = { - type: ReceiptType.MessageOut, - messageId: '', - sender, - recipient, - amount, - nonce, - len, - digest, - data: messageData, - }; - receiptMessageOut.messageId = ReceiptMessageOutCoder.getMessageId(receiptMessageOut); - - return [receiptMessageOut, o]; - } -} - -export type ReceiptMint = { - type: ReceiptType.Mint; - - subId: string; - - contractId: string; - - assetId: string; - - val: BN; - /** Value of register $pc (u64) */ - pc: BN; - /** Value of register $is (u64) */ - is: BN; -}; - -export const getMintedAssetId = (contractId: string, subId: string): string => { - const contractIdBytes = arrayify(contractId); - const subIdBytes = arrayify(subId); - - return sha256(concat([contractIdBytes, subIdBytes])); -}; - -export const createAssetId = (contractId: string, subId: string): AssetId => ({ - bits: getMintedAssetId(contractId, subId), -}); - -/** - * @deprecated Receipt Coders are deprecated and will be removed in future versions - * because decoding receipts is no longer necessary. No replacement is required as - * this functionality is obsolete. - */ -export class ReceiptMintCoder extends Coder { - constructor() { - super('ReceiptMint', 'struct ReceiptMint', 0); - } - - /** - * @deprecated `ReceiptMintCoder.getAssetId` is deprecated and will be removed in future versions. - * Use the helper function `getMintedAssetId` instead. - */ - static getAssetId(contractId: string, subId: string): string { - return getMintedAssetId(contractId, subId); - } - - encode(value: ReceiptMint): Uint8Array { - const parts: Uint8Array[] = []; - - parts.push(new B256Coder().encode(value.subId)); - parts.push(new B256Coder().encode(value.contractId)); - parts.push(new BigNumberCoder('u64').encode(value.val)); - parts.push(new BigNumberCoder('u64').encode(value.pc)); - parts.push(new BigNumberCoder('u64').encode(value.is)); - - return concat(parts); - } - - decode(data: Uint8Array, offset: number): [ReceiptMint, number] { - let decoded; - let o = offset; - - [decoded, o] = new B256Coder().decode(data, o); - const subId = decoded; - [decoded, o] = new B256Coder().decode(data, o); - const contractId = decoded; - [decoded, o] = new BigNumberCoder('u64').decode(data, o); - const val = decoded; - [decoded, o] = new BigNumberCoder('u64').decode(data, o); - const pc = decoded; - [decoded, o] = new BigNumberCoder('u64').decode(data, o); - const is = decoded; - - const assetId = ReceiptMintCoder.getAssetId(contractId, subId); - - const receiptMint: ReceiptMint = { - type: ReceiptType.Mint, - subId, - contractId, - val, - pc, - is, - assetId, - }; - - return [receiptMint, o]; - } -} - -export type ReceiptBurn = { - type: ReceiptType.Burn; - - subId: string; - - contractId: string; - - assetId: string; - - val: BN; - /** Value of register $pc (u64) */ - pc: BN; - /** Value of register $is (u64) */ - is: BN; -}; - -/** - * @deprecated Receipt Coders are deprecated and will be removed in future versions - * because decoding receipts is no longer necessary. No replacement is required as - * this functionality is obsolete. - */ -export class ReceiptBurnCoder extends Coder { - constructor() { - super('ReceiptBurn', 'struct ReceiptBurn', 0); - } - - /** - * @deprecated `ReceiptBurnCoder.getAssetId` is deprecated and will be removed in future versions. - * Use the helper function `getMintedAssetId` instead. - */ - static getAssetId(contractId: string, subId: string): string { - return getMintedAssetId(contractId, subId); - } - - encode(value: ReceiptBurn): Uint8Array { - const parts: Uint8Array[] = []; - - parts.push(new B256Coder().encode(value.subId)); - parts.push(new B256Coder().encode(value.contractId)); - parts.push(new BigNumberCoder('u64').encode(value.val)); - parts.push(new BigNumberCoder('u64').encode(value.pc)); - parts.push(new BigNumberCoder('u64').encode(value.is)); - - return concat(parts); - } - - decode(data: Uint8Array, offset: number): [ReceiptBurn, number] { - let decoded; - let o = offset; - - [decoded, o] = new B256Coder().decode(data, o); - const subId = decoded; - [decoded, o] = new B256Coder().decode(data, o); - const contractId = decoded; - [decoded, o] = new BigNumberCoder('u64').decode(data, o); - const val = decoded; - [decoded, o] = new BigNumberCoder('u64').decode(data, o); - const pc = decoded; - [decoded, o] = new BigNumberCoder('u64').decode(data, o); - const is = decoded; - - const assetId = ReceiptMintCoder.getAssetId(contractId, subId); - - const receiptBurn: ReceiptBurn = { - type: ReceiptType.Burn, - subId, - contractId, - val, - pc, - is, - assetId, - }; - - return [receiptBurn, o]; - } -} - -export type Receipt = - | ReceiptCall - | ReceiptReturn - | ReceiptReturnData - | ReceiptPanic - | ReceiptRevert - | ReceiptLog - | ReceiptLogData - | ReceiptTransfer - | ReceiptTransferOut - | ReceiptScriptResult - | ReceiptMessageOut - | ReceiptMint - | ReceiptBurn; - -/** - * @deprecated Receipt Coders are deprecated and will be removed in future versions - * because decoding receipts is no longer necessary. No replacement is required as - * this functionality is obsolete. - */ -export class ReceiptCoder extends Coder { - constructor() { - super('Receipt', 'struct Receipt', 0); - } - - encode(value: Receipt): Uint8Array { - const parts: Uint8Array[] = []; - - parts.push(new NumberCoder('u8', { padToWordSize: true }).encode(value.type)); - - const { type } = value; - - switch (value.type) { - case ReceiptType.Call: { - parts.push(new ReceiptCallCoder().encode(value)); - break; - } - case ReceiptType.Return: { - parts.push(new ReceiptReturnCoder().encode(value)); - break; - } - case ReceiptType.ReturnData: { - parts.push(new ReceiptReturnDataCoder().encode(value)); - break; - } - case ReceiptType.Panic: { - parts.push(new ReceiptPanicCoder().encode(value)); - break; - } - case ReceiptType.Revert: { - parts.push(new ReceiptRevertCoder().encode(value)); - break; - } - case ReceiptType.Log: { - parts.push(new ReceiptLogCoder().encode(value)); - break; - } - case ReceiptType.LogData: { - parts.push(new ReceiptLogDataCoder().encode(value)); - break; - } - case ReceiptType.Transfer: { - parts.push(new ReceiptTransferCoder().encode(value)); - break; - } - case ReceiptType.TransferOut: { - parts.push(new ReceiptTransferOutCoder().encode(value)); - break; - } - case ReceiptType.ScriptResult: { - parts.push(new ReceiptScriptResultCoder().encode(value)); - break; - } - case ReceiptType.MessageOut: { - parts.push(new ReceiptMessageOutCoder().encode(value)); - break; - } - case ReceiptType.Mint: { - parts.push(new ReceiptMintCoder().encode(value)); - break; - } - case ReceiptType.Burn: { - parts.push(new ReceiptBurnCoder().encode(value)); - break; - } - default: { - throw new FuelError(ErrorCode.INVALID_RECEIPT_TYPE, `Invalid receipt type: ${type}`); - } - } - - return concat(parts); - } - - decode(data: Uint8Array, offset: number): [Receipt, number] { - let decoded; - let o = offset; - - [decoded, o] = new NumberCoder('u8', { padToWordSize: true }).decode(data, o); - const type = decoded as ReceiptType; - switch (type) { - case ReceiptType.Call: { - [decoded, o] = new ReceiptCallCoder().decode(data, o); - return [decoded, o]; - } - case ReceiptType.Return: { - [decoded, o] = new ReceiptReturnCoder().decode(data, o); - return [decoded, o]; - } - case ReceiptType.ReturnData: { - [decoded, o] = new ReceiptReturnDataCoder().decode(data, o); - return [decoded, o]; - } - case ReceiptType.Panic: { - [decoded, o] = new ReceiptPanicCoder().decode(data, o); - return [decoded, o]; - } - case ReceiptType.Revert: { - [decoded, o] = new ReceiptRevertCoder().decode(data, o); - return [decoded, o]; - } - case ReceiptType.Log: { - [decoded, o] = new ReceiptLogCoder().decode(data, o); - return [decoded, o]; - } - case ReceiptType.LogData: { - [decoded, o] = new ReceiptLogDataCoder().decode(data, o); - return [decoded, o]; - } - case ReceiptType.Transfer: { - [decoded, o] = new ReceiptTransferCoder().decode(data, o); - return [decoded, o]; - } - case ReceiptType.TransferOut: { - [decoded, o] = new ReceiptTransferOutCoder().decode(data, o); - return [decoded, o]; - } - case ReceiptType.ScriptResult: { - [decoded, o] = new ReceiptScriptResultCoder().decode(data, o); - return [decoded, o]; - } - case ReceiptType.MessageOut: { - [decoded, o] = new ReceiptMessageOutCoder().decode(data, o); - return [decoded, o]; - } - case ReceiptType.Mint: { - [decoded, o] = new ReceiptMintCoder().decode(data, o); - return [decoded, o]; - } - case ReceiptType.Burn: { - [decoded, o] = new ReceiptBurnCoder().decode(data, o); - return [decoded, o]; - } - default: { - throw new FuelError(ErrorCode.INVALID_RECEIPT_TYPE, `Invalid receipt type: ${type}`); - } - } - } -} diff --git a/packages/transactions/src/index.ts b/packages/transactions/src/index.ts index 2f7c95407ec..11fc164149a 100644 --- a/packages/transactions/src/index.ts +++ b/packages/transactions/src/index.ts @@ -1,7 +1,7 @@ export * from './coders/input'; export * from './coders/output'; export * from './coders/policy'; -export * from './coders/receipt'; +export * from './receipt'; export * from './coders/storage-slot'; export * from './coders/transaction'; export * from './coders/witness'; diff --git a/packages/transactions/src/receipt.test.ts b/packages/transactions/src/receipt.test.ts new file mode 100644 index 00000000000..03771a8508d --- /dev/null +++ b/packages/transactions/src/receipt.test.ts @@ -0,0 +1,87 @@ +import { BigNumberCoder } from '@fuel-ts/abi-coder'; +import { getRandomB256 } from '@fuel-ts/address'; +import { sha256 } from '@fuel-ts/hasher'; +import type { AssetId } from '@fuel-ts/interfaces'; +import { bn } from '@fuel-ts/math'; +import { arrayify, concat } from '@fuel-ts/utils'; + +import { ByteArrayCoder } from './coders/byte-array'; +import { getMintedAssetId, createAssetId, getMessageId } from './receipt'; + +/** + * @group node + * @group browser + */ +describe('getMintedAssetId', () => { + it('should returns expected hashed asset ID', () => { + const contractId = getRandomB256(); + const subId = getRandomB256(); + + const contractIdBytes = arrayify(contractId); + const subIdBytes = arrayify(subId); + + const expected = sha256(concat([contractIdBytes, subIdBytes])); + const actual = getMintedAssetId(contractId, subId); + + expect(expected).toBe(actual); + }); +}); + +describe('createAssetId', () => { + it('returns should returns expected wrapped AssetID type', () => { + const contractId = getRandomB256(); + const subId = getRandomB256(); + + const contractIdBytes = arrayify(contractId); + const subIdBytes = arrayify(subId); + + const expected: AssetId = { bits: sha256(concat([contractIdBytes, subIdBytes])) }; + const actual = createAssetId(contractId, subId); + + expect(expected).toStrictEqual(actual); + }); +}); + +describe('getMessageId', () => { + it('should returns expected hash (W DATA)', () => { + const sender = getRandomB256(); + const recipient = getRandomB256(); + const nonce = getRandomB256(); + const amount = bn(100); + const data = arrayify(getRandomB256()); + + const parts: Uint8Array[] = []; + + parts.push(new ByteArrayCoder(32).encode(sender)); + parts.push(new ByteArrayCoder(32).encode(recipient)); + parts.push(new ByteArrayCoder(32).encode(nonce)); + parts.push(new BigNumberCoder('u64').encode(amount)); + parts.push(data); + + const expected = sha256(concat(parts)); + const actual = getMessageId({ sender, recipient, nonce, amount, data }); + + expect(expected).toStrictEqual(actual); + }); + + it('should returns expected hash (W/O DATA)', () => { + const sender = getRandomB256(); + const recipient = getRandomB256(); + const nonce = getRandomB256(); + const amount = bn(100); + const data = arrayify('0x'); + + const parts: Uint8Array[] = []; + + parts.push(new ByteArrayCoder(32).encode(sender)); + parts.push(new ByteArrayCoder(32).encode(recipient)); + parts.push(new ByteArrayCoder(32).encode(nonce)); + parts.push(new BigNumberCoder('u64').encode(amount)); + parts.push(data); + + const expected = sha256(concat(parts)); + const actual = getMessageId({ sender, recipient, nonce, amount, data }); + + expect(expected).toStrictEqual(actual); + }); +}); diff --git a/packages/transactions/src/receipt.ts b/packages/transactions/src/receipt.ts new file mode 100644 index 00000000000..e8b76ed0eb6 --- /dev/null +++ b/packages/transactions/src/receipt.ts @@ -0,0 +1,309 @@ +import { BigNumberCoder } from '@fuel-ts/abi-coder'; +import { sha256 } from '@fuel-ts/hasher'; +import type { AssetId } from '@fuel-ts/interfaces'; +import type { BN } from '@fuel-ts/math'; +import { arrayify, concat } from '@fuel-ts/utils'; + +import { ByteArrayCoder } from './coders/byte-array'; + +export enum ReceiptType /* u8 */ { + Call = 0, + Return = 1, + ReturnData = 2, + Panic = 3, + Revert = 4, + Log = 5, + LogData = 6, + Transfer = 7, + TransferOut = 8, + ScriptResult = 9, + MessageOut = 10, + Mint = 11, + Burn = 12, +} + +export type ReceiptCall = { + type: ReceiptType.Call; + /** + * @deprecated This property is deprecated and it will be removed soon. Use property `id` instead. + */ + from: string; + /** Contract ID of current context if in an internal context, zero otherwise (b256) */ + id: string; + /** Contract ID of called contract (b256) */ + to: string; + /** Amount of coins to forward, i.e. $rB (u64) */ + amount: BN; + /** Asset ID of coins to forward, i.e. MEM[$rC, 32] (b256) */ + assetId: string; + /** Gas to forward, i.e. $rD (u64) */ + gas: BN; + /** First parameter (u64) */ + param1: BN; + /** Second parameter (u64) */ + param2: BN; + /** Value of register $pc (u64) */ + pc: BN; + /** Value of register $is (u64) */ + is: BN; +}; + +export type ReceiptReturn = { + type: ReceiptType.Return; + /** Contract ID of current context if in an internal context, zero otherwise (b256) */ + id: string; + /** Value of register $rA (u64) */ + val: BN; + /** Value of register $pc (u64) */ + pc: BN; + /** Value of register $is (u64) */ + is: BN; +}; + +export type ReceiptReturnData = { + type: ReceiptType.ReturnData; + /** Contract ID of current context if in an internal context, zero otherwise (b256) */ + id: string; + /** Value of register $rA (u64) */ + ptr: BN; + /** Value of register $rB (u64) */ + len: BN; + /** Hash of MEM[$rA, $rB] (b256) */ + digest: string; + /** Value of register $pc (u64) */ + pc: BN; + /** Value of the memory range MEM[$rA, $rB]. */ + data: string; + /** Value of register $is (u64) */ + is: BN; +}; + +export type ReceiptPanic = { + type: ReceiptType.Panic; + /** Contract ID of current context if in an internal context, zero otherwise (b256) */ + id: string; + /** Panic reason (u64) */ + reason: BN; + /** Value of register $pc (u64) */ + pc: BN; + /** Value of register $is (u64) */ + is: BN; + /** Value of optional contract ID */ + contractId: string; +}; + +export type ReceiptRevert = { + type: ReceiptType.Revert; + /** Contract ID of current context if in an internal context, zero otherwise (b256) */ + id: string; + /** Value of register $rA (u64) */ + val: BN; + /** Value of register $pc (u64) */ + pc: BN; + /** Value of register $is (u64) */ + is: BN; +}; + +export type ReceiptLog = { + type: ReceiptType.Log; + /** Contract ID of current context if in an internal context, zero otherwise (b256) */ + id: string; + /** + * @deprecated This property is deprecated and it will be removed soon. Use property `ra` instead. + */ + val0: BN; + /** Value of register $rA (u64) */ + ra: BN; + /** + * @deprecated This property is deprecated and it will be removed soon. Use property `rb` instead. + */ + val1: BN; + /** Value of register $rB (u64) */ + rb: BN; + /** + * @deprecated This property is deprecated and it will be removed soon. Use property `rc` instead. + */ + val2: BN; + /** Value of register $rC (u64) */ + rc: BN; + /** + * @deprecated This property is deprecated and it will be removed soon. Use property `rd` instead. + */ + val3: BN; + /** Value of register $rD (u64) */ + rd: BN; + /** Value of register $pc (u64) */ + pc: BN; + /** Value of register $is (u64) */ + is: BN; +}; + +export type ReceiptLogData = { + type: ReceiptType.LogData; + /** Contract ID of current context if in an internal context, zero otherwise (b256) */ + id: string; + /** Value of register $rA (u64) */ + ra: BN; + /** + * @deprecated This property is deprecated and it will be removed soon. Use property `ra` instead. + */ + val0: BN; + /** Value of register $rB (u64) */ + rb: BN; + /** + * @deprecated This property is deprecated and it will be removed soon. Use property `rb` instead. + */ + val1: BN; + /** Value of register $rC (u64) */ + ptr: BN; + /** Value of register $rD (u64) */ + len: BN; + /** Hash of MEM[$rC, $rD] (b256) */ + digest: string; + /** Value of the memory range MEM[$rC, $rD]. */ + data: string; + /** Value of register $pc (u64) */ + pc: BN; + /** Value of register $is (u64) */ + is: BN; +}; + +export type ReceiptTransfer = { + type: ReceiptType.Transfer; + /** + * @deprecated This property is deprecated and it will be removed soon. Use property `id` instead. + */ + from: string; + /** Contract ID of current context if in an internal context, zero otherwise (b256) */ + id: string; + /** Contract ID of contract to transfer coins to (b256) */ + to: string; + /** Amount of coins transferred (u64) */ + amount: BN; + /** Asset ID of coins transferred (b256) */ + assetId: string; + /** Value of register $pc (u64) */ + pc: BN; + /** Value of register $is (u64) */ + is: BN; +}; + +export type ReceiptTransferOut = { + type: ReceiptType.TransferOut; + /** + * @deprecated This property is deprecated and it will be removed soon. Use property `id` instead. + */ + from: string; + /** Contract ID of current context if in an internal context, zero otherwise (b256) */ + id: string; + /** Address to transfer coins to (b256) */ + to: string; + /** Amount of coins transferred (u64) */ + amount: BN; + /** Asset ID of coins transferred (b256) */ + assetId: string; + /** Value of register $pc (u64) */ + pc: BN; + /** Value of register $is (u64) */ + is: BN; +}; + +export type ReceiptScriptResult = { + type: ReceiptType.ScriptResult; + /** Result variant with embedded `PanicReason` in first 8 bits and `instr` (u64) */ + result: BN; + /** Gas consumed by the script (u64) */ + gasUsed: BN; +}; + +export type ReceiptMessageOut = { + type: ReceiptType.MessageOut; + /** Hexadecimal string representation of the 256-bit (32-byte) message ID */ + messageId: string; + /** Hexadecimal string representation of the 256-bit (32-byte) address of the message sender: MEM[$fp, 32] */ + sender: string; + /** Hexadecimal string representation of the 256-bit (32-byte) address of the message recipient: MEM[$rA, 32] */ + recipient: string; + /** Hexadecimal string representation of a 64-bit unsigned integer; value of register $rD */ + amount: BN; + /** Hexadecimal string representation of the 256-bit (32-byte) message nonce */ + nonce: string; + /** Decimal string representation of a 16-bit unsigned integer; value of register $rC. */ + len: number; + /** Hexadecimal string representation of 256-bit (32-byte), hash of MEM[$rA + 32, $rB] */ + digest: string; + /** Hexadecimal string representation of the value of the memory range MEM[$rA + 32, $rB] */ + data: Uint8Array; +}; + +export type ReceiptMint = { + type: ReceiptType.Mint; + + subId: string; + + contractId: string; + + assetId: string; + + val: BN; + /** Value of register $pc (u64) */ + pc: BN; + /** Value of register $is (u64) */ + is: BN; +}; + +export type ReceiptBurn = { + type: ReceiptType.Burn; + + subId: string; + + contractId: string; + + assetId: string; + + val: BN; + /** Value of register $pc (u64) */ + pc: BN; + /** Value of register $is (u64) */ + is: BN; +}; + +export type Receipt = + | ReceiptCall + | ReceiptReturn + | ReceiptReturnData + | ReceiptPanic + | ReceiptRevert + | ReceiptLog + | ReceiptLogData + | ReceiptTransfer + | ReceiptTransferOut + | ReceiptScriptResult + | ReceiptMessageOut + | ReceiptMint + | ReceiptBurn; + +export const getMintedAssetId = (contractId: string, subId: string): string => { + const contractIdBytes = arrayify(contractId); + const subIdBytes = arrayify(subId); + + return sha256(concat([contractIdBytes, subIdBytes])); +}; + +export const createAssetId = (contractId: string, subId: string): AssetId => ({ + bits: getMintedAssetId(contractId, subId), +}); + +export const getMessageId = ( + value: Pick +): string => { + const parts: Uint8Array[] = []; + + parts.push(new ByteArrayCoder(32).encode(value.sender)); + parts.push(new ByteArrayCoder(32).encode(value.recipient)); + parts.push(new ByteArrayCoder(32).encode(value.nonce)); + parts.push(new BigNumberCoder('u64').encode(value.amount)); + parts.push(arrayify(value.data || '0x')); + + return sha256(concat(parts)); +};