Skip to content

Commit e0b9968

Browse files
authored
feat: add "user balance" command (#359)
1 parent cb7ec01 commit e0b9968

3 files changed

Lines changed: 127 additions & 0 deletions

File tree

.changeset/lucky-boats-deny.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"@aave/cli": patch
3+
---
4+
5+
**feat:** add 'user balance' command

packages/cli/README.md

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ USAGE
3535
* [`aave reserve`](#aave-reserve)
3636
* [`aave reserves list`](#aave-reserves-list)
3737
* [`aave spokes list`](#aave-spokes-list)
38+
* [`aave user balance`](#aave-user-balance)
3839
* [`aave user borrows`](#aave-user-borrows)
3940
* [`aave user positions`](#aave-user-positions)
4041
* [`aave user summary`](#aave-user-summary)
@@ -214,6 +215,27 @@ DESCRIPTION
214215

215216
_See code: [src/commands/spokes/list.ts](https://github.com/aave/aave-v4-sdk/blob/v4.1.4/src/commands/spokes/list.ts)_
216217

218+
## `aave user balance`
219+
220+
List user token balances that can be used in Aave v4
221+
222+
```
223+
USAGE
224+
$ aave user balance -c <chain-id> [--json] [--address <evm-address>]
225+
226+
FLAGS
227+
-c, --chain_id=<chain-id> (required) Chain ID to query balances from
228+
--address=<evm-address> User address (defaults to PRIVATE_KEY wallet address)
229+
230+
GLOBAL FLAGS
231+
--json Format output as json.
232+
233+
DESCRIPTION
234+
List user token balances that can be used in Aave v4
235+
```
236+
237+
_See code: [src/commands/user/balance.ts](https://github.com/aave/aave-v4-sdk/blob/v4.1.4/src/commands/user/balance.ts)_
238+
217239
## `aave user borrows`
218240

219241
List user borrows for a specific chain
Lines changed: 100 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,100 @@
1+
import {
2+
type ChainId,
3+
type EvmAddress,
4+
InvariantError,
5+
invariant,
6+
ok,
7+
type PercentNumber,
8+
ResultAsync,
9+
type UnexpectedError,
10+
type UserBalance,
11+
type UserBalancesRequest,
12+
} from '@aave/client';
13+
import { userBalances } from '@aave/client/actions';
14+
15+
import * as common from '../../common.js';
16+
17+
function formatPercent(value: PercentNumber | null): string {
18+
return value ? `${value.normalized.toFixed(4)}%` : 'N/A';
19+
}
20+
21+
export default class UserBalanceCommand extends common.V4Command {
22+
static override description =
23+
'List user token balances that can be used in Aave v4';
24+
25+
static override flags = {
26+
address: common.address({
27+
required: false,
28+
description: 'User address (defaults to PRIVATE_KEY wallet address)',
29+
}),
30+
chain_id: common.chain({
31+
required: true,
32+
description: 'Chain ID to query balances from',
33+
}),
34+
};
35+
36+
override headers = [
37+
{ value: 'Asset' },
38+
{ value: 'Symbol' },
39+
{ value: 'Balance' },
40+
{ value: 'Exchange' },
41+
{ value: 'Best Supply APY' },
42+
{ value: 'Best Borrow APY' },
43+
];
44+
45+
private getBalancesRequest(): ResultAsync<
46+
UserBalancesRequest,
47+
InvariantError | UnexpectedError
48+
> {
49+
return ResultAsync.fromPromise(
50+
this.parse(UserBalanceCommand),
51+
(error) => new InvariantError(String(error)),
52+
).andThen(({ flags }) => {
53+
const user = common.userAddressFromFlagOrEnv(
54+
flags.address as EvmAddress | undefined,
55+
);
56+
const chainId = flags.chain_id as ChainId;
57+
58+
invariant(chainId, 'You must provide a chain ID');
59+
60+
return ok({
61+
user,
62+
filter: {
63+
chains: {
64+
chainIds: [chainId],
65+
},
66+
},
67+
});
68+
});
69+
}
70+
71+
async run(): Promise<UserBalance[] | InvariantError | UnexpectedError> {
72+
const result = await this.getBalancesRequest()
73+
.andThen((request) => userBalances(this.client, request))
74+
.andThen((balances) => {
75+
if (balances.length === 0) {
76+
this.log('No balances found for this user.');
77+
return ok(balances);
78+
}
79+
80+
this.display(
81+
balances.map((item) => [
82+
item.info.name,
83+
item.info.symbol,
84+
item.totalAmount.value.toFixed(6),
85+
`${item.exchange.symbol}${item.exchange.value.toFixed(2)}`,
86+
formatPercent(item.highestSupplyApy),
87+
formatPercent(item.highestBorrowApy),
88+
]),
89+
);
90+
91+
return ok(balances);
92+
});
93+
94+
if (result.isErr()) {
95+
this.error(result.error);
96+
}
97+
98+
return result.value;
99+
}
100+
}

0 commit comments

Comments
 (0)