@veridex/sdk 1.0.0-beta.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 (82) hide show
  1. package/CHANGELOG.md +73 -0
  2. package/LICENSE +21 -0
  3. package/README.md +212 -0
  4. package/dist/chains/aptos/index.d.mts +140 -0
  5. package/dist/chains/aptos/index.d.ts +140 -0
  6. package/dist/chains/aptos/index.js +563 -0
  7. package/dist/chains/aptos/index.js.map +1 -0
  8. package/dist/chains/aptos/index.mjs +536 -0
  9. package/dist/chains/aptos/index.mjs.map +1 -0
  10. package/dist/chains/evm/index.d.mts +5 -0
  11. package/dist/chains/evm/index.d.ts +5 -0
  12. package/dist/chains/evm/index.js +1233 -0
  13. package/dist/chains/evm/index.js.map +1 -0
  14. package/dist/chains/evm/index.mjs +1205 -0
  15. package/dist/chains/evm/index.mjs.map +1 -0
  16. package/dist/chains/solana/index.d.mts +116 -0
  17. package/dist/chains/solana/index.d.ts +116 -0
  18. package/dist/chains/solana/index.js +513 -0
  19. package/dist/chains/solana/index.js.map +1 -0
  20. package/dist/chains/solana/index.mjs +491 -0
  21. package/dist/chains/solana/index.mjs.map +1 -0
  22. package/dist/chains/starknet/index.d.mts +172 -0
  23. package/dist/chains/starknet/index.d.ts +172 -0
  24. package/dist/chains/starknet/index.js +534 -0
  25. package/dist/chains/starknet/index.js.map +1 -0
  26. package/dist/chains/starknet/index.mjs +507 -0
  27. package/dist/chains/starknet/index.mjs.map +1 -0
  28. package/dist/chains/sui/index.d.mts +182 -0
  29. package/dist/chains/sui/index.d.ts +182 -0
  30. package/dist/chains/sui/index.js +560 -0
  31. package/dist/chains/sui/index.js.map +1 -0
  32. package/dist/chains/sui/index.mjs +533 -0
  33. package/dist/chains/sui/index.mjs.map +1 -0
  34. package/dist/constants.d.mts +150 -0
  35. package/dist/constants.d.ts +150 -0
  36. package/dist/constants.js +430 -0
  37. package/dist/constants.js.map +1 -0
  38. package/dist/constants.mjs +392 -0
  39. package/dist/constants.mjs.map +1 -0
  40. package/dist/index-0NXfbk0z.d.ts +637 -0
  41. package/dist/index-D0dLVjTA.d.mts +637 -0
  42. package/dist/index.d.mts +3101 -0
  43. package/dist/index.d.ts +3101 -0
  44. package/dist/index.js +13186 -0
  45. package/dist/index.js.map +1 -0
  46. package/dist/index.mjs +13011 -0
  47. package/dist/index.mjs.map +1 -0
  48. package/dist/payload.d.mts +125 -0
  49. package/dist/payload.d.ts +125 -0
  50. package/dist/payload.js +315 -0
  51. package/dist/payload.js.map +1 -0
  52. package/dist/payload.mjs +269 -0
  53. package/dist/payload.mjs.map +1 -0
  54. package/dist/queries/index.d.mts +148 -0
  55. package/dist/queries/index.d.ts +148 -0
  56. package/dist/queries/index.js +1533 -0
  57. package/dist/queries/index.js.map +1 -0
  58. package/dist/queries/index.mjs +1508 -0
  59. package/dist/queries/index.mjs.map +1 -0
  60. package/dist/types-ChIsqCiw.d.mts +565 -0
  61. package/dist/types-ChIsqCiw.d.ts +565 -0
  62. package/dist/types-FJL7j6gQ.d.mts +172 -0
  63. package/dist/types-FJL7j6gQ.d.ts +172 -0
  64. package/dist/types.d.mts +407 -0
  65. package/dist/types.d.ts +407 -0
  66. package/dist/types.js +19 -0
  67. package/dist/types.js.map +1 -0
  68. package/dist/types.mjs +1 -0
  69. package/dist/types.mjs.map +1 -0
  70. package/dist/utils.d.mts +81 -0
  71. package/dist/utils.d.ts +81 -0
  72. package/dist/utils.js +430 -0
  73. package/dist/utils.js.map +1 -0
  74. package/dist/utils.mjs +390 -0
  75. package/dist/utils.mjs.map +1 -0
  76. package/dist/wormhole.d.mts +167 -0
  77. package/dist/wormhole.d.ts +167 -0
  78. package/dist/wormhole.js +468 -0
  79. package/dist/wormhole.js.map +1 -0
  80. package/dist/wormhole.mjs +422 -0
  81. package/dist/wormhole.mjs.map +1 -0
  82. package/package.json +151 -0
