Skip to content
Merged
Show file tree
Hide file tree
Changes from 17 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion examples/supply/src/SupplyForm.tsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import { useSendTransaction } from '@aave/react/viem';
import {
bigDecimal,
evmAddress,
type Reserve,
useSupply,
} from '@aave/react-next';
import { useSendTransaction } from '@aave/react-next/viem';
import { useState } from 'react';
import type { WalletClient } from 'viem';

Expand Down
1 change: 1 addition & 0 deletions packages/client/src/actions/swap.ts
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ import { type CurrencyQueryOptions, DEFAULT_QUERY_OPTIONS } from '../options';
* sell: { erc20: evmAddress('0x6B175474E...') },
* amount: bigDecimal('1000'),
* kind: SwapKind.SELL,
* from: evmAddress('0x742d35cc...'),
* });
* ```
*
Expand Down
13 changes: 9 additions & 4 deletions packages/client/src/actions/transactions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -69,16 +69,21 @@ export function borrow(
*
* ```ts
* const result = await supply(client, {
* market: market.address,
* reserve: {
* reserveId: "1234567890",
* spoke: evmAddress('0x8787…'),
* chainId: chainId(1),
* },
* amount: {
* erc20: {
* currency: evmAddress('0x5678…'),
* value: bigDecimal('1000'),
* },
* },
* supplier: evmAddress('0x9abc…'),
* chainId: market.chain.chainId,
* }).andThen(sendWith(wallet)).andThen(client.waitForTransaction);
* enableCollateral: true, // Optional, defaults to true
* sender: evmAddress('0x9abc…'),
* // onBehalfOf: evmAddress('0xdef0…'), // Optional, if supplying on behalf of another user
* });
*
* if (result.isErr()) {
* // Handle error, e.g. insufficient balance, signing error, etc.
Expand Down
19 changes: 19 additions & 0 deletions packages/spec/borrow/__snapshots__/bizCore.spec.ts.snap
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html

exports[`Aave V4 Borrow Scenarios > Given a user with a supply position as collateral > When the user borrows an ERC20 asset > Then the user's borrow positions are updated 1`] = `
{
"__typename": "DecimalValue",
"decimals": 18,
"formatted": "0.000000000000000050",
"raw": 50n,
}
`;

exports[`Aave V4 Borrow Scenarios > Given a user with a supply position as collateral > When the user borrows an ERC20 asset > Then the user's borrow positions are updated 2`] = `
{
"__typename": "DecimalValue",
"decimals": 18,
"formatted": "0.000000000000000050",
"raw": 50n,
}
`;
81 changes: 81 additions & 0 deletions packages/spec/borrow/bizCore.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
import { assertOk, bigDecimal, evmAddress } from '@aave/client-next';
import { borrow, userBorrows } from '@aave/client-next/actions';
import {
client,
createNewWallet,
ETHEREUM_USDC_ADDRESS,
fundErc20Address,
} from '@aave/client-next/test-utils';
import { sendWith } from '@aave/client-next/viem';
import type { Reserve } from '@aave/graphql-next';
import { beforeAll, describe, expect, it } from 'vitest';
import { supplyToRandomERC20Reserve } from './helper';

describe('Aave V4 Borrow Scenarios', () => {
describe('Given a user with a supply position as collateral', () => {
describe('When the user borrows an ERC20 asset', () => {
const user = createNewWallet();
let reserve: Reserve;

beforeAll(async () => {
const setup = await fundErc20Address(
ETHEREUM_USDC_ADDRESS,
evmAddress(user.account!.address),
bigDecimal('100'),
6,
).andThen(() =>
supplyToRandomERC20Reserve(client, user, ETHEREUM_USDC_ADDRESS),
);

assertOk(setup);
reserve = setup.value;
});

it(`Then the user's borrow positions are updated`, async () => {
const result = await borrow(client, {
sender: evmAddress(user.account!.address),
reserve: {
spoke: reserve.spoke.address,
reserveId: reserve.id,
chainId: reserve.chain.chainId,
},
amount: {
erc20: {
value: bigDecimal('50'),
},
},
})
.andThen(sendWith(user))
.andThen(client.waitForTransaction)
.andThen(() =>
userBorrows(client, {
query: {
userSpoke: {
spoke: {
address: reserve.spoke.address,
chainId: reserve.chain.chainId,
},
user: evmAddress(user.account!.address),
},
},
}),
);

assertOk(result);
expect(result.value.length).toBe(1);
// BUG: The amount is slightly different from the total borrow amount
// expect(result.value[0]?.amount.value).toMatchSnapshot();
expect(Number(result.value[0]?.amount.value.formatted)).toBeCloseTo(
Number(bigDecimal('50')),
4,
);
expect(result.value[0]?.paid.value).toMatchSnapshot();
expect(result.value[0]?.amount.isWrappedNative).toBe(false);
});
});

describe('When the user borrows from a reserve that supports native borrowing', () => {
it.todo(`Then the user's borrow positions are updated`);
});
});
});
75 changes: 75 additions & 0 deletions packages/spec/borrow/helper.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
import type { AaveClient, Reserve, SupplyRequest } from '@aave/client-next';
import {
bigDecimal,
chainId,
type EvmAddress,
evmAddress,
invariant,
type ResultAsync,
type TxHash,
} from '@aave/client-next';
import { reserves, supply } from '@aave/client-next/actions';
import { sendWith } from '@aave/client-next/viem';
import type { WalletClient } from 'viem';

export function supplyToReserve(
client: AaveClient,
request: SupplyRequest,
user: WalletClient,
): ResultAsync<TxHash, Error> {
return supply(client, request)
.andThen(sendWith(user))
.andThen(client.waitForTransaction);
}

export function findReserveToSupply(
client: AaveClient,
token: EvmAddress,
): ResultAsync<Reserve, Error> {
return reserves(client, {
query: {
tokens: [
{
chainId: chainId(1),
address: token,
},
],
},
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

filter by supply reserves to make this semantically correct.

}).map((listReserves) => {
invariant(
listReserves.length > 0,
`No reserves found for the token ${token}`,
);
const reserveToSupply = listReserves.find(
(reserve) => reserve.canSupply === true,
);
invariant(
reserveToSupply,
`No reserve found to supply to for the token ${token}`,
);
return reserveToSupply;
});
}

export function supplyToRandomERC20Reserve(
client: AaveClient,
user: WalletClient,
token: EvmAddress,
amount = bigDecimal('100'),
): ResultAsync<Reserve, Error> {
return findReserveToSupply(client, token).andThen((reserve) =>
supplyToReserve(
client,
{
reserve: {
reserveId: reserve.id,
chainId: reserve.chain.chainId,
spoke: reserve.spoke.address,
},
amount: { erc20: { value: amount } },
sender: evmAddress(user.account!.address),
},
user,
).map(() => reserve),
);
}
File renamed without changes.
File renamed without changes.
File renamed without changes.
14 changes: 14 additions & 0 deletions packages/spec/positions/supply.todo.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import { describe, it } from 'vitest';

describe('Aave V4 User Supply Positions Scenarios', () => {
describe('Given a user with a more than one supply position', () => {
describe('When fetching supply positions ordered by', () => {
it.todo('Then it should return the supply positions ordered by amount');
it.todo('Then it should return the supply positions ordered by earned');
it.todo(
'Then it should return the supply positions ordered by isCollateral',
);
it.todo('Then it should return the supply positions ordered by reserve');
});
});
});
Original file line number Diff line number Diff line change
@@ -1,16 +1,6 @@
import { describe, it } from 'vitest';

describe('Aave V4 Borrow Scenarios', () => {
describe('Given a user with a supply position as collateral', () => {
describe('When the user borrows an ERC20 asset', () => {
it.todo(`Then the user's borrow positions are updated`);
});

describe('When the user borrows from a reserve that supports native borrowing', () => {
it.todo(`Then the user's borrow positions are updated`);
});
});

describe('Given a user with a more than one borrow position', () => {
describe('When fetching borrow positions ordered by', () => {
it.todo('Then it should return the borrow positions ordered by balance');
Expand Down
39 changes: 0 additions & 39 deletions packages/spec/repay.spec.ts

This file was deleted.

Loading