@coinbase/agentkit 0.6.2 → 0.7.0

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.
Files changed (44) hide show
  1. package/README.md +234 -0
  2. package/dist/action-providers/cdp-v2/cdpApiV2ActionProvider.d.ts +37 -0
  3. package/dist/action-providers/cdp-v2/cdpApiV2ActionProvider.js +91 -0
  4. package/dist/action-providers/cdp-v2/index.d.ts +2 -0
  5. package/dist/action-providers/cdp-v2/index.js +18 -0
  6. package/dist/action-providers/cdp-v2/schemas.d.ts +11 -0
  7. package/dist/action-providers/cdp-v2/schemas.js +13 -0
  8. package/dist/action-providers/compound/schemas.d.ts +8 -8
  9. package/dist/action-providers/index.d.ts +2 -0
  10. package/dist/action-providers/index.js +2 -0
  11. package/dist/action-providers/zerodev/index.d.ts +1 -0
  12. package/dist/action-providers/zerodev/index.js +17 -0
  13. package/dist/action-providers/zerodev/schemas.d.ts +29 -0
  14. package/dist/action-providers/zerodev/schemas.js +21 -0
  15. package/dist/action-providers/zerodev/zeroDevWalletActionProvider.d.ts +32 -0
  16. package/dist/action-providers/zerodev/zeroDevWalletActionProvider.js +66 -0
  17. package/dist/action-providers/zerodev/zeroDevWalletActionProvider.test.d.ts +1 -0
  18. package/dist/action-providers/zerodev/zeroDevWalletActionProvider.test.js +112 -0
  19. package/dist/network/svm.d.ts +1 -0
  20. package/dist/network/svm.js +6 -1
  21. package/dist/wallet-providers/cdpV2EvmWalletProvider.d.ts +105 -0
  22. package/dist/wallet-providers/cdpV2EvmWalletProvider.js +212 -0
  23. package/dist/wallet-providers/cdpV2EvmWalletProvider.test.d.ts +1 -0
  24. package/dist/wallet-providers/cdpV2EvmWalletProvider.test.js +343 -0
  25. package/dist/wallet-providers/cdpV2Shared.d.ts +41 -0
  26. package/dist/wallet-providers/cdpV2Shared.js +2 -0
  27. package/dist/wallet-providers/cdpV2SolanaWalletProvider.d.ts +111 -0
  28. package/dist/wallet-providers/cdpV2SolanaWalletProvider.js +247 -0
  29. package/dist/wallet-providers/cdpV2SolanaWalletProvider.test.d.ts +1 -0
  30. package/dist/wallet-providers/cdpV2SolanaWalletProvider.test.js +307 -0
  31. package/dist/wallet-providers/cdpV2WalletProvider.d.ts +35 -0
  32. package/dist/wallet-providers/cdpV2WalletProvider.js +42 -0
  33. package/dist/wallet-providers/cdpWalletProvider.js +1 -1
  34. package/dist/wallet-providers/cdpWalletProvider.test.js +1 -0
  35. package/dist/wallet-providers/evmWalletProvider.d.ts +7 -1
  36. package/dist/wallet-providers/evmWalletProvider.js +20 -0
  37. package/dist/wallet-providers/index.d.ts +5 -0
  38. package/dist/wallet-providers/index.js +5 -0
  39. package/dist/wallet-providers/walletProvider.test.js +22 -0
  40. package/dist/wallet-providers/zeroDevWalletProvider.d.ts +147 -0
  41. package/dist/wallet-providers/zeroDevWalletProvider.js +301 -0
  42. package/dist/wallet-providers/zeroDevWalletProvider.test.d.ts +1 -0
  43. package/dist/wallet-providers/zeroDevWalletProvider.test.js +435 -0
  44. package/package.json +5 -1
