@coinbase/agentkit 0.2.3-nightly.20250227.18 → 0.2.3-nightly.20250227.19
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +48 -0
- package/dist/action-providers/compound/compoundActionProvider.d.ts +67 -0
- package/dist/action-providers/compound/compoundActionProvider.js +365 -0
- package/dist/action-providers/compound/compoundActionProvider.test.d.ts +1 -0
- package/dist/action-providers/compound/compoundActionProvider.test.js +353 -0
- package/dist/action-providers/compound/constants.d.ts +180 -0
- package/dist/action-providers/compound/constants.js +129 -0
- package/dist/action-providers/compound/index.d.ts +1 -0
- package/dist/action-providers/compound/index.js +17 -0
- package/dist/action-providers/compound/schemas.d.ts +57 -0
- package/dist/action-providers/compound/schemas.js +58 -0
- package/dist/action-providers/compound/utils.d.ts +95 -0
- package/dist/action-providers/compound/utils.js +353 -0
- package/dist/action-providers/index.d.ts +1 -0
- package/dist/action-providers/index.js +1 -0
- package/dist/wallet-providers/index.d.ts +1 -0
- package/dist/wallet-providers/index.js +1 -0
- package/dist/wallet-providers/smartWalletProvider.d.ts +177 -0
- package/dist/wallet-providers/smartWalletProvider.js +303 -0
- package/package.json +2 -2
|
@@ -0,0 +1,353 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const viem_1 = require("viem");
|
|
4
|
+
const compoundActionProvider_1 = require("./compoundActionProvider");
|
|
5
|
+
const constants_1 = require("./constants");
|
|
6
|
+
const utils_1 = require("../../utils");
|
|
7
|
+
jest.mock("../../utils");
|
|
8
|
+
const mockApprove = utils_1.approve;
|
|
9
|
+
describe("Compound Action Provider", () => {
|
|
10
|
+
const actionProvider = new compoundActionProvider_1.CompoundActionProvider();
|
|
11
|
+
let mockWallet;
|
|
12
|
+
const MOCK_NETWORK = { protocolFamily: "evm", networkId: "base-mainnet" };
|
|
13
|
+
const MOCK_COMET_ADDRESS = constants_1.COMET_ADDRESSES["base-mainnet"];
|
|
14
|
+
const MOCK_WETH_ADDRESS = constants_1.ASSET_ADDRESSES["base-mainnet"]["weth"];
|
|
15
|
+
const MOCK_USDC_ADDRESS = constants_1.ASSET_ADDRESSES["base-mainnet"]["usdc"];
|
|
16
|
+
const MOCK_TX_HASH = "0xtesttxhash";
|
|
17
|
+
const MOCK_RECEIPT = { status: 1, blockNumber: 123456 };
|
|
18
|
+
const MOCK_WALLET_BALANCE = BigInt("10000000000000000000"); // 10 tokens in wei
|
|
19
|
+
const MOCK_TOKEN_SYMBOL = "WETH";
|
|
20
|
+
beforeEach(() => {
|
|
21
|
+
mockWallet = {
|
|
22
|
+
getAddress: jest.fn().mockResolvedValue("0xMockAddress"),
|
|
23
|
+
getNetwork: jest.fn().mockReturnValue(MOCK_NETWORK),
|
|
24
|
+
sendTransaction: jest.fn().mockResolvedValue(MOCK_TX_HASH),
|
|
25
|
+
waitForTransactionReceipt: jest.fn().mockResolvedValue(MOCK_RECEIPT),
|
|
26
|
+
readContract: jest.fn().mockImplementation(async ({ functionName, address }) => {
|
|
27
|
+
// Basic ERC20 mocks
|
|
28
|
+
if (functionName === "decimals") {
|
|
29
|
+
return address === MOCK_USDC_ADDRESS ? 6 : 18;
|
|
30
|
+
}
|
|
31
|
+
if (functionName === "symbol") {
|
|
32
|
+
return address === MOCK_USDC_ADDRESS ? "USDC" : "WETH";
|
|
33
|
+
}
|
|
34
|
+
if (functionName === "balanceOf") {
|
|
35
|
+
return address === MOCK_USDC_ADDRESS ? BigInt("1000000") : (0, viem_1.parseEther)("10");
|
|
36
|
+
}
|
|
37
|
+
// Comet contract mocks
|
|
38
|
+
if (functionName === "collateralBalanceOf") {
|
|
39
|
+
return (0, viem_1.parseEther)("5");
|
|
40
|
+
}
|
|
41
|
+
if (functionName === "borrowBalanceOf") {
|
|
42
|
+
return (0, viem_1.parseUnits)("1000", 6);
|
|
43
|
+
}
|
|
44
|
+
if (functionName === "baseToken") {
|
|
45
|
+
return MOCK_USDC_ADDRESS;
|
|
46
|
+
}
|
|
47
|
+
if (functionName === "baseTokenPriceFeed") {
|
|
48
|
+
return "0xMockPriceFeed";
|
|
49
|
+
}
|
|
50
|
+
if (functionName === "numAssets") {
|
|
51
|
+
return 1;
|
|
52
|
+
}
|
|
53
|
+
if (functionName === "getAssetInfo") {
|
|
54
|
+
return {
|
|
55
|
+
offset: 0,
|
|
56
|
+
asset: MOCK_WETH_ADDRESS,
|
|
57
|
+
priceFeed: "0xMockPriceFeed",
|
|
58
|
+
scale: BigInt(0),
|
|
59
|
+
borrowCollateralFactor: (0, viem_1.parseEther)("0.8"),
|
|
60
|
+
liquidateCollateralFactor: BigInt(0),
|
|
61
|
+
liquidationFactor: BigInt(0),
|
|
62
|
+
supplyCap: BigInt(0),
|
|
63
|
+
};
|
|
64
|
+
}
|
|
65
|
+
if (functionName === "latestRoundData") {
|
|
66
|
+
return [BigInt(1), (0, viem_1.parseUnits)("1", 8), BigInt(0), BigInt(1000), BigInt(1)];
|
|
67
|
+
}
|
|
68
|
+
throw new Error(`Unmocked contract call: ${functionName}`);
|
|
69
|
+
}),
|
|
70
|
+
};
|
|
71
|
+
jest.clearAllMocks();
|
|
72
|
+
mockApprove.mockResolvedValue("Approval successful");
|
|
73
|
+
});
|
|
74
|
+
describe("supply", () => {
|
|
75
|
+
it("should successfully supply assets", async () => {
|
|
76
|
+
const args = { assetId: "weth", amount: "1.0" };
|
|
77
|
+
const response = await actionProvider.supply(mockWallet, args);
|
|
78
|
+
expect(mockApprove).toHaveBeenCalledWith(mockWallet, MOCK_WETH_ADDRESS, MOCK_COMET_ADDRESS, (0, viem_1.parseEther)("1.0"));
|
|
79
|
+
const expectedTxData = (0, viem_1.encodeFunctionData)({
|
|
80
|
+
abi: constants_1.COMET_ABI,
|
|
81
|
+
functionName: "supply",
|
|
82
|
+
args: [MOCK_WETH_ADDRESS, (0, viem_1.parseEther)("1.0")],
|
|
83
|
+
});
|
|
84
|
+
expect(mockWallet.sendTransaction).toHaveBeenCalledWith({
|
|
85
|
+
to: MOCK_COMET_ADDRESS,
|
|
86
|
+
data: expectedTxData,
|
|
87
|
+
});
|
|
88
|
+
expect(response).toContain("Supplied 1.0 WETH to Compound");
|
|
89
|
+
expect(response).toContain(MOCK_TX_HASH);
|
|
90
|
+
});
|
|
91
|
+
it("should return error if approval fails", async () => {
|
|
92
|
+
mockApprove.mockResolvedValueOnce("Error: Approval failed");
|
|
93
|
+
const args = { assetId: "weth", amount: "1.0" };
|
|
94
|
+
const response = await actionProvider.supply(mockWallet, args);
|
|
95
|
+
expect(response).toContain("Error approving token: Error: Approval failed");
|
|
96
|
+
});
|
|
97
|
+
it("should return error if wallet balance is insufficient", async () => {
|
|
98
|
+
mockWallet.readContract = jest.fn().mockImplementation(async ({ functionName }) => {
|
|
99
|
+
if (functionName === "decimals")
|
|
100
|
+
return 18;
|
|
101
|
+
if (functionName === "balanceOf")
|
|
102
|
+
return BigInt("500000000000000000"); // 0.5 tokens
|
|
103
|
+
return MOCK_WALLET_BALANCE;
|
|
104
|
+
});
|
|
105
|
+
const args = { assetId: "weth", amount: "1.0" };
|
|
106
|
+
const response = await actionProvider.supply(mockWallet, args);
|
|
107
|
+
expect(response).toContain("Error: Insufficient balance. You have 0.5, but trying to supply 1.0");
|
|
108
|
+
});
|
|
109
|
+
it("should handle errors during the supply transaction", async () => {
|
|
110
|
+
mockWallet.sendTransaction.mockRejectedValueOnce(new Error("Failed TX"));
|
|
111
|
+
const args = { assetId: "weth", amount: "1.0" };
|
|
112
|
+
const response = await actionProvider.supply(mockWallet, args);
|
|
113
|
+
expect(response).toContain("Error supplying to Compound: Failed TX");
|
|
114
|
+
});
|
|
115
|
+
});
|
|
116
|
+
describe("withdraw", () => {
|
|
117
|
+
it("should successfully withdraw assets", async () => {
|
|
118
|
+
// Patch readContract so that borrow balance is 0 (healthy condition)
|
|
119
|
+
const originalReadContract = mockWallet.readContract;
|
|
120
|
+
mockWallet.readContract = jest
|
|
121
|
+
.fn()
|
|
122
|
+
.mockImplementation(async ({ functionName, address, args, abi }) => {
|
|
123
|
+
if (functionName === "borrowBalanceOf")
|
|
124
|
+
return BigInt(0); // No borrows
|
|
125
|
+
if (functionName === "collateralBalanceOf")
|
|
126
|
+
return (0, viem_1.parseEther)("5"); // 5 WETH supplied
|
|
127
|
+
if (functionName === "latestRoundData")
|
|
128
|
+
return [BigInt(1), (0, viem_1.parseUnits)("1", 8), BigInt(0), BigInt(1000), BigInt(1)];
|
|
129
|
+
return originalReadContract({ functionName, address, abi, args: args ?? [] });
|
|
130
|
+
});
|
|
131
|
+
const args = { assetId: "weth", amount: "1.0" };
|
|
132
|
+
const response = await actionProvider.withdraw(mockWallet, args);
|
|
133
|
+
const expectedTxData = (0, viem_1.encodeFunctionData)({
|
|
134
|
+
abi: constants_1.COMET_ABI,
|
|
135
|
+
functionName: "withdraw",
|
|
136
|
+
args: [MOCK_WETH_ADDRESS, (0, viem_1.parseEther)("1.0")],
|
|
137
|
+
});
|
|
138
|
+
expect(mockWallet.sendTransaction).toHaveBeenCalledWith({
|
|
139
|
+
to: MOCK_COMET_ADDRESS,
|
|
140
|
+
data: expectedTxData,
|
|
141
|
+
});
|
|
142
|
+
expect(response).toContain("Withdrawn 1.0 WETH from Compound");
|
|
143
|
+
expect(response).toContain(MOCK_TX_HASH);
|
|
144
|
+
});
|
|
145
|
+
it("should return error if collateral balance is insufficient", async () => {
|
|
146
|
+
mockWallet.readContract = jest.fn().mockImplementation(async ({ functionName }) => {
|
|
147
|
+
if (functionName === "decimals")
|
|
148
|
+
return 18;
|
|
149
|
+
if (functionName === "collateralBalanceOf")
|
|
150
|
+
return (0, viem_1.parseEther)("0.5"); // Less than we're trying to withdraw
|
|
151
|
+
if (functionName === "symbol")
|
|
152
|
+
return MOCK_TOKEN_SYMBOL;
|
|
153
|
+
return MOCK_WALLET_BALANCE;
|
|
154
|
+
});
|
|
155
|
+
const args = { assetId: "weth", amount: "1.0" };
|
|
156
|
+
const response = await actionProvider.withdraw(mockWallet, args);
|
|
157
|
+
expect(response).toContain("Error: Insufficient balance. Trying to withdraw 1.0, but only have 0.5 supplied");
|
|
158
|
+
});
|
|
159
|
+
it("should handle errors during withdrawal", async () => {
|
|
160
|
+
// Patch readContract to yield a healthy condition so the TX is attempted
|
|
161
|
+
const originalReadContract = mockWallet.readContract;
|
|
162
|
+
mockWallet.readContract = jest
|
|
163
|
+
.fn()
|
|
164
|
+
.mockImplementation(async ({ functionName, address, args, abi }) => {
|
|
165
|
+
if (functionName === "borrowBalanceOf")
|
|
166
|
+
return BigInt(0);
|
|
167
|
+
if (functionName === "collateralBalanceOf")
|
|
168
|
+
return (0, viem_1.parseEther)("5");
|
|
169
|
+
if (functionName === "latestRoundData")
|
|
170
|
+
return [BigInt(1), (0, viem_1.parseUnits)("1", 8), BigInt(0), BigInt(1000), BigInt(1)];
|
|
171
|
+
return originalReadContract({ functionName, address, abi, args: args ?? [] });
|
|
172
|
+
});
|
|
173
|
+
mockWallet.sendTransaction.mockRejectedValueOnce(new Error("Withdraw TX Failed"));
|
|
174
|
+
const args = { assetId: "weth", amount: "1.0" };
|
|
175
|
+
const response = await actionProvider.withdraw(mockWallet, args);
|
|
176
|
+
expect(response).toContain("Error withdrawing from Compound: Error: Withdraw TX Failed");
|
|
177
|
+
});
|
|
178
|
+
});
|
|
179
|
+
describe("borrow", () => {
|
|
180
|
+
it("should successfully borrow assets", async () => {
|
|
181
|
+
// For a healthy borrow, override:
|
|
182
|
+
const originalReadContract = mockWallet.readContract;
|
|
183
|
+
mockWallet.readContract = jest
|
|
184
|
+
.fn()
|
|
185
|
+
.mockImplementation(async ({ functionName, address, abi }) => {
|
|
186
|
+
if (functionName === "borrowBalanceOf")
|
|
187
|
+
return BigInt(0);
|
|
188
|
+
if (functionName === "collateralBalanceOf")
|
|
189
|
+
return (0, viem_1.parseEther)("5000");
|
|
190
|
+
if (functionName === "baseToken")
|
|
191
|
+
return MOCK_USDC_ADDRESS;
|
|
192
|
+
if (functionName === "baseTokenPriceFeed")
|
|
193
|
+
return "0xMockPriceFeed";
|
|
194
|
+
if (functionName === "latestRoundData") {
|
|
195
|
+
return [BigInt(1), (0, viem_1.parseUnits)("1", 8), BigInt(0), BigInt(1000), BigInt(1)];
|
|
196
|
+
}
|
|
197
|
+
if (functionName === "getAssetInfo") {
|
|
198
|
+
return {
|
|
199
|
+
offset: 0,
|
|
200
|
+
asset: MOCK_WETH_ADDRESS,
|
|
201
|
+
priceFeed: "0xMockPriceFeed",
|
|
202
|
+
scale: BigInt(0),
|
|
203
|
+
borrowCollateralFactor: (0, viem_1.parseEther)("0.8"),
|
|
204
|
+
liquidateCollateralFactor: BigInt(0),
|
|
205
|
+
liquidationFactor: BigInt(0),
|
|
206
|
+
supplyCap: BigInt(0),
|
|
207
|
+
};
|
|
208
|
+
}
|
|
209
|
+
return originalReadContract({ functionName, address, abi, args: [] });
|
|
210
|
+
});
|
|
211
|
+
const args = { assetId: "usdc", amount: "1000" };
|
|
212
|
+
const response = await actionProvider.borrow(mockWallet, args);
|
|
213
|
+
const expectedTxData = (0, viem_1.encodeFunctionData)({
|
|
214
|
+
abi: constants_1.COMET_ABI,
|
|
215
|
+
functionName: "withdraw",
|
|
216
|
+
args: [MOCK_USDC_ADDRESS, (0, viem_1.parseUnits)("1000", 6)],
|
|
217
|
+
});
|
|
218
|
+
expect(mockWallet.sendTransaction).toHaveBeenCalledWith({
|
|
219
|
+
to: MOCK_COMET_ADDRESS,
|
|
220
|
+
data: expectedTxData,
|
|
221
|
+
});
|
|
222
|
+
expect(response).toContain("Borrowed 1000 USDC from Compound");
|
|
223
|
+
});
|
|
224
|
+
it("should handle errors during borrowing", async () => {
|
|
225
|
+
// Set up the same mocks as the success case first
|
|
226
|
+
const originalReadContract = mockWallet.readContract;
|
|
227
|
+
mockWallet.readContract = jest
|
|
228
|
+
.fn()
|
|
229
|
+
.mockImplementation(async ({ functionName, address, abi }) => {
|
|
230
|
+
if (functionName === "borrowBalanceOf")
|
|
231
|
+
return BigInt(0);
|
|
232
|
+
if (functionName === "collateralBalanceOf")
|
|
233
|
+
return (0, viem_1.parseEther)("5000");
|
|
234
|
+
if (functionName === "baseToken")
|
|
235
|
+
return MOCK_USDC_ADDRESS;
|
|
236
|
+
if (functionName === "baseTokenPriceFeed")
|
|
237
|
+
return "0xMockPriceFeed";
|
|
238
|
+
if (functionName === "latestRoundData") {
|
|
239
|
+
return [BigInt(1), (0, viem_1.parseUnits)("1", 8), BigInt(0), BigInt(1000), BigInt(1)];
|
|
240
|
+
}
|
|
241
|
+
if (functionName === "getAssetInfo") {
|
|
242
|
+
return {
|
|
243
|
+
offset: 0,
|
|
244
|
+
asset: MOCK_WETH_ADDRESS,
|
|
245
|
+
priceFeed: "0xMockPriceFeed",
|
|
246
|
+
scale: BigInt(0),
|
|
247
|
+
borrowCollateralFactor: (0, viem_1.parseEther)("0.8"),
|
|
248
|
+
liquidateCollateralFactor: BigInt(0),
|
|
249
|
+
liquidationFactor: BigInt(0),
|
|
250
|
+
supplyCap: BigInt(0),
|
|
251
|
+
};
|
|
252
|
+
}
|
|
253
|
+
return originalReadContract({ functionName, address, abi, args: [] });
|
|
254
|
+
});
|
|
255
|
+
mockWallet.sendTransaction.mockRejectedValueOnce(new Error("Borrow TX Failed"));
|
|
256
|
+
const args = { assetId: "usdc", amount: "1000" };
|
|
257
|
+
const response = await actionProvider.borrow(mockWallet, args);
|
|
258
|
+
expect(response).toContain("Error borrowing from Compound: Error: Borrow TX Failed");
|
|
259
|
+
});
|
|
260
|
+
});
|
|
261
|
+
describe("repay", () => {
|
|
262
|
+
it("should successfully repay assets", async () => {
|
|
263
|
+
// Override token balance for USDC to be sufficient for repayment.
|
|
264
|
+
const originalReadContract = mockWallet.readContract;
|
|
265
|
+
mockWallet.readContract = jest
|
|
266
|
+
.fn()
|
|
267
|
+
.mockImplementation(async ({ functionName, address, args, abi }) => {
|
|
268
|
+
if (functionName === "balanceOf" && address === MOCK_USDC_ADDRESS) {
|
|
269
|
+
// Return 2000 USDC in atomic units (for 6 decimals, 2000 USDC = 2000 * 10^6)
|
|
270
|
+
return BigInt("2000000000");
|
|
271
|
+
}
|
|
272
|
+
if (functionName === "latestRoundData")
|
|
273
|
+
return [BigInt(1), (0, viem_1.parseUnits)("1", 8), BigInt(0), BigInt(1000), BigInt(1)];
|
|
274
|
+
return originalReadContract({ functionName, address, args, abi });
|
|
275
|
+
});
|
|
276
|
+
const args = { assetId: "usdc", amount: "1000" };
|
|
277
|
+
const response = await actionProvider.repay(mockWallet, args);
|
|
278
|
+
expect(mockApprove).toHaveBeenCalledWith(mockWallet, MOCK_USDC_ADDRESS, MOCK_COMET_ADDRESS, (0, viem_1.parseUnits)("1000", 6));
|
|
279
|
+
expect(mockWallet.sendTransaction).toHaveBeenCalledWith({
|
|
280
|
+
to: MOCK_COMET_ADDRESS,
|
|
281
|
+
data: (0, viem_1.encodeFunctionData)({
|
|
282
|
+
abi: constants_1.COMET_ABI,
|
|
283
|
+
functionName: "supply",
|
|
284
|
+
args: [MOCK_USDC_ADDRESS, (0, viem_1.parseUnits)("1000", 6)],
|
|
285
|
+
}),
|
|
286
|
+
});
|
|
287
|
+
expect(mockWallet.waitForTransactionReceipt).toHaveBeenCalledWith(MOCK_TX_HASH);
|
|
288
|
+
expect(response).toContain(`Repaid ${args.amount} USDC to Compound`);
|
|
289
|
+
});
|
|
290
|
+
it("should return error if wallet balance is insufficient for repay", async () => {
|
|
291
|
+
mockWallet.readContract = jest.fn().mockImplementation(async ({ functionName }) => {
|
|
292
|
+
if (functionName === "decimals")
|
|
293
|
+
return 6;
|
|
294
|
+
if (functionName === "balanceOf")
|
|
295
|
+
return BigInt("500000"); // 0.5 USDC
|
|
296
|
+
return MOCK_WALLET_BALANCE;
|
|
297
|
+
});
|
|
298
|
+
const args = { assetId: "usdc", amount: "1000" };
|
|
299
|
+
const response = await actionProvider.repay(mockWallet, args);
|
|
300
|
+
expect(response).toContain("Error: Insufficient balance. You have 0.5, but trying to repay 1000");
|
|
301
|
+
});
|
|
302
|
+
it("should handle errors during repayment", async () => {
|
|
303
|
+
// Override token balance to be sufficient, but make transaction fail
|
|
304
|
+
const originalReadContract = mockWallet.readContract;
|
|
305
|
+
mockWallet.readContract = jest
|
|
306
|
+
.fn()
|
|
307
|
+
.mockImplementation(async ({ functionName, address, args, abi }) => {
|
|
308
|
+
if (functionName === "balanceOf" && address === MOCK_USDC_ADDRESS) {
|
|
309
|
+
// Return 2000 USDC in atomic units (sufficient balance)
|
|
310
|
+
return BigInt("2000000000");
|
|
311
|
+
}
|
|
312
|
+
if (functionName === "latestRoundData")
|
|
313
|
+
return [BigInt(1), (0, viem_1.parseUnits)("1", 8), BigInt(0), BigInt(1000), BigInt(1)];
|
|
314
|
+
return originalReadContract({ functionName, address, args, abi });
|
|
315
|
+
});
|
|
316
|
+
mockApprove.mockResolvedValueOnce("Approval successful");
|
|
317
|
+
mockWallet.sendTransaction.mockRejectedValueOnce(new Error("Repay TX Failed"));
|
|
318
|
+
const args = { assetId: "usdc", amount: "1000" };
|
|
319
|
+
const response = await actionProvider.repay(mockWallet, args);
|
|
320
|
+
expect(response).toContain("Error repaying to Compound: Error: Repay TX Failed");
|
|
321
|
+
});
|
|
322
|
+
});
|
|
323
|
+
describe("getPortfolio", () => {
|
|
324
|
+
it("should return portfolio details in markdown format", async () => {
|
|
325
|
+
const response = await actionProvider.getPortfolio(mockWallet, {});
|
|
326
|
+
expect(response).toContain("# Portfolio Details");
|
|
327
|
+
expect(response).toContain("## Supply Details");
|
|
328
|
+
expect(response).toContain("## Borrow Details");
|
|
329
|
+
expect(response).toContain("## Overall Health");
|
|
330
|
+
});
|
|
331
|
+
it("should handle errors during portfolio retrieval", async () => {
|
|
332
|
+
mockWallet.readContract.mockRejectedValueOnce(new Error("Failed to fetch"));
|
|
333
|
+
const response = await actionProvider.getPortfolio(mockWallet, {});
|
|
334
|
+
expect(response).toContain("Error getting portfolio details: Failed to fetch");
|
|
335
|
+
});
|
|
336
|
+
});
|
|
337
|
+
describe("supportsNetwork", () => {
|
|
338
|
+
it("should return true for supported network", () => {
|
|
339
|
+
const result = actionProvider.supportsNetwork({
|
|
340
|
+
protocolFamily: "evm",
|
|
341
|
+
networkId: "base-mainnet",
|
|
342
|
+
});
|
|
343
|
+
expect(result).toBe(true);
|
|
344
|
+
});
|
|
345
|
+
it("should return false for unsupported network", () => {
|
|
346
|
+
const result = actionProvider.supportsNetwork({
|
|
347
|
+
protocolFamily: "evm",
|
|
348
|
+
networkId: "ethereum",
|
|
349
|
+
});
|
|
350
|
+
expect(result).toBe(false);
|
|
351
|
+
});
|
|
352
|
+
});
|
|
353
|
+
});
|
|
@@ -0,0 +1,180 @@
|
|
|
1
|
+
import { Address } from "viem";
|
|
2
|
+
import { abi as ERC20_ABI } from "../erc20/constants";
|
|
3
|
+
export declare const SUPPORTED_NETWORKS: string[];
|
|
4
|
+
export declare const COMET_ADDRESSES: Record<string, Address>;
|
|
5
|
+
export declare const ASSET_ADDRESSES: Record<string, Record<string, Address>>;
|
|
6
|
+
export { ERC20_ABI };
|
|
7
|
+
export declare const COMET_ABI: readonly [{
|
|
8
|
+
readonly inputs: readonly [{
|
|
9
|
+
readonly internalType: "address";
|
|
10
|
+
readonly name: "asset";
|
|
11
|
+
readonly type: "address";
|
|
12
|
+
}, {
|
|
13
|
+
readonly internalType: "uint256";
|
|
14
|
+
readonly name: "amount";
|
|
15
|
+
readonly type: "uint256";
|
|
16
|
+
}];
|
|
17
|
+
readonly name: "supply";
|
|
18
|
+
readonly outputs: readonly [];
|
|
19
|
+
readonly stateMutability: "nonpayable";
|
|
20
|
+
readonly type: "function";
|
|
21
|
+
}, {
|
|
22
|
+
readonly inputs: readonly [{
|
|
23
|
+
readonly internalType: "address";
|
|
24
|
+
readonly name: "asset";
|
|
25
|
+
readonly type: "address";
|
|
26
|
+
}, {
|
|
27
|
+
readonly internalType: "uint256";
|
|
28
|
+
readonly name: "amount";
|
|
29
|
+
readonly type: "uint256";
|
|
30
|
+
}];
|
|
31
|
+
readonly name: "withdraw";
|
|
32
|
+
readonly outputs: readonly [];
|
|
33
|
+
readonly stateMutability: "nonpayable";
|
|
34
|
+
readonly type: "function";
|
|
35
|
+
}, {
|
|
36
|
+
readonly inputs: readonly [{
|
|
37
|
+
readonly internalType: "address";
|
|
38
|
+
readonly name: "priceFeed";
|
|
39
|
+
readonly type: "address";
|
|
40
|
+
}];
|
|
41
|
+
readonly name: "getPrice";
|
|
42
|
+
readonly outputs: readonly [{
|
|
43
|
+
readonly internalType: "uint256";
|
|
44
|
+
readonly name: "";
|
|
45
|
+
readonly type: "uint256";
|
|
46
|
+
}];
|
|
47
|
+
readonly stateMutability: "view";
|
|
48
|
+
readonly type: "function";
|
|
49
|
+
}, {
|
|
50
|
+
readonly inputs: readonly [{
|
|
51
|
+
readonly internalType: "address";
|
|
52
|
+
readonly name: "account";
|
|
53
|
+
readonly type: "address";
|
|
54
|
+
}];
|
|
55
|
+
readonly name: "borrowBalanceOf";
|
|
56
|
+
readonly outputs: readonly [{
|
|
57
|
+
readonly internalType: "uint256";
|
|
58
|
+
readonly name: "";
|
|
59
|
+
readonly type: "uint256";
|
|
60
|
+
}];
|
|
61
|
+
readonly stateMutability: "view";
|
|
62
|
+
readonly type: "function";
|
|
63
|
+
}, {
|
|
64
|
+
readonly inputs: readonly [];
|
|
65
|
+
readonly name: "numAssets";
|
|
66
|
+
readonly outputs: readonly [{
|
|
67
|
+
readonly internalType: "uint8";
|
|
68
|
+
readonly name: "";
|
|
69
|
+
readonly type: "uint8";
|
|
70
|
+
}];
|
|
71
|
+
readonly stateMutability: "view";
|
|
72
|
+
readonly type: "function";
|
|
73
|
+
}, {
|
|
74
|
+
readonly inputs: readonly [{
|
|
75
|
+
readonly internalType: "uint8";
|
|
76
|
+
readonly name: "i";
|
|
77
|
+
readonly type: "uint8";
|
|
78
|
+
}];
|
|
79
|
+
readonly name: "getAssetInfo";
|
|
80
|
+
readonly outputs: readonly [{
|
|
81
|
+
readonly components: readonly [{
|
|
82
|
+
readonly internalType: "uint8";
|
|
83
|
+
readonly name: "offset";
|
|
84
|
+
readonly type: "uint8";
|
|
85
|
+
}, {
|
|
86
|
+
readonly internalType: "address";
|
|
87
|
+
readonly name: "asset";
|
|
88
|
+
readonly type: "address";
|
|
89
|
+
}, {
|
|
90
|
+
readonly internalType: "address";
|
|
91
|
+
readonly name: "priceFeed";
|
|
92
|
+
readonly type: "address";
|
|
93
|
+
}, {
|
|
94
|
+
readonly internalType: "uint64";
|
|
95
|
+
readonly name: "scale";
|
|
96
|
+
readonly type: "uint64";
|
|
97
|
+
}, {
|
|
98
|
+
readonly internalType: "uint64";
|
|
99
|
+
readonly name: "borrowCollateralFactor";
|
|
100
|
+
readonly type: "uint64";
|
|
101
|
+
}, {
|
|
102
|
+
readonly internalType: "uint64";
|
|
103
|
+
readonly name: "liquidateCollateralFactor";
|
|
104
|
+
readonly type: "uint64";
|
|
105
|
+
}, {
|
|
106
|
+
readonly internalType: "uint64";
|
|
107
|
+
readonly name: "liquidationFactor";
|
|
108
|
+
readonly type: "uint64";
|
|
109
|
+
}, {
|
|
110
|
+
readonly internalType: "uint128";
|
|
111
|
+
readonly name: "supplyCap";
|
|
112
|
+
readonly type: "uint128";
|
|
113
|
+
}];
|
|
114
|
+
readonly internalType: "struct CometCore.AssetInfo";
|
|
115
|
+
readonly name: "";
|
|
116
|
+
readonly type: "tuple";
|
|
117
|
+
}];
|
|
118
|
+
readonly stateMutability: "view";
|
|
119
|
+
readonly type: "function";
|
|
120
|
+
}, {
|
|
121
|
+
readonly inputs: readonly [];
|
|
122
|
+
readonly name: "baseToken";
|
|
123
|
+
readonly outputs: readonly [{
|
|
124
|
+
readonly internalType: "address";
|
|
125
|
+
readonly name: "";
|
|
126
|
+
readonly type: "address";
|
|
127
|
+
}];
|
|
128
|
+
readonly stateMutability: "view";
|
|
129
|
+
readonly type: "function";
|
|
130
|
+
}, {
|
|
131
|
+
readonly inputs: readonly [];
|
|
132
|
+
readonly name: "baseTokenPriceFeed";
|
|
133
|
+
readonly outputs: readonly [{
|
|
134
|
+
readonly internalType: "address";
|
|
135
|
+
readonly name: "";
|
|
136
|
+
readonly type: "address";
|
|
137
|
+
}];
|
|
138
|
+
readonly stateMutability: "view";
|
|
139
|
+
readonly type: "function";
|
|
140
|
+
}, {
|
|
141
|
+
readonly inputs: readonly [{
|
|
142
|
+
readonly internalType: "address";
|
|
143
|
+
readonly name: "account";
|
|
144
|
+
readonly type: "address";
|
|
145
|
+
}, {
|
|
146
|
+
readonly internalType: "address";
|
|
147
|
+
readonly name: "asset";
|
|
148
|
+
readonly type: "address";
|
|
149
|
+
}];
|
|
150
|
+
readonly name: "collateralBalanceOf";
|
|
151
|
+
readonly outputs: readonly [{
|
|
152
|
+
readonly internalType: "uint128";
|
|
153
|
+
readonly name: "balance";
|
|
154
|
+
readonly type: "uint128";
|
|
155
|
+
}];
|
|
156
|
+
readonly stateMutability: "view";
|
|
157
|
+
readonly type: "function";
|
|
158
|
+
}];
|
|
159
|
+
export declare const PRICE_FEED_ABI: readonly [{
|
|
160
|
+
readonly inputs: readonly [];
|
|
161
|
+
readonly name: "latestRoundData";
|
|
162
|
+
readonly outputs: readonly [{
|
|
163
|
+
readonly name: "roundId";
|
|
164
|
+
readonly type: "uint80";
|
|
165
|
+
}, {
|
|
166
|
+
readonly name: "answer";
|
|
167
|
+
readonly type: "int256";
|
|
168
|
+
}, {
|
|
169
|
+
readonly name: "startedAt";
|
|
170
|
+
readonly type: "uint256";
|
|
171
|
+
}, {
|
|
172
|
+
readonly name: "updatedAt";
|
|
173
|
+
readonly type: "uint256";
|
|
174
|
+
}, {
|
|
175
|
+
readonly name: "answeredInRound";
|
|
176
|
+
readonly type: "uint80";
|
|
177
|
+
}];
|
|
178
|
+
readonly stateMutability: "view";
|
|
179
|
+
readonly type: "function";
|
|
180
|
+
}];
|
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.PRICE_FEED_ABI = exports.COMET_ABI = exports.ERC20_ABI = exports.ASSET_ADDRESSES = exports.COMET_ADDRESSES = exports.SUPPORTED_NETWORKS = void 0;
|
|
4
|
+
const constants_1 = require("../erc20/constants");
|
|
5
|
+
Object.defineProperty(exports, "ERC20_ABI", { enumerable: true, get: function () { return constants_1.abi; } });
|
|
6
|
+
exports.SUPPORTED_NETWORKS = ["base-mainnet", "base-sepolia"];
|
|
7
|
+
exports.COMET_ADDRESSES = {
|
|
8
|
+
"base-mainnet": "0xb125E6687d4313864e53df431d5425969c15Eb2F",
|
|
9
|
+
"base-sepolia": "0x571621Ce60Cebb0c1D442B5afb38B1663C6Bf017",
|
|
10
|
+
};
|
|
11
|
+
exports.ASSET_ADDRESSES = {
|
|
12
|
+
"base-mainnet": {
|
|
13
|
+
weth: "0x4200000000000000000000000000000000000006",
|
|
14
|
+
cbeth: "0x2Ae3F1Ec7F1F5012CFEab0185bfc7aa3cf0DEc22",
|
|
15
|
+
cbbtc: "0xcbB7C0000aB88B473b1f5aFd9ef808440eed33Bf",
|
|
16
|
+
wsteth: "0xc1CBa3fCea344f92D9239c08C0568f6F2F0ee452",
|
|
17
|
+
usdc: "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913",
|
|
18
|
+
},
|
|
19
|
+
"base-sepolia": {
|
|
20
|
+
weth: "0x4200000000000000000000000000000000000006",
|
|
21
|
+
usdc: "0x036CbD53842c5426634e7929541eC2318f3dCF7e",
|
|
22
|
+
wsteth: "0x774eD9EDB0C5202dF9A86183804b5D9E99dC6CA3",
|
|
23
|
+
},
|
|
24
|
+
};
|
|
25
|
+
exports.COMET_ABI = [
|
|
26
|
+
{
|
|
27
|
+
inputs: [
|
|
28
|
+
{ internalType: "address", name: "asset", type: "address" },
|
|
29
|
+
{ internalType: "uint256", name: "amount", type: "uint256" },
|
|
30
|
+
],
|
|
31
|
+
name: "supply",
|
|
32
|
+
outputs: [],
|
|
33
|
+
stateMutability: "nonpayable",
|
|
34
|
+
type: "function",
|
|
35
|
+
},
|
|
36
|
+
{
|
|
37
|
+
inputs: [
|
|
38
|
+
{ internalType: "address", name: "asset", type: "address" },
|
|
39
|
+
{ internalType: "uint256", name: "amount", type: "uint256" },
|
|
40
|
+
],
|
|
41
|
+
name: "withdraw",
|
|
42
|
+
outputs: [],
|
|
43
|
+
stateMutability: "nonpayable",
|
|
44
|
+
type: "function",
|
|
45
|
+
},
|
|
46
|
+
{
|
|
47
|
+
inputs: [{ internalType: "address", name: "priceFeed", type: "address" }],
|
|
48
|
+
name: "getPrice",
|
|
49
|
+
outputs: [{ internalType: "uint256", name: "", type: "uint256" }],
|
|
50
|
+
stateMutability: "view",
|
|
51
|
+
type: "function",
|
|
52
|
+
},
|
|
53
|
+
{
|
|
54
|
+
inputs: [{ internalType: "address", name: "account", type: "address" }],
|
|
55
|
+
name: "borrowBalanceOf",
|
|
56
|
+
outputs: [{ internalType: "uint256", name: "", type: "uint256" }],
|
|
57
|
+
stateMutability: "view",
|
|
58
|
+
type: "function",
|
|
59
|
+
},
|
|
60
|
+
{
|
|
61
|
+
inputs: [],
|
|
62
|
+
name: "numAssets",
|
|
63
|
+
outputs: [{ internalType: "uint8", name: "", type: "uint8" }],
|
|
64
|
+
stateMutability: "view",
|
|
65
|
+
type: "function",
|
|
66
|
+
},
|
|
67
|
+
{
|
|
68
|
+
inputs: [{ internalType: "uint8", name: "i", type: "uint8" }],
|
|
69
|
+
name: "getAssetInfo",
|
|
70
|
+
outputs: [
|
|
71
|
+
{
|
|
72
|
+
components: [
|
|
73
|
+
{ internalType: "uint8", name: "offset", type: "uint8" },
|
|
74
|
+
{ internalType: "address", name: "asset", type: "address" },
|
|
75
|
+
{ internalType: "address", name: "priceFeed", type: "address" },
|
|
76
|
+
{ internalType: "uint64", name: "scale", type: "uint64" },
|
|
77
|
+
{ internalType: "uint64", name: "borrowCollateralFactor", type: "uint64" },
|
|
78
|
+
{ internalType: "uint64", name: "liquidateCollateralFactor", type: "uint64" },
|
|
79
|
+
{ internalType: "uint64", name: "liquidationFactor", type: "uint64" },
|
|
80
|
+
{ internalType: "uint128", name: "supplyCap", type: "uint128" },
|
|
81
|
+
],
|
|
82
|
+
internalType: "struct CometCore.AssetInfo",
|
|
83
|
+
name: "",
|
|
84
|
+
type: "tuple",
|
|
85
|
+
},
|
|
86
|
+
],
|
|
87
|
+
stateMutability: "view",
|
|
88
|
+
type: "function",
|
|
89
|
+
},
|
|
90
|
+
{
|
|
91
|
+
inputs: [],
|
|
92
|
+
name: "baseToken",
|
|
93
|
+
outputs: [{ internalType: "address", name: "", type: "address" }],
|
|
94
|
+
stateMutability: "view",
|
|
95
|
+
type: "function",
|
|
96
|
+
},
|
|
97
|
+
{
|
|
98
|
+
inputs: [],
|
|
99
|
+
name: "baseTokenPriceFeed",
|
|
100
|
+
outputs: [{ internalType: "address", name: "", type: "address" }],
|
|
101
|
+
stateMutability: "view",
|
|
102
|
+
type: "function",
|
|
103
|
+
},
|
|
104
|
+
{
|
|
105
|
+
inputs: [
|
|
106
|
+
{ internalType: "address", name: "account", type: "address" },
|
|
107
|
+
{ internalType: "address", name: "asset", type: "address" },
|
|
108
|
+
],
|
|
109
|
+
name: "collateralBalanceOf",
|
|
110
|
+
outputs: [{ internalType: "uint128", name: "balance", type: "uint128" }],
|
|
111
|
+
stateMutability: "view",
|
|
112
|
+
type: "function",
|
|
113
|
+
},
|
|
114
|
+
];
|
|
115
|
+
exports.PRICE_FEED_ABI = [
|
|
116
|
+
{
|
|
117
|
+
inputs: [],
|
|
118
|
+
name: "latestRoundData",
|
|
119
|
+
outputs: [
|
|
120
|
+
{ name: "roundId", type: "uint80" },
|
|
121
|
+
{ name: "answer", type: "int256" },
|
|
122
|
+
{ name: "startedAt", type: "uint256" },
|
|
123
|
+
{ name: "updatedAt", type: "uint256" },
|
|
124
|
+
{ name: "answeredInRound", type: "uint80" },
|
|
125
|
+
],
|
|
126
|
+
stateMutability: "view",
|
|
127
|
+
type: "function",
|
|
128
|
+
},
|
|
129
|
+
];
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from "./compoundActionProvider";
|