Skip to content

Commit 85d93fc

Browse files
committed
feat: useSendTransaction for viem/wagmi
1 parent 41efde2 commit 85d93fc

File tree

2 files changed

+127
-1
lines changed

2 files changed

+127
-1
lines changed
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
import { describe, it } from 'vitest';
2+
import { client, wallet } from '../test-utils';
3+
import { sendWith } from '../viem';
4+
import { supply } from './transactions';
5+
6+
describe('Transactions', () => {
7+
it('should be able to run a test', async () => {
8+
const result = await supply(client, {} as any).andThen(sendWith(wallet));
9+
});
10+
});

packages/react/src/viem.ts

Lines changed: 117 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1,117 @@
1-
export {};
1+
import type {
2+
SigningError,
3+
UnexpectedError,
4+
ValidationError,
5+
} from '@aave/client';
6+
import { sendTransactionAndWait } from '@aave/client/viem';
7+
import type {
8+
InsufficientBalanceError,
9+
TransactionRequest,
10+
} from '@aave/graphql';
11+
import { invariant } from '@aave/types';
12+
import type { WalletClient } from 'viem';
13+
import type { TxHash } from '../../types/dist';
14+
import { type UseAsyncTask, useAsyncTask } from './helpers';
15+
16+
export type TransactionError =
17+
| SigningError
18+
| ValidationError<InsufficientBalanceError>
19+
| UnexpectedError;
20+
21+
/**
22+
* A hook that provides a way to send Aave transactions using a viem WalletClient instance.
23+
*
24+
* First, use the `useWalletClient` wagmi hook to get the `WalletClient` instance, then pass it to this hook to create a function that can be used to send transactions.
25+
*
26+
* ```ts
27+
* const { data: wallet } = useWalletClient(); // wagmi hook
28+
*
29+
* const [sendTransaction, { loading, error, data }] = useSendTransaction(wallet);
30+
* ```
31+
*
32+
* Then, use it to send a {@link TransactionRequest} as shown below.
33+
*
34+
* ```ts
35+
* const account = useAccount(); // wagmi hook
36+
*
37+
* const [toggle, { loading, error, data }] = useEModeToggle();
38+
*
39+
* const run = async () => {
40+
* const result = await toggle({
41+
* chainId: chainId(1), // Ethereum mainnet
42+
* market: evmAddress('0x1234…'),
43+
* user: evmAddress(account.address!),
44+
* })
45+
* .andThen(sendTransaction);
46+
*
47+
* if (result.isErr()) {
48+
* console.error(`Failed to sign the transaction: ${error.message}`);
49+
* return;
50+
* }
51+
*
52+
* console.log('Transaction sent with hash:', result.value);
53+
* };
54+
* ```
55+
*
56+
* Or use it to handle an {@link ExecutionPlan} that may require multiple transactions as shown below.
57+
*
58+
* ```ts
59+
* const account = useAccount(); // wagmi hook
60+
*
61+
* const [supply, { loading, error, data }] = useSupply();
62+
*
63+
* const run = async () => {
64+
* const result = await supply({
65+
* chainId: chainId(1), // Ethereum mainnet
66+
* market: evmAddress('0x1234…'),
67+
* amount: {
68+
* erc20: {
69+
* currency: evmAddress('0x5678…'),
70+
* value: '42.42',
71+
* }
72+
* },
73+
* supplier: evmAddress(account.address!),
74+
* })
75+
* .andThen((plan) => {
76+
* switch (plan.__typename) {
77+
* case 'TransactionRequest':
78+
* return sendTransaction(plan);
79+
*
80+
* case 'ApprovalRequired':
81+
* return sendTransaction(plan.approval).andThen(() =>
82+
* sendTransaction(plan.originalTransaction),
83+
* );
84+
* }
85+
* });
86+
*
87+
* if (result.isErr()) {
88+
* switch (error.name) {
89+
* case 'SigningError':
90+
* console.error(`Failed to sign the transaction: ${error.message}`);
91+
* break;
92+
*
93+
* case 'ValidationError':
94+
* console.error(`Insufficient balance: ${error.cause.required.value} required.`);
95+
* break;
96+
* }
97+
* return;
98+
* }
99+
*
100+
* console.log('Transaction sent with hash:', result.value);
101+
* }
102+
* ```
103+
*
104+
* @param walletClient - The wallet client to use for sending transactions.
105+
*/
106+
export function useSendTransaction(
107+
walletClient: WalletClient | undefined,
108+
): UseAsyncTask<TransactionRequest, TxHash, TransactionError> {
109+
return useAsyncTask((request: TransactionRequest) => {
110+
invariant(
111+
walletClient,
112+
'Expected a WalletClient to handle the operation result.',
113+
);
114+
115+
return sendTransactionAndWait(walletClient, request);
116+
});
117+
}

0 commit comments

Comments
 (0)