@@ -0,0 +1,167 @@
1
+ import { ethers } from 'ethers';
2
+ import { VAA, VeridexPayload } from './types.js';
3
+
4
+ /**
5
+ * Veridex Protocol SDK - Wormhole Utilities
6
+ *
7
+ * Functions for fetching VAAs, parsing messages, and interacting with Wormhole
8
+ *
9
+ * This module integrates with the official @wormhole-foundation/sdk patterns for
10
+ * better chain abstraction and reliability, while providing Veridex-specific
11
+ * utilities for payload handling and VAA management.
12
+ */
13
+
14
+ /**
15
+ * Wormhole Consistency Levels
16
+ * @see https://docs.wormhole.com/wormhole/reference/glossary#consistency-level
17
+ */
18
+ declare const CONSISTENCY_LEVELS: {
19
+ /** Finalized - Wait for block finality (most secure) */
20
+ readonly FINALIZED: 200;
21
+ /** Instant - No wait for finality (fastest, less secure) */
22
+ readonly INSTANT: 201;
23
+ /** Safe - Standard finality (deprecated, use FINALIZED) */
24
+ readonly SAFE: 200;
25
+ };
26
+ /**
27
+ * Guardian network configuration
28
+ */
29
+ declare const GUARDIAN_CONFIG: {
30
+ /** Total number of guardians in mainnet */
31
+ readonly MAINNET_GUARDIAN_COUNT: 19;
32
+ /** Required signatures for mainnet quorum (13/19) */
33
+ readonly MAINNET_QUORUM: 13;
34
+ /** Total number of guardians in testnet */
35
+ readonly TESTNET_GUARDIAN_COUNT: 1;
36
+ /** Required signatures for testnet quorum */
37
+ readonly TESTNET_QUORUM: 1;
38
+ };
39
+ interface FetchVAAOptions {
40
+ testnet?: boolean;
41
+ maxRetries?: number;
42
+ retryDelayMs?: number;
43
+ onRetry?: (attempt: number, maxRetries: number) => void;
44
+ }
45
+ interface WaitForSignaturesOptions {
46
+ testnet?: boolean;
47
+ requiredSignatures?: number;
48
+ maxWaitMs?: number;
49
+ checkIntervalMs?: number;
50
+ onProgress?: (currentSignatures: number, required: number) => void;
51
+ }
52
+ /**
53
+ * Fetch a VAA from Wormhole guardians by sequence number
54
+ *
55
+ * @example
56
+ * ```ts
57
+ * const vaa = await fetchVAA(
58
+ * WORMHOLE_CHAIN_IDS.TESTNET.BASE_SEPOLIA,
59
+ * '0x000...hubAddress',
60
+ * 97n,
61
+ * { testnet: true }
62
+ * );
63
+ * ```
64
+ */
65
+ declare function fetchVAA(emitterChain: number, emitterAddress: string, sequence: bigint, options?: FetchVAAOptions): Promise<string>;
66
+ /**
67
+ * Fetch VAA by transaction hash using operations API
68
+ * This is more reliable than the transactions API when sequence numbers don't match
69
+ */
70
+ declare function fetchVAAByTxHash(txHash: string, options?: {
71
+ testnet?: boolean;
72
+ maxRetries?: number;
73
+ retryDelayMs?: number;
74
+ onRetry?: (attempt: number, maxRetries: number) => void;
75
+ }): Promise<string>;
76
+ /**
77
+ * Fetch VAA by transaction hash using transactions API (fallback)
78
+ */
79
+ declare function fetchVAAByTxHashFallback(txHash: string, options?: {
80
+ testnet?: boolean;
81
+ maxRetries?: number;
82
+ retryDelayMs?: number;
83
+ onRetry?: (attempt: number, maxRetries: number) => void;
84
+ }): Promise<string>;
85
+ /**
86
+ * Parse a base64-encoded VAA into its components
87
+ */
88
+ declare function parseVAA(vaaBase64: string): VAA;
89
+ /**
90
+ * Parse raw VAA bytes into its components
91
+ */
92
+ declare function parseVAABytes(vaaBytes: Buffer): VAA;
93
+ /**
94
+ * Parse a Veridex-specific payload from a VAA
95
+ */
96
+ declare function parseVeridexPayload(payloadHex: string): VeridexPayload;
97
+ /**
98
+ * Encode a VAA back to bytes for on-chain submission
99
+ */
100
+ declare function encodeVAAToBytes(vaaBase64: string): string;
101
+ /**
102
+ * Encode VAA to bytes for Solana (returns Uint8Array)
103
+ */
104
+ declare function encodeVAAForSolana(vaaBase64: string): Uint8Array;
105
+ /**
106
+ * Normalize an address to a 32-byte Wormhole emitter address format
107
+ */
108
+ declare function normalizeEmitterAddress(address: string): string;
109
+ /**
110
+ * Convert a 32-byte emitter address back to a 20-byte EVM address
111
+ */
112
+ declare function emitterToEvmAddress(emitterHex: string): string;
113
+ /**
114
+ * Extract the VAA sequence from a transaction receipt
115
+ */
116
+ declare function getSequenceFromTxReceipt(provider: ethers.Provider, txHash: string, wormholeCoreBridge: string): Promise<bigint>;
117
+ /**
118
+ * Wait for a Wormhole message to be signed by guardians
119
+ *
120
+ * @example
121
+ * ```ts
122
+ * const vaa = await waitForGuardianSignatures(
123
+ * WORMHOLE_CHAIN_IDS.TESTNET.BASE_SEPOLIA,
124
+ * hubEmitter,
125
+ * 97n,
126
+ * {
127
+ * testnet: true,
128
+ * onProgress: (current, required) => console.log(`${current}/${required} signatures`)
129
+ * }
130
+ * );
131
+ * ```
132
+ */
133
+ declare function waitForGuardianSignatures(emitterChain: number, emitterAddress: string, sequence: bigint, options?: WaitForSignaturesOptions): Promise<VAA>;
134
+ /**
135
+ * Get the Wormhole Core Bridge contract address for a chain
136
+ */
137
+ declare function getWormholeCoreBridge(wormholeChainId: number, testnet?: boolean): string;
138
+ /**
139
+ * Get the Wormhole Token Bridge contract address for a chain
140
+ */
141
+ declare function getWormholeTokenBridge(wormholeChainId: number, testnet?: boolean): string;
142
+ /**
143
+ * Get the Wormhole Relayer contract address for a chain
144
+ */
145
+ declare function getWormholeRelayer(wormholeChainId: number, testnet?: boolean): string;
146
+ /**
147
+ * Check if a chain supports Wormhole Relayer
148
+ */
149
+ declare function supportsRelayer(wormholeChainId: number, testnet?: boolean): boolean;
150
+ /**
151
+ * Get chain name from Wormhole chain ID
152
+ */
153
+ declare function getChainName(wormholeChainId: number): string;
154
+ /**
155
+ * Validate that a VAA has sufficient signatures for the given network
156
+ */
157
+ declare function hasQuorum(vaa: VAA, testnet?: boolean): boolean;
158
+ /**
159
+ * Validate VAA emitter matches expected source
160
+ */
161
+ declare function validateEmitter(vaa: VAA, expectedChain: number, expectedAddress: string): boolean;
162
+ /**
163
+ * Convert an EVM address to bytes32 format (for Wormhole)
164
+ */
165
+ declare function evmAddressToBytes32(address: string): string;
166
+
167
+ export { CONSISTENCY_LEVELS, type FetchVAAOptions, GUARDIAN_CONFIG, type WaitForSignaturesOptions, emitterToEvmAddress, encodeVAAForSolana, encodeVAAToBytes, evmAddressToBytes32, fetchVAA, fetchVAAByTxHash, fetchVAAByTxHashFallback, getChainName, getSequenceFromTxReceipt, getWormholeCoreBridge, getWormholeRelayer, getWormholeTokenBridge, hasQuorum, normalizeEmitterAddress, parseVAA, parseVAABytes, parseVeridexPayload, supportsRelayer, validateEmitter, waitForGuardianSignatures };
@@ -0,0 +1,468 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+
20
+ // src/wormhole.ts
21
+ var wormhole_exports = {};
22
+ __export(wormhole_exports, {
23
+ CONSISTENCY_LEVELS: () => CONSISTENCY_LEVELS,
24
+ GUARDIAN_CONFIG: () => GUARDIAN_CONFIG,
25
+ emitterToEvmAddress: () => emitterToEvmAddress,
26
+ encodeVAAForSolana: () => encodeVAAForSolana,
27
+ encodeVAAToBytes: () => encodeVAAToBytes,
28
+ evmAddressToBytes32: () => evmAddressToBytes32,
29
+ fetchVAA: () => fetchVAA,
30
+ fetchVAAByTxHash: () => fetchVAAByTxHash,
31
+ fetchVAAByTxHashFallback: () => fetchVAAByTxHashFallback,
32
+ getChainName: () => getChainName,
33
+ getSequenceFromTxReceipt: () => getSequenceFromTxReceipt,
34
+ getWormholeCoreBridge: () => getWormholeCoreBridge,
35
+ getWormholeRelayer: () => getWormholeRelayer,
36
+ getWormholeTokenBridge: () => getWormholeTokenBridge,
37
+ hasQuorum: () => hasQuorum,
38
+ normalizeEmitterAddress: () => normalizeEmitterAddress,
39
+ parseVAA: () => parseVAA,
40
+ parseVAABytes: () => parseVAABytes,
41
+ parseVeridexPayload: () => parseVeridexPayload,
42
+ supportsRelayer: () => supportsRelayer,
43
+ validateEmitter: () => validateEmitter,
44
+ waitForGuardianSignatures: () => waitForGuardianSignatures
45
+ });
46
+ module.exports = __toCommonJS(wormhole_exports);
47
+ var import_ethers = require("ethers");
48
+
49
+ // src/constants.ts
50
+ var WORMHOLE_API = {
51
+ MAINNET: "https://api.wormholescan.io",
52
+ TESTNET: "https://api.testnet.wormholescan.io",
53
+ GUARDIAN_RPC_MAINNET: "https://wormhole-v2-mainnet-api.certus.one",
54
+ GUARDIAN_RPC_TESTNET: "https://wormhole-v2-testnet-api.certus.one"
55
+ };
56
+
57
+ // src/wormhole.ts
58
+ var CONSISTENCY_LEVELS = {
59
+ /** Finalized - Wait for block finality (most secure) */
60
+ FINALIZED: 200,
61
+ /** Instant - No wait for finality (fastest, less secure) */
62
+ INSTANT: 201,
63
+ /** Safe - Standard finality (deprecated, use FINALIZED) */
64
+ SAFE: 200
65
+ };
66
+ var GUARDIAN_CONFIG = {
67
+ /** Total number of guardians in mainnet */
68
+ MAINNET_GUARDIAN_COUNT: 19,
69
+ /** Required signatures for mainnet quorum (13/19) */
70
+ MAINNET_QUORUM: 13,
71
+ /** Total number of guardians in testnet */
72
+ TESTNET_GUARDIAN_COUNT: 1,
73
+ /** Required signatures for testnet quorum */
74
+ TESTNET_QUORUM: 1
75
+ };
76
+ async function fetchVAA(emitterChain, emitterAddress, sequence, options = {}) {
77
+ const {
78
+ testnet = true,
79
+ maxRetries = 30,
80
+ retryDelayMs = 2e3,
81
+ onRetry
82
+ } = options;
83
+ const apiBase = testnet ? WORMHOLE_API.TESTNET : WORMHOLE_API.MAINNET;
84
+ const normalizedEmitter = normalizeEmitterAddress(emitterAddress);
85
+ const url = `${apiBase}/api/v1/vaas/${emitterChain}/${normalizedEmitter}/${sequence.toString()}`;
86
+ for (let i = 0; i < maxRetries; i++) {
87
+ try {
88
+ const response = await fetch(url);
89
+ if (response.ok) {
90
+ const data = await response.json();
91
+ if (data.data?.vaa) {
92
+ return data.data.vaa;
93
+ }
94
+ }
95
+ if (i < maxRetries - 1) {
96
+ onRetry?.(i + 1, maxRetries);
97
+ await sleep(retryDelayMs);
98
+ }
99
+ } catch {
100
+ if (i < maxRetries - 1) {
101
+ onRetry?.(i + 1, maxRetries);
102
+ await sleep(retryDelayMs);
103
+ }
104
+ }
105
+ }
106
+ throw new Error(`Failed to fetch VAA after ${maxRetries} attempts`);
107
+ }
108
+ async function fetchVAAByTxHash(txHash, options = {}) {
109
+ const {
110
+ testnet = true,
111
+ maxRetries = 60,
112
+ retryDelayMs = 3e3,
113
+ onRetry
114
+ } = options;
115
+ const apiBase = testnet ? WORMHOLE_API.TESTNET : WORMHOLE_API.MAINNET;
116
+ const cleanTxHash = txHash.replace(/^0x/, "");
117
+ const url = `${apiBase}/api/v1/operations?txHash=${cleanTxHash}`;
118
+ for (let i = 0; i < maxRetries; i++) {
119
+ try {
120
+ const response = await fetch(url);
121
+ if (response.ok) {
122
+ const data = await response.json();
123
+ if (data.operations && data.operations.length > 0) {
124
+ const operation = data.operations[0];
125
+ if (operation.vaa?.raw) {
126
+ return operation.vaa.raw;
127
+ }
128
+ }
129
+ }
130
+ if (i < maxRetries - 1) {
131
+ onRetry?.(i + 1, maxRetries);
132
+ await sleep(retryDelayMs);
133
+ }
134
+ } catch {
135
+ if (i < maxRetries - 1) {
136
+ onRetry?.(i + 1, maxRetries);
137
+ await sleep(retryDelayMs);
138
+ }
139
+ }
140
+ }
141
+ throw new Error(`Failed to fetch VAA after ${maxRetries} attempts`);
142
+ }
143
+ async function fetchVAAByTxHashFallback(txHash, options = {}) {
144
+ const {
145
+ testnet = true,
146
+ maxRetries = 30,
147
+ retryDelayMs = 2e3,
148
+ onRetry
149
+ } = options;
150
+ const apiBase = testnet ? WORMHOLE_API.TESTNET : WORMHOLE_API.MAINNET;
151
+ const url = `${apiBase}/api/v1/transactions/${txHash}`;
152
+ for (let i = 0; i < maxRetries; i++) {
153
+ try {
154
+ const response = await fetch(url);
155
+ if (response.ok) {
156
+ const data = await response.json();
157
+ if (data.data?.globalTx?.originTx?.vaaId) {
158
+ const vaaId = data.data.globalTx.originTx.vaaId;
159
+ const vaaUrl = `${apiBase}/api/v1/vaas/${vaaId}`;
160
+ const vaaResponse = await fetch(vaaUrl);
161
+ if (vaaResponse.ok) {
162
+ const vaaData = await vaaResponse.json();
163
+ if (vaaData.data?.vaa) {
164
+ return vaaData.data.vaa;
165
+ }
166
+ }
167
+ }
168
+ }
169
+ if (i < maxRetries - 1) {
170
+ onRetry?.(i + 1, maxRetries);
171
+ await sleep(retryDelayMs);
172
+ }
173
+ } catch {
174
+ if (i < maxRetries - 1) {
175
+ onRetry?.(i + 1, maxRetries);
176
+ await sleep(retryDelayMs);
177
+ }
178
+ }
179
+ }
180
+ throw new Error(`Failed to fetch VAA after ${maxRetries} attempts`);
181
+ }
182
+ function parseVAA(vaaBase64) {
183
+ const vaaBytes = Buffer.from(vaaBase64, "base64");
184
+ return parseVAABytes(vaaBytes);
185
+ }
186
+ function parseVAABytes(vaaBytes) {
187
+ let offset = 0;
188
+ const version = vaaBytes.readUInt8(offset);
189
+ offset += 1;
190
+ const guardianSetIndex = vaaBytes.readUInt32BE(offset);
191
+ offset += 4;
192
+ const numSignatures = vaaBytes.readUInt8(offset);
193
+ offset += 1;
194
+ const signatures = [];
195
+ for (let i = 0; i < numSignatures; i++) {
196
+ const guardianIndex = vaaBytes.readUInt8(offset);
197
+ offset += 1;
198
+ const signature = "0x" + vaaBytes.subarray(offset, offset + 65).toString("hex");
199
+ offset += 65;
200
+ signatures.push({ guardianIndex, signature });
201
+ }
202
+ const bodyOffset = offset;
203
+ const timestamp = vaaBytes.readUInt32BE(offset);
204
+ offset += 4;
205
+ const nonce = vaaBytes.readUInt32BE(offset);
206
+ offset += 4;
207
+ const emitterChain = vaaBytes.readUInt16BE(offset);
208
+ offset += 2;
209
+ const emitterAddress = "0x" + vaaBytes.subarray(offset, offset + 32).toString("hex");
210
+ offset += 32;
211
+ const sequence = vaaBytes.readBigUInt64BE(offset);
212
+ offset += 8;
213
+ const consistencyLevel = vaaBytes.readUInt8(offset);
214
+ offset += 1;
215
+ const payload = "0x" + vaaBytes.subarray(offset).toString("hex");
216
+ const body = vaaBytes.subarray(bodyOffset);
217
+ const hash = import_ethers.ethers.keccak256(import_ethers.ethers.keccak256(body));
218
+ return {
219
+ version,
220
+ guardianSetIndex,
221
+ signatures,
222
+ timestamp,
223
+ nonce,
224
+ emitterChain,
225
+ emitterAddress,
226
+ sequence,
227
+ consistencyLevel,
228
+ payload,
229
+ hash
230
+ };
231
+ }
232
+ function parseVeridexPayload(payloadHex) {
233
+ const payload = Buffer.from(payloadHex.replace("0x", ""), "hex");
234
+ let offset = 0;
235
+ const version = payload.readUInt8(offset);
236
+ offset += 1;
237
+ const userKeyHash = "0x" + payload.subarray(offset, offset + 32).toString("hex");
238
+ offset += 32;
239
+ const targetChain = payload.readUInt16BE(offset);
240
+ offset += 2;
241
+ const nonce = BigInt("0x" + payload.subarray(offset, offset + 32).toString("hex"));
242
+ offset += 32;
243
+ const publicKeyX = BigInt("0x" + payload.subarray(offset, offset + 32).toString("hex"));
244
+ offset += 32;
245
+ const publicKeyY = BigInt("0x" + payload.subarray(offset, offset + 32).toString("hex"));
246
+ offset += 32;
247
+ const actionPayload = "0x" + payload.subarray(offset).toString("hex");
248
+ return {
249
+ version,
250
+ userKeyHash,
251
+ targetChain,
252
+ nonce,
253
+ publicKeyX,
254
+ publicKeyY,
255
+ actionPayload
256
+ };
257
+ }
258
+ function encodeVAAToBytes(vaaBase64) {
259
+ const vaaBytes = Buffer.from(vaaBase64, "base64");
260
+ return "0x" + vaaBytes.toString("hex");
261
+ }
262
+ function encodeVAAForSolana(vaaBase64) {
263
+ return new Uint8Array(Buffer.from(vaaBase64, "base64"));
264
+ }
265
+ function normalizeEmitterAddress(address) {
266
+ let hex = address.replace("0x", "");
267
+ while (hex.length < 64) {
268
+ hex = "0" + hex;
269
+ }
270
+ return hex;
271
+ }
272
+ function emitterToEvmAddress(emitterHex) {
273
+ const hex = emitterHex.replace("0x", "");
274
+ return "0x" + hex.slice(-40);
275
+ }
276
+ async function getSequenceFromTxReceipt(provider, txHash, wormholeCoreBridge) {
277
+ const receipt = await provider.getTransactionReceipt(txHash);
278
+ if (!receipt) {
279
+ throw new Error(`Transaction receipt not found: ${txHash}`);
280
+ }
281
+ const LOG_MESSAGE_PUBLISHED_TOPIC = import_ethers.ethers.id(
282
+ "LogMessagePublished(address,uint64,uint32,bytes,uint8)"
283
+ );
284
+ for (const log of receipt.logs) {
285
+ if (log.address.toLowerCase() === wormholeCoreBridge.toLowerCase()) {
286
+ if (log.topics[0] === LOG_MESSAGE_PUBLISHED_TOPIC && log.topics[1]) {
287
+ const sequence = BigInt(log.topics[1]);
288
+ return sequence;
289
+ }
290
+ }
291
+ }
292
+ throw new Error("LogMessagePublished event not found in transaction");
293
+ }
294
+ async function waitForGuardianSignatures(emitterChain, emitterAddress, sequence, options = {}) {
295
+ const {
296
+ testnet = true,
297
+ requiredSignatures = testnet ? GUARDIAN_CONFIG.TESTNET_QUORUM : GUARDIAN_CONFIG.MAINNET_QUORUM,
298
+ maxWaitMs = 12e4,
299
+ checkIntervalMs = 5e3,
300
+ onProgress
301
+ } = options;
302
+ const startTime = Date.now();
303
+ while (Date.now() - startTime < maxWaitMs) {
304
+ try {
305
+ const vaaBase64 = await fetchVAA(emitterChain, emitterAddress, sequence, {
306
+ testnet,
307
+ maxRetries: 1,
308
+ retryDelayMs: 0
309
+ });
310
+ const vaa = parseVAA(vaaBase64);
311
+ onProgress?.(vaa.signatures.length, requiredSignatures);
312
+ if (vaa.signatures.length >= requiredSignatures) {
313
+ return vaa;
314
+ }
315
+ } catch {
316
+ }
317
+ await sleep(checkIntervalMs);
318
+ }
319
+ throw new Error(`Timeout waiting for guardian signatures after ${maxWaitMs / 1e3}s`);
320
+ }
321
+ function getWormholeCoreBridge(wormholeChainId, testnet = true) {
322
+ const testnetBridges = {
323
+ 10004: "0x79A1027a6A159502049F10906D333EC57E95F083",
324
+ // Base Sepolia
325
+ 10005: "0x31377888146f3253211EFEf5c676D41ECe7D58Fe",
326
+ // Optimism Sepolia
327
+ 10003: "0x6b9C8671cdDC8dEab9c719bB87cBd3e782bA6a35",
328
+ // Arbitrum Sepolia
329
+ 1: "3u8hJUVTA4jH1wYAyUur7FFZVQ8H635K3tSHHF4ssjQ5",
330
+ // Solana Devnet
331
+ 22: "0x5bc11445584a763c1fa7ed39081f1b920954da14e04b32440cba863d03e19625",
332
+ // Aptos Testnet
333
+ 21: "0x31358d198147da50db32eda2562951d53973a0c0ad5ed738e9b17d88b213d790"
334
+ // Sui Testnet
335
+ };
336
+ const mainnetBridges = {
337
+ 2: "0x98f3c9e6E3fAce36bAAd05FE09d375Ef1464288B",
338
+ // Ethereum
339
+ 30: "0xbebdb6C8ddC678FfA9f8748f85C815C556Dd8ac6",
340
+ // Base
341
+ 24: "0xEe91C335eab126dF5fDB3797EA9d6aD93aeC9722",
342
+ // Optimism
343
+ 23: "0xa5f208e072434bC67592E4C49C1B991BA79BCA46",
344
+ // Arbitrum
345
+ 5: "0x7A4B5a56256163F07b2C80A7cA55aBE66c4ec4d7",
346
+ // Polygon
347
+ 1: "worm2ZoG2kUd4vFXhvjh93UUH596ayRfgQ2MgjNMTth",
348
+ // Solana
349
+ 22: "0x5bc11445584a763c1fa7ed39081f1b920954da14e04b32440cba863d03e19625",
350
+ // Aptos
351
+ 21: "0xaeab97f96cf9877fee2883315d459552b2b921edc16d7ceac6eab944dd88919c"
352
+ // Sui
353
+ };
354
+ const bridges = testnet ? testnetBridges : mainnetBridges;
355
+ return bridges[wormholeChainId] ?? "";
356
+ }
357
+ function getWormholeTokenBridge(wormholeChainId, testnet = true) {
358
+ const testnetBridges = {
359
+ 10004: "0x86F55A04690fd7815A3D802bD587e83eA888B239",
360
+ // Base Sepolia
361
+ 10005: "0x99737Ec4B815d816c49A385943baf0380e75c0Ac",
362
+ // Optimism Sepolia
363
+ 10003: "0xC7A204bDBFe983FCD8d8E61D02b475D4073fF97e"
364
+ // Arbitrum Sepolia
365
+ };
366
+ const mainnetBridges = {
367
+ 2: "0x3ee18B2214AFF97000D974cf647E7C347E8fa585",
368
+ // Ethereum
369
+ 30: "0x8d2de8d2f73F1F4cAB472AC9A881C9b123C79627",
370
+ // Base
371
+ 24: "0x1D68124e65faFC907325e3EDbF8c4d84499DAa8b",
372
+ // Optimism
373
+ 23: "0x0b2402144Bb366A632D14B83F244D2e0e21bD39c",
374
+ // Arbitrum
375
+ 5: "0x5a58505a96D1dbf8dF91cB21B54419FC36e93fdE"
376
+ // Polygon
377
+ };
378
+ const bridges = testnet ? testnetBridges : mainnetBridges;
379
+ return bridges[wormholeChainId] ?? "";
380
+ }
381
+ function getWormholeRelayer(wormholeChainId, testnet = true) {
382
+ const testnetRelayers = {
383
+ 10004: "0x93BAD53DDfB6132b0aC8E37f6029163E63372cEE",
384
+ // Base Sepolia
385
+ 10005: "0x93BAD53DDfB6132b0aC8E37f6029163E63372cEE",
386
+ // Optimism Sepolia
387
+ 10003: "0x7B1bD7a6b4E61c2a123AC6BC2cbfC614437D0470"
388
+ // Arbitrum Sepolia
389
+ };
390
+ const mainnetRelayers = {
391
+ 2: "0x27428DD2d3DD32A4D7f7C497eAaa23130d894911",
392
+ // Ethereum
393
+ 30: "0x706F82e9bb5b0813501714Ab5974216704980e31",
394
+ // Base
395
+ 24: "0x27428DD2d3DD32A4D7f7C497eAaa23130d894911",
396
+ // Optimism
397
+ 23: "0x27428DD2d3DD32A4D7f7C497eAaa23130d894911",
398
+ // Arbitrum
399
+ 5: "0x27428DD2d3DD32A4D7f7C497eAaa23130d894911"
400
+ // Polygon
401
+ };
402
+ const relayers = testnet ? testnetRelayers : mainnetRelayers;
403
+ return relayers[wormholeChainId] ?? "";
404
+ }
405
+ function supportsRelayer(wormholeChainId, testnet = true) {
406
+ return getWormholeRelayer(wormholeChainId, testnet) !== "";
407
+ }
408
+ function getChainName(wormholeChainId) {
409
+ const names = {
410
+ 1: "Solana",
411
+ 2: "Ethereum",
412
+ 4: "BSC",
413
+ 5: "Polygon",
414
+ 6: "Avalanche",
415
+ 10: "Fantom",
416
+ 21: "Sui",
417
+ 22: "Aptos",
418
+ 23: "Arbitrum",
419
+ 24: "Optimism",
420
+ 30: "Base",
421
+ 10002: "Sepolia",
422
+ 10003: "Arbitrum Sepolia",
423
+ 10004: "Base Sepolia",
424
+ 10005: "Optimism Sepolia"
425
+ };
426
+ return names[wormholeChainId] ?? `Chain ${wormholeChainId}`;
427
+ }
428
+ function hasQuorum(vaa, testnet = true) {
429
+ const required = testnet ? GUARDIAN_CONFIG.TESTNET_QUORUM : GUARDIAN_CONFIG.MAINNET_QUORUM;
430
+ return vaa.signatures.length >= required;
431
+ }
432
+ function validateEmitter(vaa, expectedChain, expectedAddress) {
433
+ const normalizedExpected = "0x" + normalizeEmitterAddress(expectedAddress);
434
+ return vaa.emitterChain === expectedChain && vaa.emitterAddress.toLowerCase() === normalizedExpected.toLowerCase();
435
+ }
436
+ function evmAddressToBytes32(address) {
437
+ const hex = address.replace("0x", "").toLowerCase();
438
+ return "0x" + hex.padStart(64, "0");
439
+ }
440
+ function sleep(ms) {
441
+ return new Promise((resolve) => setTimeout(resolve, ms));
442
+ }
443
+ // Annotate the CommonJS export names for ESM import in node:
444
+ 0 && (module.exports = {
445
+ CONSISTENCY_LEVELS,
446
+ GUARDIAN_CONFIG,
447
+ emitterToEvmAddress,
448
+ encodeVAAForSolana,
449
+ encodeVAAToBytes,
450
+ evmAddressToBytes32,
451
+ fetchVAA,
452
+ fetchVAAByTxHash,
453
+ fetchVAAByTxHashFallback,
454
+ getChainName,
455
+ getSequenceFromTxReceipt,
456
+ getWormholeCoreBridge,
457
+ getWormholeRelayer,
458
+ getWormholeTokenBridge,
459
+ hasQuorum,
460
+ normalizeEmitterAddress,
461
+ parseVAA,
462
+ parseVAABytes,
463
+ parseVeridexPayload,
464
+ supportsRelayer,
465
+ validateEmitter,
466
+ waitForGuardianSignatures
467
+ });
468
+ //# sourceMappingURL=wormhole.js.map