@wormhole-foundation/sdk-connect 3.12.0 → 4.0.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 (73) hide show
  1. package/dist/cjs/index.d.ts +1 -0
  2. package/dist/cjs/index.d.ts.map +1 -1
  3. package/dist/cjs/index.js +1 -0
  4. package/dist/cjs/index.js.map +1 -1
  5. package/dist/cjs/indexers/AlchemyClient.d.ts +13 -0
  6. package/dist/cjs/indexers/AlchemyClient.d.ts.map +1 -0
  7. package/dist/cjs/indexers/AlchemyClient.js +105 -0
  8. package/dist/cjs/indexers/AlchemyClient.js.map +1 -0
  9. package/dist/cjs/indexers/GoldRushClient.d.ts +10 -0
  10. package/dist/cjs/indexers/GoldRushClient.d.ts.map +1 -0
  11. package/dist/cjs/indexers/GoldRushClient.js +88 -0
  12. package/dist/cjs/indexers/GoldRushClient.js.map +1 -0
  13. package/dist/cjs/indexers/__tests__/balances.test.d.ts +2 -0
  14. package/dist/cjs/indexers/__tests__/balances.test.d.ts.map +1 -0
  15. package/dist/cjs/indexers/__tests__/balances.test.js +323 -0
  16. package/dist/cjs/indexers/__tests__/balances.test.js.map +1 -0
  17. package/dist/cjs/indexers/__tests__/utils.test.d.ts +2 -0
  18. package/dist/cjs/indexers/__tests__/utils.test.d.ts.map +1 -0
  19. package/dist/cjs/indexers/__tests__/utils.test.js +71 -0
  20. package/dist/cjs/indexers/__tests__/utils.test.js.map +1 -0
  21. package/dist/cjs/indexers/balances.d.ts +5 -0
  22. package/dist/cjs/indexers/balances.d.ts.map +1 -0
  23. package/dist/cjs/indexers/balances.js +66 -0
  24. package/dist/cjs/indexers/balances.js.map +1 -0
  25. package/dist/cjs/indexers/index.d.ts +3 -0
  26. package/dist/cjs/indexers/index.d.ts.map +1 -0
  27. package/dist/cjs/indexers/index.js +21 -0
  28. package/dist/cjs/indexers/index.js.map +1 -0
  29. package/dist/cjs/indexers/types.d.ts +22 -0
  30. package/dist/cjs/indexers/types.d.ts.map +1 -0
  31. package/dist/cjs/indexers/types.js +3 -0
  32. package/dist/cjs/indexers/types.js.map +1 -0
  33. package/dist/cjs/indexers/utils.d.ts +2 -0
  34. package/dist/cjs/indexers/utils.d.ts.map +1 -0
  35. package/dist/cjs/indexers/utils.js +17 -0
  36. package/dist/cjs/indexers/utils.js.map +1 -0
  37. package/dist/esm/index.d.ts +1 -0
  38. package/dist/esm/index.d.ts.map +1 -1
  39. package/dist/esm/index.js +1 -0
  40. package/dist/esm/index.js.map +1 -1
  41. package/dist/esm/indexers/AlchemyClient.d.ts +13 -0
  42. package/dist/esm/indexers/AlchemyClient.d.ts.map +1 -0
  43. package/dist/esm/indexers/AlchemyClient.js +103 -0
  44. package/dist/esm/indexers/AlchemyClient.js.map +1 -0
  45. package/dist/esm/indexers/GoldRushClient.d.ts +10 -0
  46. package/dist/esm/indexers/GoldRushClient.d.ts.map +1 -0
  47. package/dist/esm/indexers/GoldRushClient.js +86 -0
  48. package/dist/esm/indexers/GoldRushClient.js.map +1 -0
  49. package/dist/esm/indexers/__tests__/balances.test.d.ts +2 -0
  50. package/dist/esm/indexers/__tests__/balances.test.d.ts.map +1 -0
  51. package/dist/esm/indexers/__tests__/balances.test.js +318 -0
  52. package/dist/esm/indexers/__tests__/balances.test.js.map +1 -0
  53. package/dist/esm/indexers/__tests__/utils.test.d.ts +2 -0
  54. package/dist/esm/indexers/__tests__/utils.test.d.ts.map +1 -0
  55. package/dist/esm/indexers/__tests__/utils.test.js +69 -0
  56. package/dist/esm/indexers/__tests__/utils.test.js.map +1 -0
  57. package/dist/esm/indexers/balances.d.ts +5 -0
  58. package/dist/esm/indexers/balances.d.ts.map +1 -0
  59. package/dist/esm/indexers/balances.js +59 -0
  60. package/dist/esm/indexers/balances.js.map +1 -0
  61. package/dist/esm/indexers/index.d.ts +3 -0
  62. package/dist/esm/indexers/index.d.ts.map +1 -0
  63. package/dist/esm/indexers/index.js +3 -0
  64. package/dist/esm/indexers/index.js.map +1 -0
  65. package/dist/esm/indexers/types.d.ts +22 -0
  66. package/dist/esm/indexers/types.d.ts.map +1 -0
  67. package/dist/esm/indexers/types.js +2 -0
  68. package/dist/esm/indexers/types.js.map +1 -0
  69. package/dist/esm/indexers/utils.d.ts +2 -0
  70. package/dist/esm/indexers/utils.d.ts.map +1 -0
  71. package/dist/esm/indexers/utils.js +13 -0
  72. package/dist/esm/indexers/utils.js.map +1 -0
  73. package/package.json +9 -6
