@coinbase/agentkit 0.10.0 → 0.10.2
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 +195 -23
- package/dist/action-providers/across/acrossActionProvider.js +3 -3
- package/dist/action-providers/across/schemas.d.ts +1 -1
- package/dist/action-providers/baseAccount/baseAccountActionProvider.d.ts +46 -0
- package/dist/action-providers/baseAccount/baseAccountActionProvider.js +404 -0
- package/dist/action-providers/baseAccount/baseAccountActionProvider.test.d.ts +1 -0
- package/dist/action-providers/baseAccount/baseAccountActionProvider.test.js +325 -0
- package/dist/action-providers/baseAccount/index.d.ts +2 -0
- package/dist/action-providers/baseAccount/index.js +18 -0
- package/dist/action-providers/baseAccount/schemas.d.ts +43 -0
- package/dist/action-providers/baseAccount/schemas.js +62 -0
- package/dist/action-providers/baseAccount/types.d.ts +17 -0
- package/dist/action-providers/baseAccount/types.js +2 -0
- package/dist/action-providers/baseAccount/utils.d.ts +14 -0
- package/dist/action-providers/baseAccount/utils.js +57 -0
- package/dist/action-providers/cdp/cdpApiActionProvider.d.ts +3 -12
- package/dist/action-providers/cdp/cdpApiActionProvider.js +2 -81
- package/dist/action-providers/cdp/cdpApiActionProvider.test.js +0 -125
- package/dist/action-providers/cdp/cdpEvmWalletActionProvider.d.ts +18 -3
- package/dist/action-providers/cdp/cdpEvmWalletActionProvider.js +224 -23
- package/dist/action-providers/cdp/cdpEvmWalletActionProvider.test.js +280 -0
- package/dist/action-providers/cdp/cdpSmartWalletActionProvider.d.ts +17 -2
- package/dist/action-providers/cdp/cdpSmartWalletActionProvider.js +224 -18
- package/dist/action-providers/cdp/cdpSmartWalletActionProvider.test.js +267 -1
- package/dist/action-providers/cdp/schemas.d.ts +12 -12
- package/dist/action-providers/cdp/schemas.js +17 -5
- package/dist/action-providers/cdp/swapUtils.d.ts +23 -0
- package/dist/action-providers/cdp/swapUtils.js +106 -0
- package/dist/action-providers/clanker/clankerActionProvider.d.ts +43 -0
- package/dist/action-providers/clanker/clankerActionProvider.js +130 -0
- package/dist/action-providers/clanker/clankerActionProvider.test.d.ts +4 -0
- package/dist/action-providers/clanker/clankerActionProvider.test.js +119 -0
- package/dist/action-providers/clanker/index.d.ts +2 -0
- package/dist/action-providers/clanker/index.js +18 -0
- package/dist/action-providers/clanker/schemas.d.ts +56 -0
- package/dist/action-providers/clanker/schemas.js +47 -0
- package/dist/action-providers/clanker/utils.d.ts +9 -0
- package/dist/action-providers/clanker/utils.js +23 -0
- package/dist/action-providers/compound/constants.d.ts +1 -1
- package/dist/action-providers/compound/constants.js +2 -2
- package/dist/action-providers/erc20/constants.d.ts +35 -135
- package/dist/action-providers/erc20/constants.js +37 -189
- package/dist/action-providers/erc20/erc20ActionProvider.d.ts +9 -1
- package/dist/action-providers/erc20/erc20ActionProvider.js +87 -35
- package/dist/action-providers/erc20/erc20ActionProvider.test.js +115 -52
- package/dist/action-providers/erc20/schemas.d.ts +25 -12
- package/dist/action-providers/erc20/schemas.js +34 -6
- package/dist/action-providers/erc20/utils.d.ts +19 -0
- package/dist/action-providers/erc20/utils.js +54 -0
- package/dist/action-providers/flaunch/client_utils.d.ts +25 -0
- package/dist/action-providers/flaunch/client_utils.js +62 -0
- package/dist/action-providers/flaunch/constants.d.ts +42 -21
- package/dist/action-providers/flaunch/constants.js +113 -38
- package/dist/action-providers/flaunch/flaunchActionProvider.d.ts +4 -43
- package/dist/action-providers/flaunch/flaunchActionProvider.js +133 -209
- package/dist/action-providers/flaunch/flaunchActionProvider.test.js +113 -13
- package/dist/action-providers/flaunch/metadata_utils.d.ts +12 -0
- package/dist/action-providers/flaunch/metadata_utils.js +216 -0
- package/dist/action-providers/flaunch/schemas.d.ts +39 -3
- package/dist/action-providers/flaunch/schemas.js +62 -10
- package/dist/action-providers/flaunch/{utils.d.ts → swap_utils.d.ts} +17 -19
- package/dist/action-providers/flaunch/{utils.js → swap_utils.js} +137 -172
- package/dist/action-providers/index.d.ts +4 -0
- package/dist/action-providers/index.js +4 -0
- package/dist/action-providers/jupiter/schemas.d.ts +1 -1
- package/dist/action-providers/moonwell/schemas.d.ts +2 -2
- package/dist/action-providers/morpho/morphoActionProvider.js +5 -5
- package/dist/action-providers/morpho/schemas.d.ts +2 -2
- package/dist/action-providers/pyth/pythActionProvider.d.ts +2 -2
- package/dist/action-providers/pyth/pythActionProvider.js +83 -26
- package/dist/action-providers/pyth/pythActionProvider.test.js +179 -23
- package/dist/action-providers/pyth/schemas.d.ts +6 -0
- package/dist/action-providers/pyth/schemas.js +9 -1
- package/dist/action-providers/superfluid/constants.d.ts +814 -0
- package/dist/action-providers/superfluid/constants.js +2826 -0
- package/dist/action-providers/superfluid/graphQueries/endpoints.d.ts +2 -0
- package/dist/action-providers/superfluid/graphQueries/endpoints.js +5 -0
- package/dist/action-providers/superfluid/graphQueries/queries.d.ts +1 -0
- package/dist/action-providers/superfluid/graphQueries/queries.js +35 -0
- package/dist/action-providers/superfluid/graphQueries/superfluidGraphQueries.d.ts +8 -0
- package/dist/action-providers/superfluid/graphQueries/superfluidGraphQueries.js +24 -0
- package/dist/action-providers/superfluid/graphQueries/types.d.ts +27 -0
- package/dist/action-providers/superfluid/graphQueries/types.js +2 -0
- package/dist/action-providers/superfluid/index.d.ts +7 -0
- package/dist/action-providers/superfluid/index.js +23 -0
- package/dist/action-providers/superfluid/schemas.d.ts +86 -0
- package/dist/action-providers/superfluid/schemas.js +103 -0
- package/dist/action-providers/superfluid/superfluidActionProvider.d.ts +20 -0
- package/dist/action-providers/superfluid/superfluidActionProvider.js +36 -0
- package/dist/action-providers/superfluid/superfluidPoolActionProvider.d.ts +46 -0
- package/dist/action-providers/superfluid/superfluidPoolActionProvider.js +143 -0
- package/dist/action-providers/superfluid/superfluidPoolActionProvider.test.d.ts +1 -0
- package/dist/action-providers/superfluid/superfluidPoolActionProvider.test.js +92 -0
- package/dist/action-providers/superfluid/superfluidQueryActionProvider.d.ts +27 -0
- package/dist/action-providers/superfluid/superfluidQueryActionProvider.js +71 -0
- package/dist/action-providers/superfluid/superfluidQueryActionProvider.test.d.ts +1 -0
- package/dist/action-providers/superfluid/superfluidQueryActionProvider.test.js +57 -0
- package/dist/action-providers/superfluid/superfluidStreamActionProvider.d.ts +56 -0
- package/dist/action-providers/superfluid/superfluidStreamActionProvider.js +191 -0
- package/dist/action-providers/superfluid/superfluidStreamActionProvider.test.d.ts +1 -0
- package/dist/action-providers/superfluid/superfluidStreamActionProvider.test.js +80 -0
- package/dist/action-providers/superfluid/superfluidSuperTokenCreatorActionProvider.d.ts +30 -0
- package/dist/action-providers/superfluid/superfluidSuperTokenCreatorActionProvider.js +109 -0
- package/dist/action-providers/superfluid/superfluidSuperTokenCreatorActionProvider.test.d.ts +1 -0
- package/dist/action-providers/superfluid/superfluidSuperTokenCreatorActionProvider.test.js +75 -0
- package/dist/action-providers/superfluid/superfluidWrapperActionProvider.d.ts +32 -0
- package/dist/action-providers/superfluid/superfluidWrapperActionProvider.js +101 -0
- package/dist/action-providers/superfluid/superfluidWrapperActionProvider.test.d.ts +1 -0
- package/dist/action-providers/superfluid/superfluidWrapperActionProvider.test.js +85 -0
- package/dist/action-providers/superfluid/utils/parseLogs.d.ts +19 -0
- package/dist/action-providers/superfluid/utils/parseLogs.js +81 -0
- package/dist/action-providers/truemarkets/truemarketsActionProvider.d.ts +4 -16
- package/dist/action-providers/truemarkets/truemarketsActionProvider.js +20 -41
- package/dist/action-providers/truemarkets/truemarketsActionProvider.test.js +11 -33
- package/dist/action-providers/wallet/walletActionProvider.js +24 -10
- package/dist/action-providers/wallet/walletActionProvider.test.js +6 -2
- package/dist/action-providers/x402/schemas.d.ts +7 -0
- package/dist/action-providers/x402/schemas.js +11 -1
- package/dist/action-providers/x402/utils.d.ts +55 -0
- package/dist/action-providers/x402/utils.js +160 -0
- package/dist/action-providers/x402/x402ActionProvider.d.ts +9 -9
- package/dist/action-providers/x402/x402ActionProvider.js +158 -39
- package/dist/action-providers/x402/x402ActionProvider.test.js +116 -10
- package/dist/action-providers/zeroX/index.d.ts +1 -0
- package/dist/action-providers/zeroX/index.js +17 -0
- package/dist/action-providers/zeroX/schemas.d.ts +51 -0
- package/dist/action-providers/zeroX/schemas.js +82 -0
- package/dist/action-providers/zeroX/utils.d.ts +23 -0
- package/dist/action-providers/zeroX/utils.js +106 -0
- package/dist/action-providers/zeroX/zeroXActionProvider.d.ts +57 -0
- package/dist/action-providers/zeroX/zeroXActionProvider.js +407 -0
- package/dist/action-providers/zeroX/zeroXActionProvider.test.d.ts +1 -0
- package/dist/action-providers/zeroX/zeroXActionProvider.test.js +445 -0
- package/dist/utils.d.ts +10 -0
- package/dist/utils.js +43 -13
- package/dist/wallet-providers/cdpEvmWalletProvider.d.ts +27 -2
- package/dist/wallet-providers/cdpEvmWalletProvider.js +54 -36
- package/dist/wallet-providers/cdpEvmWalletProvider.test.js +7 -0
- package/dist/wallet-providers/cdpShared.d.ts +5 -0
- package/dist/wallet-providers/cdpSmartWalletProvider.d.ts +29 -3
- package/dist/wallet-providers/cdpSmartWalletProvider.js +66 -25
- package/dist/wallet-providers/cdpSmartWalletProvider.test.js +6 -10
- package/dist/wallet-providers/cdpSolanaWalletProvider.d.ts +1 -1
- package/dist/wallet-providers/cdpSolanaWalletProvider.js +7 -7
- package/dist/wallet-providers/cdpSolanaWalletProvider.test.js +15 -12
- package/dist/wallet-providers/evmWalletProvider.d.ts +13 -2
- package/dist/wallet-providers/evmWalletProvider.js +4 -0
- package/dist/wallet-providers/legacyCdpSmartWalletProvider.d.ts +18 -2
- package/dist/wallet-providers/legacyCdpSmartWalletProvider.js +23 -2
- package/dist/wallet-providers/legacyCdpWalletProvider.d.ts +19 -2
- package/dist/wallet-providers/legacyCdpWalletProvider.js +27 -2
- package/dist/wallet-providers/legacyCdpWalletProvider.test.js +6 -0
- package/dist/wallet-providers/privyEvmDelegatedEmbeddedWalletProvider.d.ts +17 -2
- package/dist/wallet-providers/privyEvmDelegatedEmbeddedWalletProvider.js +39 -3
- package/dist/wallet-providers/privyEvmDelegatedEmbeddedWalletProvider.test.js +1 -1
- package/dist/wallet-providers/privyEvmWalletProvider.d.ts +2 -0
- package/dist/wallet-providers/privyEvmWalletProvider.js +2 -1
- package/dist/wallet-providers/privyEvmWalletProvider.test.js +12 -1
- package/dist/wallet-providers/solanaKeypairWalletProvider.d.ts +1 -1
- package/dist/wallet-providers/solanaKeypairWalletProvider.js +3 -4
- package/dist/wallet-providers/solanaKeypairWalletProvider.test.js +4 -2
- package/dist/wallet-providers/viemWalletProvider.d.ts +20 -3
- package/dist/wallet-providers/viemWalletProvider.js +33 -4
- package/dist/wallet-providers/viemWalletProvider.test.js +27 -6
- package/dist/wallet-providers/walletProvider.d.ts +1 -1
- package/dist/wallet-providers/zeroDevWalletProvider.d.ts +17 -2
- package/dist/wallet-providers/zeroDevWalletProvider.js +26 -5
- package/dist/wallet-providers/zeroDevWalletProvider.test.js +12 -2
- package/package.json +8 -4
|
@@ -36,23 +36,31 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
36
36
|
const cdpSmartWalletActionProvider_1 = require("./cdpSmartWalletActionProvider");
|
|
37
37
|
const schemas_1 = require("./schemas");
|
|
38
38
|
const spendPermissionUtils = __importStar(require("./spendPermissionUtils"));
|
|
39
|
+
const swapUtils = __importStar(require("./swapUtils"));
|
|
40
|
+
const utils = __importStar(require("../../utils"));
|
|
39
41
|
// Mock the CDP SDK and utility functions
|
|
40
42
|
jest.mock("@coinbase/cdp-sdk");
|
|
41
43
|
jest.mock("./spendPermissionUtils");
|
|
44
|
+
jest.mock("./swapUtils");
|
|
45
|
+
jest.mock("../../utils");
|
|
42
46
|
describe("CDP Smart Wallet Action Provider", () => {
|
|
43
47
|
let actionProvider;
|
|
44
48
|
let mockWalletProvider;
|
|
45
49
|
let mockCdpClient;
|
|
46
50
|
let mockSmartAccount;
|
|
51
|
+
const mockGetTokenDetails = swapUtils.getTokenDetails;
|
|
52
|
+
const mockRetryWithExponentialBackoff = utils.retryWithExponentialBackoff;
|
|
47
53
|
beforeEach(() => {
|
|
48
54
|
jest.clearAllMocks();
|
|
49
55
|
mockSmartAccount = {
|
|
50
56
|
useSpendPermission: jest.fn(),
|
|
57
|
+
swap: jest.fn(),
|
|
51
58
|
address: "0x1234567890123456789012345678901234567890",
|
|
52
59
|
};
|
|
53
60
|
mockCdpClient = {
|
|
54
61
|
evm: {
|
|
55
62
|
listSpendPermissions: jest.fn(),
|
|
63
|
+
getSwapPrice: jest.fn(),
|
|
56
64
|
},
|
|
57
65
|
};
|
|
58
66
|
mockWalletProvider = {
|
|
@@ -60,7 +68,19 @@ describe("CDP Smart Wallet Action Provider", () => {
|
|
|
60
68
|
getAddress: jest.fn(),
|
|
61
69
|
getClient: jest.fn(),
|
|
62
70
|
smartAccount: mockSmartAccount,
|
|
71
|
+
ownerAccount: {
|
|
72
|
+
type: "server",
|
|
73
|
+
address: "0xowner123",
|
|
74
|
+
},
|
|
75
|
+
sendTransaction: jest.fn(),
|
|
76
|
+
waitForTransactionReceipt: jest.fn(),
|
|
77
|
+
getPaymasterUrl: jest.fn(),
|
|
78
|
+
getCdpSdkNetwork: jest.fn(),
|
|
63
79
|
};
|
|
80
|
+
// Default setup for utility functions
|
|
81
|
+
mockRetryWithExponentialBackoff.mockImplementation(async (fn) => {
|
|
82
|
+
return await fn();
|
|
83
|
+
});
|
|
64
84
|
actionProvider = new cdpSmartWalletActionProvider_1.CdpSmartWalletActionProvider();
|
|
65
85
|
});
|
|
66
86
|
describe("listSpendPermissions", () => {
|
|
@@ -74,6 +94,7 @@ describe("CDP Smart Wallet Action Provider", () => {
|
|
|
74
94
|
});
|
|
75
95
|
mockWalletProvider.getAddress.mockReturnValue("0x1234567890123456789012345678901234567890");
|
|
76
96
|
mockWalletProvider.getClient.mockReturnValue(mockCdpClient);
|
|
97
|
+
mockWalletProvider.getCdpSdkNetwork.mockReturnValue("base-sepolia");
|
|
77
98
|
});
|
|
78
99
|
it("should successfully list spend permissions for EVM networks", async () => {
|
|
79
100
|
const expectedResult = "Found 1 spend permission(s):\n1. Token: ETH, Allowance: 1000, Period: 3600 seconds, Start: 123456, End: 234567";
|
|
@@ -110,6 +131,7 @@ describe("CDP Smart Wallet Action Provider", () => {
|
|
|
110
131
|
});
|
|
111
132
|
mockWalletProvider.getAddress.mockReturnValue("0x1234567890123456789012345678901234567890");
|
|
112
133
|
mockWalletProvider.getClient.mockReturnValue(mockCdpClient);
|
|
134
|
+
mockWalletProvider.getCdpSdkNetwork.mockReturnValue("base-sepolia");
|
|
113
135
|
});
|
|
114
136
|
it("should successfully use spend permission for EVM networks", async () => {
|
|
115
137
|
const mockPermission = {
|
|
@@ -140,6 +162,7 @@ describe("CDP Smart Wallet Action Provider", () => {
|
|
|
140
162
|
protocolFamily: "evm",
|
|
141
163
|
networkId: "base-mainnet",
|
|
142
164
|
});
|
|
165
|
+
mockWalletProvider.getCdpSdkNetwork.mockReturnValue("base");
|
|
143
166
|
const mockPermission = { spender: "0x1234", token: "ETH" };
|
|
144
167
|
const mockSpendResult = { status: "completed" };
|
|
145
168
|
spendPermissionUtils.findLatestSpendPermission.mockResolvedValue(mockPermission);
|
|
@@ -156,6 +179,9 @@ describe("CDP Smart Wallet Action Provider", () => {
|
|
|
156
179
|
protocolFamily: "evm",
|
|
157
180
|
networkId: "ethereum-mainnet",
|
|
158
181
|
});
|
|
182
|
+
mockWalletProvider.getCdpSdkNetwork.mockImplementation(() => {
|
|
183
|
+
throw new Error("Unsupported network for smart wallets: ethereum-mainnet");
|
|
184
|
+
});
|
|
159
185
|
await expect(actionProvider.useSpendPermission(mockWalletProvider, mockArgs)).rejects.toThrow("Unsupported network for smart wallets: ethereum-mainnet");
|
|
160
186
|
});
|
|
161
187
|
it("should return error message for non-EVM networks", async () => {
|
|
@@ -163,7 +189,7 @@ describe("CDP Smart Wallet Action Provider", () => {
|
|
|
163
189
|
protocolFamily: "svm",
|
|
164
190
|
networkId: "solana-devnet",
|
|
165
191
|
});
|
|
166
|
-
await expect(actionProvider.useSpendPermission(mockWalletProvider, mockArgs)).rejects.toThrow("
|
|
192
|
+
await expect(actionProvider.useSpendPermission(mockWalletProvider, mockArgs)).rejects.toThrow("Spend permissions are currently only supported on EVM networks.");
|
|
167
193
|
});
|
|
168
194
|
it("should handle spend permission not found error", async () => {
|
|
169
195
|
spendPermissionUtils.findLatestSpendPermission.mockRejectedValue(new Error("No spend permissions found"));
|
|
@@ -188,6 +214,246 @@ describe("CDP Smart Wallet Action Provider", () => {
|
|
|
188
214
|
expect(() => schemas_1.UseSpendPermissionSchema.parse(invalidInput)).toThrow();
|
|
189
215
|
});
|
|
190
216
|
});
|
|
217
|
+
describe("getSwapPrice", () => {
|
|
218
|
+
const mockArgs = {
|
|
219
|
+
fromToken: "0xeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee", // ETH
|
|
220
|
+
toToken: "0x833589fcd6edb6e08f4c7c32d4f71b54bda02913", // USDC on Base
|
|
221
|
+
fromAmount: "0.1",
|
|
222
|
+
slippageBps: 100,
|
|
223
|
+
};
|
|
224
|
+
beforeEach(() => {
|
|
225
|
+
mockWalletProvider.getClient.mockReturnValue(mockCdpClient);
|
|
226
|
+
mockWalletProvider.getAddress.mockReturnValue("0x1234567890123456789012345678901234567890");
|
|
227
|
+
mockWalletProvider.getCdpSdkNetwork.mockReturnValue("base");
|
|
228
|
+
mockGetTokenDetails.mockResolvedValue({
|
|
229
|
+
fromTokenDecimals: 18,
|
|
230
|
+
toTokenDecimals: 6,
|
|
231
|
+
fromTokenName: "ETH",
|
|
232
|
+
toTokenName: "USDC",
|
|
233
|
+
});
|
|
234
|
+
});
|
|
235
|
+
it("should get swap price quote on base-mainnet", async () => {
|
|
236
|
+
mockWalletProvider.getNetwork.mockReturnValue({
|
|
237
|
+
protocolFamily: "evm",
|
|
238
|
+
networkId: "base-mainnet",
|
|
239
|
+
});
|
|
240
|
+
mockCdpClient.evm.getSwapPrice.mockResolvedValue({
|
|
241
|
+
toAmount: "990000", // 0.99 USDC
|
|
242
|
+
minToAmount: "980000", // 0.98 USDC
|
|
243
|
+
liquidityAvailable: true,
|
|
244
|
+
issues: {},
|
|
245
|
+
});
|
|
246
|
+
const result = await actionProvider.getSwapPrice(mockWalletProvider, mockArgs);
|
|
247
|
+
const parsedResult = JSON.parse(result);
|
|
248
|
+
expect(mockCdpClient.evm.getSwapPrice).toHaveBeenCalledWith({
|
|
249
|
+
fromToken: mockArgs.fromToken,
|
|
250
|
+
toToken: mockArgs.toToken,
|
|
251
|
+
fromAmount: 100000000000000000n, // 0.1 ETH in wei
|
|
252
|
+
network: "base",
|
|
253
|
+
taker: "0x1234567890123456789012345678901234567890",
|
|
254
|
+
});
|
|
255
|
+
expect(parsedResult.success).toBe(true);
|
|
256
|
+
expect(parsedResult.fromAmount).toBe("0.1");
|
|
257
|
+
expect(parsedResult.toAmount).toBe("0.99");
|
|
258
|
+
expect(parsedResult.liquidityAvailable).toBe(true);
|
|
259
|
+
});
|
|
260
|
+
it("should get swap price quote on base-sepolia", async () => {
|
|
261
|
+
mockWalletProvider.getNetwork.mockReturnValue({
|
|
262
|
+
protocolFamily: "evm",
|
|
263
|
+
networkId: "base-sepolia",
|
|
264
|
+
});
|
|
265
|
+
mockWalletProvider.getCdpSdkNetwork.mockReturnValue("base-sepolia");
|
|
266
|
+
mockCdpClient.evm.getSwapPrice.mockResolvedValue({
|
|
267
|
+
toAmount: "990000",
|
|
268
|
+
minToAmount: "980000",
|
|
269
|
+
liquidityAvailable: true,
|
|
270
|
+
issues: {},
|
|
271
|
+
});
|
|
272
|
+
const result = await actionProvider.getSwapPrice(mockWalletProvider, mockArgs);
|
|
273
|
+
const parsedResult = JSON.parse(result);
|
|
274
|
+
expect(mockCdpClient.evm.getSwapPrice).toHaveBeenCalledWith({
|
|
275
|
+
fromToken: mockArgs.fromToken,
|
|
276
|
+
toToken: mockArgs.toToken,
|
|
277
|
+
fromAmount: 100000000000000000n,
|
|
278
|
+
network: "base-sepolia",
|
|
279
|
+
taker: "0x1234567890123456789012345678901234567890",
|
|
280
|
+
});
|
|
281
|
+
expect(parsedResult.success).toBe(true);
|
|
282
|
+
});
|
|
283
|
+
it("should return error for unsupported networks", async () => {
|
|
284
|
+
mockWalletProvider.getNetwork.mockReturnValue({
|
|
285
|
+
protocolFamily: "evm",
|
|
286
|
+
networkId: "ethereum-mainnet",
|
|
287
|
+
});
|
|
288
|
+
const result = await actionProvider.getSwapPrice(mockWalletProvider, mockArgs);
|
|
289
|
+
const parsedResult = JSON.parse(result);
|
|
290
|
+
expect(parsedResult.success).toBe(false);
|
|
291
|
+
expect(parsedResult.error).toContain("CDP Swap API for smart wallets is currently only supported on Base networks");
|
|
292
|
+
});
|
|
293
|
+
it("should handle swap price API errors", async () => {
|
|
294
|
+
mockWalletProvider.getNetwork.mockReturnValue({
|
|
295
|
+
protocolFamily: "evm",
|
|
296
|
+
networkId: "base-mainnet",
|
|
297
|
+
});
|
|
298
|
+
mockCdpClient.evm.getSwapPrice.mockRejectedValue(new Error("API Error"));
|
|
299
|
+
const result = await actionProvider.getSwapPrice(mockWalletProvider, mockArgs);
|
|
300
|
+
const parsedResult = JSON.parse(result);
|
|
301
|
+
expect(parsedResult.success).toBe(false);
|
|
302
|
+
expect(parsedResult.error).toContain("Error fetching swap price: Error: API Error");
|
|
303
|
+
});
|
|
304
|
+
});
|
|
305
|
+
describe("swap", () => {
|
|
306
|
+
const mockArgs = {
|
|
307
|
+
fromToken: "0xeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee", // ETH
|
|
308
|
+
toToken: "0x833589fcd6edb6e08f4c7c32d4f71b54bda02913", // USDC on Base
|
|
309
|
+
fromAmount: "0.1",
|
|
310
|
+
slippageBps: 100,
|
|
311
|
+
};
|
|
312
|
+
beforeEach(() => {
|
|
313
|
+
mockWalletProvider.getClient.mockReturnValue(mockCdpClient);
|
|
314
|
+
mockWalletProvider.getAddress.mockReturnValue("0x1234567890123456789012345678901234567890");
|
|
315
|
+
mockWalletProvider.getCdpSdkNetwork.mockReturnValue("base");
|
|
316
|
+
mockWalletProvider.waitForTransactionReceipt.mockResolvedValue({ status: "complete" });
|
|
317
|
+
mockWalletProvider.getPaymasterUrl.mockReturnValue("https://paymaster.example");
|
|
318
|
+
mockGetTokenDetails.mockResolvedValue({
|
|
319
|
+
fromTokenDecimals: 18,
|
|
320
|
+
toTokenDecimals: 6,
|
|
321
|
+
fromTokenName: "ETH",
|
|
322
|
+
toTokenName: "USDC",
|
|
323
|
+
});
|
|
324
|
+
});
|
|
325
|
+
it("should execute swap on base-mainnet", async () => {
|
|
326
|
+
mockWalletProvider.getNetwork.mockReturnValue({
|
|
327
|
+
protocolFamily: "evm",
|
|
328
|
+
networkId: "base-mainnet",
|
|
329
|
+
});
|
|
330
|
+
mockCdpClient.evm.getSwapPrice.mockResolvedValue({
|
|
331
|
+
liquidityAvailable: true,
|
|
332
|
+
issues: {},
|
|
333
|
+
toAmount: "990000", // 0.99 USDC
|
|
334
|
+
minToAmount: "980000", // 0.98 USDC
|
|
335
|
+
});
|
|
336
|
+
mockSmartAccount.swap.mockResolvedValue({ userOpHash: "0xswap789" });
|
|
337
|
+
const result = await actionProvider.swap(mockWalletProvider, mockArgs);
|
|
338
|
+
const parsedResult = JSON.parse(result);
|
|
339
|
+
expect(mockSmartAccount.swap).toHaveBeenCalledWith({
|
|
340
|
+
network: "base",
|
|
341
|
+
fromToken: mockArgs.fromToken,
|
|
342
|
+
toToken: mockArgs.toToken,
|
|
343
|
+
fromAmount: 100000000000000000n, // 0.1 ETH in wei
|
|
344
|
+
slippageBps: 100,
|
|
345
|
+
paymasterUrl: "https://paymaster.example",
|
|
346
|
+
signerAddress: "0xowner123",
|
|
347
|
+
});
|
|
348
|
+
expect(parsedResult.success).toBe(true);
|
|
349
|
+
expect(parsedResult.transactionHash).toBe("0xswap789");
|
|
350
|
+
expect(parsedResult.fromAmount).toBe("0.1");
|
|
351
|
+
expect(parsedResult.toAmount).toBe("0.99");
|
|
352
|
+
});
|
|
353
|
+
it("should return error for unsupported networks", async () => {
|
|
354
|
+
mockWalletProvider.getNetwork.mockReturnValue({
|
|
355
|
+
protocolFamily: "evm",
|
|
356
|
+
networkId: "ethereum-mainnet",
|
|
357
|
+
});
|
|
358
|
+
const result = await actionProvider.swap(mockWalletProvider, mockArgs);
|
|
359
|
+
const parsedResult = JSON.parse(result);
|
|
360
|
+
expect(parsedResult.success).toBe(false);
|
|
361
|
+
expect(parsedResult.error).toContain("CDP Swap API for smart wallets is currently only supported on Base networks");
|
|
362
|
+
});
|
|
363
|
+
it("should throw error for local owner account", async () => {
|
|
364
|
+
mockWalletProvider.getNetwork.mockReturnValue({
|
|
365
|
+
protocolFamily: "evm",
|
|
366
|
+
networkId: "base-mainnet",
|
|
367
|
+
});
|
|
368
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
369
|
+
mockWalletProvider.ownerAccount = {
|
|
370
|
+
type: "local",
|
|
371
|
+
address: "0xlocal123",
|
|
372
|
+
};
|
|
373
|
+
await expect(actionProvider.swap(mockWalletProvider, mockArgs)).rejects.toThrow("Smart wallet owner account is not a CDP server account");
|
|
374
|
+
});
|
|
375
|
+
it("should return error when liquidity is not available", async () => {
|
|
376
|
+
mockWalletProvider.getNetwork.mockReturnValue({
|
|
377
|
+
protocolFamily: "evm",
|
|
378
|
+
networkId: "base-mainnet",
|
|
379
|
+
});
|
|
380
|
+
mockCdpClient.evm.getSwapPrice.mockResolvedValue({
|
|
381
|
+
liquidityAvailable: false,
|
|
382
|
+
issues: {},
|
|
383
|
+
toAmount: "0",
|
|
384
|
+
minToAmount: "0",
|
|
385
|
+
});
|
|
386
|
+
const result = await actionProvider.swap(mockWalletProvider, mockArgs);
|
|
387
|
+
const parsedResult = JSON.parse(result);
|
|
388
|
+
expect(parsedResult.success).toBe(false);
|
|
389
|
+
expect(parsedResult.error).toContain("No liquidity available to swap");
|
|
390
|
+
});
|
|
391
|
+
it("should return error when balance is insufficient", async () => {
|
|
392
|
+
mockWalletProvider.getNetwork.mockReturnValue({
|
|
393
|
+
protocolFamily: "evm",
|
|
394
|
+
networkId: "base-mainnet",
|
|
395
|
+
});
|
|
396
|
+
mockCdpClient.evm.getSwapPrice.mockResolvedValue({
|
|
397
|
+
liquidityAvailable: true,
|
|
398
|
+
issues: {
|
|
399
|
+
balance: {
|
|
400
|
+
currentBalance: "50000000000000000", // 0.05 ETH
|
|
401
|
+
},
|
|
402
|
+
},
|
|
403
|
+
toAmount: "990000",
|
|
404
|
+
minToAmount: "980000",
|
|
405
|
+
});
|
|
406
|
+
const result = await actionProvider.swap(mockWalletProvider, mockArgs);
|
|
407
|
+
const parsedResult = JSON.parse(result);
|
|
408
|
+
expect(parsedResult.success).toBe(false);
|
|
409
|
+
expect(parsedResult.error).toContain("Balance is not enough to perform swap");
|
|
410
|
+
expect(parsedResult.error).toContain("but only have 0.05 ETH");
|
|
411
|
+
});
|
|
412
|
+
it("should handle approval transaction when allowance is insufficient", async () => {
|
|
413
|
+
mockWalletProvider.getNetwork.mockReturnValue({
|
|
414
|
+
protocolFamily: "evm",
|
|
415
|
+
networkId: "base-mainnet",
|
|
416
|
+
});
|
|
417
|
+
mockCdpClient.evm.getSwapPrice.mockResolvedValue({
|
|
418
|
+
liquidityAvailable: true,
|
|
419
|
+
issues: {
|
|
420
|
+
allowance: {
|
|
421
|
+
requiredAllowance: "100000000000000000",
|
|
422
|
+
currentAllowance: "0",
|
|
423
|
+
},
|
|
424
|
+
},
|
|
425
|
+
toAmount: "990000",
|
|
426
|
+
minToAmount: "980000",
|
|
427
|
+
});
|
|
428
|
+
mockWalletProvider.sendTransaction.mockResolvedValue("0xapproval123");
|
|
429
|
+
mockWalletProvider.waitForTransactionReceipt.mockResolvedValueOnce({ status: "complete" }); // For approval
|
|
430
|
+
mockWalletProvider.waitForTransactionReceipt.mockResolvedValueOnce({ status: "complete" }); // For swap
|
|
431
|
+
mockSmartAccount.swap.mockResolvedValue({ userOpHash: "0xswap789" });
|
|
432
|
+
const result = await actionProvider.swap(mockWalletProvider, mockArgs);
|
|
433
|
+
const parsedResult = JSON.parse(result);
|
|
434
|
+
expect(mockWalletProvider.sendTransaction).toHaveBeenCalled();
|
|
435
|
+
expect(parsedResult.success).toBe(true);
|
|
436
|
+
expect(parsedResult.approvalTxHash).toBe("0xapproval123");
|
|
437
|
+
expect(parsedResult.transactionHash).toBe("0xswap789");
|
|
438
|
+
});
|
|
439
|
+
it("should handle swap execution errors", async () => {
|
|
440
|
+
mockWalletProvider.getNetwork.mockReturnValue({
|
|
441
|
+
protocolFamily: "evm",
|
|
442
|
+
networkId: "base-mainnet",
|
|
443
|
+
});
|
|
444
|
+
mockCdpClient.evm.getSwapPrice.mockResolvedValue({
|
|
445
|
+
liquidityAvailable: true,
|
|
446
|
+
issues: {},
|
|
447
|
+
toAmount: "990000",
|
|
448
|
+
minToAmount: "980000",
|
|
449
|
+
});
|
|
450
|
+
mockSmartAccount.swap.mockRejectedValue(new Error("Swap execution failed"));
|
|
451
|
+
const result = await actionProvider.swap(mockWalletProvider, mockArgs);
|
|
452
|
+
const parsedResult = JSON.parse(result);
|
|
453
|
+
expect(parsedResult.success).toBe(false);
|
|
454
|
+
expect(parsedResult.error).toContain("Swap failed: Error: Swap execution failed");
|
|
455
|
+
});
|
|
456
|
+
});
|
|
191
457
|
describe("supportsNetwork", () => {
|
|
192
458
|
it("should return true for any network", () => {
|
|
193
459
|
const evmNetwork = { protocolFamily: "evm", networkId: "base-sepolia" };
|
|
@@ -13,20 +13,20 @@ export declare const RequestFaucetFundsV2Schema: z.ZodObject<{
|
|
|
13
13
|
* Input schema for swap tokens action.
|
|
14
14
|
*/
|
|
15
15
|
export declare const SwapSchema: z.ZodObject<{
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
16
|
+
fromToken: z.ZodString;
|
|
17
|
+
toToken: z.ZodString;
|
|
18
|
+
fromAmount: z.ZodString;
|
|
19
|
+
slippageBps: z.ZodDefault<z.ZodOptional<z.ZodNumber>>;
|
|
20
20
|
}, "strip", z.ZodTypeAny, {
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
21
|
+
fromToken: string;
|
|
22
|
+
toToken: string;
|
|
23
|
+
fromAmount: string;
|
|
24
|
+
slippageBps: number;
|
|
25
25
|
}, {
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
26
|
+
fromToken: string;
|
|
27
|
+
toToken: string;
|
|
28
|
+
fromAmount: string;
|
|
29
|
+
slippageBps?: number | undefined;
|
|
30
30
|
}>;
|
|
31
31
|
/**
|
|
32
32
|
* Input schema for listing spend permissions action.
|
|
@@ -16,13 +16,25 @@ exports.RequestFaucetFundsV2Schema = zod_1.z
|
|
|
16
16
|
*/
|
|
17
17
|
exports.SwapSchema = zod_1.z
|
|
18
18
|
.object({
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
19
|
+
fromToken: zod_1.z
|
|
20
|
+
.string()
|
|
21
|
+
.regex(/^0x[a-fA-F0-9]{40}$/, "Invalid Ethereum address format")
|
|
22
|
+
.describe("The token contract address to swap from"),
|
|
23
|
+
toToken: zod_1.z
|
|
24
|
+
.string()
|
|
25
|
+
.regex(/^0x[a-fA-F0-9]{40}$/, "Invalid Ethereum address format")
|
|
26
|
+
.describe("The token contract address to swap to"),
|
|
27
|
+
fromAmount: zod_1.z
|
|
23
28
|
.string()
|
|
29
|
+
.describe("The amount of fromToken to sell in whole units (e.g., 1.5 WETH, 10.5 USDC)"),
|
|
30
|
+
slippageBps: zod_1.z
|
|
31
|
+
.number()
|
|
32
|
+
.int()
|
|
33
|
+
.min(0)
|
|
34
|
+
.max(10000)
|
|
24
35
|
.optional()
|
|
25
|
-
.
|
|
36
|
+
.default(100)
|
|
37
|
+
.describe("The maximum acceptable slippage in basis points (0-10000, default: 100 = 1%)"),
|
|
26
38
|
})
|
|
27
39
|
.strip()
|
|
28
40
|
.describe("Instructions for swapping tokens");
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { EvmWalletProvider } from "../../wallet-providers";
|
|
2
|
+
export declare const PERMIT2_ADDRESS = "0x000000000022D473030F116dDEE9F6B43aC78BA3";
|
|
3
|
+
/**
|
|
4
|
+
* Checks if a token is native ETH.
|
|
5
|
+
*
|
|
6
|
+
* @param token - The token address to check.
|
|
7
|
+
* @returns True if the token is native ETH, false otherwise.
|
|
8
|
+
*/
|
|
9
|
+
export declare function isNativeEth(token: string): boolean;
|
|
10
|
+
/**
|
|
11
|
+
* Gets the details (decimals and name) for both fromToken and toToken
|
|
12
|
+
*
|
|
13
|
+
* @param walletProvider - The EVM wallet provider to read contracts
|
|
14
|
+
* @param fromToken - The contract address of the from token
|
|
15
|
+
* @param toToken - The contract address of the to token
|
|
16
|
+
* @returns Promise<{fromTokenDecimals: number, toTokenDecimals: number, fromTokenName: string, toTokenName: string}>
|
|
17
|
+
*/
|
|
18
|
+
export declare function getTokenDetails(walletProvider: EvmWalletProvider, fromToken: string, toToken: string): Promise<{
|
|
19
|
+
fromTokenDecimals: number;
|
|
20
|
+
toTokenDecimals: number;
|
|
21
|
+
fromTokenName: string;
|
|
22
|
+
toTokenName: string;
|
|
23
|
+
}>;
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.PERMIT2_ADDRESS = void 0;
|
|
4
|
+
exports.isNativeEth = isNativeEth;
|
|
5
|
+
exports.getTokenDetails = getTokenDetails;
|
|
6
|
+
const viem_1 = require("viem");
|
|
7
|
+
// Permit2 contract address is the same across all networks
|
|
8
|
+
exports.PERMIT2_ADDRESS = "0x000000000022D473030F116dDEE9F6B43aC78BA3";
|
|
9
|
+
/**
|
|
10
|
+
* Checks if a token is native ETH.
|
|
11
|
+
*
|
|
12
|
+
* @param token - The token address to check.
|
|
13
|
+
* @returns True if the token is native ETH, false otherwise.
|
|
14
|
+
*/
|
|
15
|
+
function isNativeEth(token) {
|
|
16
|
+
return token.toLowerCase() === "0xeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee";
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Gets the details (decimals and name) for both fromToken and toToken
|
|
20
|
+
*
|
|
21
|
+
* @param walletProvider - The EVM wallet provider to read contracts
|
|
22
|
+
* @param fromToken - The contract address of the from token
|
|
23
|
+
* @param toToken - The contract address of the to token
|
|
24
|
+
* @returns Promise<{fromTokenDecimals: number, toTokenDecimals: number, fromTokenName: string, toTokenName: string}>
|
|
25
|
+
*/
|
|
26
|
+
async function getTokenDetails(walletProvider, fromToken, toToken) {
|
|
27
|
+
// Initialize default values for native ETH
|
|
28
|
+
let fromTokenDecimals = 18;
|
|
29
|
+
let fromTokenName = "ETH";
|
|
30
|
+
let toTokenDecimals = 18;
|
|
31
|
+
let toTokenName = "ETH";
|
|
32
|
+
// Prepare multicall contracts array
|
|
33
|
+
const contracts = [];
|
|
34
|
+
const contractIndexMap = {
|
|
35
|
+
fromDecimals: -1,
|
|
36
|
+
fromName: -1,
|
|
37
|
+
toDecimals: -1,
|
|
38
|
+
toName: -1,
|
|
39
|
+
};
|
|
40
|
+
// Add from token contracts if not native ETH
|
|
41
|
+
if (!isNativeEth(fromToken)) {
|
|
42
|
+
contractIndexMap.fromDecimals = contracts.length;
|
|
43
|
+
contracts.push({
|
|
44
|
+
address: fromToken,
|
|
45
|
+
abi: viem_1.erc20Abi,
|
|
46
|
+
functionName: "decimals",
|
|
47
|
+
});
|
|
48
|
+
contractIndexMap.fromName = contracts.length;
|
|
49
|
+
contracts.push({
|
|
50
|
+
address: fromToken,
|
|
51
|
+
abi: viem_1.erc20Abi,
|
|
52
|
+
functionName: "name",
|
|
53
|
+
});
|
|
54
|
+
}
|
|
55
|
+
// Add to token contracts if not native ETH
|
|
56
|
+
if (!isNativeEth(toToken)) {
|
|
57
|
+
contractIndexMap.toDecimals = contracts.length;
|
|
58
|
+
contracts.push({
|
|
59
|
+
address: toToken,
|
|
60
|
+
abi: viem_1.erc20Abi,
|
|
61
|
+
functionName: "decimals",
|
|
62
|
+
});
|
|
63
|
+
contractIndexMap.toName = contracts.length;
|
|
64
|
+
contracts.push({
|
|
65
|
+
address: toToken,
|
|
66
|
+
abi: viem_1.erc20Abi,
|
|
67
|
+
functionName: "name",
|
|
68
|
+
});
|
|
69
|
+
}
|
|
70
|
+
// Execute multicall if there are contracts to call
|
|
71
|
+
if (contracts.length > 0) {
|
|
72
|
+
try {
|
|
73
|
+
const results = await walletProvider.getPublicClient().multicall({
|
|
74
|
+
contracts,
|
|
75
|
+
});
|
|
76
|
+
// Extract from token details
|
|
77
|
+
if (contractIndexMap.fromDecimals !== -1) {
|
|
78
|
+
const decimalsResult = results[contractIndexMap.fromDecimals];
|
|
79
|
+
const nameResult = results[contractIndexMap.fromName];
|
|
80
|
+
if (decimalsResult.status === "success" && nameResult.status === "success") {
|
|
81
|
+
fromTokenDecimals = decimalsResult.result;
|
|
82
|
+
fromTokenName = nameResult.result;
|
|
83
|
+
}
|
|
84
|
+
else {
|
|
85
|
+
throw new Error(`Failed to read details for fromToken ${fromToken}. This address may not be a valid ERC20 contract.`);
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
// Extract to token details
|
|
89
|
+
if (contractIndexMap.toDecimals !== -1) {
|
|
90
|
+
const decimalsResult = results[contractIndexMap.toDecimals];
|
|
91
|
+
const nameResult = results[contractIndexMap.toName];
|
|
92
|
+
if (decimalsResult.status === "success" && nameResult.status === "success") {
|
|
93
|
+
toTokenDecimals = decimalsResult.result;
|
|
94
|
+
toTokenName = nameResult.result;
|
|
95
|
+
}
|
|
96
|
+
else {
|
|
97
|
+
throw new Error(`Failed to read details for toToken ${toToken}. This address may not be a valid ERC20 contract.`);
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
catch (error) {
|
|
102
|
+
throw new Error(`Failed to read token details via multicall. Error: ${error}`);
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
return { fromTokenDecimals, toTokenDecimals, fromTokenName, toTokenName };
|
|
106
|
+
}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
import { ActionProvider } from "../actionProvider";
|
|
3
|
+
import { Network } from "../../network";
|
|
4
|
+
import { EvmWalletProvider } from "../../wallet-providers";
|
|
5
|
+
import { ClankTokenSchema } from "./schemas";
|
|
6
|
+
/**
|
|
7
|
+
* ClankerActionProvider provides actions for clanker operations.
|
|
8
|
+
*
|
|
9
|
+
* @description
|
|
10
|
+
* This provider is designed to work with EvmWalletProvider for blockchain interactions.
|
|
11
|
+
* It supports all evm networks.
|
|
12
|
+
*/
|
|
13
|
+
export declare class ClankerActionProvider extends ActionProvider<EvmWalletProvider> {
|
|
14
|
+
/**
|
|
15
|
+
* Constructor for the ClankerActionProvider.
|
|
16
|
+
*/
|
|
17
|
+
constructor();
|
|
18
|
+
/**
|
|
19
|
+
* Clanker action provider
|
|
20
|
+
*
|
|
21
|
+
* @description
|
|
22
|
+
* This action deploys a clanker token using the Clanker sdk
|
|
23
|
+
* It automatically includes the coin in the Clanker ecosystem
|
|
24
|
+
*
|
|
25
|
+
* @param walletProvider - The wallet provider instance for blockchain interactions
|
|
26
|
+
* @param args - Clanker arguments (modify these to fine tune token deployment, like initial quote token and rewards config)
|
|
27
|
+
* @returns A promise that resolves to a string describing the clanker result
|
|
28
|
+
*/
|
|
29
|
+
clankToken(walletProvider: EvmWalletProvider, args: z.infer<typeof ClankTokenSchema>): Promise<string>;
|
|
30
|
+
/**
|
|
31
|
+
* Checks if this provider supports the given network.
|
|
32
|
+
*
|
|
33
|
+
* @param network - The network to check support for
|
|
34
|
+
* @returns True if the network is supported
|
|
35
|
+
*/
|
|
36
|
+
supportsNetwork(network: Network): boolean;
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Factory function to create a new ClankerActionProvider instance.
|
|
40
|
+
*
|
|
41
|
+
* @returns A new ClankerActionProvider instance
|
|
42
|
+
*/
|
|
43
|
+
export declare const clankerActionProvider: () => ClankerActionProvider;
|