@coinbase/agentkit 0.3.0 → 0.5.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.
- package/README.md +90 -7
- package/dist/action-providers/across/acrossActionProvider.d.ts +50 -0
- package/dist/action-providers/across/acrossActionProvider.js +333 -0
- package/dist/action-providers/across/acrossActionProvider.test.d.ts +1 -0
- package/dist/action-providers/across/acrossActionProvider.test.js +391 -0
- package/dist/action-providers/across/constants.d.ts +1 -0
- package/dist/action-providers/across/constants.js +2 -0
- package/dist/action-providers/across/index.d.ts +1 -0
- package/dist/action-providers/across/index.js +17 -0
- package/dist/action-providers/across/schemas.d.ts +36 -0
- package/dist/action-providers/across/schemas.js +46 -0
- package/dist/action-providers/across/utils.d.ts +7 -0
- package/dist/action-providers/across/utils.js +25 -0
- package/dist/action-providers/defillama/constants.d.ts +8 -0
- package/dist/action-providers/defillama/constants.js +11 -0
- package/dist/action-providers/defillama/defillamaActionProvider.d.ts +54 -0
- package/dist/action-providers/defillama/defillamaActionProvider.js +180 -0
- package/dist/action-providers/defillama/defillamaActionProvider.test.d.ts +1 -0
- package/dist/action-providers/defillama/defillamaActionProvider.test.js +114 -0
- package/dist/action-providers/defillama/index.d.ts +1 -0
- package/dist/action-providers/defillama/index.js +17 -0
- package/dist/action-providers/defillama/schemas.d.ts +34 -0
- package/dist/action-providers/defillama/schemas.js +34 -0
- package/dist/action-providers/defillama/types.d.ts +73 -0
- package/dist/action-providers/defillama/types.js +2 -0
- package/dist/action-providers/defillama/utils.d.ts +10 -0
- package/dist/action-providers/defillama/utils.js +87 -0
- package/dist/action-providers/defillama/utils.test.d.ts +1 -0
- package/dist/action-providers/defillama/utils.test.js +124 -0
- package/dist/action-providers/erc20/constants.d.ts +2 -0
- package/dist/action-providers/erc20/constants.js +12 -1
- package/dist/action-providers/erc20/erc20ActionProvider.js +18 -0
- package/dist/action-providers/erc20/erc20ActionProvider.test.js +4 -0
- package/dist/action-providers/index.d.ts +3 -0
- package/dist/action-providers/index.js +3 -0
- package/dist/action-providers/messari/constants.d.ts +17 -0
- package/dist/action-providers/messari/constants.js +20 -0
- package/dist/action-providers/messari/index.d.ts +5 -0
- package/dist/action-providers/messari/index.js +21 -0
- package/dist/action-providers/messari/messariActionProvider.d.ts +42 -0
- package/dist/action-providers/messari/messariActionProvider.js +128 -0
- package/dist/action-providers/messari/messariActionProvider.test.d.ts +1 -0
- package/dist/action-providers/messari/messariActionProvider.test.js +152 -0
- package/dist/action-providers/messari/schemas.d.ts +11 -0
- package/dist/action-providers/messari/schemas.js +16 -0
- package/dist/action-providers/messari/types.d.ts +40 -0
- package/dist/action-providers/messari/types.js +2 -0
- package/dist/action-providers/messari/utils.d.ts +22 -0
- package/dist/action-providers/messari/utils.js +65 -0
- package/dist/action-providers/morpho/morphoActionProvider.js +11 -4
- package/dist/action-providers/morpho/morphoActionProvider.test.js +2 -0
- package/dist/wallet-providers/cdpWalletProvider.d.ts +11 -2
- package/dist/wallet-providers/cdpWalletProvider.js +24 -0
- package/dist/wallet-providers/cdpWalletProvider.test.d.ts +1 -0
- package/dist/wallet-providers/cdpWalletProvider.test.js +701 -0
- package/dist/wallet-providers/evmWalletProvider.test.d.ts +1 -0
- package/dist/wallet-providers/evmWalletProvider.test.js +56 -0
- package/dist/wallet-providers/index.d.ts +1 -0
- package/dist/wallet-providers/index.js +1 -0
- package/dist/wallet-providers/privyEvmDelegatedEmbeddedWalletProvider.d.ts +167 -0
- package/dist/wallet-providers/privyEvmDelegatedEmbeddedWalletProvider.js +438 -0
- package/dist/wallet-providers/privyEvmDelegatedEmbeddedWalletProvider.test.d.ts +1 -0
- package/dist/wallet-providers/privyEvmDelegatedEmbeddedWalletProvider.test.js +280 -0
- package/dist/wallet-providers/privyEvmWalletProvider.test.d.ts +1 -0
- package/dist/wallet-providers/privyEvmWalletProvider.test.js +331 -0
- package/dist/wallet-providers/privyShared.d.ts +9 -0
- package/dist/wallet-providers/privyShared.js +16 -5
- package/dist/wallet-providers/privySvmWalletProvider.test.d.ts +1 -0
- package/dist/wallet-providers/privySvmWalletProvider.test.js +310 -0
- package/dist/wallet-providers/privyWalletProvider.d.ts +21 -8
- package/dist/wallet-providers/privyWalletProvider.js +39 -7
- package/dist/wallet-providers/privyWalletProvider.test.d.ts +1 -0
- package/dist/wallet-providers/privyWalletProvider.test.js +124 -0
- package/dist/wallet-providers/smartWalletProvider.test.d.ts +1 -0
- package/dist/wallet-providers/smartWalletProvider.test.js +388 -0
- package/dist/wallet-providers/solanaKeypairWalletProvider.test.js +210 -16
- package/dist/wallet-providers/svmWalletProvider.test.d.ts +1 -0
- package/dist/wallet-providers/svmWalletProvider.test.js +55 -0
- package/dist/wallet-providers/viemWalletProvider.test.d.ts +1 -0
- package/dist/wallet-providers/viemWalletProvider.test.js +338 -0
- package/dist/wallet-providers/walletProvider.test.d.ts +1 -0
- package/dist/wallet-providers/walletProvider.test.js +103 -0
- package/package.json +24 -20
|
@@ -0,0 +1,701 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const cdpWalletProvider_1 = require("./cdpWalletProvider");
|
|
4
|
+
const coinbase_sdk_1 = require("@coinbase/coinbase-sdk");
|
|
5
|
+
const decimal_js_1 = require("decimal.js");
|
|
6
|
+
global.fetch = jest.fn(() => Promise.resolve({
|
|
7
|
+
ok: true,
|
|
8
|
+
json: () => Promise.resolve({}),
|
|
9
|
+
}));
|
|
10
|
+
// =========================================================
|
|
11
|
+
// consts
|
|
12
|
+
// =========================================================
|
|
13
|
+
const mockPublicClient = {
|
|
14
|
+
waitForTransactionReceipt: jest.fn(),
|
|
15
|
+
readContract: jest.fn(),
|
|
16
|
+
getTransactionCount: jest.fn(),
|
|
17
|
+
estimateFeesPerGas: jest.fn(),
|
|
18
|
+
estimateGas: jest.fn(),
|
|
19
|
+
};
|
|
20
|
+
// =========================================================
|
|
21
|
+
// mocks
|
|
22
|
+
// =========================================================
|
|
23
|
+
jest.mock("../analytics", () => ({
|
|
24
|
+
sendAnalyticsEvent: jest.fn().mockImplementation(() => Promise.resolve()),
|
|
25
|
+
}));
|
|
26
|
+
jest.mock("../../package.json", () => ({
|
|
27
|
+
version: "1.0.0",
|
|
28
|
+
}));
|
|
29
|
+
jest.mock("viem", () => {
|
|
30
|
+
return {
|
|
31
|
+
createPublicClient: jest.fn(() => mockPublicClient),
|
|
32
|
+
createWalletClient: jest.fn(),
|
|
33
|
+
http: jest.fn(),
|
|
34
|
+
zeroAddress: "0x0000000000000000000000000000000000000000",
|
|
35
|
+
parseEther: jest.fn((_value) => BigInt(1000000000000000000)),
|
|
36
|
+
keccak256: jest.fn((_value) => "0xmockhash"),
|
|
37
|
+
serializeTransaction: jest.fn((_tx) => "0xserialized"),
|
|
38
|
+
};
|
|
39
|
+
});
|
|
40
|
+
jest.mock("../network", () => {
|
|
41
|
+
return {
|
|
42
|
+
NETWORK_ID_TO_CHAIN_ID: {
|
|
43
|
+
mainnet: "1",
|
|
44
|
+
"base-sepolia": "84532",
|
|
45
|
+
},
|
|
46
|
+
};
|
|
47
|
+
});
|
|
48
|
+
// Mock Coinbase SDK
|
|
49
|
+
jest.mock("@coinbase/coinbase-sdk", () => {
|
|
50
|
+
const mockWalletAddressFn = jest.fn();
|
|
51
|
+
mockWalletAddressFn.mockImplementation((model) => {
|
|
52
|
+
const typedModel = model;
|
|
53
|
+
return {
|
|
54
|
+
address_id: typedModel.address_id,
|
|
55
|
+
wallet_id: typedModel.wallet_id,
|
|
56
|
+
network_id: typedModel.network_id,
|
|
57
|
+
public_key: typedModel.public_key,
|
|
58
|
+
index: typedModel.index,
|
|
59
|
+
getId: jest.fn().mockReturnValue(typedModel.address_id),
|
|
60
|
+
};
|
|
61
|
+
});
|
|
62
|
+
// Create a mock for ExternalAddress
|
|
63
|
+
const mockExternalAddress = jest.fn().mockImplementation(() => {
|
|
64
|
+
return {
|
|
65
|
+
broadcastExternalTransaction: jest.fn().mockImplementation(async () => ({
|
|
66
|
+
transactionHash: "0x9876543210fedcba9876543210fedcba9876543210fedcba9876543210fedcba",
|
|
67
|
+
})),
|
|
68
|
+
};
|
|
69
|
+
});
|
|
70
|
+
return {
|
|
71
|
+
Wallet: {
|
|
72
|
+
import: jest.fn(),
|
|
73
|
+
create: jest.fn(),
|
|
74
|
+
},
|
|
75
|
+
Coinbase: {
|
|
76
|
+
assets: {
|
|
77
|
+
Usdc: "USDC",
|
|
78
|
+
Cbbtc: "CBBTC",
|
|
79
|
+
Eurc: "EURC",
|
|
80
|
+
Eth: "ETH",
|
|
81
|
+
},
|
|
82
|
+
configure: jest.fn(),
|
|
83
|
+
configureFromJson: jest.fn(),
|
|
84
|
+
networks: {
|
|
85
|
+
BaseSepolia: "base-sepolia",
|
|
86
|
+
},
|
|
87
|
+
},
|
|
88
|
+
assets: {
|
|
89
|
+
Usdc: "USDC",
|
|
90
|
+
Cbbtc: "CBBTC",
|
|
91
|
+
Eurc: "EURC",
|
|
92
|
+
Eth: "ETH",
|
|
93
|
+
},
|
|
94
|
+
hashTypedDataMessage: jest.fn(),
|
|
95
|
+
hashMessage: jest.fn(),
|
|
96
|
+
WalletAddress: mockWalletAddressFn,
|
|
97
|
+
ExternalAddress: mockExternalAddress,
|
|
98
|
+
};
|
|
99
|
+
});
|
|
100
|
+
const mockWalletObj = {
|
|
101
|
+
getDefaultAddress: jest.fn(),
|
|
102
|
+
getNetworkId: jest.fn(),
|
|
103
|
+
getBalance: jest.fn(),
|
|
104
|
+
createPayloadSignature: jest.fn(),
|
|
105
|
+
createTransfer: jest.fn(),
|
|
106
|
+
createTrade: jest.fn(),
|
|
107
|
+
deployToken: jest.fn(),
|
|
108
|
+
deployContract: jest.fn(),
|
|
109
|
+
deployNFT: jest.fn(),
|
|
110
|
+
export: jest.fn(),
|
|
111
|
+
};
|
|
112
|
+
// =========================================================
|
|
113
|
+
// test constants
|
|
114
|
+
// =========================================================
|
|
115
|
+
const MOCK_ADDRESS = "0x742d35Cc6634C0532925a3b844Bc454e4438f44e";
|
|
116
|
+
const MOCK_NETWORK_ID = "mainnet";
|
|
117
|
+
const MOCK_PRIVATE_KEY = "0xabcdef1234567890abcdef1234567890abcdef1234567890abcdef1234567890";
|
|
118
|
+
const MOCK_TRANSACTION_HASH = "0x9876543210fedcba9876543210fedcba9876543210fedcba9876543210fedcba";
|
|
119
|
+
const MOCK_SIGNATURE = "0x1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef1b01";
|
|
120
|
+
const MOCK_BALANCE = 1000000000000000000n;
|
|
121
|
+
const MOCK_NETWORK = {
|
|
122
|
+
protocolFamily: "evm",
|
|
123
|
+
networkId: MOCK_NETWORK_ID,
|
|
124
|
+
};
|
|
125
|
+
describe("CdpWalletProvider", () => {
|
|
126
|
+
let provider;
|
|
127
|
+
beforeEach(async () => {
|
|
128
|
+
jest.clearAllMocks();
|
|
129
|
+
const mockWalletAddress = {
|
|
130
|
+
wallet_id: "mock-wallet-id",
|
|
131
|
+
network_id: MOCK_NETWORK_ID,
|
|
132
|
+
public_key: "mock-public-key",
|
|
133
|
+
address_id: MOCK_ADDRESS,
|
|
134
|
+
index: 0,
|
|
135
|
+
getId: jest.fn().mockReturnValue(MOCK_ADDRESS),
|
|
136
|
+
};
|
|
137
|
+
mockWalletObj.getDefaultAddress.mockResolvedValue(mockWalletAddress);
|
|
138
|
+
mockWalletObj.getNetworkId.mockReturnValue(MOCK_NETWORK_ID);
|
|
139
|
+
mockWalletObj.getBalance.mockResolvedValue(new decimal_js_1.Decimal(1));
|
|
140
|
+
const mockPayloadSignature = {
|
|
141
|
+
getStatus: jest.fn().mockReturnValue("completed"),
|
|
142
|
+
getSignature: jest.fn().mockReturnValue(MOCK_SIGNATURE),
|
|
143
|
+
};
|
|
144
|
+
mockWalletObj.createPayloadSignature.mockResolvedValue(mockPayloadSignature);
|
|
145
|
+
const mockTransferResult = {
|
|
146
|
+
getTransactionHash: jest.fn().mockReturnValue(MOCK_TRANSACTION_HASH),
|
|
147
|
+
wait: jest.fn(),
|
|
148
|
+
};
|
|
149
|
+
mockTransferResult.wait.mockResolvedValue(mockTransferResult);
|
|
150
|
+
mockWalletObj.createTransfer.mockResolvedValue(mockTransferResult);
|
|
151
|
+
mockWalletObj.export.mockReturnValue({
|
|
152
|
+
seed: MOCK_PRIVATE_KEY,
|
|
153
|
+
networkId: MOCK_NETWORK_ID,
|
|
154
|
+
});
|
|
155
|
+
jest.spyOn(coinbase_sdk_1.Wallet, "import").mockResolvedValue(mockWalletObj);
|
|
156
|
+
jest.spyOn(coinbase_sdk_1.Wallet, "create").mockResolvedValue(mockWalletObj);
|
|
157
|
+
mockPublicClient.waitForTransactionReceipt.mockResolvedValue({
|
|
158
|
+
transactionHash: MOCK_TRANSACTION_HASH,
|
|
159
|
+
});
|
|
160
|
+
mockPublicClient.readContract.mockResolvedValue("mock_result");
|
|
161
|
+
mockPublicClient.getTransactionCount.mockResolvedValue(1);
|
|
162
|
+
mockPublicClient.estimateFeesPerGas.mockResolvedValue({
|
|
163
|
+
maxFeePerGas: BigInt(100000000),
|
|
164
|
+
maxPriorityFeePerGas: BigInt(10000000),
|
|
165
|
+
});
|
|
166
|
+
mockPublicClient.estimateGas.mockResolvedValue(BigInt(21000));
|
|
167
|
+
provider = await cdpWalletProvider_1.CdpWalletProvider.configureWithWallet({
|
|
168
|
+
wallet: mockWalletObj,
|
|
169
|
+
networkId: MOCK_NETWORK_ID,
|
|
170
|
+
});
|
|
171
|
+
});
|
|
172
|
+
// =========================================================
|
|
173
|
+
// initialization tests
|
|
174
|
+
// =========================================================
|
|
175
|
+
describe("initialization", () => {
|
|
176
|
+
it("should initialize with wallet data", async () => {
|
|
177
|
+
const walletData = JSON.stringify({
|
|
178
|
+
seed: MOCK_PRIVATE_KEY,
|
|
179
|
+
networkId: MOCK_NETWORK_ID,
|
|
180
|
+
});
|
|
181
|
+
const provider = await cdpWalletProvider_1.CdpWalletProvider.configureWithWallet({
|
|
182
|
+
cdpWalletData: walletData,
|
|
183
|
+
networkId: MOCK_NETWORK_ID,
|
|
184
|
+
});
|
|
185
|
+
expect(coinbase_sdk_1.Wallet.import).toHaveBeenCalled();
|
|
186
|
+
expect(provider.getAddress()).toBe(MOCK_ADDRESS);
|
|
187
|
+
expect(provider.getNetwork()).toEqual(MOCK_NETWORK);
|
|
188
|
+
});
|
|
189
|
+
it("should initialize with mnemonic phrase", async () => {
|
|
190
|
+
const mnemonicPhrase = "test test test test test test test test test test test junk";
|
|
191
|
+
const provider = await cdpWalletProvider_1.CdpWalletProvider.configureWithWallet({
|
|
192
|
+
mnemonicPhrase,
|
|
193
|
+
networkId: MOCK_NETWORK_ID,
|
|
194
|
+
});
|
|
195
|
+
expect(coinbase_sdk_1.Wallet.import).toHaveBeenCalledWith({ mnemonicPhrase }, MOCK_NETWORK_ID);
|
|
196
|
+
expect(provider.getAddress()).toBe(MOCK_ADDRESS);
|
|
197
|
+
expect(provider.getNetwork()).toEqual(MOCK_NETWORK);
|
|
198
|
+
});
|
|
199
|
+
it("should initialize with API keys", async () => {
|
|
200
|
+
const apiKeyName = "test-key";
|
|
201
|
+
const apiKeyPrivateKey = "private-key";
|
|
202
|
+
const provider = await cdpWalletProvider_1.CdpWalletProvider.configureWithWallet({
|
|
203
|
+
apiKeyName,
|
|
204
|
+
apiKeyPrivateKey,
|
|
205
|
+
networkId: MOCK_NETWORK_ID,
|
|
206
|
+
});
|
|
207
|
+
expect(coinbase_sdk_1.Coinbase.configure).toHaveBeenCalledWith({
|
|
208
|
+
apiKeyName,
|
|
209
|
+
privateKey: apiKeyPrivateKey,
|
|
210
|
+
source: "agentkit",
|
|
211
|
+
sourceVersion: "1.0.0",
|
|
212
|
+
});
|
|
213
|
+
expect(provider.getAddress()).toBe(MOCK_ADDRESS);
|
|
214
|
+
expect(provider.getNetwork()).toEqual(MOCK_NETWORK);
|
|
215
|
+
});
|
|
216
|
+
it("should initialize with an existing wallet", async () => {
|
|
217
|
+
const provider = await cdpWalletProvider_1.CdpWalletProvider.configureWithWallet({
|
|
218
|
+
wallet: mockWalletObj,
|
|
219
|
+
networkId: MOCK_NETWORK_ID,
|
|
220
|
+
});
|
|
221
|
+
expect(provider.getAddress()).toBe(MOCK_ADDRESS);
|
|
222
|
+
expect(provider.getNetwork()).toEqual(MOCK_NETWORK);
|
|
223
|
+
});
|
|
224
|
+
it("should default to base-sepolia if network not provided", async () => {
|
|
225
|
+
mockWalletObj.getNetworkId.mockReturnValueOnce("base-sepolia");
|
|
226
|
+
const provider = await cdpWalletProvider_1.CdpWalletProvider.configureWithWallet({
|
|
227
|
+
wallet: mockWalletObj,
|
|
228
|
+
});
|
|
229
|
+
expect(provider.getNetwork().networkId).toBe("base-sepolia");
|
|
230
|
+
});
|
|
231
|
+
it("should handle initialization failures gracefully", async () => {
|
|
232
|
+
jest.spyOn(coinbase_sdk_1.Wallet, "create").mockRejectedValueOnce(new Error("Failed to create wallet"));
|
|
233
|
+
await expect(cdpWalletProvider_1.CdpWalletProvider.configureWithWallet({
|
|
234
|
+
networkId: MOCK_NETWORK_ID,
|
|
235
|
+
})).rejects.toThrow("Failed to create wallet");
|
|
236
|
+
});
|
|
237
|
+
});
|
|
238
|
+
// =========================================================
|
|
239
|
+
// basic wallet method tests
|
|
240
|
+
// =========================================================
|
|
241
|
+
describe("basic wallet methods", () => {
|
|
242
|
+
it("should get the address", () => {
|
|
243
|
+
expect(provider.getAddress()).toBe(MOCK_ADDRESS);
|
|
244
|
+
});
|
|
245
|
+
it("should get the network", () => {
|
|
246
|
+
expect(provider.getNetwork()).toEqual(MOCK_NETWORK);
|
|
247
|
+
});
|
|
248
|
+
it("should get the name", () => {
|
|
249
|
+
expect(provider.getName()).toBe("cdp_wallet_provider");
|
|
250
|
+
});
|
|
251
|
+
it("should get the balance", async () => {
|
|
252
|
+
const balance = await provider.getBalance();
|
|
253
|
+
expect(balance).toBe(MOCK_BALANCE);
|
|
254
|
+
expect(mockWalletObj.getBalance).toHaveBeenCalled();
|
|
255
|
+
});
|
|
256
|
+
it("should handle connection errors during balance check", async () => {
|
|
257
|
+
mockWalletObj.getBalance.mockRejectedValueOnce(new Error("Network connection error"));
|
|
258
|
+
await expect(provider.getBalance()).rejects.toThrow("Network connection error");
|
|
259
|
+
});
|
|
260
|
+
it("should handle timeout errors during balance check", async () => {
|
|
261
|
+
mockWalletObj.getBalance.mockRejectedValueOnce(new Error("Request timed out"));
|
|
262
|
+
await expect(provider.getBalance()).rejects.toThrow("Request timed out");
|
|
263
|
+
});
|
|
264
|
+
});
|
|
265
|
+
// =========================================================
|
|
266
|
+
// signing operation tests
|
|
267
|
+
// =========================================================
|
|
268
|
+
describe("signing operations", () => {
|
|
269
|
+
it("should sign messages", async () => {
|
|
270
|
+
const signature = await provider.signMessage("Hello, world!");
|
|
271
|
+
expect(mockWalletObj.createPayloadSignature).toHaveBeenCalled();
|
|
272
|
+
expect(signature).toBe(MOCK_SIGNATURE);
|
|
273
|
+
});
|
|
274
|
+
it("should sign typed data", async () => {
|
|
275
|
+
const typedData = {
|
|
276
|
+
domain: { name: "Example" },
|
|
277
|
+
types: { Test: [{ name: "test", type: "string" }] },
|
|
278
|
+
message: { test: "example" },
|
|
279
|
+
primaryType: "Test",
|
|
280
|
+
};
|
|
281
|
+
const signature = await provider.signTypedData(typedData);
|
|
282
|
+
expect(mockWalletObj.createPayloadSignature).toHaveBeenCalled();
|
|
283
|
+
expect(signature).toBe(MOCK_SIGNATURE);
|
|
284
|
+
});
|
|
285
|
+
it("should sign transactions", async () => {
|
|
286
|
+
const tx = {
|
|
287
|
+
to: "0x1234567890123456789012345678901234567890",
|
|
288
|
+
value: BigInt(1000000000000000000),
|
|
289
|
+
};
|
|
290
|
+
const signedTx = await provider.signTransaction(tx);
|
|
291
|
+
expect(mockWalletObj.createPayloadSignature).toHaveBeenCalled();
|
|
292
|
+
expect(signedTx).toBe(MOCK_SIGNATURE);
|
|
293
|
+
});
|
|
294
|
+
it("should handle signing failures", async () => {
|
|
295
|
+
mockWalletObj.createPayloadSignature.mockRejectedValueOnce(new Error("Signing failed"));
|
|
296
|
+
const message = "Hello, world!";
|
|
297
|
+
await expect(provider.signMessage(message)).rejects.toThrow("Signing failed");
|
|
298
|
+
});
|
|
299
|
+
});
|
|
300
|
+
// =========================================================
|
|
301
|
+
// transaction operation tests
|
|
302
|
+
// =========================================================
|
|
303
|
+
describe("transaction operations", () => {
|
|
304
|
+
it("should send transactions", async () => {
|
|
305
|
+
const validSignature = "0x" + "1".repeat(64) + "2".repeat(64) + "01"; // r, s, v format (130 chars + 0x prefix)
|
|
306
|
+
const mockSignature = {
|
|
307
|
+
model: {},
|
|
308
|
+
getId: jest.fn().mockReturnValue("signature-id"),
|
|
309
|
+
getWalletId: jest.fn().mockReturnValue("mock-wallet-id"),
|
|
310
|
+
getAddressId: jest.fn().mockReturnValue(MOCK_ADDRESS),
|
|
311
|
+
getNetworkId: jest.fn().mockReturnValue(MOCK_NETWORK_ID),
|
|
312
|
+
getSignature: jest.fn().mockReturnValue(validSignature),
|
|
313
|
+
getPayload: jest.fn().mockReturnValue("0xpayload"),
|
|
314
|
+
getEncodedPayload: jest.fn().mockReturnValue("0xencodedpayload"),
|
|
315
|
+
getStatus: jest.fn().mockReturnValue("completed"),
|
|
316
|
+
};
|
|
317
|
+
mockWalletObj.createPayloadSignature.mockResolvedValue(mockSignature);
|
|
318
|
+
const transaction = {
|
|
319
|
+
to: "0x1234567890123456789012345678901234567890",
|
|
320
|
+
value: BigInt(1000000000000000000),
|
|
321
|
+
};
|
|
322
|
+
const txHash = await provider.sendTransaction(transaction);
|
|
323
|
+
expect(mockWalletObj.createPayloadSignature).toHaveBeenCalled();
|
|
324
|
+
expect(txHash).toBe(MOCK_TRANSACTION_HASH);
|
|
325
|
+
});
|
|
326
|
+
it("should execute a native transfer", async () => {
|
|
327
|
+
const to = "0x1234567890123456789012345678901234567890";
|
|
328
|
+
const value = "1.0";
|
|
329
|
+
const txHash = await provider.nativeTransfer(to, value);
|
|
330
|
+
expect(mockWalletObj.createTransfer).toHaveBeenCalledWith({
|
|
331
|
+
assetId: "ETH",
|
|
332
|
+
destination: to,
|
|
333
|
+
amount: new decimal_js_1.Decimal(1),
|
|
334
|
+
gasless: false,
|
|
335
|
+
});
|
|
336
|
+
expect(txHash).toBe(MOCK_TRANSACTION_HASH);
|
|
337
|
+
});
|
|
338
|
+
it("should handle transaction failures during send", async () => {
|
|
339
|
+
mockWalletObj.createPayloadSignature.mockRejectedValueOnce(new Error("Transaction signing failed"));
|
|
340
|
+
const transaction = {
|
|
341
|
+
to: "0x1234567890123456789012345678901234567890",
|
|
342
|
+
value: BigInt(1000000000000000000),
|
|
343
|
+
};
|
|
344
|
+
await expect(provider.sendTransaction(transaction)).rejects.toThrow("Transaction signing failed");
|
|
345
|
+
});
|
|
346
|
+
it("should handle network errors during transfers", async () => {
|
|
347
|
+
mockWalletObj.createTransfer.mockRejectedValueOnce(new Error("Network connection error"));
|
|
348
|
+
const to = "0x1234567890123456789012345678901234567890";
|
|
349
|
+
const value = "1.0";
|
|
350
|
+
await expect(provider.nativeTransfer(to, value)).rejects.toThrow("Network connection error");
|
|
351
|
+
});
|
|
352
|
+
it("should handle receipt timeout errors", async () => {
|
|
353
|
+
mockPublicClient.waitForTransactionReceipt.mockRejectedValueOnce(new Error("Timed out"));
|
|
354
|
+
const hash = "0x1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef";
|
|
355
|
+
await expect(provider.waitForTransactionReceipt(hash)).rejects.toThrow("Timed out");
|
|
356
|
+
});
|
|
357
|
+
it("should handle transaction timeout during sending", async () => {
|
|
358
|
+
mockWalletObj.createPayloadSignature.mockRejectedValueOnce(new Error("Transaction timed out"));
|
|
359
|
+
const transaction = {
|
|
360
|
+
to: "0x1234567890123456789012345678901234567890",
|
|
361
|
+
value: BigInt(1000000000000000000),
|
|
362
|
+
};
|
|
363
|
+
await expect(provider.sendTransaction(transaction)).rejects.toThrow("Transaction timed out");
|
|
364
|
+
});
|
|
365
|
+
it("should handle receipt waiting timeout with specific error", async () => {
|
|
366
|
+
mockPublicClient.waitForTransactionReceipt.mockRejectedValueOnce(new Error("Transaction receipt waiting timed out"));
|
|
367
|
+
const hash = "0x1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef";
|
|
368
|
+
await expect(provider.waitForTransactionReceipt(hash)).rejects.toThrow("Transaction receipt waiting timed out");
|
|
369
|
+
});
|
|
370
|
+
it("should handle transaction with invalid address", async () => {
|
|
371
|
+
const mockError = new Error("Invalid address format");
|
|
372
|
+
mockWalletObj.createTransfer.mockRejectedValueOnce(mockError);
|
|
373
|
+
const invalidAddress = "not_a_valid_address";
|
|
374
|
+
const value = "1.0";
|
|
375
|
+
await expect(provider.nativeTransfer(invalidAddress, value)).rejects.toThrow("Invalid address format");
|
|
376
|
+
});
|
|
377
|
+
});
|
|
378
|
+
// =========================================================
|
|
379
|
+
// contract interaction tests
|
|
380
|
+
// =========================================================
|
|
381
|
+
describe("contract interactions", () => {
|
|
382
|
+
it("should read contract data", async () => {
|
|
383
|
+
const abi = [
|
|
384
|
+
{
|
|
385
|
+
name: "balanceOf",
|
|
386
|
+
type: "function",
|
|
387
|
+
inputs: [{ name: "account", type: "address" }],
|
|
388
|
+
outputs: [{ name: "balance", type: "uint256" }],
|
|
389
|
+
stateMutability: "view",
|
|
390
|
+
},
|
|
391
|
+
];
|
|
392
|
+
const result = await provider.readContract({
|
|
393
|
+
address: "0x1234567890123456789012345678901234567890",
|
|
394
|
+
abi,
|
|
395
|
+
functionName: "balanceOf",
|
|
396
|
+
args: [MOCK_ADDRESS],
|
|
397
|
+
});
|
|
398
|
+
expect(result).toBe("mock_result");
|
|
399
|
+
expect(mockPublicClient.readContract).toHaveBeenCalled();
|
|
400
|
+
});
|
|
401
|
+
it("should handle network errors during contract reads", async () => {
|
|
402
|
+
mockPublicClient.readContract.mockRejectedValueOnce(new Error("Contract read error"));
|
|
403
|
+
const abi = [
|
|
404
|
+
{
|
|
405
|
+
name: "balanceOf",
|
|
406
|
+
type: "function",
|
|
407
|
+
inputs: [{ name: "account", type: "address" }],
|
|
408
|
+
outputs: [{ name: "balance", type: "uint256" }],
|
|
409
|
+
stateMutability: "view",
|
|
410
|
+
},
|
|
411
|
+
];
|
|
412
|
+
await expect(provider.readContract({
|
|
413
|
+
address: "0x1234567890123456789012345678901234567890",
|
|
414
|
+
abi,
|
|
415
|
+
functionName: "balanceOf",
|
|
416
|
+
args: [MOCK_ADDRESS],
|
|
417
|
+
})).rejects.toThrow("Contract read error");
|
|
418
|
+
});
|
|
419
|
+
it("should handle invalid ABI format in contract reads", async () => {
|
|
420
|
+
mockPublicClient.readContract.mockRejectedValueOnce(new TypeError("Invalid ABI format"));
|
|
421
|
+
const invalidAbi = "not_a_valid_abi";
|
|
422
|
+
await expect(provider.readContract({
|
|
423
|
+
address: "0x1234567890123456789012345678901234567890",
|
|
424
|
+
abi: invalidAbi,
|
|
425
|
+
functionName: "balanceOf",
|
|
426
|
+
args: [MOCK_ADDRESS],
|
|
427
|
+
})).rejects.toThrow("Invalid ABI format");
|
|
428
|
+
});
|
|
429
|
+
it("should handle contract execution reverts", async () => {
|
|
430
|
+
mockPublicClient.readContract.mockRejectedValueOnce(new Error("execution reverted: Insufficient funds"));
|
|
431
|
+
const abi = [
|
|
432
|
+
{
|
|
433
|
+
name: "transfer",
|
|
434
|
+
type: "function",
|
|
435
|
+
inputs: [
|
|
436
|
+
{ name: "to", type: "address" },
|
|
437
|
+
{ name: "amount", type: "uint256" },
|
|
438
|
+
],
|
|
439
|
+
outputs: [{ name: "success", type: "bool" }],
|
|
440
|
+
stateMutability: "nonpayable",
|
|
441
|
+
},
|
|
442
|
+
];
|
|
443
|
+
await expect(provider.readContract({
|
|
444
|
+
address: "0x1234567890123456789012345678901234567890",
|
|
445
|
+
abi,
|
|
446
|
+
functionName: "transfer",
|
|
447
|
+
args: ["0x1234567890123456789012345678901234567890", 1000n],
|
|
448
|
+
})).rejects.toThrow("execution reverted: Insufficient funds");
|
|
449
|
+
});
|
|
450
|
+
});
|
|
451
|
+
// =========================================================
|
|
452
|
+
// trading operations
|
|
453
|
+
// =========================================================
|
|
454
|
+
describe("trading operations", () => {
|
|
455
|
+
it("should create a trade", async () => {
|
|
456
|
+
const mockTradeTransaction = {
|
|
457
|
+
isTerminalState: jest.fn().mockReturnValue(true),
|
|
458
|
+
getTransactionHash: jest.fn().mockReturnValue(MOCK_TRANSACTION_HASH),
|
|
459
|
+
getTransactionLink: jest
|
|
460
|
+
.fn()
|
|
461
|
+
.mockReturnValue(`https://etherscan.io/tx/${MOCK_TRANSACTION_HASH}`),
|
|
462
|
+
getStatus: jest.fn().mockReturnValue("completed"),
|
|
463
|
+
};
|
|
464
|
+
const mockTradeResult = {
|
|
465
|
+
model: {},
|
|
466
|
+
getId: jest.fn().mockReturnValue("trade-id"),
|
|
467
|
+
getNetworkId: jest.fn().mockReturnValue(MOCK_NETWORK_ID),
|
|
468
|
+
getWalletId: jest.fn().mockReturnValue("mock-wallet-id"),
|
|
469
|
+
getFromAmount: jest.fn().mockReturnValue(new decimal_js_1.Decimal(1)),
|
|
470
|
+
getToAmount: jest.fn().mockReturnValue(new decimal_js_1.Decimal(100)),
|
|
471
|
+
getFromAssetId: jest.fn().mockReturnValue("ETH"),
|
|
472
|
+
getToAssetId: jest.fn().mockReturnValue("USDC"),
|
|
473
|
+
getStatus: jest.fn().mockReturnValue("completed"),
|
|
474
|
+
setModel: jest.fn(),
|
|
475
|
+
to_amount: "100",
|
|
476
|
+
transaction: { transaction_hash: MOCK_TRANSACTION_HASH },
|
|
477
|
+
getTransaction: jest.fn().mockReturnValue(mockTradeTransaction),
|
|
478
|
+
getAddressId: jest.fn().mockReturnValue(MOCK_ADDRESS),
|
|
479
|
+
reload: jest.fn(),
|
|
480
|
+
getApproveTransaction: jest.fn(),
|
|
481
|
+
sign: jest.fn(),
|
|
482
|
+
broadcast: jest.fn(),
|
|
483
|
+
wait: jest.fn(),
|
|
484
|
+
};
|
|
485
|
+
mockTradeResult.wait.mockResolvedValue(mockTradeResult);
|
|
486
|
+
mockTradeResult.reload.mockResolvedValue(mockTradeResult);
|
|
487
|
+
mockWalletObj.createTrade.mockResolvedValue(mockTradeResult);
|
|
488
|
+
const options = {
|
|
489
|
+
fromAssetId: "ETH",
|
|
490
|
+
toAssetId: "USDC",
|
|
491
|
+
amount: new decimal_js_1.Decimal("1.0"),
|
|
492
|
+
};
|
|
493
|
+
const trade = await provider.createTrade(options);
|
|
494
|
+
expect(mockWalletObj.createTrade).toHaveBeenCalledWith(options);
|
|
495
|
+
expect(trade).toBe(mockTradeResult);
|
|
496
|
+
});
|
|
497
|
+
it("should handle trade creation failures", async () => {
|
|
498
|
+
mockWalletObj.createTrade.mockRejectedValueOnce(new Error("Trade creation failed"));
|
|
499
|
+
const options = {
|
|
500
|
+
fromAssetId: "ETH",
|
|
501
|
+
toAssetId: "USDC",
|
|
502
|
+
amount: new decimal_js_1.Decimal("1.0"),
|
|
503
|
+
};
|
|
504
|
+
await expect(provider.createTrade(options)).rejects.toThrow("Trade creation failed");
|
|
505
|
+
});
|
|
506
|
+
it("should handle trade state checking", async () => {
|
|
507
|
+
const mockTradeTransaction = {
|
|
508
|
+
isTerminalState: jest.fn().mockReturnValue(true),
|
|
509
|
+
getTransactionHash: jest.fn().mockReturnValue(MOCK_TRANSACTION_HASH),
|
|
510
|
+
getStatus: jest.fn().mockReturnValue("completed"),
|
|
511
|
+
};
|
|
512
|
+
const mockTradeResult = {
|
|
513
|
+
model: {},
|
|
514
|
+
getId: jest.fn().mockReturnValue("trade-id"),
|
|
515
|
+
getStatus: jest.fn().mockReturnValueOnce("pending").mockReturnValueOnce("completed"),
|
|
516
|
+
getTransaction: jest.fn().mockReturnValue(mockTradeTransaction),
|
|
517
|
+
reload: jest.fn().mockImplementation(() => Promise.resolve(mockTradeResult)),
|
|
518
|
+
wait: jest.fn().mockImplementation(() => Promise.resolve(mockTradeResult)),
|
|
519
|
+
};
|
|
520
|
+
jest.spyOn(mockTradeResult, "reload");
|
|
521
|
+
jest.spyOn(mockTradeResult, "wait");
|
|
522
|
+
mockWalletObj.createTrade.mockResolvedValue(mockTradeResult);
|
|
523
|
+
const options = {
|
|
524
|
+
fromAssetId: "ETH",
|
|
525
|
+
toAssetId: "USDC",
|
|
526
|
+
amount: new decimal_js_1.Decimal("1.0"),
|
|
527
|
+
};
|
|
528
|
+
const trade = await provider.createTrade(options);
|
|
529
|
+
await trade.reload();
|
|
530
|
+
await trade.wait();
|
|
531
|
+
expect(mockTradeResult.reload).toHaveBeenCalled();
|
|
532
|
+
expect(mockTradeResult.wait).toHaveBeenCalled();
|
|
533
|
+
});
|
|
534
|
+
});
|
|
535
|
+
// =========================================================
|
|
536
|
+
// token & contract deployment operations
|
|
537
|
+
// =========================================================
|
|
538
|
+
describe("token and contract deployment", () => {
|
|
539
|
+
it("should deploy a token", async () => {
|
|
540
|
+
const mockTokenResult = {
|
|
541
|
+
model: {},
|
|
542
|
+
isExternal: false,
|
|
543
|
+
getId: jest.fn().mockReturnValue("token-id"),
|
|
544
|
+
getNetworkId: jest.fn().mockReturnValue(MOCK_NETWORK_ID),
|
|
545
|
+
getWalletId: jest.fn().mockReturnValue("mock-wallet-id"),
|
|
546
|
+
getAddress: jest.fn().mockReturnValue("0xtoken"),
|
|
547
|
+
address: "0xtoken",
|
|
548
|
+
};
|
|
549
|
+
mockWalletObj.deployToken.mockResolvedValue(mockTokenResult);
|
|
550
|
+
const options = {
|
|
551
|
+
name: "Test Token",
|
|
552
|
+
symbol: "TEST",
|
|
553
|
+
totalSupply: new decimal_js_1.Decimal("1000000"),
|
|
554
|
+
};
|
|
555
|
+
const token = await provider.deployToken(options);
|
|
556
|
+
expect(mockWalletObj.deployToken).toHaveBeenCalledWith(options);
|
|
557
|
+
expect(token).toBe(mockTokenResult);
|
|
558
|
+
});
|
|
559
|
+
it("should handle token deployment failures", async () => {
|
|
560
|
+
mockWalletObj.deployToken.mockRejectedValueOnce(new Error("Token deployment failed"));
|
|
561
|
+
const options = {
|
|
562
|
+
name: "Test Token",
|
|
563
|
+
symbol: "TEST",
|
|
564
|
+
totalSupply: new decimal_js_1.Decimal("1000000"),
|
|
565
|
+
};
|
|
566
|
+
await expect(provider.deployToken(options)).rejects.toThrow("Token deployment failed");
|
|
567
|
+
});
|
|
568
|
+
it("should deploy a contract", async () => {
|
|
569
|
+
const options = {
|
|
570
|
+
solidityVersion: "0.8.0",
|
|
571
|
+
solidityInputJson: "{}",
|
|
572
|
+
contractName: "TestContract",
|
|
573
|
+
constructorArgs: { _name: "Test" },
|
|
574
|
+
};
|
|
575
|
+
const mockContractResult = {
|
|
576
|
+
model: {},
|
|
577
|
+
isExternal: false,
|
|
578
|
+
getId: jest.fn().mockReturnValue("contract-id"),
|
|
579
|
+
getNetworkId: jest.fn().mockReturnValue(MOCK_NETWORK_ID),
|
|
580
|
+
getWalletId: jest.fn().mockReturnValue("mock-wallet-id"),
|
|
581
|
+
getAddress: jest.fn().mockReturnValue("0xcontract"),
|
|
582
|
+
address: "0xcontract",
|
|
583
|
+
};
|
|
584
|
+
mockWalletObj.deployContract.mockResolvedValue(mockContractResult);
|
|
585
|
+
const contract = await provider.deployContract(options);
|
|
586
|
+
expect(mockWalletObj.deployContract).toHaveBeenCalledWith(options);
|
|
587
|
+
expect(contract).toBe(mockContractResult);
|
|
588
|
+
});
|
|
589
|
+
it("should handle contract deployment failures", async () => {
|
|
590
|
+
mockWalletObj.deployContract.mockRejectedValueOnce(new Error("Contract deployment failed"));
|
|
591
|
+
const options = {
|
|
592
|
+
solidityVersion: "0.8.0",
|
|
593
|
+
solidityInputJson: "{}",
|
|
594
|
+
contractName: "TestContract",
|
|
595
|
+
constructorArgs: { _name: "Test" },
|
|
596
|
+
};
|
|
597
|
+
await expect(provider.deployContract(options)).rejects.toThrow("Contract deployment failed");
|
|
598
|
+
});
|
|
599
|
+
it("should deploy an NFT", async () => {
|
|
600
|
+
const options = {
|
|
601
|
+
name: "Test NFT",
|
|
602
|
+
symbol: "TNFT",
|
|
603
|
+
baseURI: "https://example.com/nft/",
|
|
604
|
+
};
|
|
605
|
+
const mockNftResult = {
|
|
606
|
+
model: {},
|
|
607
|
+
isExternal: false,
|
|
608
|
+
getId: jest.fn().mockReturnValue("nft-id"),
|
|
609
|
+
getNetworkId: jest.fn().mockReturnValue(MOCK_NETWORK_ID),
|
|
610
|
+
getWalletId: jest.fn().mockReturnValue("mock-wallet-id"),
|
|
611
|
+
getAddress: jest.fn().mockReturnValue("0xnft"),
|
|
612
|
+
address: "0xnft",
|
|
613
|
+
};
|
|
614
|
+
mockWalletObj.deployNFT.mockResolvedValue(mockNftResult);
|
|
615
|
+
const nft = await provider.deployNFT(options);
|
|
616
|
+
expect(mockWalletObj.deployNFT).toHaveBeenCalledWith(options);
|
|
617
|
+
expect(nft).toBe(mockNftResult);
|
|
618
|
+
});
|
|
619
|
+
it("should handle NFT deployment failures", async () => {
|
|
620
|
+
mockWalletObj.deployNFT.mockRejectedValueOnce(new Error("NFT deployment failed"));
|
|
621
|
+
const options = {
|
|
622
|
+
name: "Test NFT",
|
|
623
|
+
symbol: "TNFT",
|
|
624
|
+
baseURI: "https://example.com/nft/",
|
|
625
|
+
};
|
|
626
|
+
await expect(provider.deployNFT(options)).rejects.toThrow("NFT deployment failed");
|
|
627
|
+
});
|
|
628
|
+
});
|
|
629
|
+
// =========================================================
|
|
630
|
+
// transfer operations
|
|
631
|
+
// =========================================================
|
|
632
|
+
describe("transfer operations", () => {
|
|
633
|
+
it("should execute a native transfer", async () => {
|
|
634
|
+
const to = "0x1234567890123456789012345678901234567890";
|
|
635
|
+
const value = "1.0";
|
|
636
|
+
const txHash = await provider.nativeTransfer(to, value);
|
|
637
|
+
expect(mockWalletObj.createTransfer).toHaveBeenCalledWith({
|
|
638
|
+
assetId: "ETH",
|
|
639
|
+
destination: to,
|
|
640
|
+
amount: new decimal_js_1.Decimal(1),
|
|
641
|
+
gasless: false,
|
|
642
|
+
});
|
|
643
|
+
expect(txHash).toBe(MOCK_TRANSACTION_HASH);
|
|
644
|
+
});
|
|
645
|
+
it("should handle native transfer failures", async () => {
|
|
646
|
+
mockWalletObj.createTransfer.mockRejectedValueOnce(new Error("Network connection error"));
|
|
647
|
+
const to = "0x1234567890123456789012345678901234567890";
|
|
648
|
+
const value = "1.0";
|
|
649
|
+
await expect(provider.nativeTransfer(to, value)).rejects.toThrow("Network connection error");
|
|
650
|
+
});
|
|
651
|
+
it("should execute gasless ERC20 transfer", async () => {
|
|
652
|
+
const destination = "0x1234567890123456789012345678901234567890";
|
|
653
|
+
const amount = 1000000000n;
|
|
654
|
+
const assetId = "USDC";
|
|
655
|
+
const hash = await provider.gaslessERC20Transfer(assetId, destination, amount);
|
|
656
|
+
expect(hash).toBe(MOCK_TRANSACTION_HASH);
|
|
657
|
+
expect(mockWalletObj.createTransfer).toHaveBeenCalledWith({
|
|
658
|
+
amount,
|
|
659
|
+
assetId,
|
|
660
|
+
destination,
|
|
661
|
+
gasless: true,
|
|
662
|
+
});
|
|
663
|
+
});
|
|
664
|
+
it("should handle gasless ERC20 transfer failures", async () => {
|
|
665
|
+
mockWalletObj.createTransfer.mockRejectedValueOnce(new Error("Gasless transfer failed"));
|
|
666
|
+
const destination = "0x1234567890123456789012345678901234567890";
|
|
667
|
+
const amount = 1000000000n;
|
|
668
|
+
const assetId = "USDC";
|
|
669
|
+
await expect(provider.gaslessERC20Transfer(assetId, destination, amount)).rejects.toThrow("Gasless transfer failed");
|
|
670
|
+
});
|
|
671
|
+
it("should handle transfer for amounts below minimum", async () => {
|
|
672
|
+
const to = "0x1234567890123456789012345678901234567890";
|
|
673
|
+
const value = "0.000000001";
|
|
674
|
+
const hash = await provider.nativeTransfer(to, value);
|
|
675
|
+
expect(hash).toBe(MOCK_TRANSACTION_HASH);
|
|
676
|
+
expect(mockWalletObj.createTransfer).toHaveBeenCalled();
|
|
677
|
+
});
|
|
678
|
+
});
|
|
679
|
+
// =========================================================
|
|
680
|
+
// wallet management
|
|
681
|
+
// =========================================================
|
|
682
|
+
describe("wallet management", () => {
|
|
683
|
+
it("should export wallet data", async () => {
|
|
684
|
+
const data = await provider.exportWallet();
|
|
685
|
+
expect(data).toEqual({
|
|
686
|
+
seed: MOCK_PRIVATE_KEY,
|
|
687
|
+
networkId: MOCK_NETWORK_ID,
|
|
688
|
+
});
|
|
689
|
+
expect(mockWalletObj.export).toHaveBeenCalled();
|
|
690
|
+
});
|
|
691
|
+
it("should handle wallet export failures", async () => {
|
|
692
|
+
mockWalletObj.export.mockImplementationOnce(() => {
|
|
693
|
+
throw new Error("Export failed");
|
|
694
|
+
});
|
|
695
|
+
await expect(provider.exportWallet()).rejects.toThrow("Export failed");
|
|
696
|
+
});
|
|
697
|
+
it("should get wallet network ID", () => {
|
|
698
|
+
expect(provider.getNetwork().networkId).toBe(MOCK_NETWORK_ID);
|
|
699
|
+
});
|
|
700
|
+
});
|
|
701
|
+
});
|