@@ -0,0 +1,318 @@
1
+ import fetchMock from "@fetch-mock/jest";
2
+ import { getWalletBalances } from "../balances.js";
3
+ describe("balances", () => {
4
+ beforeEach(() => {
5
+ fetchMock.mockGlobal();
6
+ });
7
+ afterEach(() => {
8
+ fetchMock.clearHistory();
9
+ fetchMock.removeRoutes();
10
+ fetchMock.unmockGlobal();
11
+ });
12
+ describe("getWalletBalances()", () => {
13
+ const walletAddr = "0x1234567890123456789012345678901234567890";
14
+ const network = "Mainnet";
15
+ const chain = "Ethereum";
16
+ it("should throw error when no indexers provided", async () => {
17
+ await expect(getWalletBalances(walletAddr, network, chain)).rejects.toThrow(`Can't get balances without an indexer.`);
18
+ });
19
+ it("should return balances from GoldRush indexer", async () => {
20
+ const mockGoldRushResponse = {
21
+ data: {
22
+ items: [
23
+ { contract_address: "0xToken1", balance: "100" },
24
+ { contract_address: "0xToken2", balance: "200" },
25
+ {
26
+ contract_address: "0xEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE",
27
+ balance: "1000",
28
+ },
29
+ { contract_address: "0xToken3", balance: "invalid" }, // invalid balance
30
+ { contract_address: "0xToken4" }, // missing balance
31
+ ],
32
+ },
33
+ };
34
+ fetchMock.getOnce(`https://api.covalenthq.com/v1/eth-mainnet/address/${walletAddr}/balances_v2/?key=test-key`, { status: 200, body: mockGoldRushResponse });
35
+ const result = await getWalletBalances(walletAddr, network, chain, {
36
+ goldRush: { apiKey: "test-key", timeoutMs: 100 },
37
+ });
38
+ expect(result).toEqual({
39
+ "0xtoken1": 100n,
40
+ "0xtoken2": 200n,
41
+ native: 1000n,
42
+ });
43
+ expect(fetchMock).toHaveFetchedTimes(1);
44
+ });
45
+ it("should fallback to Alchemy when GoldRush fails", async () => {
46
+ const mockAlchemyBatchResponse = [
47
+ {
48
+ id: 1,
49
+ result: {
50
+ tokenBalances: [
51
+ {
52
+ contractAddress: "0xtoken1",
53
+ tokenBalance: "0x0000000000000000000000000000000000000000000000000de0b6b3a7640000",
54
+ }, // 1000000000000000000 (1e18)
55
+ {
56
+ contractAddress: "0xtoken2",
57
+ balance: "0x00000000000000000000000000000000000000000000000000000000000000c8",
58
+ }, // 200 (older API format)
59
+ { contractAddress: "0xtoken3", tokenBalance: "0x64" }, // 100
60
+ ],
61
+ },
62
+ },
63
+ {
64
+ id: 2,
65
+ result: "0x2386f26fc10000", // 10000000000000000
66
+ },
67
+ ];
68
+ // First call fails (GoldRush), second call succeeds (Alchemy batch request)
69
+ fetchMock
70
+ .getOnce(`https://api.covalenthq.com/v1/eth-mainnet/address/${walletAddr}/balances_v2/?key=test-key`, {
71
+ throws: new Error("GoldRush API error"),
72
+ })
73
+ .postOnce("https://eth-mainnet.g.alchemy.com/v2/test-key", {
74
+ status: 200,
75
+ body: mockAlchemyBatchResponse,
76
+ });
77
+ const result = await getWalletBalances(walletAddr, network, chain, {
78
+ goldRush: { apiKey: "test-key", timeoutMs: 100 },
79
+ alchemy: { apiKey: "test-key", timeoutMs: 100 },
80
+ });
81
+ expect(result).toEqual({
82
+ "0xtoken1": 1000000000000000000n,
83
+ "0xtoken2": 200n,
84
+ "0xtoken3": 100n,
85
+ native: 10000000000000000n,
86
+ });
87
+ expect(fetchMock).toHaveFetchedTimes(2);
88
+ expect(fetchMock).toHaveLastFetched("https://eth-mainnet.g.alchemy.com/v2/test-key");
89
+ });
90
+ it("should skip indexer when chain is not supported", async () => {
91
+ const mockGoldRushResponse = {
92
+ data: {
93
+ items: [{ contract_address: "0xToken1", balance: "100" }],
94
+ },
95
+ };
96
+ fetchMock.getOnce(`https://api.covalenthq.com/v1/solana-mainnet/address/${walletAddr}/balances_v2/?key=test-key`, { status: 200, body: mockGoldRushResponse });
97
+ // Use a chain that only GoldRush supports (e.g., Solana for Mainnet)
98
+ const result = await getWalletBalances(walletAddr, network, "Solana", {
99
+ goldRush: { apiKey: "test-key", timeoutMs: 100 },
100
+ alchemy: { apiKey: "test-key", timeoutMs: 100 },
101
+ });
102
+ expect(result).toEqual({
103
+ "0xtoken1": 100n,
104
+ });
105
+ // Should only call GoldRush since Alchemy doesn't support Solana
106
+ expect(fetchMock).toHaveFetchedTimes(1);
107
+ });
108
+ it("should throw error when all indexers fail", async () => {
109
+ // All fetch calls fail
110
+ fetchMock
111
+ .getOnce(`https://api.covalenthq.com/v1/eth-mainnet/address/${walletAddr}/balances_v2/?key=test-key`, {
112
+ throws: new Error("GoldRush API error"),
113
+ })
114
+ .postOnce("https://eth-mainnet.g.alchemy.com/v2/test-key", {
115
+ throws: new Error("Alchemy batch API error"),
116
+ });
117
+ await expect(getWalletBalances(walletAddr, network, chain, {
118
+ goldRush: { apiKey: "test-key", timeoutMs: 100 },
119
+ alchemy: { apiKey: "test-key", timeoutMs: 100 },
120
+ })).rejects.toThrow(`Failed to get a successful response from indexers`);
121
+ expect(fetchMock).toHaveFetchedTimes(2);
122
+ });
123
+ it("should handle timeout and abort requests", async () => {
124
+ jest.useFakeTimers();
125
+ const mockAlchemyBatchResponse = [
126
+ {
127
+ id: 1,
128
+ result: {
129
+ tokenBalances: [
130
+ { contractAddress: "0xtoken1", balance: "0x64" }, // 100 in hex
131
+ ],
132
+ },
133
+ },
134
+ {
135
+ id: 2,
136
+ result: "0x64", // 100
137
+ },
138
+ ];
139
+ // First call (GoldRush) hangs and gets aborted, second call (Alchemy batch) succeeds
140
+ fetchMock
141
+ .getOnce(`https://api.covalenthq.com/v1/eth-mainnet/address/${walletAddr}/balances_v2/?key=test-key`, (_url, options) => {
142
+ return new Promise((resolve, reject) => {
143
+ const timer = setTimeout(() => { }, 200); // Keep event loop alive
144
+ const signal = options?.signal;
145
+ if (signal) {
146
+ signal.addEventListener("abort", () => {
147
+ clearTimeout(timer);
148
+ reject(signal.reason);
149
+ });
150
+ }
151
+ });
152
+ })
153
+ .postOnce("https://eth-mainnet.g.alchemy.com/v2/test-key", {
154
+ status: 200,
155
+ body: mockAlchemyBatchResponse,
156
+ });
157
+ const resultPromise = getWalletBalances(walletAddr, network, chain, {
158
+ goldRush: { apiKey: "test-key", timeoutMs: 100 },
159
+ alchemy: { apiKey: "test-key", timeoutMs: 100 },
160
+ });
161
+ // Fast-forward time to trigger timeout
162
+ await jest.advanceTimersByTimeAsync(100);
163
+ const result = await resultPromise;
164
+ expect(result).toEqual({
165
+ "0xtoken1": 100n,
166
+ native: 100n,
167
+ });
168
+ expect(fetchMock).toHaveFetchedTimes(2);
169
+ jest.useRealTimers();
170
+ });
171
+ it("should return native balance if included in indexer response", async () => {
172
+ const mockGoldRushResponse = {
173
+ data: {
174
+ items: [
175
+ { contract_address: "0xToken1", balance: "100" },
176
+ {
177
+ contract_address: "0xEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE",
178
+ balance: "500",
179
+ },
180
+ ],
181
+ },
182
+ };
183
+ fetchMock.getOnce(`https://api.covalenthq.com/v1/eth-mainnet/address/${walletAddr}/balances_v2/?key=test-key`, { status: 200, body: mockGoldRushResponse });
184
+ const result = await getWalletBalances(walletAddr, network, chain, {
185
+ goldRush: { apiKey: "test-key", timeoutMs: 100 },
186
+ });
187
+ expect(result).toEqual({
188
+ "0xtoken1": 100n,
189
+ native: 500n,
190
+ });
191
+ expect(result.native).toBe(500n);
192
+ });
193
+ it("should skip indexers with empty or missing API keys", async () => {
194
+ const mockAlchemyBatchResponse = [
195
+ {
196
+ id: 1,
197
+ result: {
198
+ tokenBalances: [
199
+ { contractAddress: "0xtoken1", balance: "0x64" }, // 100 in hex
200
+ ],
201
+ },
202
+ },
203
+ {
204
+ id: 2,
205
+ result: "0xc8", // 200
206
+ },
207
+ ];
208
+ fetchMock.postOnce("https://eth-mainnet.g.alchemy.com/v2/test-key", {
209
+ status: 200,
210
+ body: mockAlchemyBatchResponse,
211
+ });
212
+ // GoldRush has empty API key, only Alchemy should be called
213
+ const result = await getWalletBalances(walletAddr, network, chain, {
214
+ goldRush: { apiKey: "", timeoutMs: 100 },
215
+ alchemy: { apiKey: "test-key", timeoutMs: 100 },
216
+ });
217
+ expect(result).toEqual({
218
+ "0xtoken1": 100n,
219
+ native: 200n,
220
+ });
221
+ // Should only call Alchemy since GoldRush has empty API key
222
+ expect(fetchMock).toHaveFetchedTimes(1);
223
+ expect(fetchMock).toHaveLastFetched("https://eth-mainnet.g.alchemy.com/v2/test-key");
224
+ });
225
+ it("should skip tokens with invalid balance values from Alchemy", async () => {
226
+ const mockAlchemyBatchResponse = [
227
+ {
228
+ id: 1,
229
+ result: {
230
+ tokenBalances: [
231
+ { contractAddress: "0xtoken1", tokenBalance: "0x64" }, // 100 - valid
232
+ { contractAddress: "0xtoken2", tokenBalance: "invalid_hex" }, // invalid
233
+ { contractAddress: "0xtoken3", balance: "not a number" }, // invalid
234
+ { contractAddress: "0xtoken4", tokenBalance: "0xc8" }, // 200 - valid
235
+ { contractAddress: "0xtoken5" }, // missing balance field
236
+ ],
237
+ },
238
+ },
239
+ {
240
+ id: 2,
241
+ result: "0x12c", // 300 - valid
242
+ },
243
+ ];
244
+ fetchMock.postOnce("https://eth-mainnet.g.alchemy.com/v2/test-key", {
245
+ status: 200,
246
+ body: mockAlchemyBatchResponse,
247
+ });
248
+ const result = await getWalletBalances(walletAddr, network, chain, {
249
+ alchemy: { apiKey: "test-key", timeoutMs: 100 },
250
+ });
251
+ // Only valid tokens should be included
252
+ expect(result).toEqual({
253
+ "0xtoken1": 100n,
254
+ "0xtoken4": 200n,
255
+ native: 300n,
256
+ });
257
+ expect(fetchMock).toHaveFetchedTimes(1);
258
+ });
259
+ it("should return Solana balances from GoldRush indexer", async () => {
260
+ const solanaWalletAddr = "7yLKkp1HS2v9eJtPqT3crvhv7usuNWmQ87GLx48Ck8jJ";
261
+ const solanaNetwork = "Mainnet";
262
+ const solanaChain = "Solana";
263
+ const mockGoldRushSolanaResponse = {
264
+ data: {
265
+ address: "7yLKkp1HS2v9eJtPqT3crvhv7usuNWmQ87GLx48Ck8jJ",
266
+ updated_at: "2025-11-13T16:43:58.954959826Z",
267
+ chain_name: "solana-mainnet",
268
+ items: [
269
+ {
270
+ contract_address: "11111111111111111111111111111111",
271
+ contract_name: "Solana",
272
+ contract_ticker_symbol: "SOL",
273
+ native_token: true,
274
+ balance: "1835627474",
275
+ },
276
+ {
277
+ contract_address: "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v",
278
+ contract_name: "USD Coin",
279
+ contract_ticker_symbol: "USDC",
280
+ native_token: false,
281
+ balance: "123874778",
282
+ },
283
+ {
284
+ contract_address: "7vfCXTUXx5WJV5JADk17DUJ4ksgau7utNKj4b963voxs",
285
+ contract_name: "Ether (Portal)",
286
+ contract_ticker_symbol: "ETH",
287
+ native_token: false,
288
+ balance: "2455863",
289
+ },
290
+ {
291
+ contract_address: "So11111111111111111111111111111111111111112",
292
+ contract_name: "Wrapped SOL",
293
+ contract_ticker_symbol: "SOL",
294
+ native_token: false,
295
+ balance: "199700",
296
+ },
297
+ ],
298
+ },
299
+ };
300
+ fetchMock.getOnce(`https://api.covalenthq.com/v1/solana-mainnet/address/${solanaWalletAddr}/balances_v2/?key=test-key`, { status: 200, body: mockGoldRushSolanaResponse });
301
+ const result = await getWalletBalances(solanaWalletAddr, solanaNetwork, solanaChain, {
302
+ goldRush: { apiKey: "test-key", timeoutMs: 100 },
303
+ });
304
+ expect(result).toEqual({
305
+ // Native SOL (contract_address: 11111111111111111111111111111111)
306
+ native: 1835627474n,
307
+ // USDC
308
+ epjfwdd5aufqssqem2qn1xzybapc8g4weggkzwytdt1v: 123874778n,
309
+ // ETH (Portal)
310
+ "7vfcxtuxx5wjv5jadk17duj4ksgau7utnkj4b963voxs": 2455863n,
311
+ // Wrapped SOL
312
+ so11111111111111111111111111111111111111112: 199700n,
313
+ });
314
+ expect(fetchMock).toHaveFetchedTimes(1);
315
+ });
316
+ });
317
+ });
318
+ //# sourceMappingURL=balances.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"balances.test.js","sourceRoot":"","sources":["../../../../src/indexers/__tests__/balances.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=utils.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"utils.test.d.ts","sourceRoot":"","sources":["../../../../src/indexers/__tests__/utils.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,69 @@
1
+ import { parseBalance } from "../utils.js";
2
+ describe("utils", () => {
3
+ describe("parseBalance()", () => {
4
+ describe("valid inputs", () => {
5
+ it("should parse decimal string", () => {
6
+ const result = parseBalance("100");
7
+ expect(result).not.toBeNull();
8
+ expect(result.toString()).toBe("100");
9
+ });
10
+ it("should parse hex string with 0x prefix", () => {
11
+ const result = parseBalance("0x64");
12
+ expect(result).not.toBeNull();
13
+ expect(result.toString()).toBe("100");
14
+ });
15
+ it("should parse full-length hex balance from Alchemy", () => {
16
+ const result = parseBalance("0x0000000000000000000000000000000000000000000000000de0b6b3a7640000");
17
+ expect(result).not.toBeNull();
18
+ expect(result.toString()).toBe("1000000000000000000");
19
+ });
20
+ it("should parse string with leading/trailing whitespace", () => {
21
+ const result = parseBalance(" 123 ");
22
+ expect(result).not.toBeNull();
23
+ expect(result.toString()).toBe("123");
24
+ });
25
+ it("should parse zero as decimal", () => {
26
+ const result = parseBalance("0");
27
+ expect(result).not.toBeNull();
28
+ expect(result.toString()).toBe("0");
29
+ });
30
+ it("should parse large balance value", () => {
31
+ const result = parseBalance("1000000000000000000");
32
+ expect(result).not.toBeNull();
33
+ expect(result.toString()).toBe("1000000000000000000");
34
+ });
35
+ it("should parse hex zero", () => {
36
+ const result = parseBalance("0x0");
37
+ expect(result).not.toBeNull();
38
+ expect(result.toString()).toBe("0");
39
+ });
40
+ });
41
+ describe("edge cases", () => {
42
+ it("should return null for empty string", () => {
43
+ expect(parseBalance("")).toBe(null);
44
+ });
45
+ it("should return 0n for 0x alone", () => {
46
+ const result = parseBalance("0x");
47
+ expect(result).not.toBeNull();
48
+ expect(result.toString()).toBe("0");
49
+ });
50
+ it("should return 0n for string with only whitespace", () => {
51
+ const result = parseBalance(" ");
52
+ expect(result).not.toBeNull();
53
+ expect(result.toString()).toBe("0");
54
+ });
55
+ });
56
+ describe("invalid inputs that return null", () => {
57
+ it("should return null for undefined", () => {
58
+ expect(parseBalance(undefined)).toBe(null);
59
+ });
60
+ it("should return null for invalid hex string", () => {
61
+ expect(parseBalance("invalid_hex")).toBe(null);
62
+ });
63
+ it("should return null for non-numeric string", () => {
64
+ expect(parseBalance("not a number")).toBe(null);
65
+ });
66
+ });
67
+ });
68
+ });
69
+ //# sourceMappingURL=utils.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"utils.test.js","sourceRoot":"","sources":["../../../../src/indexers/__tests__/utils.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,5 @@
1
+ import type { Chain, Network } from "@wormhole-foundation/sdk-base";
2
+ import type { Balances } from "@wormhole-foundation/sdk-definitions";
3
+ import type { IndexerConfig } from "./types.js";
4
+ export declare function getWalletBalances(walletAddr: string, network: Network, chain: Chain, indexers?: IndexerConfig): Promise<Balances>;
5
+ //# sourceMappingURL=balances.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"balances.d.ts","sourceRoot":"","sources":["../../../src/indexers/balances.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAE,OAAO,EAAE,MAAM,+BAA+B,CAAC;AACpE,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,sCAAsC,CAAC;AAGrE,OAAO,KAAK,EAAE,aAAa,EAAuB,MAAM,YAAY,CAAC;AA4CrE,wBAAsB,iBAAiB,CACrC,UAAU,EAAE,MAAM,EAClB,OAAO,EAAE,OAAO,EAChB,KAAK,EAAE,KAAK,EACZ,QAAQ,CAAC,EAAE,aAAa,GACvB,OAAO,CAAC,QAAQ,CAAC,CAgCnB"}
@@ -0,0 +1,59 @@
1
+ import AlchemyClient from "./AlchemyClient.js";
2
+ import GoldRushClient from "./GoldRushClient.js";
3
+ const DEFAULT_TIMEOUT_MS = 5000;
4
+ async function tryClient({ client, network, chain, walletAddr, name, timeoutMs = DEFAULT_TIMEOUT_MS, }) {
5
+ if (!client) {
6
+ return null;
7
+ }
8
+ try {
9
+ if (!client.supportsChain(network, chain)) {
10
+ console.info(`Network=${network} Chain=${chain} not supported by ${name} indexer API`);
11
+ return null;
12
+ }
13
+ const controller = new AbortController();
14
+ const timeout = setTimeout(() => {
15
+ controller.abort(new Error(`${name} request timed out after ${timeoutMs}ms`));
16
+ }, timeoutMs);
17
+ let balances;
18
+ try {
19
+ balances = await client.getBalances(network, chain, walletAddr, controller.signal);
20
+ }
21
+ finally {
22
+ clearTimeout(timeout);
23
+ }
24
+ return balances;
25
+ }
26
+ catch (e) {
27
+ console.info(`Error querying ${name} indexer API: ${e}`);
28
+ return null;
29
+ }
30
+ }
31
+ export async function getWalletBalances(walletAddr, network, chain, indexers) {
32
+ if (!indexers) {
33
+ throw new Error("Can't get balances without an indexer.");
34
+ }
35
+ const { goldRush, alchemy } = indexers;
36
+ const commonConfig = { network, chain, walletAddr };
37
+ const clientConfigs = [
38
+ {
39
+ ...commonConfig,
40
+ client: goldRush?.apiKey ? new GoldRushClient(goldRush.apiKey) : undefined,
41
+ name: "Gold Rush",
42
+ timeoutMs: goldRush?.timeoutMs,
43
+ },
44
+ {
45
+ ...commonConfig,
46
+ client: alchemy?.apiKey ? new AlchemyClient(alchemy.apiKey) : undefined,
47
+ name: "Alchemy",
48
+ timeoutMs: alchemy?.timeoutMs,
49
+ },
50
+ ];
51
+ for (const config of clientConfigs) {
52
+ const result = await tryClient(config);
53
+ if (result) {
54
+ return result;
55
+ }
56
+ }
57
+ throw new Error("Failed to get a successful response from indexers");
58
+ }
59
+ //# sourceMappingURL=balances.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"balances.js","sourceRoot":"","sources":["../../../src/indexers/balances.ts"],"names":[],"mappings":"AAEA,OAAO,aAAa,MAAM,oBAAoB,CAAC;AAC/C,OAAO,cAAc,MAAM,qBAAqB,CAAC;AAGjD,MAAM,kBAAkB,GAAG,IAAI,CAAC;AAEhC,KAAK,UAAU,SAAS,CAAC,EACvB,MAAM,EACN,OAAO,EACP,KAAK,EACL,UAAU,EACV,IAAI,EACJ,SAAS,GAAG,kBAAkB,GACV;IACpB,IAAI,CAAC,MAAM,EAAE,CAAC;QACZ,OAAO,IAAI,CAAC;IACd,CAAC;IAED,IAAI,CAAC;QACH,IAAI,CAAC,MAAM,CAAC,aAAa,CAAC,OAAO,EAAE,KAAK,CAAC,EAAE,CAAC;YAC1C,OAAO,CAAC,IAAI,CAAC,WAAW,OAAO,UAAU,KAAK,qBAAqB,IAAI,cAAc,CAAC,CAAC;YAEvF,OAAO,IAAI,CAAC;QACd,CAAC;QAED,MAAM,UAAU,GAAG,IAAI,eAAe,EAAE,CAAC;QAEzC,MAAM,OAAO,GAAG,UAAU,CAAC,GAAG,EAAE;YAC9B,UAAU,CAAC,KAAK,CAAC,IAAI,KAAK,CAAC,GAAG,IAAI,4BAA4B,SAAS,IAAI,CAAC,CAAC,CAAC;QAChF,CAAC,EAAE,SAAS,CAAC,CAAC;QAEd,IAAI,QAAkB,CAAC;QAEvB,IAAI,CAAC;YACH,QAAQ,GAAG,MAAM,MAAM,CAAC,WAAW,CAAC,OAAO,EAAE,KAAK,EAAE,UAAU,EAAE,UAAU,CAAC,MAAM,CAAC,CAAC;QACrF,CAAC;gBAAS,CAAC;YACT,YAAY,CAAC,OAAO,CAAC,CAAC;QACxB,CAAC;QAED,OAAO,QAAQ,CAAC;IAClB,CAAC;IAAC,OAAO,CAAC,EAAE,CAAC;QACX,OAAO,CAAC,IAAI,CAAC,kBAAkB,IAAI,iBAAiB,CAAC,EAAE,CAAC,CAAC;QACzD,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,iBAAiB,CACrC,UAAkB,EAClB,OAAgB,EAChB,KAAY,EACZ,QAAwB;IAExB,IAAI,CAAC,QAAQ,EAAE,CAAC;QACd,MAAM,IAAI,KAAK,CAAC,wCAAwC,CAAC,CAAC;IAC5D,CAAC;IAED,MAAM,EAAE,QAAQ,EAAE,OAAO,EAAE,GAAG,QAAQ,CAAC;IACvC,MAAM,YAAY,GAAG,EAAE,OAAO,EAAE,KAAK,EAAE,UAAU,EAAE,CAAC;IAEpD,MAAM,aAAa,GAA+B;QAChD;YACE,GAAG,YAAY;YACf,MAAM,EAAE,QAAQ,EAAE,MAAM,CAAC,CAAC,CAAC,IAAI,cAAc,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,SAAS;YAC1E,IAAI,EAAE,WAAW;YACjB,SAAS,EAAE,QAAQ,EAAE,SAAS;SAC/B;QACD;YACE,GAAG,YAAY;YACf,MAAM,EAAE,OAAO,EAAE,MAAM,CAAC,CAAC,CAAC,IAAI,aAAa,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,SAAS;YACvE,IAAI,EAAE,SAAS;YACf,SAAS,EAAE,OAAO,EAAE,SAAS;SAC9B;KACF,CAAC;IAEF,KAAK,MAAM,MAAM,IAAI,aAAa,EAAE,CAAC;QACnC,MAAM,MAAM,GAAG,MAAM,SAAS,CAAC,MAAM,CAAC,CAAC;QAEvC,IAAI,MAAM,EAAE,CAAC;YACX,OAAO,MAAM,CAAC;QAChB,CAAC;IACH,CAAC;IAED,MAAM,IAAI,KAAK,CAAC,mDAAmD,CAAC,CAAC;AACvE,CAAC"}
@@ -0,0 +1,3 @@
1
+ export * from "./types.js";
2
+ export { getWalletBalances } from "./balances.js";
3
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/indexers/index.ts"],"names":[],"mappings":"AAAA,cAAc,YAAY,CAAC;AAC3B,OAAO,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAC"}
@@ -0,0 +1,3 @@
1
+ export * from "./types.js";
2
+ export { getWalletBalances } from "./balances.js";
3
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/indexers/index.ts"],"names":[],"mappings":"AAAA,cAAc,YAAY,CAAC;AAC3B,OAAO,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAC"}
@@ -0,0 +1,22 @@
1
+ import type { Chain, Network } from "@wormhole-foundation/sdk-base";
2
+ import type AlchemyClient from "./AlchemyClient.js";
3
+ import type GoldRushClient from "./GoldRushClient.js";
4
+ export interface IndexerConfig {
5
+ goldRush?: {
6
+ apiKey: string;
7
+ timeoutMs: number;
8
+ };
9
+ alchemy?: {
10
+ apiKey: string;
11
+ timeoutMs: number;
12
+ };
13
+ }
14
+ export interface IndexerClientConfig {
15
+ chain: Chain;
16
+ client?: GoldRushClient | AlchemyClient;
17
+ name: string;
18
+ network: Network;
19
+ timeoutMs?: number;
20
+ walletAddr: string;
21
+ }
22
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/indexers/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAE,OAAO,EAAE,MAAM,+BAA+B,CAAC;AACpE,OAAO,KAAK,aAAa,MAAM,oBAAoB,CAAC;AACpD,OAAO,KAAK,cAAc,MAAM,qBAAqB,CAAC;AAEtD,MAAM,WAAW,aAAa;IAC5B,QAAQ,CAAC,EAAE;QACT,MAAM,EAAE,MAAM,CAAC;QACf,SAAS,EAAE,MAAM,CAAC;KACnB,CAAC;IACF,OAAO,CAAC,EAAE;QACR,MAAM,EAAE,MAAM,CAAC;QACf,SAAS,EAAE,MAAM,CAAC;KACnB,CAAC;CACH;AAED,MAAM,WAAW,mBAAmB;IAClC,KAAK,EAAE,KAAK,CAAC;IACb,MAAM,CAAC,EAAE,cAAc,GAAG,aAAa,CAAC;IACxC,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,OAAO,CAAC;IACjB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;CACpB"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../../src/indexers/types.ts"],"names":[],"mappings":""}
@@ -0,0 +1,2 @@
1
+ export declare function parseBalance(balance: string | undefined): bigint | null;
2
+ //# sourceMappingURL=utils.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../../src/indexers/utils.ts"],"names":[],"mappings":"AAEA,wBAAgB,YAAY,CAAC,OAAO,EAAE,MAAM,GAAG,SAAS,GAAG,MAAM,GAAG,IAAI,CASvE"}
@@ -0,0 +1,13 @@
1
+ import { encoding } from "@wormhole-foundation/sdk-base";
2
+ export function parseBalance(balance) {
3
+ try {
4
+ if (!balance) {
5
+ return null;
6
+ }
7
+ return encoding.bignum.decode(balance.trim());
8
+ }
9
+ catch {
10
+ return null;
11
+ }
12
+ }
13
+ //# sourceMappingURL=utils.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"utils.js","sourceRoot":"","sources":["../../../src/indexers/utils.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,+BAA+B,CAAC;AAEzD,MAAM,UAAU,YAAY,CAAC,OAA2B;IACtD,IAAI,CAAC;QACH,IAAI,CAAC,OAAO,EAAE,CAAC;YACb,OAAO,IAAI,CAAC;QACd,CAAC;QACD,OAAO,QAAQ,CAAC,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,IAAI,EAAE,CAAC,CAAC;IAChD,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@wormhole-foundation/sdk-connect",
3
- "version": "3.12.0",
3
+ "version": "4.0.0",
4
4
  "repository": {
5
5
  "type": "git",
6
6
  "url": "git+https://github.com/wormhole-foundation/wormhole-sdk-ts.git"
@@ -92,14 +92,17 @@
92
92
  "clean": "rm -rf ./dist && rm -rf ./.turbo",
93
93
  "lint": "npm run prettier && eslint --fix ./src --ext .ts",
94
94
  "prettier": "prettier --write ./src",
95
- "test": "jest --config ./jest.config.ts __tests__/*.ts",
95
+ "test": "jest --config ./jest.config.ts --testMatch '**/__tests__/**/*.test.ts'",
96
96
  "coverage": "jest --config ./jest.config.ts --coverage",
97
97
  "docs": "typedoc"
98
98
  },
99
99
  "dependencies": {
100
- "axios": "^1.4.0",
101
- "@wormhole-foundation/sdk-base": "3.12.0",
102
- "@wormhole-foundation/sdk-definitions": "3.12.0"
100
+ "@wormhole-foundation/sdk-base": "4.0.0",
101
+ "@wormhole-foundation/sdk-definitions": "4.0.0",
102
+ "axios": "^1.4.0"
103
103
  },
104
- "type": "module"
104
+ "type": "module",
105
+ "devDependencies": {
106
+ "@fetch-mock/jest": "^0.2.20"
107
+ }
105
108
  }