@veridex/sdk 1.0.0-beta.9 → 1.0.1

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 (130) hide show
  1. package/LICENSE +170 -21
  2. package/README.md +574 -117
  3. package/dist/EVMClient-DtqvdfUP.d.mts +376 -0
  4. package/dist/auth/prepareAuth.d.mts +25 -0
  5. package/dist/auth/prepareAuth.js +2406 -0
  6. package/dist/auth/prepareAuth.js.map +1 -0
  7. package/dist/auth/prepareAuth.mjs +151 -0
  8. package/dist/auth/prepareAuth.mjs.map +1 -0
  9. package/dist/chains/aptos/index.d.mts +6 -5
  10. package/dist/chains/aptos/index.js +66 -39
  11. package/dist/chains/aptos/index.js.map +1 -1
  12. package/dist/chains/aptos/index.mjs +5 -547
  13. package/dist/chains/aptos/index.mjs.map +1 -1
  14. package/dist/chains/avalanche/index.d.mts +137 -0
  15. package/dist/chains/avalanche/index.js +1555 -0
  16. package/dist/chains/avalanche/index.js.map +1 -0
  17. package/dist/chains/avalanche/index.mjs +10 -0
  18. package/dist/chains/avalanche/index.mjs.map +1 -0
  19. package/dist/chains/evm/index.d.mts +5 -3
  20. package/dist/chains/evm/index.js +165 -3
  21. package/dist/chains/evm/index.js.map +1 -1
  22. package/dist/chains/evm/index.mjs +8 -1200
  23. package/dist/chains/evm/index.mjs.map +1 -1
  24. package/dist/chains/solana/index.d.mts +1 -1
  25. package/dist/chains/solana/index.js.map +1 -1
  26. package/dist/chains/solana/index.mjs +4 -486
  27. package/dist/chains/solana/index.mjs.map +1 -1
  28. package/dist/chains/stacks/index.d.mts +559 -0
  29. package/dist/chains/stacks/index.js +1207 -0
  30. package/dist/chains/stacks/index.js.map +1 -0
  31. package/dist/chains/stacks/index.mjs +71 -0
  32. package/dist/chains/stacks/index.mjs.map +1 -0
  33. package/dist/chains/starknet/index.d.mts +3 -3
  34. package/dist/chains/starknet/index.js.map +1 -1
  35. package/dist/chains/starknet/index.mjs +5 -503
  36. package/dist/chains/starknet/index.mjs.map +1 -1
  37. package/dist/chains/sui/index.d.mts +2 -2
  38. package/dist/chains/sui/index.js.map +1 -1
  39. package/dist/chains/sui/index.mjs +5 -529
  40. package/dist/chains/sui/index.mjs.map +1 -1
  41. package/dist/chunk-5T6KPH7A.mjs +1082 -0
  42. package/dist/chunk-5T6KPH7A.mjs.map +1 -0
  43. package/dist/chunk-72ZA3OYQ.mjs +20 -0
  44. package/dist/chunk-72ZA3OYQ.mjs.map +1 -0
  45. package/dist/chunk-EFIURACP.mjs +438 -0
  46. package/dist/chunk-EFIURACP.mjs.map +1 -0
  47. package/dist/chunk-F3YAGZSW.mjs +269 -0
  48. package/dist/chunk-F3YAGZSW.mjs.map +1 -0
  49. package/dist/chunk-GWJRKDSA.mjs +549 -0
  50. package/dist/chunk-GWJRKDSA.mjs.map +1 -0
  51. package/dist/chunk-M3MM4YMF.mjs +417 -0
  52. package/dist/chunk-M3MM4YMF.mjs.map +1 -0
  53. package/dist/chunk-N4A2RMUN.mjs +216 -0
  54. package/dist/chunk-N4A2RMUN.mjs.map +1 -0
  55. package/dist/chunk-NUWSMJFJ.mjs +179 -0
  56. package/dist/chunk-NUWSMJFJ.mjs.map +1 -0
  57. package/dist/chunk-OVMMTL6H.mjs +330 -0
  58. package/dist/chunk-OVMMTL6H.mjs.map +1 -0
  59. package/dist/chunk-PDHZ5X5O.mjs +565 -0
  60. package/dist/chunk-PDHZ5X5O.mjs.map +1 -0
  61. package/dist/chunk-PRHNGA4G.mjs +464 -0
  62. package/dist/chunk-PRHNGA4G.mjs.map +1 -0
  63. package/dist/chunk-Q5O3M5LP.mjs +422 -0
  64. package/dist/chunk-Q5O3M5LP.mjs.map +1 -0
  65. package/dist/chunk-QDO6NQ7P.mjs +840 -0
  66. package/dist/chunk-QDO6NQ7P.mjs.map +1 -0
  67. package/dist/chunk-QT4ZZ4GM.mjs +509 -0
  68. package/dist/chunk-QT4ZZ4GM.mjs.map +1 -0
  69. package/dist/chunk-USDA5JTN.mjs +1249 -0
  70. package/dist/chunk-USDA5JTN.mjs.map +1 -0
  71. package/dist/chunk-V636MIV3.mjs +52 -0
  72. package/dist/chunk-V636MIV3.mjs.map +1 -0
  73. package/dist/chunk-X7BZMSPQ.mjs +407 -0
  74. package/dist/chunk-X7BZMSPQ.mjs.map +1 -0
  75. package/dist/chunk-YCUJZ6Z7.mjs +829 -0
  76. package/dist/chunk-YCUJZ6Z7.mjs.map +1 -0
  77. package/dist/constants.d.mts +1 -1
  78. package/dist/constants.js +26 -12
  79. package/dist/constants.js.map +1 -1
  80. package/dist/constants.mjs +16 -375
  81. package/dist/constants.mjs.map +1 -1
  82. package/dist/index-DDalBhAm.d.mts +243 -0
  83. package/dist/index.d.mts +2508 -556
  84. package/dist/index.js +14576 -9628
  85. package/dist/index.js.map +1 -1
  86. package/dist/index.mjs +4108 -7840
  87. package/dist/index.mjs.map +1 -1
  88. package/dist/passkey.d.mts +182 -0
  89. package/dist/passkey.js +914 -0
  90. package/dist/passkey.js.map +1 -0
  91. package/dist/passkey.mjs +15 -0
  92. package/dist/passkey.mjs.map +1 -0
  93. package/dist/payload.js.map +1 -1
  94. package/dist/payload.mjs +25 -244
  95. package/dist/payload.mjs.map +1 -1
  96. package/dist/portfolio-V347KZOL.mjs +13 -0
  97. package/dist/portfolio-V347KZOL.mjs.map +1 -0
  98. package/dist/queries/index.js +145 -12
  99. package/dist/queries/index.js.map +1 -1
  100. package/dist/queries/index.mjs +14 -1496
  101. package/dist/queries/index.mjs.map +1 -1
  102. package/dist/{types-FJL7j6gQ.d.ts → types-B7V5VNbO.d.mts} +6 -2
  103. package/dist/{types-ChIsqCiw.d.mts → types-DP2CQT8p.d.mts} +12 -1
  104. package/dist/types.d.mts +16 -0
  105. package/dist/types.js.map +1 -1
  106. package/dist/utils.js +25 -11
  107. package/dist/utils.js.map +1 -1
  108. package/dist/utils.mjs +19 -371
  109. package/dist/utils.mjs.map +1 -1
  110. package/dist/wormhole.js.map +1 -1
  111. package/dist/wormhole.mjs +25 -397
  112. package/dist/wormhole.mjs.map +1 -1
  113. package/package.json +28 -3
  114. package/scripts/patch-noble-curves.js +78 -0
  115. package/dist/chains/aptos/index.d.ts +0 -145
  116. package/dist/chains/evm/index.d.ts +0 -5
  117. package/dist/chains/solana/index.d.ts +0 -116
  118. package/dist/chains/starknet/index.d.ts +0 -172
  119. package/dist/chains/sui/index.d.ts +0 -182
  120. package/dist/constants.d.ts +0 -150
  121. package/dist/index-0NXfbk0z.d.ts +0 -637
  122. package/dist/index-D0dLVjTA.d.mts +0 -637
  123. package/dist/index.d.ts +0 -3123
  124. package/dist/payload.d.ts +0 -125
  125. package/dist/queries/index.d.ts +0 -148
  126. package/dist/types-ChIsqCiw.d.ts +0 -565
  127. package/dist/types-FJL7j6gQ.d.mts +0 -172
  128. package/dist/types.d.ts +0 -407
  129. package/dist/utils.d.ts +0 -81
  130. package/dist/wormhole.d.ts +0 -167
