Skip to content

Commit 31ea182

Browse files
committed
fix: viem's adapter to use WalletClient.account in sendTransaction
1 parent 582c25a commit 31ea182

File tree

10 files changed

+131
-145
lines changed

10 files changed

+131
-145
lines changed

packages/client/src/test-utils.ts

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,13 +10,15 @@ import {
1010
ResultAsync,
1111
} from '@aave/types-next';
1212
import {
13+
type Account,
1314
type Chain,
1415
createPublicClient,
1516
createWalletClient,
1617
defineChain,
1718
http,
1819
parseEther,
1920
parseUnits,
21+
type Transport,
2022
type WalletClient,
2123
} from 'viem';
2224
import { generatePrivateKey, privateKeyToAccount } from 'viem/accounts';
@@ -95,14 +97,18 @@ export const client = AaveClient.create({
9597
},
9698
});
9799

98-
export function createNewWallet(
100+
export async function createNewWallet(
99101
privateKey: `0x${string}` = generatePrivateKey(),
100-
): WalletClient {
101-
return createWalletClient({
102+
): Promise<WalletClient<Transport, Chain, Account>> {
103+
const wallet = createWalletClient({
102104
account: privateKeyToAccount(privateKey),
103105
chain: ethereumForkChain,
104106
transport: http(),
105107
});
108+
109+
await fundNativeAddress(evmAddress(wallet.account.address));
110+
111+
return wallet;
106112
}
107113

108114
// Tenderly RPC type for setBalance

packages/client/src/viem.test.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,14 +18,14 @@ import { setupRpcInterceptor } from './rpc.helpers';
1818
import { createNewWallet } from './test-utils';
1919
import { sendWith } from './viem';
2020

21-
const walletClient = createNewWallet();
21+
const walletClient = await createNewWallet();
2222

2323
describe(`Given a viem's WalletClient instance`, () => {
2424
describe(`And the '${sendWith.name}' handler is used to send a TransactionRequest`, () => {
2525
const request: TransactionRequest = {
2626
__typename: 'TransactionRequest',
27-
to: evmAddress(walletClient.account!.address),
28-
from: evmAddress(walletClient.account!.address),
27+
to: evmAddress(walletClient.account.address),
28+
from: evmAddress(walletClient.account.address),
2929
data: '0x' as BlockchainData,
3030
value: 0n,
3131
chainId: chainId(1),

packages/client/src/viem.ts

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -24,12 +24,14 @@ import {
2424
txHash,
2525
} from '@aave/types-next';
2626
import {
27+
type Account,
2728
type Chain,
2829
type defineChain,
2930
type ProviderRpcError,
3031
type RpcError,
3132
SwitchChainError,
3233
TransactionExecutionError,
34+
type Transport,
3335
type TypedData,
3436
type TypedDataDomain,
3537
UserRejectedRequestError,
@@ -117,12 +119,12 @@ function ensureChain(
117119
}
118120

119121
function sendEip1559Transaction(
120-
walletClient: WalletClient,
122+
walletClient: WalletClient<Transport, Chain, Account>,
121123
request: TransactionRequest,
122124
): ResultAsync<TxHash, CancelError | SigningError> {
123125
return ResultAsync.fromPromise(
124126
sendTransactionWithViem(walletClient, {
125-
account: request.from,
127+
account: walletClient.account,
126128
data: request.data,
127129
to: request.to,
128130
value: BigInt(request.value),
@@ -143,14 +145,23 @@ function sendEip1559Transaction(
143145
).map(txHash);
144146
}
145147

148+
function isWalletClientWithAccount(
149+
walletClient: WalletClient,
150+
): walletClient is WalletClient<Transport, Chain, Account> {
151+
return walletClient.account !== undefined;
152+
}
153+
146154
/**
147155
* @internal
148156
*/
149157
export function sendTransaction(
150158
walletClient: WalletClient,
151159
request: TransactionRequest,
152160
): ResultAsync<TxHash, CancelError | SigningError> {
153-
// TODO: verify if wallet account is correct, switch if possible
161+
invariant(
162+
isWalletClientWithAccount(walletClient),
163+
'Wallet client with account is required',
164+
);
154165

155166
return ensureChain(walletClient, request).andThen((_) =>
156167
sendEip1559Transaction(walletClient, request),

packages/spec/borrow/business.spec.ts

Lines changed: 9 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -12,21 +12,19 @@ import { beforeAll, describe, expect, it } from 'vitest';
1212
import { assertSingleElementArray } from '../test-utils';
1313
import { supplyToRandomERC20Reserve } from './helper';
1414

15+
const user = await createNewWallet();
16+
1517
describe('Aave V4 Borrow Scenarios', () => {
1618
describe('Given a user with a supply position as collateral', () => {
1719
describe('When the user borrows an ERC20 asset', () => {
18-
const user = createNewWallet();
1920
let reserve: Reserve;
2021

2122
beforeAll(async () => {
22-
const setup = await fundErc20Address(
23-
evmAddress(user.account!.address),
24-
{
25-
address: ETHEREUM_USDC_ADDRESS,
26-
amount: bigDecimal('100'),
27-
decimals: 6,
28-
},
29-
).andThen(() =>
23+
const setup = await fundErc20Address(evmAddress(user.account.address), {
24+
address: ETHEREUM_USDC_ADDRESS,
25+
amount: bigDecimal('100'),
26+
decimals: 6,
27+
}).andThen(() =>
3028
supplyToRandomERC20Reserve(client, user, ETHEREUM_USDC_ADDRESS),
3129
);
3230

@@ -38,7 +36,7 @@ describe('Aave V4 Borrow Scenarios', () => {
3836
const amountToBorrow = bigDecimal('50');
3937

4038
const result = await borrow(client, {
41-
sender: evmAddress(user.account!.address),
39+
sender: evmAddress(user.account.address),
4240
reserve: {
4341
spoke: reserve.spoke.address,
4442
reserveId: reserve.id,
@@ -60,7 +58,7 @@ describe('Aave V4 Borrow Scenarios', () => {
6058
address: reserve.spoke.address,
6159
chainId: reserve.chain.chainId,
6260
},
63-
user: evmAddress(user.account!.address),
61+
user: evmAddress(user.account.address),
6462
},
6563
},
6664
}),

packages/spec/borrow/helper.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -11,12 +11,12 @@ import {
1111
import { reserves, supply } from '@aave/client-next/actions';
1212
import { ETHEREUM_FORK_ID } from '@aave/client-next/test-utils';
1313
import { sendWith } from '@aave/client-next/viem';
14-
import type { WalletClient } from 'viem';
14+
import type { Account, Chain, Transport, WalletClient } from 'viem';
1515

1616
export function supplyToReserve(
1717
client: AaveClient,
1818
request: SupplyRequest,
19-
user: WalletClient,
19+
user: WalletClient<Transport, Chain, Account>,
2020
): ResultAsync<TxHash, Error> {
2121
return supply(client, request)
2222
.andThen(sendWith(user))
@@ -55,7 +55,7 @@ export function findReserveToSupply(
5555

5656
export function supplyToRandomERC20Reserve(
5757
client: AaveClient,
58-
user: WalletClient,
58+
user: WalletClient<Transport, Chain, Account>,
5959
token: EvmAddress,
6060
amount = bigDecimal('100'),
6161
): ResultAsync<Reserve, Error> {
@@ -69,7 +69,7 @@ export function supplyToRandomERC20Reserve(
6969
spoke: reserve.spoke.address,
7070
},
7171
amount: { erc20: { value: amount } },
72-
sender: evmAddress(user.account!.address),
72+
sender: evmAddress(user.account.address),
7373
},
7474
user,
7575
).map(() => reserve),

packages/spec/positions/business.spec.ts

Lines changed: 28 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -23,20 +23,17 @@ import { beforeAll, describe, expect, it } from 'vitest';
2323
import { supplyToRandomERC20Reserve, supplyToReserve } from '../borrow/helper';
2424
import { supplyAndBorrow } from '../repay/helper';
2525

26+
const user = await createNewWallet();
27+
2628
describe('Aave V4 Health Factor Positions Scenarios', () => {
2729
describe('Given a user with a one supply position as collateral', () => {
2830
describe('When the user checks the health factor', () => {
29-
const user = createNewWallet();
30-
3131
beforeAll(async () => {
32-
const setup = await fundErc20Address(
33-
evmAddress(user.account!.address),
34-
{
35-
address: ETHEREUM_USDC_ADDRESS,
36-
amount: bigDecimal('200'),
37-
decimals: 6,
38-
},
39-
).andThen(() =>
32+
const setup = await fundErc20Address(evmAddress(user.account.address), {
33+
address: ETHEREUM_USDC_ADDRESS,
34+
amount: bigDecimal('200'),
35+
decimals: 6,
36+
}).andThen(() =>
4037
supplyToRandomERC20Reserve(client, user, ETHEREUM_USDC_ADDRESS),
4138
);
4239

@@ -45,7 +42,7 @@ describe('Aave V4 Health Factor Positions Scenarios', () => {
4542

4643
it('Then the health factor should be null', async () => {
4744
const summary = await userSummary(client, {
48-
user: evmAddress(user.account!.address),
45+
user: evmAddress(user.account.address),
4946
filter: {
5047
chainIds: [ETHEREUM_FORK_ID],
5148
},
@@ -56,18 +53,14 @@ describe('Aave V4 Health Factor Positions Scenarios', () => {
5653
});
5754

5855
describe('And the user has a one borrow position', () => {
59-
const user = createNewWallet();
6056
let reserve: Reserve;
6157

6258
beforeAll(async () => {
63-
const setup = await fundErc20Address(
64-
evmAddress(user.account!.address),
65-
{
66-
address: ETHEREUM_USDC_ADDRESS,
67-
amount: bigDecimal('300'),
68-
decimals: 6,
69-
},
70-
).andThen(() => supplyAndBorrow(client, user, ETHEREUM_USDC_ADDRESS));
59+
const setup = await fundErc20Address(evmAddress(user.account.address), {
60+
address: ETHEREUM_USDC_ADDRESS,
61+
amount: bigDecimal('300'),
62+
decimals: 6,
63+
}).andThen(() => supplyAndBorrow(client, user, ETHEREUM_USDC_ADDRESS));
7164

7265
assertOk(setup);
7366
reserve = setup.value;
@@ -76,7 +69,7 @@ describe('Aave V4 Health Factor Positions Scenarios', () => {
7669
describe('When the user checks the health factor', () => {
7770
it('Then the health factor should be a number greater than 1', async () => {
7871
const summary = await userSummary(client, {
79-
user: evmAddress(user.account!.address),
72+
user: evmAddress(user.account.address),
8073
filter: {
8174
chainIds: [ETHEREUM_FORK_ID],
8275
},
@@ -91,7 +84,7 @@ describe('Aave V4 Health Factor Positions Scenarios', () => {
9184

9285
beforeAll(async () => {
9386
const summary = await userSummary(client, {
94-
user: evmAddress(user.account!.address),
87+
user: evmAddress(user.account.address),
9588
filter: {
9689
chainIds: [ETHEREUM_FORK_ID],
9790
},
@@ -109,7 +102,7 @@ describe('Aave V4 Health Factor Positions Scenarios', () => {
109102
chainId: reserve.chain.chainId,
110103
},
111104
enableCollateral: true,
112-
sender: evmAddress(user.account!.address),
105+
sender: evmAddress(user.account.address),
113106
},
114107
user,
115108
);
@@ -119,7 +112,7 @@ describe('Aave V4 Health Factor Positions Scenarios', () => {
119112

120113
it('Then the health factor should be greater than before supplying more collateral', async () => {
121114
const summary = await userSummary(client, {
122-
user: evmAddress(user.account!.address),
115+
user: evmAddress(user.account.address),
123116
filter: {
124117
chainIds: [ETHEREUM_FORK_ID],
125118
},
@@ -136,7 +129,7 @@ describe('Aave V4 Health Factor Positions Scenarios', () => {
136129

137130
beforeAll(async () => {
138131
const summary = await userSummary(client, {
139-
user: evmAddress(user.account!.address),
132+
user: evmAddress(user.account.address),
140133
filter: {
141134
chainIds: [ETHEREUM_FORK_ID],
142135
},
@@ -150,7 +143,7 @@ describe('Aave V4 Health Factor Positions Scenarios', () => {
150143
reserveId: reserve.id,
151144
chainId: reserve.chain.chainId,
152145
},
153-
sender: evmAddress(user.account!.address),
146+
sender: evmAddress(user.account.address),
154147
amount: {
155148
erc20: {
156149
value: {
@@ -167,7 +160,7 @@ describe('Aave V4 Health Factor Positions Scenarios', () => {
167160

168161
it('Then the health factor should be greater than before repaying partially', async () => {
169162
const summary = await userSummary(client, {
170-
user: evmAddress(user.account!.address),
163+
user: evmAddress(user.account.address),
171164
filter: {
172165
chainIds: [ETHEREUM_FORK_ID],
173166
},
@@ -184,7 +177,7 @@ describe('Aave V4 Health Factor Positions Scenarios', () => {
184177

185178
beforeAll(async () => {
186179
const summary = await userSummary(client, {
187-
user: evmAddress(user.account!.address),
180+
user: evmAddress(user.account.address),
188181
filter: {
189182
chainIds: [ETHEREUM_FORK_ID],
190183
},
@@ -193,7 +186,7 @@ describe('Aave V4 Health Factor Positions Scenarios', () => {
193186
HFBeforeBorrow = summary.value.lowestHealthFactor!;
194187

195188
const setup = await borrow(client, {
196-
sender: evmAddress(user.account!.address),
189+
sender: evmAddress(user.account.address),
197190
reserve: {
198191
spoke: reserve.spoke.address,
199192
reserveId: reserve.id,
@@ -213,7 +206,7 @@ describe('Aave V4 Health Factor Positions Scenarios', () => {
213206

214207
it('Then the health factor should be less than before borrowing more money', async () => {
215208
const summary = await userSummary(client, {
216-
user: evmAddress(user.account!.address),
209+
user: evmAddress(user.account.address),
217210
filter: {
218211
chainIds: [ETHEREUM_FORK_ID],
219212
},
@@ -230,7 +223,7 @@ describe('Aave V4 Health Factor Positions Scenarios', () => {
230223

231224
beforeAll(async () => {
232225
const summary = await userSummary(client, {
233-
user: evmAddress(user.account!.address),
226+
user: evmAddress(user.account.address),
234227
filter: {
235228
chainIds: [ETHEREUM_FORK_ID],
236229
},
@@ -244,7 +237,7 @@ describe('Aave V4 Health Factor Positions Scenarios', () => {
244237
reserveId: reserve.id,
245238
chainId: reserve.chain.chainId,
246239
},
247-
sender: evmAddress(user.account!.address),
240+
sender: evmAddress(user.account.address),
248241
amount: {
249242
erc20: {
250243
exact: bigDecimal('25'),
@@ -259,7 +252,7 @@ describe('Aave V4 Health Factor Positions Scenarios', () => {
259252

260253
it('Then the health factor should be less than before withdrawing collateral', async () => {
261254
const summary = await userSummary(client, {
262-
user: evmAddress(user.account!.address),
255+
user: evmAddress(user.account.address),
263256
filter: {
264257
chainIds: [ETHEREUM_FORK_ID],
265258
},
@@ -279,7 +272,7 @@ describe('Aave V4 Health Factor Positions Scenarios', () => {
279272
reserveId: reserve.id,
280273
chainId: reserve.chain.chainId,
281274
},
282-
sender: evmAddress(user.account!.address),
275+
sender: evmAddress(user.account.address),
283276
amount: {
284277
erc20: {
285278
value: {
@@ -298,7 +291,7 @@ describe('Aave V4 Health Factor Positions Scenarios', () => {
298291

299292
it('Then the health factor should be null', async () => {
300293
const summary = await userSummary(client, {
301-
user: evmAddress(user.account!.address),
294+
user: evmAddress(user.account.address),
302295
filter: {
303296
chainIds: [ETHEREUM_FORK_ID],
304297
},

0 commit comments

Comments
 (0)