@@ -0,0 +1,435 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const zeroDevWalletProvider_1 = require("./zeroDevWalletProvider");
4
+ const viem_1 = require("viem");
5
+ const sdk_1 = require("@zerodev/sdk");
6
+ const ecdsa_validator_1 = require("@zerodev/ecdsa-validator");
7
+ const intent_1 = require("@zerodev/intent");
8
+ // =========================================================
9
+ // Consts
10
+ // =========================================================
11
+ const MOCK_ADDRESS = "0x742d35Cc6634C0532925a3b844Bc454e4438f44e";
12
+ const MOCK_NETWORK_ID = "mainnet";
13
+ const MOCK_PROJECT_ID = "project-1234";
14
+ const MOCK_TRANSACTION_HASH = "0x9876543210fedcba9876543210fedcba9876543210fedcba9876543210fedcba";
15
+ const MOCK_SIGNATURE = "0x1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef1b";
16
+ const MOCK_NETWORK = {
17
+ protocolFamily: "evm",
18
+ networkId: MOCK_NETWORK_ID,
19
+ chainId: "1",
20
+ };
21
+ const mockPublicClient = {
22
+ readContract: jest.fn(),
23
+ waitForTransactionReceipt: jest.fn(),
24
+ getBalance: jest.fn(),
25
+ };
26
+ // =========================================================
27
+ // Mocks
28
+ // =========================================================
29
+ // Mock Viem
30
+ jest.mock("viem", () => {
31
+ return {
32
+ createPublicClient: jest.fn(() => mockPublicClient),
33
+ http: jest.fn(),
34
+ zeroAddress: "0x0000000000000000000000000000000000000000",
35
+ toAccount: jest.fn(),
36
+ };
37
+ });
38
+ // Mock ZeroDev SDK
39
+ jest.mock("@zerodev/sdk", () => ({
40
+ createKernelAccount: jest.fn(),
41
+ KERNEL_V3_2: "v3.2",
42
+ getEntryPoint: jest.fn().mockReturnValue("0xENTRYPOINT"),
43
+ }));
44
+ // Mock ECDSA Validator
45
+ jest.mock("@zerodev/ecdsa-validator", () => ({
46
+ signerToEcdsaValidator: jest.fn(),
47
+ }));
48
+ // Mock Intent
49
+ jest.mock("@zerodev/intent", () => ({
50
+ createIntentClient: jest.fn(),
51
+ installIntentExecutor: jest.fn(),
52
+ INTENT_V0_3: "v0.3",
53
+ }));
54
+ jest.mock("../network", () => ({
55
+ NETWORK_ID_TO_VIEM_CHAIN: {
56
+ mainnet: { id: 1, name: "Ethereum" },
57
+ sepolia: { id: 11155111, name: "Sepolia" },
58
+ },
59
+ }));
60
+ jest.mock("../analytics", () => ({
61
+ sendAnalyticsEvent: jest.fn().mockImplementation(() => Promise.resolve()),
62
+ }));
63
+ // =========================================================
64
+ // Mock Implementations
65
+ // =========================================================
66
+ const mockKernelAccount = {
67
+ address: MOCK_ADDRESS,
68
+ signMessage: jest.fn(),
69
+ signTypedData: jest.fn(),
70
+ };
71
+ const mockIntentClient = {
72
+ sendUserIntent: jest.fn(),
73
+ waitForUserIntentExecutionReceipt: jest.fn(),
74
+ };
75
+ const mockEvmWalletProvider = {
76
+ getAddress: jest.fn().mockReturnValue(MOCK_ADDRESS),
77
+ signMessage: jest.fn(),
78
+ signTransaction: jest.fn(),
79
+ signTypedData: jest.fn(),
80
+ getNetwork: jest.fn().mockReturnValue(MOCK_NETWORK),
81
+ toSigner: jest.fn().mockReturnValue({
82
+ address: MOCK_ADDRESS,
83
+ signMessage: jest.fn(),
84
+ signTransaction: jest.fn(),
85
+ signTypedData: jest.fn(),
86
+ }),
87
+ };
88
+ // =========================================================
89
+ // Test Suite
90
+ // =========================================================
91
+ describe("ZeroDevWalletProvider", () => {
92
+ let provider;
93
+ beforeEach(async () => {
94
+ jest.clearAllMocks();
95
+ // Configure mock implementations
96
+ sdk_1.createKernelAccount.mockResolvedValue(mockKernelAccount);
97
+ intent_1.createIntentClient.mockResolvedValue(mockIntentClient);
98
+ ecdsa_validator_1.signerToEcdsaValidator.mockResolvedValue({ validator: "mock-validator" });
99
+ mockPublicClient.readContract.mockResolvedValue("mock_result");
100
+ mockPublicClient.waitForTransactionReceipt.mockResolvedValue({
101
+ transactionHash: MOCK_TRANSACTION_HASH,
102
+ });
103
+ mockPublicClient.getBalance.mockResolvedValue(BigInt(1000000000000000000));
104
+ mockKernelAccount.signMessage.mockResolvedValue(MOCK_SIGNATURE);
105
+ mockKernelAccount.signTypedData.mockResolvedValue(MOCK_SIGNATURE);
106
+ // Mock Intent Client behavior
107
+ mockIntentClient.sendUserIntent.mockResolvedValue({
108
+ outputUiHash: { uiHash: "0xmockUiHash" },
109
+ inputsUiHash: { uiHash: "0xmockUiHash" },
110
+ });
111
+ mockIntentClient.waitForUserIntentExecutionReceipt.mockResolvedValue({
112
+ intentHash: "0xmockIntentHash",
113
+ sender: MOCK_ADDRESS,
114
+ relayer: MOCK_ADDRESS,
115
+ executionChainId: "0x1",
116
+ logs: [],
117
+ receipt: { transactionHash: MOCK_TRANSACTION_HASH },
118
+ });
119
+ // Create provider instance
120
+ provider = await zeroDevWalletProvider_1.ZeroDevWalletProvider.configureWithWallet({
121
+ signer: mockEvmWalletProvider.toSigner(),
122
+ projectId: MOCK_PROJECT_ID,
123
+ networkId: MOCK_NETWORK_ID,
124
+ entryPointVersion: "0.7",
125
+ });
126
+ });
127
+ // =========================================================
128
+ // Initialization Tests
129
+ // =========================================================
130
+ describe("initialization", () => {
131
+ it("should initialize with a signer", async () => {
132
+ expect(provider).toBeInstanceOf(zeroDevWalletProvider_1.ZeroDevWalletProvider);
133
+ expect(provider.getAddress()).toBe(MOCK_ADDRESS);
134
+ expect(provider.getNetwork()).toEqual(MOCK_NETWORK);
135
+ expect(sdk_1.createKernelAccount).toHaveBeenCalled();
136
+ expect(intent_1.createIntentClient).toHaveBeenCalled();
137
+ });
138
+ it("should throw error when signer is not provided", async () => {
139
+ await expect(zeroDevWalletProvider_1.ZeroDevWalletProvider.configureWithWallet({
140
+ signer: undefined,
141
+ projectId: MOCK_PROJECT_ID,
142
+ networkId: MOCK_NETWORK_ID,
143
+ })).rejects.toThrow("Signer is required");
144
+ });
145
+ it("should throw error when project ID is not provided", async () => {
146
+ await expect(zeroDevWalletProvider_1.ZeroDevWalletProvider.configureWithWallet({
147
+ signer: mockEvmWalletProvider.toSigner(),
148
+ projectId: "",
149
+ networkId: MOCK_NETWORK_ID,
150
+ })).rejects.toThrow("ZeroDev project ID is required");
151
+ });
152
+ it("should initialize with a specific address if provided", async () => {
153
+ const customAddress = "0xCustomAddress";
154
+ await zeroDevWalletProvider_1.ZeroDevWalletProvider.configureWithWallet({
155
+ signer: mockEvmWalletProvider.toSigner(),
156
+ projectId: MOCK_PROJECT_ID,
157
+ networkId: MOCK_NETWORK_ID,
158
+ address: customAddress,
159
+ });
160
+ expect(sdk_1.createKernelAccount).toHaveBeenCalledWith(expect.anything(), expect.objectContaining({
161
+ address: customAddress,
162
+ }));
163
+ });
164
+ });
165
+ // =========================================================
166
+ // Basic Wallet Methods Tests
167
+ // =========================================================
168
+ describe("basic wallet methods", () => {
169
+ it("should get the address", () => {
170
+ expect(provider.getAddress()).toBe(MOCK_ADDRESS);
171
+ });
172
+ it("should get the network", () => {
173
+ expect(provider.getNetwork()).toEqual(MOCK_NETWORK);
174
+ });
175
+ it("should get the name", () => {
176
+ expect(provider.getName()).toBe("zerodev_wallet_provider");
177
+ });
178
+ it("should get the balance", async () => {
179
+ const balance = await provider.getBalance();
180
+ expect(balance).toBe(BigInt(1000000000000000000));
181
+ expect(mockPublicClient.getBalance).toHaveBeenCalledWith({
182
+ address: MOCK_ADDRESS,
183
+ });
184
+ });
185
+ it("should get the kernel account", () => {
186
+ expect(provider.getKernelAccount()).toBe(mockKernelAccount);
187
+ });
188
+ it("should get the intent client", () => {
189
+ expect(provider.getIntentClient()).toBe(mockIntentClient);
190
+ });
191
+ });
192
+ // =========================================================
193
+ // Signing Operations Tests
194
+ // =========================================================
195
+ describe("signing operations", () => {
196
+ it("should sign messages", async () => {
197
+ const message = "Hello, world!";
198
+ const signature = await provider.signMessage(message);
199
+ expect(mockKernelAccount.signMessage).toHaveBeenCalledWith({
200
+ message: message,
201
+ });
202
+ expect(signature).toBe(MOCK_SIGNATURE);
203
+ });
204
+ it("should sign Uint8Array messages", async () => {
205
+ const messageBytes = new TextEncoder().encode("Hello, world!");
206
+ const signature = await provider.signMessage(messageBytes);
207
+ expect(mockKernelAccount.signMessage).toHaveBeenCalledWith({
208
+ message: "Hello, world!",
209
+ });
210
+ expect(signature).toBe(MOCK_SIGNATURE);
211
+ });
212
+ it("should sign typed data", async () => {
213
+ const typedData = {
214
+ domain: { name: "Example" },
215
+ types: { Test: [{ name: "test", type: "string" }] },
216
+ message: { test: "example" },
217
+ primaryType: "Test",
218
+ };
219
+ const signature = await provider.signTypedData(typedData);
220
+ expect(mockKernelAccount.signTypedData).toHaveBeenCalledWith(typedData);
221
+ expect(signature).toBe(MOCK_SIGNATURE);
222
+ });
223
+ it("should throw error when signing transactions directly", async () => {
224
+ const tx = {
225
+ to: "0x1234567890123456789012345678901234567890",
226
+ value: BigInt(1000000000000000000),
227
+ };
228
+ await expect(provider.signTransaction(tx)).rejects.toThrow("signTransaction is not supported for ZeroDev Wallet Provider");
229
+ });
230
+ });
231
+ // =========================================================
232
+ // Transaction Operations Tests
233
+ // =========================================================
234
+ describe("transaction operations", () => {
235
+ it("should send native token transfer transactions", async () => {
236
+ const to = "0x1234567890123456789012345678901234567890";
237
+ const value = BigInt(1000000000000000000);
238
+ const transaction = {
239
+ to,
240
+ value,
241
+ data: "0x",
242
+ };
243
+ const txHash = await provider.sendTransaction(transaction);
244
+ expect(mockIntentClient.sendUserIntent).toHaveBeenCalledWith({
245
+ calls: [
246
+ {
247
+ to,
248
+ value,
249
+ data: "0x",
250
+ },
251
+ ],
252
+ outputTokens: [
253
+ {
254
+ address: viem_1.zeroAddress,
255
+ chainId: 1,
256
+ amount: value,
257
+ },
258
+ ],
259
+ });
260
+ expect(mockIntentClient.waitForUserIntentExecutionReceipt).toHaveBeenCalled();
261
+ expect(txHash).toBe(MOCK_TRANSACTION_HASH);
262
+ });
263
+ it("should send contract interaction transactions", async () => {
264
+ const to = "0x1234567890123456789012345678901234567890";
265
+ const data = "0xabcdef";
266
+ const transaction = {
267
+ to,
268
+ data,
269
+ };
270
+ const txHash = await provider.sendTransaction(transaction);
271
+ expect(mockIntentClient.sendUserIntent).toHaveBeenCalledWith({
272
+ calls: [
273
+ {
274
+ to,
275
+ value: BigInt(0),
276
+ data,
277
+ },
278
+ ],
279
+ chainId: 1,
280
+ });
281
+ expect(mockIntentClient.waitForUserIntentExecutionReceipt).toHaveBeenCalled();
282
+ expect(txHash).toBe(MOCK_TRANSACTION_HASH);
283
+ });
284
+ it("should handle native transfers using nativeTransfer method", async () => {
285
+ const to = "0x1234567890123456789012345678901234567890";
286
+ const value = "1.0";
287
+ const valueInWei = BigInt(parseFloat(value) * 10 ** 18);
288
+ const txHash = await provider.nativeTransfer(to, value);
289
+ expect(mockIntentClient.sendUserIntent).toHaveBeenCalledWith({
290
+ calls: [
291
+ {
292
+ to: to,
293
+ value: valueInWei,
294
+ data: "0x",
295
+ },
296
+ ],
297
+ outputTokens: [
298
+ {
299
+ address: viem_1.zeroAddress,
300
+ chainId: 1,
301
+ amount: valueInWei,
302
+ },
303
+ ],
304
+ });
305
+ expect(mockIntentClient.waitForUserIntentExecutionReceipt).toHaveBeenCalled();
306
+ expect(txHash).toBe(MOCK_TRANSACTION_HASH);
307
+ });
308
+ it("should wait for transaction receipt", async () => {
309
+ const hash = "0x1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef";
310
+ await provider.waitForTransactionReceipt(hash);
311
+ expect(mockPublicClient.waitForTransactionReceipt).toHaveBeenCalledWith({ hash });
312
+ });
313
+ it("should handle transaction failures", async () => {
314
+ mockIntentClient.sendUserIntent.mockRejectedValueOnce(new Error("Transaction failed"));
315
+ const transaction = {
316
+ to: "0x1234567890123456789012345678901234567890",
317
+ value: BigInt(1000000000000000000),
318
+ };
319
+ await expect(provider.sendTransaction(transaction)).rejects.toThrow("Transaction failed");
320
+ });
321
+ it("should handle receipt waiting failures", async () => {
322
+ mockIntentClient.waitForUserIntentExecutionReceipt.mockRejectedValueOnce(new Error("Receipt waiting failed"));
323
+ const transaction = {
324
+ to: "0x1234567890123456789012345678901234567890",
325
+ value: BigInt(1000000000000000000),
326
+ };
327
+ await expect(provider.sendTransaction(transaction)).rejects.toThrow("Receipt waiting failed");
328
+ });
329
+ it("should handle missing transaction hash in receipt", async () => {
330
+ mockIntentClient.waitForUserIntentExecutionReceipt.mockResolvedValueOnce({
331
+ receipt: {},
332
+ });
333
+ const transaction = {
334
+ to: "0x1234567890123456789012345678901234567890",
335
+ value: BigInt(1000000000000000000),
336
+ };
337
+ const txHash = await provider.sendTransaction(transaction);
338
+ expect(txHash).toBe("0x");
339
+ });
340
+ });
341
+ // =========================================================
342
+ // Contract Interaction Tests
343
+ // =========================================================
344
+ describe("contract interactions", () => {
345
+ it("should read contract data", async () => {
346
+ const abi = [
347
+ {
348
+ name: "balanceOf",
349
+ type: "function",
350
+ inputs: [{ name: "account", type: "address" }],
351
+ outputs: [{ name: "balance", type: "uint256" }],
352
+ stateMutability: "view",
353
+ },
354
+ ];
355
+ const result = await provider.readContract({
356
+ address: "0x1234567890123456789012345678901234567890",
357
+ abi,
358
+ functionName: "balanceOf",
359
+ args: [MOCK_ADDRESS],
360
+ });
361
+ expect(result).toBe("mock_result");
362
+ expect(mockPublicClient.readContract).toHaveBeenCalled();
363
+ });
364
+ it("should handle contract read failures", async () => {
365
+ mockPublicClient.readContract.mockRejectedValueOnce(new Error("Contract read failed"));
366
+ const abi = [
367
+ {
368
+ name: "balanceOf",
369
+ type: "function",
370
+ inputs: [{ name: "account", type: "address" }],
371
+ outputs: [{ name: "balance", type: "uint256" }],
372
+ stateMutability: "view",
373
+ },
374
+ ];
375
+ await expect(provider.readContract({
376
+ address: "0x1234567890123456789012345678901234567890",
377
+ abi,
378
+ functionName: "balanceOf",
379
+ args: [MOCK_ADDRESS],
380
+ })).rejects.toThrow("Contract read failed");
381
+ });
382
+ });
383
+ // =========================================================
384
+ // Chain Abstracted Balance Tests
385
+ // =========================================================
386
+ describe("chain abstracted balance", () => {
387
+ it("should get chain abstracted balance", async () => {
388
+ const mockCABResult = {
389
+ balance: BigInt(1000000000000000000),
390
+ tokenAddress: "0x1234567890123456789012345678901234567890",
391
+ };
392
+ mockIntentClient.getCAB = jest.fn().mockResolvedValue(mockCABResult);
393
+ const options = {
394
+ tokenTickers: ["USDC"],
395
+ networks: [1],
396
+ };
397
+ const result = await provider.getCAB(options);
398
+ expect(mockIntentClient.getCAB).toHaveBeenCalledWith(options);
399
+ expect(result).toEqual(mockCABResult);
400
+ });
401
+ it("should handle getCAB failures", async () => {
402
+ mockIntentClient.getCAB = jest.fn().mockRejectedValue(new Error("CAB check failed"));
403
+ const options = {
404
+ tokenTickers: ["USDC"],
405
+ networks: [1234],
406
+ };
407
+ await expect(provider.getCAB(options)).rejects.toThrow("CAB check failed");
408
+ });
409
+ });
410
+ // =========================================================
411
+ // Error Handling Tests
412
+ // =========================================================
413
+ describe("error handling", () => {
414
+ it("should handle intent client initialization failures", async () => {
415
+ intent_1.createIntentClient.mockRejectedValueOnce(new Error("Intent client initialization failed"));
416
+ await expect(zeroDevWalletProvider_1.ZeroDevWalletProvider.configureWithWallet({
417
+ signer: mockEvmWalletProvider.toSigner(),
418
+ projectId: MOCK_PROJECT_ID,
419
+ networkId: MOCK_NETWORK_ID,
420
+ })).rejects.toThrow("Intent client initialization failed");
421
+ });
422
+ it("should handle kernel account initialization failures", async () => {
423
+ sdk_1.createKernelAccount.mockRejectedValueOnce(new Error("Kernel account initialization failed"));
424
+ await expect(zeroDevWalletProvider_1.ZeroDevWalletProvider.configureWithWallet({
425
+ signer: mockEvmWalletProvider.toSigner(),
426
+ projectId: MOCK_PROJECT_ID,
427
+ networkId: MOCK_NETWORK_ID,
428
+ })).rejects.toThrow("Kernel account initialization failed");
429
+ });
430
+ it("should handle balance check failures", async () => {
431
+ mockPublicClient.getBalance.mockRejectedValueOnce(new Error("Balance check failed"));
432
+ await expect(provider.getBalance()).rejects.toThrow("Balance check failed");
433
+ });
434
+ });
435
+ });
package/package.json CHANGED
@@ -2,7 +2,7 @@
2
2
  "name": "@coinbase/agentkit",
