Skip to content

Commit f3eeeeb

Browse files
committed
feat: ethers useSendTransaction implementation
1 parent 6eae963 commit f3eeeeb

File tree

1 file changed

+112
-1
lines changed

1 file changed

+112
-1
lines changed

packages/react/src/ethers.ts

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

0 commit comments

Comments
 (0)