diff --git a/.changeset/lovely-rivers-impress.md b/.changeset/lovely-rivers-impress.md new file mode 100644 index 00000000000..35fdf6b03e6 --- /dev/null +++ b/.changeset/lovely-rivers-impress.md @@ -0,0 +1,6 @@ +--- +"@fuel-ts/abi-typegen": patch +"@fuel-ts/abi-coder": patch +--- + +feat: support message types diff --git a/packages/abi-coder/src/types/JsonAbiNew.ts b/packages/abi-coder/src/types/JsonAbiNew.ts index 4d9481c1128..6aff2ad11c1 100644 --- a/packages/abi-coder/src/types/JsonAbiNew.ts +++ b/packages/abi-coder/src/types/JsonAbiNew.ts @@ -91,7 +91,7 @@ export interface LoggedType { } export interface MessageType { - readonly message_id: string; + readonly messageId: string; readonly concreteTypeId: string; } export interface Configurable { diff --git a/packages/abi-coder/test/fixtures/forc-projects/exhaustive-examples/src/main.sw b/packages/abi-coder/test/fixtures/forc-projects/exhaustive-examples/src/main.sw index abed2d93caf..388aaa095ba 100644 --- a/packages/abi-coder/test/fixtures/forc-projects/exhaustive-examples/src/main.sw +++ b/packages/abi-coder/test/fixtures/forc-projects/exhaustive-examples/src/main.sw @@ -2,6 +2,7 @@ contract; use std::b512::B512; use std::bytes::Bytes; use std::string::String; +use std::message::send_typed_message; enum EnumWithGeneric { VariantOne: A, @@ -181,6 +182,8 @@ abi MyContract { arg3: (str[5], bool), arg4: MyOtherStruct, ); + #[payable] + fn send_typed_message_bool(recipient: b256, msg_data: bool, coins: u64); } impl MyContract for Contract { @@ -339,4 +342,8 @@ impl MyContract for Contract { fn simple_vector(arg: Vec) -> Vec { arg } + #[payable] + fn send_typed_message_bool(recipient: b256, msg_data: bool, coins: u64) { + send_typed_message(recipient, msg_data, coins); + } } diff --git a/packages/abi-typegen/src/types/interfaces/JsonAbiNew.ts b/packages/abi-typegen/src/types/interfaces/JsonAbiNew.ts index 4d9481c1128..6aff2ad11c1 100644 --- a/packages/abi-typegen/src/types/interfaces/JsonAbiNew.ts +++ b/packages/abi-typegen/src/types/interfaces/JsonAbiNew.ts @@ -91,7 +91,7 @@ export interface LoggedType { } export interface MessageType { - readonly message_id: string; + readonly messageId: string; readonly concreteTypeId: string; } export interface Configurable { diff --git a/packages/fuel-gauge/src/contract.test.ts b/packages/fuel-gauge/src/contract.test.ts index ceddce13951..23948c13eb4 100644 --- a/packages/fuel-gauge/src/contract.test.ts +++ b/packages/fuel-gauge/src/contract.test.ts @@ -13,14 +13,16 @@ import { Predicate, PolicyType, buildFunctionResult, + ReceiptType, } from 'fuels'; -import type { ScriptTransactionRequest, TransferParams } from 'fuels'; +import type { ReceiptMessageOut, ScriptTransactionRequest, TransferParams } from 'fuels'; import { expectToThrowFuelError, ASSET_A, ASSET_B, launchTestNode } from 'fuels/test-utils'; import type { DeployContractConfig } from 'fuels/test-utils'; import { CallTestContract, CallTestContractFactory, + SmoContractFactory, StorageTestContract, StorageTestContractFactory, } from '../test/typegen/contracts'; @@ -1111,4 +1113,51 @@ describe('Contract', () => { expect(scriptGasLimit?.toNumber()).toBe(gasLimit); expect(bn(maxFeePolicy?.data).toNumber()).toBe(maxFee); }); + + it('can call SMO contract', async () => { + using launched = await launchTestNode({ + contractsConfigs: [ + { + factory: SmoContractFactory, + }, + ], + }); + + const { + provider, + wallets: [recipient], + contracts: [contract], + } = launched; + + const data = [1, 2, 3, 4, 5, 6, 7, 8]; + const baseAssetId = provider.getBaseAssetId(); + + const { waitForResult } = await contract + .multiCall([ + contract.functions + .send_typed_message_u8(recipient.address.toB256(), 10, 1) + .callParams({ forward: [1, baseAssetId] }), + contract.functions + .send_typed_message_bool(recipient.address.toB256(), true, 1) + .callParams({ forward: [1, baseAssetId] }), + contract.functions + .send_typed_message_bytes(recipient.address.toB256(), data, 1) + .callParams({ forward: [1, baseAssetId] }), + ]) + .call(); + + const { + transactionResult: { receipts }, + } = await waitForResult(); + + const messageOutReceipts = receipts.filter( + ({ type }) => ReceiptType.MessageOut === type + ) as ReceiptMessageOut[]; + + expect(messageOutReceipts.length).toBe(3); + + messageOutReceipts.forEach((receipt) => { + expect(receipt.recipient).toBe(recipient.address.toB256()); + }); + }); }); diff --git a/packages/fuel-gauge/test/fixtures/forc-projects/Forc.toml b/packages/fuel-gauge/test/fixtures/forc-projects/Forc.toml index 1520dd7b675..a7dc648d366 100644 --- a/packages/fuel-gauge/test/fixtures/forc-projects/Forc.toml +++ b/packages/fuel-gauge/test/fixtures/forc-projects/Forc.toml @@ -18,6 +18,7 @@ members = [ "generic-types-contract", "large-contract", "multi-token-contract", + "smo-contract", "options", "payable-annotation", "predicate-address", diff --git a/packages/fuel-gauge/test/fixtures/forc-projects/smo-contract/Forc.toml b/packages/fuel-gauge/test/fixtures/forc-projects/smo-contract/Forc.toml new file mode 100644 index 00000000000..96cfa63afbd --- /dev/null +++ b/packages/fuel-gauge/test/fixtures/forc-projects/smo-contract/Forc.toml @@ -0,0 +1,7 @@ +[project] +authors = ["Fuel Labs "] +entry = "main.sw" +license = "Apache-2.0" +name = "smo-contract" + +[dependencies] diff --git a/packages/fuel-gauge/test/fixtures/forc-projects/smo-contract/src/main.sw b/packages/fuel-gauge/test/fixtures/forc-projects/smo-contract/src/main.sw new file mode 100644 index 00000000000..7463a9c2496 --- /dev/null +++ b/packages/fuel-gauge/test/fixtures/forc-projects/smo-contract/src/main.sw @@ -0,0 +1,28 @@ +contract; + +use std::message::send_typed_message; +use std::bytes::Bytes; + +abi SMOContract { + #[payable] + fn send_typed_message_bool(recipient: b256, msg_data: bool, coins: u64); + #[payable] + fn send_typed_message_u8(recipient: b256, msg_data: u8, coins: u64); + #[payable] + fn send_typed_message_bytes(recipient: b256, msg_data: Bytes, coins: u64); +} + +impl SMOContract for Contract { + #[payable] + fn send_typed_message_bool(recipient: b256, msg_data: bool, coins: u64) { + send_typed_message(recipient, msg_data, coins); + } + #[payable] + fn send_typed_message_u8(recipient: b256, msg_data: u8, coins: u64) { + send_typed_message(recipient, msg_data, coins); + } + #[payable] + fn send_typed_message_bytes(recipient: b256, msg_data: Bytes, coins: u64) { + send_typed_message(recipient, msg_data, coins); + } +}