3
3
  "description": "Coinbase AgentKit core primitives",
4
4
  "repository": "https://github.com/coinbase/agentkit",
5
- "version": "0.6.2",
5
+ "version": "0.7.0",
6
6
  "author": "Coinbase Inc.",
7
7
  "license": "Apache-2.0",
8
8
  "main": "dist/index.js",
@@ -24,6 +24,7 @@
24
24
  "dependencies": {
25
25
  "@across-protocol/app-sdk": "^0.2.0",
26
26
  "@alloralabs/allora-sdk": "^0.1.0",
27
+ "@coinbase/cdp-sdk": "^1.3.0",
27
28
  "@coinbase/coinbase-sdk": "^0.20.0",
28
29
  "@jup-ag/api": "^6.0.39",
29
30
  "@privy-io/public-api": "^2.18.5",
@@ -34,6 +35,9 @@
34
35
  "canonicalize": "^2.1.0",
35
36
  "decimal.js": "^10.5.0",
36
37
  "ethers": "^6.13.5",
38
+ "@zerodev/ecdsa-validator": "^5.4.5",
39
+ "@zerodev/intent": "^0.0.24",
40
+ "@zerodev/sdk": "^5.4.28",
37
41
  "md5": "^2.3.0",
38
42
  "opensea-js": "^7.1.18",
39
43
  "reflect-metadata": "^0.2.2",