@@ -0,0 +1,330 @@
1
+ import {
2
+ WORMHOLE_QUERY_PROXY_URLS
3
+ } from "./chunk-72ZA3OYQ.mjs";
4
+ import {
5
+ MAINNET_CHAINS,
6
+ TESTNET_CHAINS
7
+ } from "./chunk-X7BZMSPQ.mjs";
8
+
9
+ // src/queries/hubState.ts
10
+ import axios from "axios";
11
+ import { Buffer } from "buffer";
12
+ import { ethers } from "ethers";
13
+ import {
14
+ EthCallQueryRequest,
15
+ EthCallQueryResponse,
16
+ PerChainQueryRequest,
17
+ QueryRequest,
18
+ QueryResponse,
19
+ hexToUint8Array,
20
+ isValidHexString
21
+ } from "@wormhole-foundation/wormhole-query-sdk";
22
+ var QueryHubStateError = class extends Error {
23
+ code;
24
+ cause;
25
+ constructor(code, message, cause) {
26
+ super(message);
27
+ this.name = "QueryHubStateError";
28
+ this.code = code;
29
+ this.cause = cause;
30
+ }
31
+ };
32
+ function resolveNetwork(options) {
33
+ if (options?.network) return options.network;
34
+ const envCandidates = [
35
+ globalThis?.process?.env?.NEXT_PUBLIC_VERIDEX_NETWORK,
36
+ globalThis?.process?.env?.VERIDEX_NETWORK,
37
+ globalThis?.process?.env?.NEXT_PUBLIC_WORMHOLE_NETWORK,
38
+ globalThis?.process?.env?.WORMHOLE_NETWORK
39
+ ].filter(Boolean);
40
+ const env = envCandidates[0]?.toLowerCase();
41
+ if (env === "mainnet" || env === "testnet") return env;
42
+ return "testnet";
43
+ }
44
+ function concatBytes(parts) {
45
+ const total = parts.reduce((sum, p) => sum + p.length, 0);
46
+ const out = new Uint8Array(total);
47
+ let offset = 0;
48
+ for (const p of parts) {
49
+ out.set(p, offset);
50
+ offset += p.length;
51
+ }
52
+ return out;
53
+ }
54
+ function signaturesToProofBytes(signatures) {
55
+ const chunks = [];
56
+ for (const sig of signatures) {
57
+ if (typeof sig !== "string" || sig.length !== 132 || !/^[0-9a-fA-F]+$/.test(sig)) {
58
+ throw new QueryHubStateError(
59
+ "PROXY_RESPONSE_INVALID",
60
+ `Invalid guardian signature format (expected 132 hex chars): ${String(sig)}`
61
+ );
62
+ }
63
+ chunks.push(hexToUint8Array(`0x${sig}`));
64
+ }
65
+ return concatBytes(chunks);
66
+ }
67
+ function decodeQueryBytes(bytes) {
68
+ if (typeof bytes !== "string" || bytes.length === 0) {
69
+ throw new QueryHubStateError("PROXY_RESPONSE_INVALID", "Missing query response bytes");
70
+ }
71
+ if (isValidHexString(bytes)) {
72
+ return hexToUint8Array(bytes);
73
+ }
74
+ try {
75
+ if (typeof atob === "function") {
76
+ const raw = atob(bytes);
77
+ const arr = new Uint8Array(raw.length);
78
+ for (let i = 0; i < raw.length; i++) arr[i] = raw.charCodeAt(i);
79
+ return arr;
80
+ }
81
+ } catch {
82
+ }
83
+ try {
84
+ return new Uint8Array(Buffer.from(bytes, "base64"));
85
+ } catch (cause) {
86
+ throw new QueryHubStateError("PROXY_RESPONSE_INVALID", "Unrecognized query response bytes encoding", cause);
87
+ }
88
+ }
89
+ function sleep(ms) {
90
+ return new Promise((resolve) => setTimeout(resolve, ms));
91
+ }
92
+ async function withExponentialBackoff(fn, maxAttempts) {
93
+ let attempt = 0;
94
+ let lastError;
95
+ while (attempt < maxAttempts) {
96
+ try {
97
+ return await fn();
98
+ } catch (err) {
99
+ lastError = err;
100
+ attempt += 1;
101
+ if (attempt >= maxAttempts) break;
102
+ const baseMs = 250;
103
+ const backoffMs = Math.min(5e3, baseMs * 2 ** (attempt - 1));
104
+ const jitterMs = Math.floor(Math.random() * 100);
105
+ await sleep(backoffMs + jitterMs);
106
+ }
107
+ }
108
+ throw lastError;
109
+ }
110
+ function getHubConfig(network) {
111
+ if (network === "testnet") {
112
+ const baseSepolia = TESTNET_CHAINS.baseSepolia;
113
+ if (!baseSepolia?.contracts?.hub) {
114
+ throw new QueryHubStateError("MISSING_HUB_ADDRESS", "Missing Base Sepolia hub address in SDK constants");
115
+ }
116
+ return {
117
+ wormholeChainId: baseSepolia.wormholeChainId,
118
+ hubAddress: baseSepolia.contracts.hub,
119
+ endpoint: WORMHOLE_QUERY_PROXY_URLS.testnet,
120
+ rpcUrl: baseSepolia.rpcUrl
121
+ };
122
+ }
123
+ if (network === "mainnet") {
124
+ const base = MAINNET_CHAINS.base;
125
+ const hubAddress = base?.contracts?.hub;
126
+ if (!hubAddress) {
127
+ throw new QueryHubStateError(
128
+ "MISSING_HUB_ADDRESS",
129
+ "Missing mainnet hub address in SDK constants (MAINNET_CHAINS.base.contracts.hub)"
130
+ );
131
+ }
132
+ return {
133
+ wormholeChainId: base.wormholeChainId,
134
+ hubAddress,
135
+ endpoint: WORMHOLE_QUERY_PROXY_URLS.mainnet,
136
+ rpcUrl: base.rpcUrl
137
+ };
138
+ }
139
+ throw new QueryHubStateError("UNSUPPORTED_NETWORK", `Unsupported network: ${network}`);
140
+ }
141
+ function encodeHubCalls(hubAddress, userKeyHash) {
142
+ const nonceAbiCandidates = [
143
+ "function getUserNonce(bytes32 userKeyHash) view returns (uint256)",
144
+ "function userNonces(bytes32 userKeyHash) view returns (uint256)",
145
+ "function getNonceByHash(bytes32 userKeyHash) view returns (uint256)"
146
+ ];
147
+ const registeredAbiCandidates = [
148
+ "function registeredKeys(bytes32 userKeyHash) view returns (bool)",
149
+ "function isKeyRegisteredByHash(bytes32 userKeyHash) view returns (bool)"
150
+ ];
151
+ const actionHashAbiCandidates = [
152
+ "function getUserLastActionHash(bytes32 userKeyHash) view returns (bytes32)",
153
+ "function userLastActionHash(bytes32 userKeyHash) view returns (bytes32)"
154
+ ];
155
+ const iface = new ethers.Interface([
156
+ ...nonceAbiCandidates,
157
+ ...registeredAbiCandidates,
158
+ ...actionHashAbiCandidates
159
+ ]);
160
+ const nonceFnNames = ["getUserNonce", "userNonces", "getNonceByHash"];
161
+ const regFnNames = ["registeredKeys", "isKeyRegisteredByHash"];
162
+ const actionHashFnNames = ["getUserLastActionHash", "userLastActionHash"];
163
+ return [
164
+ ...nonceFnNames.map((fn) => ({
165
+ to: hubAddress,
166
+ data: iface.encodeFunctionData(fn, [userKeyHash])
167
+ })),
168
+ ...regFnNames.map((fn) => ({
169
+ to: hubAddress,
170
+ data: iface.encodeFunctionData(fn, [userKeyHash])
171
+ })),
172
+ ...actionHashFnNames.map((fn) => ({
173
+ to: hubAddress,
174
+ data: iface.encodeFunctionData(fn, [userKeyHash])
175
+ }))
176
+ ];
177
+ }
178
+ function decodeFirstNonce(results) {
179
+ const candidates = [
180
+ "function getUserNonce(bytes32 userKeyHash) view returns (uint256)",
181
+ "function userNonces(bytes32 userKeyHash) view returns (uint256)",
182
+ "function getNonceByHash(bytes32 userKeyHash) view returns (uint256)"
183
+ ];
184
+ const iface = new ethers.Interface(candidates);
185
+ const fnNames = ["getUserNonce", "userNonces", "getNonceByHash"];
186
+ for (let idx = 0; idx < fnNames.length; idx++) {
187
+ const fnName = fnNames[idx];
188
+ try {
189
+ const data = results[idx];
190
+ if (!data || data === "0x") continue;
191
+ const decoded = iface.decodeFunctionResult(fnName, data);
192
+ return decoded[0];
193
+ } catch {
194
+ }
195
+ }
196
+ throw new QueryHubStateError("QUERY_RESPONSE_INVALID", "Unable to decode user nonce from query response");
197
+ }
198
+ function decodeFirstIsRegistered(results) {
199
+ const nonceCandidateCount = 3;
200
+ const candidates = [
201
+ "function registeredKeys(bytes32 userKeyHash) view returns (bool)",
202
+ "function isKeyRegisteredByHash(bytes32 userKeyHash) view returns (bool)"
203
+ ];
204
+ const iface = new ethers.Interface(candidates);
205
+ const fnNames = ["registeredKeys", "isKeyRegisteredByHash"];
206
+ for (let i = 0; i < fnNames.length; i++) {
207
+ const fnName = fnNames[i];
208
+ try {
209
+ const data = results[nonceCandidateCount + i];
210
+ if (!data || data === "0x") continue;
211
+ const decoded = iface.decodeFunctionResult(fnName, data);
212
+ return Boolean(decoded[0]);
213
+ } catch {
214
+ }
215
+ }
216
+ return false;
217
+ }
218
+ function decodeLastActionHash(results) {
219
+ const nonceCandidateCount = 3;
220
+ const registeredCandidateCount = 2;
221
+ const actionHashOffset = nonceCandidateCount + registeredCandidateCount;
222
+ const candidates = [
223
+ "function getUserLastActionHash(bytes32 userKeyHash) view returns (bytes32)",
224
+ "function userLastActionHash(bytes32 userKeyHash) view returns (bytes32)"
225
+ ];
226
+ const iface = new ethers.Interface(candidates);
227
+ const fnNames = ["getUserLastActionHash", "userLastActionHash"];
228
+ for (let i = 0; i < fnNames.length; i++) {
229
+ const fnName = fnNames[i];
230
+ try {
231
+ const data = results[actionHashOffset + i];
232
+ if (!data || data === "0x") continue;
233
+ const decoded = iface.decodeFunctionResult(fnName, data);
234
+ return decoded[0];
235
+ } catch {
236
+ }
237
+ }
238
+ return ethers.ZeroHash;
239
+ }
240
+ async function queryHubState(userKeyHash, apiKey, options) {
241
+ if (typeof userKeyHash !== "string" || userKeyHash.length === 0) {
242
+ throw new QueryHubStateError("INVALID_ARGUMENT", "userKeyHash is required");
243
+ }
244
+ if (!isValidHexString(userKeyHash) || hexToUint8Array(userKeyHash).length !== 32) {
245
+ throw new QueryHubStateError("INVALID_ARGUMENT", "userKeyHash must be a 32-byte hex string");
246
+ }
247
+ if (typeof apiKey !== "string" || apiKey.length === 0) {
248
+ throw new QueryHubStateError("INVALID_ARGUMENT", "apiKey is required");
249
+ }
250
+ const network = resolveNetwork(options);
251
+ const maxAgeSeconds = options?.maxAge ?? 60;
252
+ const maxAttempts = options?.maxAttempts ?? 4;
253
+ const { wormholeChainId, hubAddress, endpoint, rpcUrl } = getHubConfig(network);
254
+ const provider = new ethers.JsonRpcProvider(rpcUrl);
255
+ const callData = encodeHubCalls(hubAddress, userKeyHash);
256
+ const doFetch = async () => {
257
+ try {
258
+ const latestBlock = await provider.getBlockNumber();
259
+ const blockTag = Math.max(0, latestBlock - 2);
260
+ const request = new QueryRequest(Date.now() & 4294967295, [
261
+ new PerChainQueryRequest(wormholeChainId, new EthCallQueryRequest(blockTag, callData))
262
+ ]);
263
+ const requestHex = Buffer.from(request.serialize()).toString("hex");
264
+ const response = await axios.post(
265
+ endpoint,
266
+ { bytes: requestHex },
267
+ {
268
+ headers: {
269
+ "X-API-Key": apiKey,
270
+ "Content-Type": "application/json"
271
+ },
272
+ timeout: 1e4
273
+ }
274
+ );
275
+ const data = response.data;
276
+ const signatures = data?.signatures;
277
+ const bytes = data?.bytes;
278
+ if (!Array.isArray(signatures) || typeof bytes !== "string") {
279
+ throw new QueryHubStateError("PROXY_RESPONSE_INVALID", "Query Proxy response missing signatures/bytes");
280
+ }
281
+ const proof = signaturesToProofBytes(signatures);
282
+ const queryBytes = decodeQueryBytes(bytes);
283
+ const parsed = QueryResponse.from(queryBytes);
284
+ const perChain = parsed.responses.find((r) => r.chainId === wormholeChainId);
285
+ if (!perChain) {
286
+ throw new QueryHubStateError("QUERY_RESPONSE_INVALID", "Missing per-chain response for hub chain");
287
+ }
288
+ const chainResp = EthCallQueryResponse.from(perChain.response.serialize());
289
+ const blockTime = Number(chainResp.blockTime);
290
+ const nowSeconds = Math.floor(Date.now() / 1e3);
291
+ if (nowSeconds - blockTime > maxAgeSeconds) {
292
+ throw new QueryHubStateError(
293
+ "ATTESTATION_STALE",
294
+ `Guardian attestation is stale (blockTime=${blockTime}, now=${nowSeconds}, maxAge=${maxAgeSeconds}s)`
295
+ );
296
+ }
297
+ const nonce = decodeFirstNonce(chainResp.results);
298
+ const isRegistered = decodeFirstIsRegistered(chainResp.results);
299
+ const lastActionHash = decodeLastActionHash(chainResp.results);
300
+ return {
301
+ nonce,
302
+ isRegistered,
303
+ blockTime,
304
+ proof,
305
+ lastActionHash
306
+ };
307
+ } catch (err) {
308
+ if (err instanceof QueryHubStateError) throw err;
309
+ if (axios.isAxiosError(err)) {
310
+ const ax = err;
311
+ const status = ax.response?.status;
312
+ const statusText = ax.response?.statusText;
313
+ const details = typeof ax.response?.data === "string" ? ax.response?.data : void 0;
314
+ throw new QueryHubStateError(
315
+ "PROXY_HTTP_ERROR",
316
+ `Query Proxy request failed${status ? ` (${status} ${statusText ?? ""})` : ""}${details ? `: ${details}` : ""}`,
317
+ err
318
+ );
319
+ }
320
+ throw new QueryHubStateError("PROXY_HTTP_ERROR", "Query Proxy request failed", err);
321
+ }
322
+ };
323
+ return await withExponentialBackoff(doFetch, maxAttempts);
324
+ }
325
+
326
+ export {
327
+ QueryHubStateError,
328
+ queryHubState
329
+ };
330
+ //# sourceMappingURL=chunk-OVMMTL6H.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/queries/hubState.ts"],"sourcesContent":["import axios, { AxiosError } from 'axios';\nimport { Buffer } from 'buffer';\nimport { ethers } from 'ethers';\nimport {\n EthCallQueryRequest,\n EthCallQueryResponse,\n PerChainQueryRequest,\n QueryRequest,\n QueryResponse,\n hexToUint8Array,\n isValidHexString,\n} from '@wormhole-foundation/wormhole-query-sdk';\n\nimport { MAINNET_CHAINS, TESTNET_CHAINS } from '../constants.js';\nimport { WORMHOLE_QUERY_PROXY_URLS } from './constants.js';\n\nexport type QueryHubStateNetwork = 'testnet' | 'mainnet';\n\nexport type QueryHubStateOptions = {\n /** Max response age in seconds (default: 60). */\n maxAge?: number;\n network?: QueryHubStateNetwork;\n /** Maximum attempts including the first try (default: 4). */\n maxAttempts?: number;\n};\n\nexport type HubStateResult = {\n nonce: bigint;\n isRegistered: boolean;\n blockTime: number;\n proof: Uint8Array;\n /** Last action hash (Issue #9/#10 - for action-hash binding) */\n lastActionHash?: string;\n};\n\nexport type QueryHubStateErrorCode =\n | 'INVALID_ARGUMENT'\n | 'UNSUPPORTED_NETWORK'\n | 'MISSING_HUB_ADDRESS'\n | 'PROXY_HTTP_ERROR'\n | 'PROXY_RESPONSE_INVALID'\n | 'ATTESTATION_STALE'\n | 'QUERY_RESPONSE_INVALID';\n\nexport class QueryHubStateError extends Error {\n code: QueryHubStateErrorCode;\n cause?: unknown;\n\n constructor(code: QueryHubStateErrorCode, message: string, cause?: unknown) {\n super(message);\n this.name = 'QueryHubStateError';\n this.code = code;\n this.cause = cause;\n }\n}\n\nfunction resolveNetwork(options?: QueryHubStateOptions): QueryHubStateNetwork {\n if (options?.network) return options.network;\n\n const envCandidates = [\n (globalThis as any)?.process?.env?.NEXT_PUBLIC_VERIDEX_NETWORK,\n (globalThis as any)?.process?.env?.VERIDEX_NETWORK,\n (globalThis as any)?.process?.env?.NEXT_PUBLIC_WORMHOLE_NETWORK,\n (globalThis as any)?.process?.env?.WORMHOLE_NETWORK,\n ].filter(Boolean);\n\n const env = (envCandidates[0] as string | undefined)?.toLowerCase();\n if (env === 'mainnet' || env === 'testnet') return env;\n\n // Default to testnet to support Base Sepolia out-of-the-box.\n return 'testnet';\n}\n\nfunction concatBytes(parts: Uint8Array[]): Uint8Array {\n const total = parts.reduce((sum, p) => sum + p.length, 0);\n const out = new Uint8Array(total);\n let offset = 0;\n for (const p of parts) {\n out.set(p, offset);\n offset += p.length;\n }\n return out;\n}\n\nfunction signaturesToProofBytes(signatures: string[]): Uint8Array {\n const chunks: Uint8Array[] = [];\n\n for (const sig of signatures) {\n if (typeof sig !== 'string' || sig.length !== 132 || !/^[0-9a-fA-F]+$/.test(sig)) {\n throw new QueryHubStateError(\n 'PROXY_RESPONSE_INVALID',\n `Invalid guardian signature format (expected 132 hex chars): ${String(sig)}`\n );\n }\n // Avoid Node Buffer-backed Uint8Array (can surface as SharedArrayBuffer in DTS types).\n chunks.push(hexToUint8Array(`0x${sig}`));\n }\n\n return concatBytes(chunks);\n}\n\nfunction decodeQueryBytes(bytes: string): Uint8Array {\n if (typeof bytes !== 'string' || bytes.length === 0) {\n throw new QueryHubStateError('PROXY_RESPONSE_INVALID', 'Missing query response bytes');\n }\n\n // Query Proxy commonly returns a 0x-prefixed hex string.\n if (isValidHexString(bytes)) {\n return hexToUint8Array(bytes);\n }\n\n // Fallback: attempt base64 decoding.\n try {\n if (typeof atob === 'function') {\n const raw = atob(bytes);\n const arr = new Uint8Array(raw.length);\n for (let i = 0; i < raw.length; i++) arr[i] = raw.charCodeAt(i);\n return arr;\n }\n } catch {\n // ignore\n }\n\n try {\n return new Uint8Array(Buffer.from(bytes, 'base64'));\n } catch (cause) {\n throw new QueryHubStateError('PROXY_RESPONSE_INVALID', 'Unrecognized query response bytes encoding', cause);\n }\n}\n\nfunction sleep(ms: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, ms));\n}\n\nasync function withExponentialBackoff<T>(\n fn: () => Promise<T>,\n maxAttempts: number\n): Promise<T> {\n let attempt = 0;\n let lastError: unknown;\n\n while (attempt < maxAttempts) {\n try {\n return await fn();\n } catch (err) {\n lastError = err;\n attempt += 1;\n if (attempt >= maxAttempts) break;\n\n const baseMs = 250;\n const backoffMs = Math.min(5_000, baseMs * 2 ** (attempt - 1));\n const jitterMs = Math.floor(Math.random() * 100);\n await sleep(backoffMs + jitterMs);\n }\n }\n\n throw lastError;\n}\n\nfunction getHubConfig(network: QueryHubStateNetwork): {\n wormholeChainId: number;\n hubAddress: string;\n endpoint: string;\n rpcUrl: string;\n} {\n if (network === 'testnet') {\n const baseSepolia = TESTNET_CHAINS.baseSepolia;\n if (!baseSepolia?.contracts?.hub) {\n throw new QueryHubStateError('MISSING_HUB_ADDRESS', 'Missing Base Sepolia hub address in SDK constants');\n }\n\n return {\n wormholeChainId: baseSepolia.wormholeChainId,\n hubAddress: baseSepolia.contracts.hub,\n endpoint: WORMHOLE_QUERY_PROXY_URLS.testnet,\n rpcUrl: baseSepolia.rpcUrl,\n };\n }\n\n if (network === 'mainnet') {\n const base = MAINNET_CHAINS.base;\n const hubAddress = (base?.contracts as any)?.hub as string | undefined;\n\n if (!hubAddress) {\n throw new QueryHubStateError(\n 'MISSING_HUB_ADDRESS',\n 'Missing mainnet hub address in SDK constants (MAINNET_CHAINS.base.contracts.hub)'\n );\n }\n\n return {\n wormholeChainId: base.wormholeChainId,\n hubAddress,\n endpoint: WORMHOLE_QUERY_PROXY_URLS.mainnet,\n rpcUrl: base.rpcUrl,\n };\n }\n\n throw new QueryHubStateError('UNSUPPORTED_NETWORK', `Unsupported network: ${network}`);\n}\n\nfunction encodeHubCalls(hubAddress: string, userKeyHash: string): { to: string; data: string }[] {\n // Support both the spec name and known on-chain variants.\n const nonceAbiCandidates = [\n 'function getUserNonce(bytes32 userKeyHash) view returns (uint256)',\n 'function userNonces(bytes32 userKeyHash) view returns (uint256)',\n 'function getNonceByHash(bytes32 userKeyHash) view returns (uint256)',\n ];\n\n const registeredAbiCandidates = [\n 'function registeredKeys(bytes32 userKeyHash) view returns (bool)',\n 'function isKeyRegisteredByHash(bytes32 userKeyHash) view returns (bool)',\n ];\n\n // Issue #9/#10: Add getUserLastActionHash for action-hash binding\n const actionHashAbiCandidates = [\n 'function getUserLastActionHash(bytes32 userKeyHash) view returns (bytes32)',\n 'function userLastActionHash(bytes32 userKeyHash) view returns (bytes32)',\n ];\n\n // We encode *all* candidates; the proxy will execute each call, and we decode the first successful one.\n // This makes the client resilient to Hub ABI differences across deployments.\n const iface = new ethers.Interface([\n ...nonceAbiCandidates,\n ...registeredAbiCandidates,\n ...actionHashAbiCandidates,\n ]);\n\n const nonceFnNames = ['getUserNonce', 'userNonces', 'getNonceByHash'] as const;\n const regFnNames = ['registeredKeys', 'isKeyRegisteredByHash'] as const;\n const actionHashFnNames = ['getUserLastActionHash', 'userLastActionHash'] as const;\n\n return [\n ...nonceFnNames.map((fn) => ({\n to: hubAddress,\n data: iface.encodeFunctionData(fn, [userKeyHash]),\n })),\n ...regFnNames.map((fn) => ({\n to: hubAddress,\n data: iface.encodeFunctionData(fn, [userKeyHash]),\n })),\n ...actionHashFnNames.map((fn) => ({\n to: hubAddress,\n data: iface.encodeFunctionData(fn, [userKeyHash]),\n })),\n ];\n}\n\nfunction decodeFirstNonce(results: string[]): bigint {\n const candidates = [\n 'function getUserNonce(bytes32 userKeyHash) view returns (uint256)',\n 'function userNonces(bytes32 userKeyHash) view returns (uint256)',\n 'function getNonceByHash(bytes32 userKeyHash) view returns (uint256)',\n ];\n const iface = new ethers.Interface(candidates);\n const fnNames = ['getUserNonce', 'userNonces', 'getNonceByHash'] as const;\n\n for (let idx = 0; idx < fnNames.length; idx++) {\n const fnName = fnNames[idx];\n try {\n const data = results[idx];\n if (!data || data === '0x') continue;\n const decoded = iface.decodeFunctionResult(fnName, data);\n return decoded[0] as bigint;\n } catch {\n // keep trying\n }\n }\n\n throw new QueryHubStateError('QUERY_RESPONSE_INVALID', 'Unable to decode user nonce from query response');\n}\n\nfunction decodeFirstIsRegistered(results: string[]): boolean {\n const nonceCandidateCount = 3;\n const candidates = [\n 'function registeredKeys(bytes32 userKeyHash) view returns (bool)',\n 'function isKeyRegisteredByHash(bytes32 userKeyHash) view returns (bool)',\n ];\n const iface = new ethers.Interface(candidates);\n const fnNames = ['registeredKeys', 'isKeyRegisteredByHash'] as const;\n\n for (let i = 0; i < fnNames.length; i++) {\n const fnName = fnNames[i];\n try {\n const data = results[nonceCandidateCount + i];\n if (!data || data === '0x') continue;\n const decoded = iface.decodeFunctionResult(fnName, data);\n return Boolean(decoded[0]);\n } catch {\n // keep trying\n }\n }\n\n // If the hub deployment doesn’t support registration, treat as false.\n return false;\n}\n\n/** * Decode last action hash from query results (Issue #9/#10)\n * Returns zero hash if not available (backwards compatibility)\n */\nfunction decodeLastActionHash(results: string[]): string {\n const nonceCandidateCount = 3;\n const registeredCandidateCount = 2;\n const actionHashOffset = nonceCandidateCount + registeredCandidateCount;\n\n const candidates = [\n 'function getUserLastActionHash(bytes32 userKeyHash) view returns (bytes32)',\n 'function userLastActionHash(bytes32 userKeyHash) view returns (bytes32)',\n ];\n const iface = new ethers.Interface(candidates);\n const fnNames = ['getUserLastActionHash', 'userLastActionHash'] as const;\n\n for (let i = 0; i < fnNames.length; i++) {\n const fnName = fnNames[i];\n try {\n const data = results[actionHashOffset + i];\n if (!data || data === '0x') continue;\n const decoded = iface.decodeFunctionResult(fnName, data);\n return decoded[0] as string;\n } catch {\n // keep trying\n }\n }\n\n // Backwards compatibility: return zero hash if not available\n return ethers.ZeroHash;\n}\n\n/** * Fetch Guardian-attested Hub state directly from the Wormhole Query Proxy.\n *\n * Client-side only: this avoids relayer API costs and produces a Guardian-signed proof\n * that can be forwarded to the relayer for on-chain verification/submission.\n */\nexport async function queryHubState(\n userKeyHash: string,\n apiKey: string,\n options?: QueryHubStateOptions\n): Promise<HubStateResult> {\n if (typeof userKeyHash !== 'string' || userKeyHash.length === 0) {\n throw new QueryHubStateError('INVALID_ARGUMENT', 'userKeyHash is required');\n }\n if (!isValidHexString(userKeyHash) || hexToUint8Array(userKeyHash).length !== 32) {\n throw new QueryHubStateError('INVALID_ARGUMENT', 'userKeyHash must be a 32-byte hex string');\n }\n if (typeof apiKey !== 'string' || apiKey.length === 0) {\n throw new QueryHubStateError('INVALID_ARGUMENT', 'apiKey is required');\n }\n\n const network = resolveNetwork(options);\n const maxAgeSeconds = options?.maxAge ?? 60;\n const maxAttempts = options?.maxAttempts ?? 4;\n\n const { wormholeChainId, hubAddress, endpoint, rpcUrl } = getHubConfig(network);\n\n const provider = new ethers.JsonRpcProvider(rpcUrl);\n\n const callData = encodeHubCalls(hubAddress, userKeyHash);\n\n const doFetch = async () => {\n try {\n const latestBlock = await provider.getBlockNumber();\n const blockTag = Math.max(0, latestBlock - 2);\n\n const request = new QueryRequest(Date.now() & 0xffffffff, [\n new PerChainQueryRequest(wormholeChainId, new EthCallQueryRequest(blockTag, callData)),\n ]);\n\n // Wormhole Query Proxy expects raw hex WITHOUT 0x prefix\n const requestHex = Buffer.from(request.serialize()).toString('hex');\n\n const response = await axios.post(\n endpoint,\n { bytes: requestHex },\n {\n headers: {\n 'X-API-Key': apiKey,\n 'Content-Type': 'application/json',\n },\n timeout: 10_000,\n }\n );\n\n const data = response.data as any;\n const signatures = data?.signatures as string[] | undefined;\n const bytes = data?.bytes as string | undefined;\n\n if (!Array.isArray(signatures) || typeof bytes !== 'string') {\n throw new QueryHubStateError('PROXY_RESPONSE_INVALID', 'Query Proxy response missing signatures/bytes');\n }\n\n const proof = signaturesToProofBytes(signatures);\n const queryBytes = decodeQueryBytes(bytes);\n const parsed = QueryResponse.from(queryBytes);\n\n const perChain = parsed.responses.find((r) => r.chainId === wormholeChainId);\n if (!perChain) {\n throw new QueryHubStateError('QUERY_RESPONSE_INVALID', 'Missing per-chain response for hub chain');\n }\n\n // The SDK provides a parser for the chain-specific response.\n const chainResp = EthCallQueryResponse.from(perChain.response.serialize());\n const blockTime = Number(chainResp.blockTime);\n\n const nowSeconds = Math.floor(Date.now() / 1000);\n if (nowSeconds - blockTime > maxAgeSeconds) {\n throw new QueryHubStateError(\n 'ATTESTATION_STALE',\n `Guardian attestation is stale (blockTime=${blockTime}, now=${nowSeconds}, maxAge=${maxAgeSeconds}s)`\n );\n }\n\n const nonce = decodeFirstNonce(chainResp.results);\n const isRegistered = decodeFirstIsRegistered(chainResp.results);\n const lastActionHash = decodeLastActionHash(chainResp.results);\n\n return {\n nonce,\n isRegistered,\n blockTime,\n proof,\n lastActionHash,\n } satisfies HubStateResult;\n } catch (err) {\n if (err instanceof QueryHubStateError) throw err;\n if (axios.isAxiosError(err)) {\n const ax = err as AxiosError;\n const status = ax.response?.status;\n const statusText = ax.response?.statusText;\n const details = typeof ax.response?.data === 'string' ? ax.response?.data : undefined;\n\n throw new QueryHubStateError(\n 'PROXY_HTTP_ERROR',\n `Query Proxy request failed${status ? ` (${status} ${statusText ?? ''})` : ''}${details ? `: ${details}` : ''}`,\n err\n );\n }\n\n throw new QueryHubStateError('PROXY_HTTP_ERROR', 'Query Proxy request failed', err);\n }\n };\n\n return await withExponentialBackoff(doFetch, maxAttempts);\n}\n"],"mappings":"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","names":[]}