From af5b033c5ffd9aab34c226bbc40b902ac9753396 Mon Sep 17 00:00:00 2001 From: Jordan Ribbink Date: Mon, 9 Jun 2025 07:20:36 -0700 Subject: [PATCH 01/11] Add `useCrossVmSpendFt` docs --- docs/tools/kit/index.md | 60 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 60 insertions(+) diff --git a/docs/tools/kit/index.md b/docs/tools/kit/index.md index 70b0ce5df6..fb646dc3e6 100644 --- a/docs/tools/kit/index.md +++ b/docs/tools/kit/index.md @@ -23,6 +23,7 @@ sidebar_position: 1 ### Cross-VM (Flow EVM ↔ Cadence) Hooks - [`useCrossVmTokenBalance`](#usecrossvmtokenbalance) – Query fungible token balances across Cadence and Flow EVM +- [`useCrossVmSpendNft`](#usecrossvmspendnft) – Bridge NFTs from Cadence to Flow EVM and execute arbitrary EVM transactions to atomically spend them ## Installation @@ -480,5 +481,64 @@ function QueryExample() { } ``` +--- + +### `useCrossVmSpendFt` + +```tsx +import { useCrossVmSpendFt } from "@onflow/kit" +``` + +Bridge NFTs from Cadence to Flow EVM and execute arbitrary EVM transactions to atomically spend them. + +#### Parameters: +- `mutation?: UseMutationOptions` – Optional TanStackQuery mutation options + +##### UseCrossVmSpendFtMutateArgs + +```typescript +interface UseCrossVmSpendFtMutateArgs { + vaultIdentifier: string; // Cadence vault identifier (e.g. "0x1cf0e2f2f715450.ExampleToken.Vault") + amount: string; // Amount of tokens to bridge, as a decimal string (e.g. "1.23") + calls: EVMBatchCall[]; // Array of EVM calls to execute after bridging +} +``` + +#### Returns: `UseMutationResult` + +```tsx +function CrossVmSpendFtExample() { + const { spendFt, isPending, error, data: txId } = useCrossVmSpendFt() + + const handleSpendFt = () => { + spendFt({ + vaultIdentifier: "0x1cf0e2f2f715450.ExampleToken.Vault", // Cadence vault identifier + amount: "1.23", // Amount of tokens to bridge to EVM + calls: [ + { + abi: myEvmContractAbi, // EVM contract ABI + address: "0x01234567890abcdef01234567890abcdef", // EVM contract address + function: "transfer", // EVM function to call + args: [ + "0xabcdef01234567890abcdef01234567890abcdef", // Recipient address + ], + }, + ], + }) + } + + return ( +
+ + {isPending &&

Sending transaction...

} + {error &&

Error: {error.message}

} + {txId &&

Cadence Transaction ID: {txId}

} +
+ ) +} +``` + [commit-reveal scheme]: ../../build/advanced-concepts/randomness#commit-reveal-scheme [Configuration Guide]: ../flow-cli/flow.json/configuration.md From ad5012bc348a90cf02b466c319c3d868b5328a03 Mon Sep 17 00:00:00 2001 From: Jordan Ribbink Date: Mon, 9 Jun 2025 07:26:17 -0700 Subject: [PATCH 02/11] rename --- docs/tools/kit/index.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/tools/kit/index.md b/docs/tools/kit/index.md index fb646dc3e6..3165026ea0 100644 --- a/docs/tools/kit/index.md +++ b/docs/tools/kit/index.md @@ -494,7 +494,7 @@ Bridge NFTs from Cadence to Flow EVM and execute arbitrary EVM transactions to a #### Parameters: - `mutation?: UseMutationOptions` – Optional TanStackQuery mutation options -##### UseCrossVmSpendFtMutateArgs +Where `UseCrossVmSpendFtMutateArgs` is defined as: ```typescript interface UseCrossVmSpendFtMutateArgs { From c6aa0083e6f09242d983123c70f0e4be5ddee22e Mon Sep 17 00:00:00 2001 From: Jordan Ribbink Date: Mon, 9 Jun 2025 14:56:25 -0700 Subject: [PATCH 03/11] update result --- docs/tools/kit/index.md | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/docs/tools/kit/index.md b/docs/tools/kit/index.md index 3165026ea0..a155d303c1 100644 --- a/docs/tools/kit/index.md +++ b/docs/tools/kit/index.md @@ -504,7 +504,19 @@ interface UseCrossVmSpendFtMutateArgs { } ``` -#### Returns: `UseMutationResult` +#### Returns: `UseCrossVmSpendFtResult` + +Where `UseCrossVmSpendFtResult` is defined as: + +```typescript +type UseCrossVmSpendFtResult = Omit< + UseMutationResult, + "mutate" | "mutateAsync" +> & { + spendFt: (args: UseCrossVmSpendFtMutateArgs) => void; // Function to trigger the FT bridging and EVM calls + spendFtAsync: (args: UseCrossVmSpendFtMutateArgs) => Promise; // Async version of spendFt +} +``` ```tsx function CrossVmSpendFtExample() { From 3d639c1292800776e16385143b2501e8691acb14 Mon Sep 17 00:00:00 2001 From: Jordan Ribbink Date: Mon, 9 Jun 2025 14:57:22 -0700 Subject: [PATCH 04/11] add internal type comment --- docs/tools/kit/index.md | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/tools/kit/index.md b/docs/tools/kit/index.md index a155d303c1..4031fe7ff0 100644 --- a/docs/tools/kit/index.md +++ b/docs/tools/kit/index.md @@ -497,6 +497,7 @@ Bridge NFTs from Cadence to Flow EVM and execute arbitrary EVM transactions to a Where `UseCrossVmSpendFtMutateArgs` is defined as: ```typescript +// internal type, not exported interface UseCrossVmSpendFtMutateArgs { vaultIdentifier: string; // Cadence vault identifier (e.g. "0x1cf0e2f2f715450.ExampleToken.Vault") amount: string; // Amount of tokens to bridge, as a decimal string (e.g. "1.23") From 119c87bd395fd63d296dc84956b784a003043ed0 Mon Sep 17 00:00:00 2001 From: Jordan Ribbink Date: Mon, 9 Jun 2025 14:57:39 -0700 Subject: [PATCH 05/11] remove type --- docs/tools/kit/index.md | 1 - 1 file changed, 1 deletion(-) diff --git a/docs/tools/kit/index.md b/docs/tools/kit/index.md index 4031fe7ff0..a155d303c1 100644 --- a/docs/tools/kit/index.md +++ b/docs/tools/kit/index.md @@ -497,7 +497,6 @@ Bridge NFTs from Cadence to Flow EVM and execute arbitrary EVM transactions to a Where `UseCrossVmSpendFtMutateArgs` is defined as: ```typescript -// internal type, not exported interface UseCrossVmSpendFtMutateArgs { vaultIdentifier: string; // Cadence vault identifier (e.g. "0x1cf0e2f2f715450.ExampleToken.Vault") amount: string; // Amount of tokens to bridge, as a decimal string (e.g. "1.23") From aab8b19ce53f679167177c81342707bf8d070978 Mon Sep 17 00:00:00 2001 From: Jordan Ribbink Date: Mon, 9 Jun 2025 15:12:02 -0700 Subject: [PATCH 06/11] switch to interface --- docs/tools/kit/index.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/tools/kit/index.md b/docs/tools/kit/index.md index a155d303c1..56af7f020c 100644 --- a/docs/tools/kit/index.md +++ b/docs/tools/kit/index.md @@ -509,10 +509,10 @@ interface UseCrossVmSpendFtMutateArgs { Where `UseCrossVmSpendFtResult` is defined as: ```typescript -type UseCrossVmSpendFtResult = Omit< +interface UseCrossVmSpendFtResult extends Omit< UseMutationResult, "mutate" | "mutateAsync" -> & { +> { spendFt: (args: UseCrossVmSpendFtMutateArgs) => void; // Function to trigger the FT bridging and EVM calls spendFtAsync: (args: UseCrossVmSpendFtMutateArgs) => Promise; // Async version of spendFt } From 02b680e2c41f176b2abe2e15fbf5943126f4b502 Mon Sep 17 00:00:00 2001 From: Jordan Ribbink Date: Mon, 9 Jun 2025 15:18:58 -0700 Subject: [PATCH 07/11] fix NFT --- docs/tools/kit/index.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/tools/kit/index.md b/docs/tools/kit/index.md index 56af7f020c..70ef81061c 100644 --- a/docs/tools/kit/index.md +++ b/docs/tools/kit/index.md @@ -489,7 +489,7 @@ function QueryExample() { import { useCrossVmSpendFt } from "@onflow/kit" ``` -Bridge NFTs from Cadence to Flow EVM and execute arbitrary EVM transactions to atomically spend them. +Bridge FTs from Cadence to Flow EVM and execute arbitrary EVM transactions to atomically spend them. #### Parameters: - `mutation?: UseMutationOptions` – Optional TanStackQuery mutation options From 12821b2f2751b6bfc99af4be1dcffd90f9caf6ef Mon Sep 17 00:00:00 2001 From: Jordan Ribbink Date: Mon, 9 Jun 2025 15:31:42 -0700 Subject: [PATCH 08/11] add emu callout --- docs/tools/kit/index.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/docs/tools/kit/index.md b/docs/tools/kit/index.md index 70ef81061c..6c6b164981 100644 --- a/docs/tools/kit/index.md +++ b/docs/tools/kit/index.md @@ -485,6 +485,10 @@ function QueryExample() { ### `useCrossVmSpendFt` + +This feature is currently only supported on Testnet & Mainnet networks. Emulator support will be added in a future release. + + ```tsx import { useCrossVmSpendFt } from "@onflow/kit" ``` From 47e4417857af94fe9581a3b5d2c6bef887c7ce4e Mon Sep 17 00:00:00 2001 From: Jordan Ribbink Date: Mon, 9 Jun 2025 15:42:17 -0700 Subject: [PATCH 09/11] Add callout to token balance hook --- docs/tools/kit/index.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/docs/tools/kit/index.md b/docs/tools/kit/index.md index 6c6b164981..36ba59acd1 100644 --- a/docs/tools/kit/index.md +++ b/docs/tools/kit/index.md @@ -421,6 +421,10 @@ function TransactionStatusComponent() { ### `useCrossVmTokenBalance` + +This feature is currently only supported on Testnet & Mainnet networks. Emulator support will be added in a future release. + + ```tsx import { useFlowQuery } from '@onflow/kit'; ``` From 87d461111cd85ee2a436e14454715b0685f2c895 Mon Sep 17 00:00:00 2001 From: Jordan Ribbink Date: Tue, 10 Jun 2025 09:41:58 -0700 Subject: [PATCH 10/11] update naming --- docs/tools/kit/index.md | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/docs/tools/kit/index.md b/docs/tools/kit/index.md index 36ba59acd1..389b974ee2 100644 --- a/docs/tools/kit/index.md +++ b/docs/tools/kit/index.md @@ -487,51 +487,51 @@ function QueryExample() { --- -### `useCrossVmSpendFt` +### `useCrossVmSpendToken` This feature is currently only supported on Testnet & Mainnet networks. Emulator support will be added in a future release. ```tsx -import { useCrossVmSpendFt } from "@onflow/kit" +import { useCrossVmSpendToken } from "@onflow/kit" ``` Bridge FTs from Cadence to Flow EVM and execute arbitrary EVM transactions to atomically spend them. #### Parameters: -- `mutation?: UseMutationOptions` – Optional TanStackQuery mutation options +- `mutation?: UseMutationOptions` – Optional TanStackQuery mutation options -Where `UseCrossVmSpendFtMutateArgs` is defined as: +Where `UseCrossVmSpendTokenMutateArgs` is defined as: ```typescript -interface UseCrossVmSpendFtMutateArgs { +interface UseCrossVmSpendTokenMutateArgs { vaultIdentifier: string; // Cadence vault identifier (e.g. "0x1cf0e2f2f715450.ExampleToken.Vault") amount: string; // Amount of tokens to bridge, as a decimal string (e.g. "1.23") calls: EVMBatchCall[]; // Array of EVM calls to execute after bridging } ``` -#### Returns: `UseCrossVmSpendFtResult` +#### Returns: `UseCrossVmSpendTokenResult` -Where `UseCrossVmSpendFtResult` is defined as: +Where `UseCrossVmSpendTokenResult` is defined as: ```typescript -interface UseCrossVmSpendFtResult extends Omit< - UseMutationResult, +interface UseCrossVmSpendTokenResult extends Omit< + UseMutationResult, "mutate" | "mutateAsync" > { - spendFt: (args: UseCrossVmSpendFtMutateArgs) => void; // Function to trigger the FT bridging and EVM calls - spendFtAsync: (args: UseCrossVmSpendFtMutateArgs) => Promise; // Async version of spendFt + spendToken: (args: UseCrossVmSpendTokenMutateArgs) => void; // Function to trigger the FT bridging and EVM calls + spendTokenAsync: (args: UseCrossVmSpendTokenMutateArgs) => Promise; // Async version of spendToken } ``` ```tsx -function CrossVmSpendFtExample() { - const { spendFt, isPending, error, data: txId } = useCrossVmSpendFt() +function CrossVmSpendTokenExample() { + const { spendToken, isPending, error, data: txId } = useCrossVmSpendToken() - const handleSpendFt = () => { - spendFt({ + const handleSpendToken = () => { + spendToken({ vaultIdentifier: "0x1cf0e2f2f715450.ExampleToken.Vault", // Cadence vault identifier amount: "1.23", // Amount of tokens to bridge to EVM calls: [ From 48afa32691b10476c39784eb1e68898a97053df0 Mon Sep 17 00:00:00 2001 From: Jordan Ribbink <17958158+jribbink@users.noreply.github.com> Date: Tue, 10 Jun 2025 10:11:39 -0700 Subject: [PATCH 11/11] Add `useCrossVmBatchTransaction` docs (#1294) --- docs/tools/kit/index.md | 104 ++++++++++++++++++- docs/tutorials/cross-vm-apps/add-to-wagmi.md | 5 + 2 files changed, 107 insertions(+), 2 deletions(-) diff --git a/docs/tools/kit/index.md b/docs/tools/kit/index.md index 389b974ee2..8a386fe87b 100644 --- a/docs/tools/kit/index.md +++ b/docs/tools/kit/index.md @@ -23,7 +23,8 @@ sidebar_position: 1 ### Cross-VM (Flow EVM ↔ Cadence) Hooks - [`useCrossVmTokenBalance`](#usecrossvmtokenbalance) – Query fungible token balances across Cadence and Flow EVM -- [`useCrossVmSpendNft`](#usecrossvmspendnft) – Bridge NFTs from Cadence to Flow EVM and execute arbitrary EVM transactions to atomically spend them +- [`useCrossVmBatchTransaction`](#usecrossvmbatchtransaction) – Execute mutliple EVM transactions in a single atomic Cadence transaction +- [`useCrossVmSpendToken`](#usecrossvmspendnft) – Bridge fungible tokens from Cadence to Flow EVM and execute arbitrary EVM transactions ## Installation @@ -487,6 +488,105 @@ function QueryExample() { --- +## Cross-VM Hooks + +### `useCrossVmBatchTransaction` + + +This feature is currently only supported on Testnet & Mainnet networks. Emulator support will be added in a future release. + + +```tsx +import { useCrossVmBatchTransaction } from "@onflow/kit" +``` + +This hook allows you to execute multiple EVM transactions in a single atomic Cadence transaction. It is useful for batch processing EVM calls while ensuring they are executed together, either all succeeding or allowing for some to fail without affecting the others. + +#### Parameters: +- `mutation?: UseMutationOptions` – Optional TanStackQuery mutation options + +#### Returns: `UseCrossVmBatchTransactionResult` + +Where `UseCrossVmBatchTransactionResult` is defined as: + +```typescript +interface UseCrossVmBatchTransactionResult extends Omit< + UseMutationResult, + "mutate" | "mutateAsync" +> { + mutate: (calls: UseCrossVmBatchTransactionMutateArgs) => void + mutateAsync: (calls: UseCrossVmBatchTransactionMutateArgs) => Promise +} +``` + +Where `UseCrossVmBatchTransactionMutateArgs` is defined as: + +```typescript +interface UseCrossVmBatchTransactionMutateArgs { + calls: EvmBatchCall[] + mustPass?: boolean +} +``` + +Where `EvmBatchCall` is defined as: + +```typescript +interface EvmBatchCall { + // The target EVM contract address (as a string) + address: string + // The contract ABI fragment + abi: Abi + // The name of the function to call + functionName: string + // The function arguments + args?: readonly unknown[] + // The gas limit for the call + gasLimit?: bigint + // The value to send with the call + value?: bigint +} +``` + +```tsx +function CrossVmBatchTransactionExample() { + const { sendBatchTransaction, isPending, error, data: txId } = useCrossVmBatchTransaction({ + mutation: { + onSuccess: (txId) => console.log("TX ID:", txId), + }, + }) + + const sendTransaction = () => { + const calls = [ + { + address: "0x1234567890abcdef", + abi: { + // ABI definition for the contract + }, + functionName: "transfer", + args: ["0xabcdef1234567890", 100n], // Example arguments + gasLimit: 21000n, // Example gas limit + }, + // Add more calls as needed + ] + + sendBatchTransaction({calls}) + } + + return ( +
+ + {isPending &&

Sending transaction...

} + {error &&

Error: {error.message}

} + {txId &&

Transaction ID: {txId}

} +
+ ) +} +``` + +--- + ### `useCrossVmSpendToken` @@ -549,7 +649,7 @@ function CrossVmSpendTokenExample() { return (
- {isPending &&

Sending transaction...

} diff --git a/docs/tutorials/cross-vm-apps/add-to-wagmi.md b/docs/tutorials/cross-vm-apps/add-to-wagmi.md index f351790152..9fb7472ebe 100644 --- a/docs/tutorials/cross-vm-apps/add-to-wagmi.md +++ b/docs/tutorials/cross-vm-apps/add-to-wagmi.md @@ -129,6 +129,10 @@ export const config = createConfig({ ## Step 3: Add the Batch Transaction Utility + +You can skip this step by using a [pre-built utility from the `@onflow/kit`] package. However, if you want to understand how batch transactions work under the hood, continue with this custom implementation. + + Create a custom hook in `src/hooks/useBatchTransactions.ts` to handle batch transactions. This utility allows you to execute multiple EVM transactions in a single Cadence transaction: ```typescript @@ -512,3 +516,4 @@ For a complete reference implementation, check out the [FCL + RainbowKit + wagmi [Testnet Cadence Flowscan]: https://testnet.flowscan.io [Cadence Owned Accounts]: ../../build/basics/accounts.md [Testnet EVM Flowscan]: https://evm-testnet.flowscan.io +[pre-built utility from the `@onflow/kit`]: ../../tools/kit/index.md#usecrossvmbatchtransaction \ No newline at end of file