@n1xyz/wallet-widget 0.0.35-alpha.43 → 0.0.35-alpha.45

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.
@@ -46,7 +46,6 @@ export declare const prepareBurnTx: (withdrawalId: string, params: {
46
46
  destinationAddress: string;
47
47
  }) => Promise<{
48
48
  tx: string;
49
- canonicalParams?: any;
50
49
  blockhash: string;
51
50
  lastValidBlockHeight: number;
52
51
  }>;
@@ -65,7 +64,6 @@ export declare const prepareClaimTx: (depositId: string, params: {
65
64
  lookupTableAddress?: string;
66
65
  }) => Promise<{
67
66
  tx: string;
68
- canonicalParams?: any;
69
67
  blockhash: string;
70
68
  lastValidBlockHeight: number;
71
69
  }>;
@@ -1 +1 @@
1
- {"version":3,"file":"client.js","sourceRoot":"","sources":["../../../../src/features/onboarding-flow/bridge-assist/client.ts"],"names":[],"mappings":"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","sourcesContent":["import { BridgeAssistError } from './types';\nimport { getBridgeAssistConfig } from './config';\nimport { logger } from '../../../utils/logger';\nimport { createDepositError } from '../../../utils/errors';\nimport type { PendingDepositStage } from '../utils/deposit/storage';\n\nexport interface BridgeAssistStatus {\n stage: PendingDepositStage;\n tx?: string | null;\n reason?: string | null;\n bridgeTx?: string | null;\n solanaTx?: string | null;\n mintTx?: string | null;\n attestationId?: string | null;\n depositId?: string | null;\n}\n\nconst mapStage = (stage: string | null | undefined): PendingDepositStage => {\n const s = (stage ?? '').toLowerCase();\n if (s === 'failed' || s === 'error') return 'failed';\n if (s === 'confirmed' || s === 'complete' || s === 'completed') return 'solana_confirmed';\n if (s === 'submitted' || s === 'processing' || s === 'pending') return 'solana_submitted';\n // Fallback to initiated if unknown\n return 'initiated';\n};\n\nconst handleResponse = async (response: Response): Promise<any> => {\n if (!response.ok) {\n let errorMessage = response.statusText;\n let retryAfter: number | undefined;\n\n const retryHeader = response.headers.get('Retry-After');\n if (retryHeader) {\n retryAfter = parseInt(retryHeader, 10);\n }\n\n try {\n const errorBody = await response.json();\n if (errorBody.message) {\n errorMessage = errorBody.message;\n } else if (errorBody.error) {\n errorMessage = errorBody.error;\n } else if (Array.isArray(errorBody.errors) && errorBody.errors.length) {\n errorMessage = errorBody.errors.join(', ');\n }\n } catch {\n // ignore json parse error\n }\n throw new BridgeAssistError(errorMessage, response.status, retryAfter);\n }\n return response.json();\n};\n\nexport const createBridgeDeposit = async (\n params: {\n wallet: string;\n chain: string;\n solanaAddress: string;\n amount: string;\n bridgeTx: string;\n depositId?: string;\n attestationId?: string | null;\n }\n): Promise<BridgeAssistStatus | null> => {\n const config = getBridgeAssistConfig();\n if (!config) return null;\n try {\n const response = await fetch(`${config.baseUrl}/deposits`, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n },\n body: JSON.stringify(params)\n });\n const body = await handleResponse(response);\n const stage = mapStage(body?.stage);\n return {\n stage,\n tx: body?.tx ?? body?.solanaTx ?? null,\n bridgeTx: body?.bridgeTx ?? params.bridgeTx ?? null,\n solanaTx: body?.solanaTx ?? body?.tx ?? null,\n attestationId: body?.attestationId ?? params.attestationId ?? null,\n depositId: body?.depositId ?? params.depositId ?? null,\n reason: body?.reason ?? null,\n };\n } catch (error) {\n logger.logError(createDepositError('BRIDGE_FAILED', 'Failed to create bridge deposit', {\n cause: error instanceof Error ? error : undefined,\n }));\n throw error;\n }\n}\n\nexport const fetchBridgeStatus = async (depositId: string): Promise<BridgeAssistStatus | null> => {\n const config = getBridgeAssistConfig();\n if (!config) return null;\n if (!depositId) return null;\n try {\n const response = await fetch(`${config.baseUrl}/deposits/${depositId}`, {\n method: 'GET',\n });\n if (response.status === 404) {\n return null;\n }\n const body = await handleResponse(response);\n const stage = mapStage(body?.stage);\n return {\n stage,\n tx: body?.solanaTx ?? body?.tx ?? null,\n bridgeTx: body?.bridgeTx ?? null,\n solanaTx: body?.solanaTx ?? null,\n mintTx: body?.mintTx ?? null,\n attestationId: body?.attestationId ?? null,\n depositId: body?.depositId ?? depositId,\n reason: body?.reason ?? null,\n };\n } catch (error) {\n logger.logError(createDepositError('BRIDGE_FAILED', 'Failed to fetch bridge status', {\n cause: error instanceof Error ? error : undefined,\n context: { depositId },\n }));\n throw error;\n }\n};\n\nexport const submitBridgeClaim = async (\n depositId: string,\n params: {\n solanaTx?: string;\n message?: string;\n attestation?: string;\n sourceChain?: string;\n destinationAddress?: string;\n blockhash?: string;\n lastValidBlockHeight?: number;\n lookupTableAddress?: string;\n userSignature?: string;\n txHash?: string;\n }\n): Promise<{\n tx?: string;\n requiresUserSignature?: boolean;\n stage?: string;\n blockhash?: string;\n lastValidBlockHeight?: number;\n lookupTableAddress?: string;\n signedTx?: string;\n} | null> => {\n const config = getBridgeAssistConfig();\n if (!config) return null;\n\n if (!depositId) throw new Error('Missing depositId for submitBridgeClaim');\n if (!params.message) throw new Error('Missing message for submitBridgeClaim');\n if (!params.attestation) throw new Error('Missing attestation for submitBridgeClaim');\n if (!params.sourceChain) throw new Error('Missing sourceChain for submitBridgeClaim');\n if (!params.destinationAddress) throw new Error('Missing destinationAddress for submitBridgeClaim');\n if (!params.userSignature) throw new Error('Missing userSignature for submitBridgeClaim');\n if (!params.txHash) throw new Error('Missing txHash (hash of signed tx) for submitBridgeClaim');\n\n try {\n // Single-request flow: always send full payload\n const payload = params;\n const url = `${config.baseUrl}/deposits/${depositId}/claim`;\n\n const response = await fetch(url, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n },\n body: JSON.stringify(payload)\n });\n return handleResponse(response);\n } catch (error) {\n logger.logError(createDepositError('CLAIM_FAILED', 'Failed to submit bridge claim', {\n cause: error instanceof Error ? error : undefined,\n context: { depositId },\n }));\n throw error;\n }\n}\n\nexport const prepareBurnTx = async (\n withdrawalId: string,\n params: {\n userAddress: string;\n amount: string;\n destinationChain: string;\n destinationAddress: string;\n }\n): Promise<{ tx: string; canonicalParams?: any; blockhash: string; lastValidBlockHeight: number }> => {\n const config = getBridgeAssistConfig();\n if (!config) throw new BridgeAssistError('Bridge Assist not configured');\n if (!withdrawalId) throw new Error('Missing withdrawalId for prepareBurnTx');\n\n try {\n const response = await fetch(`${config.baseUrl}/withdrawals/${withdrawalId}/prepare-burn`, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n },\n body: JSON.stringify(params),\n });\n return handleResponse(response);\n } catch (error) {\n logger.logError(createDepositError('BRIDGE_FAILED', 'Failed to prepare burn transaction', {\n cause: error instanceof Error ? error : undefined,\n context: { withdrawalId },\n }));\n throw error;\n }\n};\n\nexport const submitBurnTx = async (\n withdrawalId: string,\n params: {\n userSignature: string; // base64\n txHash: string; // hex\n }\n): Promise<{ burnTx: string; explorerUrl?: string }> => {\n const config = getBridgeAssistConfig();\n if (!config) throw new BridgeAssistError('Bridge Assist not configured');\n if (!withdrawalId) throw new Error('Missing withdrawalId for submitBurnTx');\n\n try {\n const response = await fetch(`${config.baseUrl}/withdrawals/${withdrawalId}/submit-burn`, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n },\n body: JSON.stringify(params),\n });\n return handleResponse(response);\n } catch (error) {\n logger.logError(createDepositError('BRIDGE_FAILED', 'Failed to submit burn transaction', {\n cause: error instanceof Error ? error : undefined,\n context: { withdrawalId },\n }));\n throw error;\n }\n};\n\nexport const prepareClaimTx = async (\n depositId: string,\n params: {\n message: string;\n attestation: string;\n sourceChain: string;\n destinationAddress: string;\n lookupTableAddress?: string;\n }\n): Promise<{ tx: string; canonicalParams?: any; blockhash: string; lastValidBlockHeight: number }> => {\n const config = getBridgeAssistConfig();\n if (!config) throw new BridgeAssistError('Bridge Assist not configured');\n if (!depositId) throw new Error('Missing depositId for prepareClaimTx');\n\n try {\n const response = await fetch(`${config.baseUrl}/deposits/${depositId}/prepare-claim`, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n },\n body: JSON.stringify(params),\n });\n return handleResponse(response);\n } catch (error) {\n logger.logError(createDepositError('CLAIM_FAILED', 'Failed to prepare claim transaction', {\n cause: error instanceof Error ? error : undefined,\n context: { depositId },\n }));\n throw error;\n }\n};\n\nexport const submitClaimTx = async (\n depositId: string,\n params: {\n userSignature: string;\n txHash: string;\n }\n): Promise<{ tx: string; stage?: string }> => {\n const config = getBridgeAssistConfig();\n if (!config) throw new BridgeAssistError('Bridge Assist not configured');\n if (!depositId) throw new Error('Missing depositId for submitClaimTx');\n\n try {\n const response = await fetch(`${config.baseUrl}/deposits/${depositId}/submit-claim`, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n },\n body: JSON.stringify(params),\n });\n return handleResponse(response);\n } catch (error) {\n logger.logError(createDepositError('CLAIM_FAILED', 'Failed to submit claim transaction', {\n cause: error instanceof Error ? error : undefined,\n context: { depositId },\n }));\n throw error;\n }\n};\n\nexport const reattestDeposit = async (depositId: string): Promise<boolean> => {\n const config = getBridgeAssistConfig();\n if (!config) return false;\n try {\n const response = await fetch(`${config.baseUrl}/deposits/${depositId}/reattest`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({ depositId }),\n });\n return response.ok;\n } catch {\n return false;\n }\n};\n\nexport const fetchServerFeePayer = async (): Promise<string | null> => {\n const config = getBridgeAssistConfig();\n if (!config) return null;\n try {\n const response = await fetch(`${config.baseUrl}/health`, {\n method: 'GET',\n });\n const data = await handleResponse(response);\n return data.feePayer || null;\n } catch (error) {\n logger.logError(createDepositError('BRIDGE_FAILED', 'Failed to fetch server fee payer', {\n cause: error instanceof Error ? error : undefined,\n }));\n // Surface a clear, typed error for callers so UI can show \"server not available\" and retry.\n // Network/CORS failures typically land here with no HTTP status.\n throw new BridgeAssistError('Bridge Assist server is not available', undefined);\n }\n}\n\n"]}
1
+ {"version":3,"file":"client.js","sourceRoot":"","sources":["../../../../src/features/onboarding-flow/bridge-assist/client.ts"],"names":[],"mappings":"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","sourcesContent":["import { BridgeAssistError } from './types';\nimport { getBridgeAssistConfig } from './config';\nimport { logger } from '../../../utils/logger';\nimport { createDepositError } from '../../../utils/errors';\nimport type { PendingDepositStage } from '../utils/deposit/storage';\n\nexport interface BridgeAssistStatus {\n stage: PendingDepositStage;\n tx?: string | null;\n reason?: string | null;\n bridgeTx?: string | null;\n solanaTx?: string | null;\n mintTx?: string | null;\n attestationId?: string | null;\n depositId?: string | null;\n}\n\nconst mapStage = (stage: string | null | undefined): PendingDepositStage => {\n const s = (stage ?? '').toLowerCase();\n if (s === 'failed' || s === 'error') return 'failed';\n if (s === 'confirmed' || s === 'complete' || s === 'completed') return 'solana_confirmed';\n if (s === 'submitted' || s === 'processing' || s === 'pending') return 'solana_submitted';\n // Fallback to initiated if unknown\n return 'initiated';\n};\n\nconst handleResponse = async (response: Response): Promise<any> => {\n if (!response.ok) {\n let errorMessage = response.statusText;\n let retryAfter: number | undefined;\n\n const retryHeader = response.headers.get('Retry-After');\n if (retryHeader) {\n retryAfter = parseInt(retryHeader, 10);\n }\n\n try {\n const errorBody = await response.json();\n if (errorBody.message) {\n errorMessage = errorBody.message;\n } else if (errorBody.error) {\n errorMessage = errorBody.error;\n } else if (Array.isArray(errorBody.errors) && errorBody.errors.length) {\n errorMessage = errorBody.errors.join(', ');\n }\n } catch {\n // ignore json parse error\n }\n throw new BridgeAssistError(errorMessage, response.status, retryAfter);\n }\n return response.json();\n};\n\nexport const createBridgeDeposit = async (\n params: {\n wallet: string;\n chain: string;\n solanaAddress: string;\n amount: string;\n bridgeTx: string;\n depositId?: string;\n attestationId?: string | null;\n }\n): Promise<BridgeAssistStatus | null> => {\n const config = getBridgeAssistConfig();\n if (!config) return null;\n try {\n const response = await fetch(`${config.baseUrl}/deposits`, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n },\n body: JSON.stringify(params)\n });\n const body = await handleResponse(response);\n const stage = mapStage(body?.stage);\n return {\n stage,\n tx: body?.tx ?? body?.solanaTx ?? null,\n bridgeTx: body?.bridgeTx ?? params.bridgeTx ?? null,\n solanaTx: body?.solanaTx ?? body?.tx ?? null,\n attestationId: body?.attestationId ?? params.attestationId ?? null,\n depositId: body?.depositId ?? params.depositId ?? null,\n reason: body?.reason ?? null,\n };\n } catch (error) {\n logger.logError(createDepositError('BRIDGE_FAILED', 'Failed to create bridge deposit', {\n cause: error instanceof Error ? error : undefined,\n }));\n throw error;\n }\n}\n\nexport const fetchBridgeStatus = async (depositId: string): Promise<BridgeAssistStatus | null> => {\n const config = getBridgeAssistConfig();\n if (!config) return null;\n if (!depositId) return null;\n try {\n const response = await fetch(`${config.baseUrl}/deposits/${depositId}`, {\n method: 'GET',\n });\n if (response.status === 404) {\n return null;\n }\n const body = await handleResponse(response);\n const stage = mapStage(body?.stage);\n return {\n stage,\n tx: body?.solanaTx ?? body?.tx ?? null,\n bridgeTx: body?.bridgeTx ?? null,\n solanaTx: body?.solanaTx ?? null,\n mintTx: body?.mintTx ?? null,\n attestationId: body?.attestationId ?? null,\n depositId: body?.depositId ?? depositId,\n reason: body?.reason ?? null,\n };\n } catch (error) {\n logger.logError(createDepositError('BRIDGE_FAILED', 'Failed to fetch bridge status', {\n cause: error instanceof Error ? error : undefined,\n context: { depositId },\n }));\n throw error;\n }\n};\n\nexport const submitBridgeClaim = async (\n depositId: string,\n params: {\n solanaTx?: string;\n message?: string;\n attestation?: string;\n sourceChain?: string;\n destinationAddress?: string;\n blockhash?: string;\n lastValidBlockHeight?: number;\n lookupTableAddress?: string;\n userSignature?: string;\n txHash?: string;\n }\n): Promise<{\n tx?: string;\n requiresUserSignature?: boolean;\n stage?: string;\n blockhash?: string;\n lastValidBlockHeight?: number;\n lookupTableAddress?: string;\n signedTx?: string;\n} | null> => {\n const config = getBridgeAssistConfig();\n if (!config) return null;\n\n if (!depositId) throw new Error('Missing depositId for submitBridgeClaim');\n if (!params.message) throw new Error('Missing message for submitBridgeClaim');\n if (!params.attestation) throw new Error('Missing attestation for submitBridgeClaim');\n if (!params.sourceChain) throw new Error('Missing sourceChain for submitBridgeClaim');\n if (!params.destinationAddress) throw new Error('Missing destinationAddress for submitBridgeClaim');\n if (!params.userSignature) throw new Error('Missing userSignature for submitBridgeClaim');\n if (!params.txHash) throw new Error('Missing txHash (hash of signed tx) for submitBridgeClaim');\n\n try {\n // Single-request flow: always send full payload\n const payload = params;\n const url = `${config.baseUrl}/deposits/${depositId}/claim`;\n\n const response = await fetch(url, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n },\n body: JSON.stringify(payload)\n });\n return handleResponse(response);\n } catch (error) {\n logger.logError(createDepositError('CLAIM_FAILED', 'Failed to submit bridge claim', {\n cause: error instanceof Error ? error : undefined,\n context: { depositId },\n }));\n throw error;\n }\n}\n\nexport const prepareBurnTx = async (\n withdrawalId: string,\n params: {\n userAddress: string;\n amount: string;\n destinationChain: string;\n destinationAddress: string;\n }\n): Promise<{ tx: string; blockhash: string; lastValidBlockHeight: number }> => {\n const config = getBridgeAssistConfig();\n if (!config) throw new BridgeAssistError('Bridge Assist not configured');\n if (!withdrawalId) throw new Error('Missing withdrawalId for prepareBurnTx');\n\n try {\n const response = await fetch(`${config.baseUrl}/withdrawals/${withdrawalId}/prepare-burn`, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n },\n body: JSON.stringify(params),\n });\n return handleResponse(response);\n } catch (error) {\n logger.logError(createDepositError('BRIDGE_FAILED', 'Failed to prepare burn transaction', {\n cause: error instanceof Error ? error : undefined,\n context: { withdrawalId },\n }));\n throw error;\n }\n};\n\nexport const submitBurnTx = async (\n withdrawalId: string,\n params: {\n userSignature: string; // base64\n txHash: string; // hex\n }\n): Promise<{ burnTx: string; explorerUrl?: string }> => {\n const config = getBridgeAssistConfig();\n if (!config) throw new BridgeAssistError('Bridge Assist not configured');\n if (!withdrawalId) throw new Error('Missing withdrawalId for submitBurnTx');\n\n try {\n const response = await fetch(`${config.baseUrl}/withdrawals/${withdrawalId}/submit-burn`, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n },\n body: JSON.stringify(params),\n });\n return handleResponse(response);\n } catch (error) {\n logger.logError(createDepositError('BRIDGE_FAILED', 'Failed to submit burn transaction', {\n cause: error instanceof Error ? error : undefined,\n context: { withdrawalId },\n }));\n throw error;\n }\n};\n\nexport const prepareClaimTx = async (\n depositId: string,\n params: {\n message: string;\n attestation: string;\n sourceChain: string;\n destinationAddress: string;\n lookupTableAddress?: string;\n }\n): Promise<{ tx: string; blockhash: string; lastValidBlockHeight: number }> => {\n const config = getBridgeAssistConfig();\n if (!config) throw new BridgeAssistError('Bridge Assist not configured');\n if (!depositId) throw new Error('Missing depositId for prepareClaimTx');\n\n try {\n const response = await fetch(`${config.baseUrl}/deposits/${depositId}/prepare-claim`, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n },\n body: JSON.stringify(params),\n });\n return handleResponse(response);\n } catch (error) {\n logger.logError(createDepositError('CLAIM_FAILED', 'Failed to prepare claim transaction', {\n cause: error instanceof Error ? error : undefined,\n context: { depositId },\n }));\n throw error;\n }\n};\n\nexport const submitClaimTx = async (\n depositId: string,\n params: {\n userSignature: string;\n txHash: string;\n }\n): Promise<{ tx: string; stage?: string }> => {\n const config = getBridgeAssistConfig();\n if (!config) throw new BridgeAssistError('Bridge Assist not configured');\n if (!depositId) throw new Error('Missing depositId for submitClaimTx');\n\n try {\n const response = await fetch(`${config.baseUrl}/deposits/${depositId}/submit-claim`, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n },\n body: JSON.stringify(params),\n });\n return handleResponse(response);\n } catch (error) {\n logger.logError(createDepositError('CLAIM_FAILED', 'Failed to submit claim transaction', {\n cause: error instanceof Error ? error : undefined,\n context: { depositId },\n }));\n throw error;\n }\n};\n\nexport const reattestDeposit = async (depositId: string): Promise<boolean> => {\n const config = getBridgeAssistConfig();\n if (!config) return false;\n try {\n const response = await fetch(`${config.baseUrl}/deposits/${depositId}/reattest`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({ depositId }),\n });\n return response.ok;\n } catch {\n return false;\n }\n};\n\nexport const fetchServerFeePayer = async (): Promise<string | null> => {\n const config = getBridgeAssistConfig();\n if (!config) return null;\n try {\n const response = await fetch(`${config.baseUrl}/health`, {\n method: 'GET',\n });\n const data = await handleResponse(response);\n return data.feePayer || null;\n } catch (error) {\n logger.logError(createDepositError('BRIDGE_FAILED', 'Failed to fetch server fee payer', {\n cause: error instanceof Error ? error : undefined,\n }));\n // Surface a clear, typed error for callers so UI can show \"server not available\" and retry.\n // Network/CORS failures typically land here with no HTTP status.\n throw new BridgeAssistError('Bridge Assist server is not available', undefined);\n }\n}\n\n"]}
@@ -0,0 +1,35 @@
1
+ import { VersionedTransaction } from '@solana/web3.js';
2
+ export interface ClaimCanonicalParams {
3
+ message: string;
4
+ attestation: string;
5
+ eventNonce: string;
6
+ sourceChain: string;
7
+ destinationAddress: string;
8
+ feePayer: string;
9
+ userAddress: string;
10
+ lookupTableAddress: string;
11
+ lookupTableAddresses: string[];
12
+ feeRecipient: string;
13
+ blockhash: string;
14
+ lastValidBlockHeight: number;
15
+ needsUserAta: boolean;
16
+ needsFeePayerAta: boolean;
17
+ computeUnitPrice?: number;
18
+ computeUnitLimit?: number;
19
+ usdcFeeMicroUnits?: number;
20
+ solRebateLamports?: number;
21
+ }
22
+ export interface BurnCanonicalParams {
23
+ amount: string;
24
+ destinationChain: string;
25
+ destinationAddress: string;
26
+ feePayer: string;
27
+ userAddress: string;
28
+ messageAccountPubkey: string;
29
+ blockhash: string;
30
+ lastValidBlockHeight: number;
31
+ computeUnitPrice?: number;
32
+ computeUnitLimit?: number;
33
+ }
34
+ export declare const buildBurnTx: (params: BurnCanonicalParams) => VersionedTransaction;
35
+ export declare const buildClaimTx: (params: ClaimCanonicalParams) => VersionedTransaction;
@@ -0,0 +1,375 @@
1
+ var __assign = (this && this.__assign) || function () {
2
+ __assign = Object.assign || function(t) {
3
+ for (var s, i = 1, n = arguments.length; i < n; i++) {
4
+ s = arguments[i];
5
+ for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
6
+ t[p] = s[p];
7
+ }
8
+ return t;
9
+ };
10
+ return __assign.apply(this, arguments);
11
+ };
12
+ /**
13
+ * Pure CCTP transaction builders for the widget side.
14
+ * Local copy of the logic from @n1xyz/cctp-tx-builder so the widget
15
+ * can rebuild transactions from canonical params without depending on
16
+ * an unpublished workspace package at runtime.
17
+ *
18
+ * Security model: the widget never signs raw bytes from bridge-assist.
19
+ * Both sides build byte-identical transactions from canonical params.
20
+ */
21
+ import { Buffer } from 'buffer';
22
+ import { AddressLookupTableAccount, ComputeBudgetProgram, PublicKey, TransactionInstruction, TransactionMessage, VersionedTransaction, } from '@solana/web3.js';
23
+ import { sha256 } from '@noble/hashes/sha2';
24
+ import { ArbitrumSepolia, BaseSepolia, EthereumSepolia, SolanaDevnet, Arbitrum, Base, Ethereum, Solana, } from '@circle-fin/bridge-kit/chains';
25
+ // ─── Constants ───────────────────────────────────────────────────────
26
+ var DEFAULT_COMPUTE_UNIT_PRICE = 200000;
27
+ var DEFAULT_COMPUTE_UNIT_LIMIT = 400000;
28
+ var DEFAULT_USDC_FEE_MICRO_UNITS = 500000;
29
+ var DEFAULT_SOL_REBATE_LAMPORTS = 3000000;
30
+ var TOKEN_PROGRAM_ID = new PublicKey('TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA');
31
+ var ASSOCIATED_TOKEN_PROGRAM_ID = new PublicKey('ATokenGPvbdGVxr1b2hvZbsiqW5xWH25efTNsLJA8knL');
32
+ var SYSTEM_PROGRAM_ID = new PublicKey('11111111111111111111111111111111');
33
+ // ─── Chain Config ────────────────────────────────────────────────────
34
+ var getIsTestnet = function () { var _a; return ((_a = process.env.TESTNET) !== null && _a !== void 0 ? _a : process.env.NEXT_PUBLIC_TESTNET) !== 'false'; };
35
+ var getSolanaChain = function () {
36
+ return getIsTestnet() ? SolanaDevnet : Solana;
37
+ };
38
+ var mapChainToBridgeKit = function (chain) {
39
+ var lower = chain.toLowerCase().trim();
40
+ var testnet = getIsTestnet();
41
+ if (lower === 'arbitrum' || lower === 'arb')
42
+ return testnet ? ArbitrumSepolia : Arbitrum;
43
+ if (lower === 'solana')
44
+ return testnet ? SolanaDevnet : Solana;
45
+ if (lower === 'base')
46
+ return testnet ? BaseSepolia : Base;
47
+ if (lower === 'ethereum' || lower === 'evm')
48
+ return testnet ? EthereumSepolia : Ethereum;
49
+ throw new Error("Unsupported chain \"".concat(chain, "\""));
50
+ };
51
+ var detectFormat = function (address) {
52
+ if (/^0x[0-9a-fA-F]{40}$/.test(address))
53
+ return 'evm';
54
+ if (/^0x[0-9a-fA-F]{64}$/.test(address))
55
+ return 'bytes32';
56
+ try {
57
+ var pubkey = new PublicKey(address);
58
+ if (pubkey.toBuffer().length === 32)
59
+ return 'solana';
60
+ }
61
+ catch (_a) { }
62
+ throw new Error("Unsupported address format: ".concat(address));
63
+ };
64
+ var toBytes32 = function (address) {
65
+ var fmt = detectFormat(address);
66
+ switch (fmt) {
67
+ case 'evm': {
68
+ var hex = address.startsWith('0x') ? address.slice(2) : address;
69
+ return '0x' + '0'.repeat(24) + hex;
70
+ }
71
+ case 'bytes32':
72
+ return address;
73
+ case 'solana': {
74
+ var pubkey = new PublicKey(address);
75
+ return '0x' + Buffer.from(pubkey.toBuffer()).toString('hex');
76
+ }
77
+ }
78
+ };
79
+ var convertAddress = function (address, targetFormat) {
80
+ var current = detectFormat(address);
81
+ if (current === targetFormat)
82
+ return address;
83
+ var asBytes32 = toBytes32(address);
84
+ switch (targetFormat) {
85
+ case 'bytes32':
86
+ return asBytes32;
87
+ case 'solana': {
88
+ var hex = asBytes32.startsWith('0x') ? asBytes32.slice(2) : asBytes32;
89
+ return new PublicKey(Buffer.from(hex, 'hex')).toBase58();
90
+ }
91
+ case 'evm': {
92
+ var hex = asBytes32.startsWith('0x') ? asBytes32.slice(2) : asBytes32;
93
+ return '0x' + hex.slice(-40);
94
+ }
95
+ }
96
+ };
97
+ // ─── ATA ─────────────────────────────────────────────────────────────
98
+ var getAssociatedTokenAddress = function (mint, owner) {
99
+ return PublicKey.findProgramAddressSync([owner.toBuffer(), TOKEN_PROGRAM_ID.toBuffer(), mint.toBuffer()], ASSOCIATED_TOKEN_PROGRAM_ID)[0];
100
+ };
101
+ // ─── PDAs ────────────────────────────────────────────────────────────
102
+ var derivePdas = function (sourceChain, destinationChain, messageTransmitterProgramId, tokenMessengerProgramId) {
103
+ var remoteMintKey = new PublicKey(convertAddress(sourceChain.usdcAddress, 'solana'));
104
+ var destinationUsdcMint = new PublicKey(destinationChain.usdcAddress);
105
+ var tokenMessengerPda = PublicKey.findProgramAddressSync([Buffer.from('token_messenger')], tokenMessengerProgramId)[0];
106
+ var messageTransmitterPda = PublicKey.findProgramAddressSync([Buffer.from('message_transmitter')], messageTransmitterProgramId)[0];
107
+ var tokenMinterPda = PublicKey.findProgramAddressSync([Buffer.from('token_minter')], tokenMessengerProgramId)[0];
108
+ var localTokenPda = PublicKey.findProgramAddressSync([Buffer.from('local_token'), destinationUsdcMint.toBuffer()], tokenMessengerProgramId)[0];
109
+ var domainSeed = Buffer.from(sourceChain.cctp.domain.toString(), 'utf8');
110
+ var remoteTokenMessengerPda = PublicKey.findProgramAddressSync([Buffer.from('remote_token_messenger'), domainSeed], tokenMessengerProgramId)[0];
111
+ var tokenPairPda = PublicKey.findProgramAddressSync([Buffer.from('token_pair'), domainSeed, remoteMintKey.toBuffer()], tokenMessengerProgramId)[0];
112
+ var custodyPda = PublicKey.findProgramAddressSync([Buffer.from('custody'), destinationUsdcMint.toBuffer()], tokenMessengerProgramId)[0];
113
+ var messageTransmitterAuthorityPda = PublicKey.findProgramAddressSync([Buffer.from('message_transmitter_authority'), tokenMessengerProgramId.toBuffer()], messageTransmitterProgramId)[0];
114
+ return {
115
+ tokenMessengerPda: tokenMessengerPda,
116
+ messageTransmitterPda: messageTransmitterPda,
117
+ tokenMinterPda: tokenMinterPda,
118
+ localTokenPda: localTokenPda,
119
+ remoteTokenMessengerPda: remoteTokenMessengerPda,
120
+ tokenPairPda: tokenPairPda,
121
+ custodyPda: custodyPda,
122
+ messageTransmitterAuthorityPda: messageTransmitterAuthorityPda,
123
+ remoteMintKey: remoteMintKey,
124
+ };
125
+ };
126
+ // ─── Instruction Helpers ─────────────────────────────────────────────
127
+ var buildCreateAtaInstruction = function (payer, ata, owner, mint) {
128
+ return new TransactionInstruction({
129
+ programId: ASSOCIATED_TOKEN_PROGRAM_ID,
130
+ data: Buffer.alloc(0),
131
+ keys: [
132
+ { pubkey: payer, isSigner: true, isWritable: true },
133
+ { pubkey: ata, isSigner: false, isWritable: true },
134
+ { pubkey: owner, isSigner: false, isWritable: false },
135
+ { pubkey: mint, isSigner: false, isWritable: false },
136
+ { pubkey: SYSTEM_PROGRAM_ID, isSigner: false, isWritable: false },
137
+ { pubkey: TOKEN_PROGRAM_ID, isSigner: false, isWritable: false },
138
+ ],
139
+ });
140
+ };
141
+ var buildSplTransferInstruction = function (source, destination, owner, amount) {
142
+ var data = Buffer.alloc(9);
143
+ data[0] = 3;
144
+ data.writeBigUInt64LE(amount, 1);
145
+ return new TransactionInstruction({
146
+ programId: TOKEN_PROGRAM_ID,
147
+ data: data,
148
+ keys: [
149
+ { pubkey: source, isSigner: false, isWritable: true },
150
+ { pubkey: destination, isSigner: false, isWritable: true },
151
+ { pubkey: owner, isSigner: true, isWritable: false },
152
+ ],
153
+ });
154
+ };
155
+ var buildSystemTransferInstruction = function (from, to, lamports) {
156
+ var data = Buffer.alloc(12);
157
+ data.writeUInt32LE(2, 0);
158
+ data.writeBigUInt64LE(BigInt(lamports), 4);
159
+ return new TransactionInstruction({
160
+ programId: SYSTEM_PROGRAM_ID,
161
+ data: data,
162
+ keys: [
163
+ { pubkey: from, isSigner: true, isWritable: true },
164
+ { pubkey: to, isSigner: false, isWritable: true },
165
+ ],
166
+ });
167
+ };
168
+ // ─── Lookup Table Helper ─────────────────────────────────────────────
169
+ function createLookupTableState(addresses) {
170
+ var META_SIZE = 56;
171
+ var data = Buffer.alloc(META_SIZE + addresses.length * 32);
172
+ data.writeUInt32LE(1, 0);
173
+ data.writeBigUInt64LE(BigInt('18446744073709551615'), 4);
174
+ data.writeBigUInt64LE(BigInt(0), 12);
175
+ data[20] = 0;
176
+ data[21] = 0;
177
+ var offset = META_SIZE;
178
+ for (var _i = 0, addresses_1 = addresses; _i < addresses_1.length; _i++) {
179
+ var addr = addresses_1[_i];
180
+ data.set(addr.toBuffer(), offset);
181
+ offset += 32;
182
+ }
183
+ return data;
184
+ }
185
+ // ─── buildBurnTx ─────────────────────────────────────────────────────
186
+ export var buildBurnTx = function (params) {
187
+ var _a, _b;
188
+ var feePayerPubkey = new PublicKey(params.feePayer);
189
+ var userPubkey = new PublicKey(params.userAddress);
190
+ var messageAccountPubkey = new PublicKey(params.messageAccountPubkey);
191
+ var toChain = mapChainToBridgeKit(params.destinationChain);
192
+ var fromChain = getSolanaChain();
193
+ var v2config = fromChain.cctp.contracts.v2;
194
+ if (!v2config || v2config.type !== 'split') {
195
+ throw new Error('Unsupported CCTP v2 contract configuration for Solana.');
196
+ }
197
+ var tokenMessengerProgramId = new PublicKey(v2config.tokenMessenger);
198
+ var messageTransmitterProgramId = new PublicKey(v2config.messageTransmitter);
199
+ var pdas = derivePdas(toChain, fromChain, messageTransmitterProgramId, tokenMessengerProgramId);
200
+ var senderAuthorityPda = PublicKey.findProgramAddressSync([Buffer.from('sender_authority')], tokenMessengerProgramId)[0];
201
+ var denylistAccount = PublicKey.findProgramAddressSync([Buffer.from('denylist_account'), userPubkey.toBuffer()], tokenMessengerProgramId)[0];
202
+ var eventAuthority = PublicKey.findProgramAddressSync([Buffer.from('__event_authority')], tokenMessengerProgramId)[0];
203
+ var usdcMint = new PublicKey(fromChain.usdcAddress);
204
+ var userUsdcAta = getAssociatedTokenAddress(usdcMint, userPubkey);
205
+ var amountInBaseUnits = Math.round(parseFloat(params.amount) * 1e6).toString();
206
+ var mintRecipientHex = toBytes32(params.destinationAddress).replace(/^0x/, '');
207
+ var discriminator = sha256(Buffer.from('global:deposit_for_burn')).slice(0, 8);
208
+ var instructionData = Buffer.alloc(96);
209
+ var offset = 0;
210
+ instructionData.set(discriminator, offset);
211
+ offset += 8;
212
+ instructionData.writeBigUInt64LE(BigInt(amountInBaseUnits), offset);
213
+ offset += 8;
214
+ instructionData.writeUInt32LE(toChain.cctp.domain, offset);
215
+ offset += 4;
216
+ var mintRecipientBuf = Buffer.from(mintRecipientHex, 'hex');
217
+ if (mintRecipientBuf.length !== 32) {
218
+ throw new Error("mintRecipient must be exactly 32 bytes, got ".concat(mintRecipientBuf.length));
219
+ }
220
+ instructionData.set(mintRecipientBuf, offset);
221
+ var burnInstruction = new TransactionInstruction({
222
+ programId: tokenMessengerProgramId,
223
+ data: instructionData,
224
+ keys: [
225
+ { pubkey: userPubkey, isSigner: true, isWritable: true },
226
+ { pubkey: feePayerPubkey, isSigner: true, isWritable: true },
227
+ { pubkey: senderAuthorityPda, isSigner: false, isWritable: false },
228
+ { pubkey: userUsdcAta, isSigner: false, isWritable: true },
229
+ { pubkey: denylistAccount, isSigner: false, isWritable: false },
230
+ { pubkey: pdas.messageTransmitterPda, isSigner: false, isWritable: true },
231
+ { pubkey: pdas.tokenMessengerPda, isSigner: false, isWritable: false },
232
+ { pubkey: pdas.remoteTokenMessengerPda, isSigner: false, isWritable: false },
233
+ { pubkey: pdas.tokenMinterPda, isSigner: false, isWritable: true },
234
+ { pubkey: pdas.localTokenPda, isSigner: false, isWritable: true },
235
+ { pubkey: usdcMint, isSigner: false, isWritable: true },
236
+ { pubkey: messageAccountPubkey, isSigner: true, isWritable: true },
237
+ { pubkey: messageTransmitterProgramId, isSigner: false, isWritable: false },
238
+ { pubkey: tokenMessengerProgramId, isSigner: false, isWritable: false },
239
+ { pubkey: TOKEN_PROGRAM_ID, isSigner: false, isWritable: false },
240
+ { pubkey: SYSTEM_PROGRAM_ID, isSigner: false, isWritable: false },
241
+ { pubkey: eventAuthority, isSigner: false, isWritable: false },
242
+ { pubkey: tokenMessengerProgramId, isSigner: false, isWritable: false },
243
+ ],
244
+ });
245
+ var instructions = [
246
+ ComputeBudgetProgram.setComputeUnitPrice({
247
+ microLamports: (_a = params.computeUnitPrice) !== null && _a !== void 0 ? _a : DEFAULT_COMPUTE_UNIT_PRICE,
248
+ }),
249
+ ComputeBudgetProgram.setComputeUnitLimit({
250
+ units: (_b = params.computeUnitLimit) !== null && _b !== void 0 ? _b : DEFAULT_COMPUTE_UNIT_LIMIT,
251
+ }),
252
+ burnInstruction,
253
+ ];
254
+ var messageV0 = new TransactionMessage({
255
+ payerKey: feePayerPubkey,
256
+ recentBlockhash: params.blockhash,
257
+ instructions: instructions,
258
+ }).compileToV0Message();
259
+ return new VersionedTransaction(messageV0);
260
+ };
261
+ // ─── buildClaimTx ────────────────────────────────────────────────────
262
+ var encodeReceiveMessageData = function (message, attestation) {
263
+ var msgHex = message.startsWith('0x') ? message.slice(2) : message;
264
+ var attHex = attestation.startsWith('0x') ? attestation.slice(2) : attestation;
265
+ var msgBytes = Buffer.from(msgHex, 'hex');
266
+ var attBytes = Buffer.from(attHex, 'hex');
267
+ var discriminator = sha256(Buffer.from('global:receive_message')).slice(0, 8);
268
+ var totalLen = 8 + 4 + msgBytes.length + 4 + attBytes.length;
269
+ var data = Buffer.alloc(totalLen);
270
+ var offset = 0;
271
+ data.set(discriminator, offset);
272
+ offset += 8;
273
+ data.writeUInt32LE(msgBytes.length, offset);
274
+ offset += 4;
275
+ data.set(msgBytes, offset);
276
+ offset += msgBytes.length;
277
+ data.writeUInt32LE(attBytes.length, offset);
278
+ offset += 4;
279
+ data.set(attBytes, offset);
280
+ return data;
281
+ };
282
+ export var buildClaimTx = function (params) {
283
+ var _a, _b, _c, _d;
284
+ var feePayerPubkey = new PublicKey(params.feePayer);
285
+ var userPubkey = new PublicKey(params.userAddress);
286
+ var destinationPubkey = new PublicKey(params.destinationAddress);
287
+ var fromChain = mapChainToBridgeKit(params.sourceChain);
288
+ var toChain = getSolanaChain();
289
+ var v2config = toChain.cctp.contracts.v2;
290
+ if (!v2config || v2config.type !== 'split') {
291
+ throw new Error('Unsupported CCTP v2 contract configuration for Solana.');
292
+ }
293
+ var tokenMessengerProgramId = new PublicKey(v2config.tokenMessenger);
294
+ var messageTransmitterProgramId = new PublicKey(v2config.messageTransmitter);
295
+ var pdas = derivePdas(fromChain, toChain, messageTransmitterProgramId, tokenMessengerProgramId);
296
+ var nonceHex = params.eventNonce.replace(/^0x/, '');
297
+ if (nonceHex.length !== 64) {
298
+ throw new Error("Invalid eventNonce: expected 64 hex chars, got ".concat(nonceHex.length));
299
+ }
300
+ var nonceBuf = Buffer.from(nonceHex, 'hex');
301
+ var usedNoncePda = PublicKey.findProgramAddressSync([Buffer.from('used_nonce'), nonceBuf], messageTransmitterProgramId)[0];
302
+ var eventAuthority = PublicKey.findProgramAddressSync([Buffer.from('__event_authority')], tokenMessengerProgramId)[0];
303
+ var usdcMint = new PublicKey(toChain.usdcAddress);
304
+ var userUsdcAta = getAssociatedTokenAddress(usdcMint, destinationPubkey);
305
+ var feePayerAta = getAssociatedTokenAddress(usdcMint, feePayerPubkey);
306
+ var feeRecipientPubkey = new PublicKey(params.feeRecipient);
307
+ var feeRecipientAta = getAssociatedTokenAddress(usdcMint, feeRecipientPubkey);
308
+ var instructionData = encodeReceiveMessageData(params.message, params.attestation);
309
+ var receiveMessageIx = new TransactionInstruction({
310
+ programId: messageTransmitterProgramId,
311
+ data: instructionData,
312
+ keys: [
313
+ { pubkey: feePayerPubkey, isSigner: true, isWritable: true },
314
+ { pubkey: feePayerPubkey, isSigner: true, isWritable: false },
315
+ { pubkey: pdas.messageTransmitterAuthorityPda, isSigner: false, isWritable: false },
316
+ { pubkey: pdas.messageTransmitterPda, isSigner: false, isWritable: true },
317
+ { pubkey: usedNoncePda, isSigner: false, isWritable: true },
318
+ { pubkey: tokenMessengerProgramId, isSigner: false, isWritable: false },
319
+ { pubkey: SYSTEM_PROGRAM_ID, isSigner: false, isWritable: false },
320
+ { pubkey: pdas.tokenMessengerPda, isSigner: false, isWritable: false },
321
+ { pubkey: pdas.remoteTokenMessengerPda, isSigner: false, isWritable: false },
322
+ { pubkey: pdas.tokenMinterPda, isSigner: false, isWritable: true },
323
+ { pubkey: pdas.localTokenPda, isSigner: false, isWritable: true },
324
+ { pubkey: pdas.tokenPairPda, isSigner: false, isWritable: false },
325
+ { pubkey: feeRecipientAta, isSigner: false, isWritable: true },
326
+ { pubkey: userUsdcAta, isSigner: false, isWritable: true },
327
+ { pubkey: pdas.custodyPda, isSigner: false, isWritable: true },
328
+ { pubkey: TOKEN_PROGRAM_ID, isSigner: false, isWritable: false },
329
+ { pubkey: eventAuthority, isSigner: false, isWritable: false },
330
+ { pubkey: tokenMessengerProgramId, isSigner: false, isWritable: false },
331
+ ],
332
+ });
333
+ var instructions = [];
334
+ instructions.push(ComputeBudgetProgram.setComputeUnitPrice({
335
+ microLamports: (_a = params.computeUnitPrice) !== null && _a !== void 0 ? _a : DEFAULT_COMPUTE_UNIT_PRICE,
336
+ }), ComputeBudgetProgram.setComputeUnitLimit({
337
+ units: (_b = params.computeUnitLimit) !== null && _b !== void 0 ? _b : DEFAULT_COMPUTE_UNIT_LIMIT,
338
+ }));
339
+ if (params.needsUserAta) {
340
+ instructions.push(buildCreateAtaInstruction(feePayerPubkey, userUsdcAta, destinationPubkey, usdcMint));
341
+ }
342
+ if (params.needsFeePayerAta) {
343
+ instructions.push(buildCreateAtaInstruction(feePayerPubkey, feePayerAta, feePayerPubkey, usdcMint));
344
+ }
345
+ instructions.push(receiveMessageIx);
346
+ var feeAmount = BigInt((_c = params.usdcFeeMicroUnits) !== null && _c !== void 0 ? _c : DEFAULT_USDC_FEE_MICRO_UNITS);
347
+ instructions.push(buildSplTransferInstruction(userUsdcAta, feePayerAta, userPubkey, feeAmount));
348
+ var solRebate = (_d = params.solRebateLamports) !== null && _d !== void 0 ? _d : DEFAULT_SOL_REBATE_LAMPORTS;
349
+ instructions.push(buildSystemTransferInstruction(feePayerPubkey, userPubkey, solRebate));
350
+ var normalizedInstructions = instructions.map(function (ix) {
351
+ var newKeys = ix.keys.map(function (meta) {
352
+ var _a;
353
+ if (meta.pubkey.equals(feePayerPubkey)) {
354
+ return __assign(__assign({}, meta), { isSigner: true, isWritable: (_a = meta.isWritable) !== null && _a !== void 0 ? _a : true });
355
+ }
356
+ if (meta.pubkey.equals(userPubkey)) {
357
+ return __assign(__assign({}, meta), { isSigner: true });
358
+ }
359
+ return __assign(__assign({}, meta), { isSigner: false });
360
+ });
361
+ return new TransactionInstruction({ programId: ix.programId, data: ix.data, keys: newKeys });
362
+ });
363
+ var lookupTableKey = new PublicKey(params.lookupTableAddress);
364
+ var lookupTableAccount = new AddressLookupTableAccount({
365
+ key: lookupTableKey,
366
+ state: AddressLookupTableAccount.deserialize(createLookupTableState(params.lookupTableAddresses.map(function (a) { return new PublicKey(a); }))),
367
+ });
368
+ var messageV0 = new TransactionMessage({
369
+ payerKey: feePayerPubkey,
370
+ recentBlockhash: params.blockhash,
371
+ instructions: normalizedInstructions,
372
+ }).compileToV0Message([lookupTableAccount]);
373
+ return new VersionedTransaction(messageV0);
374
+ };
375
+ //# sourceMappingURL=canonicalBuilders.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"canonicalBuilders.js","sourceRoot":"","sources":["../../../../src/features/onboarding-flow/cctp/canonicalBuilders.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Pure CCTP transaction builders for the widget side.\n * Local copy of the logic from @n1xyz/cctp-tx-builder so the widget\n * can rebuild transactions from canonical params without depending on\n * an unpublished workspace package at runtime.\n *\n * Security model: the widget never signs raw bytes from bridge-assist.\n * Both sides build byte-identical transactions from canonical params.\n */\nimport { Buffer } from 'buffer';\nimport {\n AddressLookupTableAccount,\n ComputeBudgetProgram,\n PublicKey,\n TransactionInstruction,\n TransactionMessage,\n VersionedTransaction,\n} from '@solana/web3.js';\nimport { sha256 } from '@noble/hashes/sha2';\nimport {\n ArbitrumSepolia,\n BaseSepolia,\n EthereumSepolia,\n SolanaDevnet,\n Arbitrum,\n Base,\n Ethereum,\n Solana,\n} from '@circle-fin/bridge-kit/chains';\n\n// ─── Types ───────────────────────────────────────────────────────────\n\nexport interface ClaimCanonicalParams {\n message: string;\n attestation: string;\n eventNonce: string;\n sourceChain: string;\n destinationAddress: string;\n feePayer: string;\n userAddress: string;\n lookupTableAddress: string;\n lookupTableAddresses: string[];\n feeRecipient: string;\n blockhash: string;\n lastValidBlockHeight: number;\n needsUserAta: boolean;\n needsFeePayerAta: boolean;\n computeUnitPrice?: number;\n computeUnitLimit?: number;\n usdcFeeMicroUnits?: number;\n solRebateLamports?: number;\n}\n\nexport interface BurnCanonicalParams {\n amount: string;\n destinationChain: string;\n destinationAddress: string;\n feePayer: string;\n userAddress: string;\n messageAccountPubkey: string;\n blockhash: string;\n lastValidBlockHeight: number;\n computeUnitPrice?: number;\n computeUnitLimit?: number;\n}\n\n// ─── Constants ───────────────────────────────────────────────────────\n\nconst DEFAULT_COMPUTE_UNIT_PRICE = 200_000;\nconst DEFAULT_COMPUTE_UNIT_LIMIT = 400_000;\nconst DEFAULT_USDC_FEE_MICRO_UNITS = 500_000;\nconst DEFAULT_SOL_REBATE_LAMPORTS = 3_000_000;\nconst TOKEN_PROGRAM_ID = new PublicKey('TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA');\nconst ASSOCIATED_TOKEN_PROGRAM_ID = new PublicKey('ATokenGPvbdGVxr1b2hvZbsiqW5xWH25efTNsLJA8knL');\nconst SYSTEM_PROGRAM_ID = new PublicKey('11111111111111111111111111111111');\n\n// ─── Chain Config ────────────────────────────────────────────────────\n\nconst getIsTestnet = (): boolean =>\n (process.env.TESTNET ?? process.env.NEXT_PUBLIC_TESTNET) !== 'false';\n\nconst getSolanaChain = (): any =>\n getIsTestnet() ? SolanaDevnet : Solana;\n\nconst mapChainToBridgeKit = (chain: string): any => {\n const lower = chain.toLowerCase().trim();\n const testnet = getIsTestnet();\n if (lower === 'arbitrum' || lower === 'arb') return testnet ? ArbitrumSepolia : Arbitrum;\n if (lower === 'solana') return testnet ? SolanaDevnet : Solana;\n if (lower === 'base') return testnet ? BaseSepolia : Base;\n if (lower === 'ethereum' || lower === 'evm') return testnet ? EthereumSepolia : Ethereum;\n throw new Error(`Unsupported chain \"${chain}\"`);\n};\n\nconst detectFormat = (address: string): 'evm' | 'solana' | 'bytes32' => {\n if (/^0x[0-9a-fA-F]{40}$/.test(address)) return 'evm';\n if (/^0x[0-9a-fA-F]{64}$/.test(address)) return 'bytes32';\n try {\n const pubkey = new PublicKey(address);\n if (pubkey.toBuffer().length === 32) return 'solana';\n } catch { }\n throw new Error(`Unsupported address format: ${address}`);\n};\n\nconst toBytes32 = (address: string): string => {\n const fmt = detectFormat(address);\n switch (fmt) {\n case 'evm': {\n const hex = address.startsWith('0x') ? address.slice(2) : address;\n return '0x' + '0'.repeat(24) + hex;\n }\n case 'bytes32':\n return address;\n case 'solana': {\n const pubkey = new PublicKey(address);\n return '0x' + Buffer.from(pubkey.toBuffer()).toString('hex');\n }\n }\n};\n\nconst convertAddress = (address: string, targetFormat: 'evm' | 'solana' | 'bytes32'): string => {\n const current = detectFormat(address);\n if (current === targetFormat) return address;\n const asBytes32 = toBytes32(address);\n switch (targetFormat) {\n case 'bytes32':\n return asBytes32;\n case 'solana': {\n const hex = asBytes32.startsWith('0x') ? asBytes32.slice(2) : asBytes32;\n return new PublicKey(Buffer.from(hex, 'hex')).toBase58();\n }\n case 'evm': {\n const hex = asBytes32.startsWith('0x') ? asBytes32.slice(2) : asBytes32;\n return '0x' + hex.slice(-40);\n }\n }\n};\n\n// ─── ATA ─────────────────────────────────────────────────────────────\n\nconst getAssociatedTokenAddress = (mint: PublicKey, owner: PublicKey): PublicKey =>\n PublicKey.findProgramAddressSync(\n [owner.toBuffer(), TOKEN_PROGRAM_ID.toBuffer(), mint.toBuffer()],\n ASSOCIATED_TOKEN_PROGRAM_ID\n )[0];\n\n// ─── PDAs ────────────────────────────────────────────────────────────\n\nconst derivePdas = (\n sourceChain: any,\n destinationChain: any,\n messageTransmitterProgramId: PublicKey,\n tokenMessengerProgramId: PublicKey\n) => {\n const remoteMintKey = new PublicKey(convertAddress(sourceChain.usdcAddress, 'solana'));\n const destinationUsdcMint = new PublicKey(destinationChain.usdcAddress);\n\n const [tokenMessengerPda] = PublicKey.findProgramAddressSync(\n [Buffer.from('token_messenger')], tokenMessengerProgramId);\n const [messageTransmitterPda] = PublicKey.findProgramAddressSync(\n [Buffer.from('message_transmitter')], messageTransmitterProgramId);\n const [tokenMinterPda] = PublicKey.findProgramAddressSync(\n [Buffer.from('token_minter')], tokenMessengerProgramId);\n const [localTokenPda] = PublicKey.findProgramAddressSync(\n [Buffer.from('local_token'), destinationUsdcMint.toBuffer()], tokenMessengerProgramId);\n const domainSeed = Buffer.from(sourceChain.cctp.domain.toString(), 'utf8');\n const [remoteTokenMessengerPda] = PublicKey.findProgramAddressSync(\n [Buffer.from('remote_token_messenger'), domainSeed], tokenMessengerProgramId);\n const [tokenPairPda] = PublicKey.findProgramAddressSync(\n [Buffer.from('token_pair'), domainSeed, remoteMintKey.toBuffer()], tokenMessengerProgramId);\n const [custodyPda] = PublicKey.findProgramAddressSync(\n [Buffer.from('custody'), destinationUsdcMint.toBuffer()], tokenMessengerProgramId);\n const [messageTransmitterAuthorityPda] = PublicKey.findProgramAddressSync(\n [Buffer.from('message_transmitter_authority'), tokenMessengerProgramId.toBuffer()],\n messageTransmitterProgramId);\n\n return {\n tokenMessengerPda, messageTransmitterPda, tokenMinterPda, localTokenPda,\n remoteTokenMessengerPda, tokenPairPda, custodyPda, messageTransmitterAuthorityPda, remoteMintKey,\n };\n};\n\n// ─── Instruction Helpers ─────────────────────────────────────────────\n\nconst buildCreateAtaInstruction = (\n payer: PublicKey, ata: PublicKey, owner: PublicKey, mint: PublicKey\n): TransactionInstruction =>\n new TransactionInstruction({\n programId: ASSOCIATED_TOKEN_PROGRAM_ID,\n data: Buffer.alloc(0),\n keys: [\n { pubkey: payer, isSigner: true, isWritable: true },\n { pubkey: ata, isSigner: false, isWritable: true },\n { pubkey: owner, isSigner: false, isWritable: false },\n { pubkey: mint, isSigner: false, isWritable: false },\n { pubkey: SYSTEM_PROGRAM_ID, isSigner: false, isWritable: false },\n { pubkey: TOKEN_PROGRAM_ID, isSigner: false, isWritable: false },\n ],\n });\n\nconst buildSplTransferInstruction = (\n source: PublicKey, destination: PublicKey, owner: PublicKey, amount: bigint\n): TransactionInstruction => {\n const data = Buffer.alloc(9);\n data[0] = 3;\n data.writeBigUInt64LE(amount, 1);\n return new TransactionInstruction({\n programId: TOKEN_PROGRAM_ID, data,\n keys: [\n { pubkey: source, isSigner: false, isWritable: true },\n { pubkey: destination, isSigner: false, isWritable: true },\n { pubkey: owner, isSigner: true, isWritable: false },\n ],\n });\n};\n\nconst buildSystemTransferInstruction = (\n from: PublicKey, to: PublicKey, lamports: number\n): TransactionInstruction => {\n const data = Buffer.alloc(12);\n data.writeUInt32LE(2, 0);\n data.writeBigUInt64LE(BigInt(lamports), 4);\n return new TransactionInstruction({\n programId: SYSTEM_PROGRAM_ID, data,\n keys: [\n { pubkey: from, isSigner: true, isWritable: true },\n { pubkey: to, isSigner: false, isWritable: true },\n ],\n });\n};\n\n// ─── Lookup Table Helper ─────────────────────────────────────────────\n\nfunction createLookupTableState(addresses: PublicKey[]): Uint8Array {\n const META_SIZE = 56;\n const data = Buffer.alloc(META_SIZE + addresses.length * 32);\n data.writeUInt32LE(1, 0);\n data.writeBigUInt64LE(BigInt('18446744073709551615'), 4);\n data.writeBigUInt64LE(BigInt(0), 12);\n data[20] = 0;\n data[21] = 0;\n let offset = META_SIZE;\n for (const addr of addresses) {\n data.set(addr.toBuffer(), offset);\n offset += 32;\n }\n return data;\n}\n\n// ─── buildBurnTx ─────────────────────────────────────────────────────\n\nexport const buildBurnTx = (params: BurnCanonicalParams): VersionedTransaction => {\n const feePayerPubkey = new PublicKey(params.feePayer);\n const userPubkey = new PublicKey(params.userAddress);\n const messageAccountPubkey = new PublicKey(params.messageAccountPubkey);\n\n const toChain = mapChainToBridgeKit(params.destinationChain);\n const fromChain = getSolanaChain();\n\n const v2config = fromChain.cctp.contracts.v2;\n if (!v2config || v2config.type !== 'split') {\n throw new Error('Unsupported CCTP v2 contract configuration for Solana.');\n }\n\n const tokenMessengerProgramId = new PublicKey(v2config.tokenMessenger);\n const messageTransmitterProgramId = new PublicKey(v2config.messageTransmitter);\n\n const pdas = derivePdas(toChain, fromChain, messageTransmitterProgramId, tokenMessengerProgramId);\n\n const [senderAuthorityPda] = PublicKey.findProgramAddressSync(\n [Buffer.from('sender_authority')], tokenMessengerProgramId);\n const [denylistAccount] = PublicKey.findProgramAddressSync(\n [Buffer.from('denylist_account'), userPubkey.toBuffer()], tokenMessengerProgramId);\n const [eventAuthority] = PublicKey.findProgramAddressSync(\n [Buffer.from('__event_authority')], tokenMessengerProgramId);\n\n const usdcMint = new PublicKey(fromChain.usdcAddress);\n const userUsdcAta = getAssociatedTokenAddress(usdcMint, userPubkey);\n\n const amountInBaseUnits = Math.round(parseFloat(params.amount) * 1e6).toString();\n const mintRecipientHex = toBytes32(params.destinationAddress).replace(/^0x/, '');\n\n const discriminator = sha256(Buffer.from('global:deposit_for_burn')).slice(0, 8);\n const instructionData = Buffer.alloc(96);\n let offset = 0;\n instructionData.set(discriminator, offset); offset += 8;\n instructionData.writeBigUInt64LE(BigInt(amountInBaseUnits), offset); offset += 8;\n instructionData.writeUInt32LE(toChain.cctp.domain, offset); offset += 4;\n const mintRecipientBuf = Buffer.from(mintRecipientHex, 'hex');\n if (mintRecipientBuf.length !== 32) {\n throw new Error(`mintRecipient must be exactly 32 bytes, got ${mintRecipientBuf.length}`);\n }\n instructionData.set(mintRecipientBuf, offset);\n\n const burnInstruction = new TransactionInstruction({\n programId: tokenMessengerProgramId,\n data: instructionData,\n keys: [\n { pubkey: userPubkey, isSigner: true, isWritable: true },\n { pubkey: feePayerPubkey, isSigner: true, isWritable: true },\n { pubkey: senderAuthorityPda, isSigner: false, isWritable: false },\n { pubkey: userUsdcAta, isSigner: false, isWritable: true },\n { pubkey: denylistAccount, isSigner: false, isWritable: false },\n { pubkey: pdas.messageTransmitterPda, isSigner: false, isWritable: true },\n { pubkey: pdas.tokenMessengerPda, isSigner: false, isWritable: false },\n { pubkey: pdas.remoteTokenMessengerPda, isSigner: false, isWritable: false },\n { pubkey: pdas.tokenMinterPda, isSigner: false, isWritable: true },\n { pubkey: pdas.localTokenPda, isSigner: false, isWritable: true },\n { pubkey: usdcMint, isSigner: false, isWritable: true },\n { pubkey: messageAccountPubkey, isSigner: true, isWritable: true },\n { pubkey: messageTransmitterProgramId, isSigner: false, isWritable: false },\n { pubkey: tokenMessengerProgramId, isSigner: false, isWritable: false },\n { pubkey: TOKEN_PROGRAM_ID, isSigner: false, isWritable: false },\n { pubkey: SYSTEM_PROGRAM_ID, isSigner: false, isWritable: false },\n { pubkey: eventAuthority, isSigner: false, isWritable: false },\n { pubkey: tokenMessengerProgramId, isSigner: false, isWritable: false },\n ],\n });\n\n const instructions: TransactionInstruction[] = [\n ComputeBudgetProgram.setComputeUnitPrice({\n microLamports: params.computeUnitPrice ?? DEFAULT_COMPUTE_UNIT_PRICE,\n }),\n ComputeBudgetProgram.setComputeUnitLimit({\n units: params.computeUnitLimit ?? DEFAULT_COMPUTE_UNIT_LIMIT,\n }),\n burnInstruction,\n ];\n\n const messageV0 = new TransactionMessage({\n payerKey: feePayerPubkey,\n recentBlockhash: params.blockhash,\n instructions,\n }).compileToV0Message();\n\n return new VersionedTransaction(messageV0);\n};\n\n// ─── buildClaimTx ────────────────────────────────────────────────────\n\nconst encodeReceiveMessageData = (message: string, attestation: string): Buffer => {\n const msgHex = message.startsWith('0x') ? message.slice(2) : message;\n const attHex = attestation.startsWith('0x') ? attestation.slice(2) : attestation;\n const msgBytes = Buffer.from(msgHex, 'hex');\n const attBytes = Buffer.from(attHex, 'hex');\n\n const discriminator = sha256(Buffer.from('global:receive_message')).slice(0, 8);\n const totalLen = 8 + 4 + msgBytes.length + 4 + attBytes.length;\n const data = Buffer.alloc(totalLen);\n let offset = 0;\n data.set(discriminator, offset); offset += 8;\n data.writeUInt32LE(msgBytes.length, offset); offset += 4;\n data.set(msgBytes, offset); offset += msgBytes.length;\n data.writeUInt32LE(attBytes.length, offset); offset += 4;\n data.set(attBytes, offset);\n return data;\n};\n\nexport const buildClaimTx = (params: ClaimCanonicalParams): VersionedTransaction => {\n const feePayerPubkey = new PublicKey(params.feePayer);\n const userPubkey = new PublicKey(params.userAddress);\n const destinationPubkey = new PublicKey(params.destinationAddress);\n\n const fromChain = mapChainToBridgeKit(params.sourceChain);\n const toChain = getSolanaChain();\n\n const v2config = toChain.cctp.contracts.v2;\n if (!v2config || v2config.type !== 'split') {\n throw new Error('Unsupported CCTP v2 contract configuration for Solana.');\n }\n\n const tokenMessengerProgramId = new PublicKey(v2config.tokenMessenger);\n const messageTransmitterProgramId = new PublicKey(v2config.messageTransmitter);\n\n const pdas = derivePdas(fromChain, toChain, messageTransmitterProgramId, tokenMessengerProgramId);\n\n const nonceHex = params.eventNonce.replace(/^0x/, '');\n if (nonceHex.length !== 64) {\n throw new Error(`Invalid eventNonce: expected 64 hex chars, got ${nonceHex.length}`);\n }\n const nonceBuf = Buffer.from(nonceHex, 'hex');\n const [usedNoncePda] = PublicKey.findProgramAddressSync(\n [Buffer.from('used_nonce'), nonceBuf], messageTransmitterProgramId);\n\n const [eventAuthority] = PublicKey.findProgramAddressSync(\n [Buffer.from('__event_authority')], tokenMessengerProgramId);\n\n const usdcMint = new PublicKey(toChain.usdcAddress);\n const userUsdcAta = getAssociatedTokenAddress(usdcMint, destinationPubkey);\n const feePayerAta = getAssociatedTokenAddress(usdcMint, feePayerPubkey);\n const feeRecipientPubkey = new PublicKey(params.feeRecipient);\n const feeRecipientAta = getAssociatedTokenAddress(usdcMint, feeRecipientPubkey);\n\n const instructionData = encodeReceiveMessageData(params.message, params.attestation);\n\n const receiveMessageIx = new TransactionInstruction({\n programId: messageTransmitterProgramId,\n data: instructionData,\n keys: [\n { pubkey: feePayerPubkey, isSigner: true, isWritable: true },\n { pubkey: feePayerPubkey, isSigner: true, isWritable: false },\n { pubkey: pdas.messageTransmitterAuthorityPda, isSigner: false, isWritable: false },\n { pubkey: pdas.messageTransmitterPda, isSigner: false, isWritable: true },\n { pubkey: usedNoncePda, isSigner: false, isWritable: true },\n { pubkey: tokenMessengerProgramId, isSigner: false, isWritable: false },\n { pubkey: SYSTEM_PROGRAM_ID, isSigner: false, isWritable: false },\n { pubkey: pdas.tokenMessengerPda, isSigner: false, isWritable: false },\n { pubkey: pdas.remoteTokenMessengerPda, isSigner: false, isWritable: false },\n { pubkey: pdas.tokenMinterPda, isSigner: false, isWritable: true },\n { pubkey: pdas.localTokenPda, isSigner: false, isWritable: true },\n { pubkey: pdas.tokenPairPda, isSigner: false, isWritable: false },\n { pubkey: feeRecipientAta, isSigner: false, isWritable: true },\n { pubkey: userUsdcAta, isSigner: false, isWritable: true },\n { pubkey: pdas.custodyPda, isSigner: false, isWritable: true },\n { pubkey: TOKEN_PROGRAM_ID, isSigner: false, isWritable: false },\n { pubkey: eventAuthority, isSigner: false, isWritable: false },\n { pubkey: tokenMessengerProgramId, isSigner: false, isWritable: false },\n ],\n });\n\n const instructions: TransactionInstruction[] = [];\n\n instructions.push(\n ComputeBudgetProgram.setComputeUnitPrice({\n microLamports: params.computeUnitPrice ?? DEFAULT_COMPUTE_UNIT_PRICE,\n }),\n ComputeBudgetProgram.setComputeUnitLimit({\n units: params.computeUnitLimit ?? DEFAULT_COMPUTE_UNIT_LIMIT,\n }),\n );\n\n if (params.needsUserAta) {\n instructions.push(buildCreateAtaInstruction(feePayerPubkey, userUsdcAta, destinationPubkey, usdcMint));\n }\n if (params.needsFeePayerAta) {\n instructions.push(buildCreateAtaInstruction(feePayerPubkey, feePayerAta, feePayerPubkey, usdcMint));\n }\n\n instructions.push(receiveMessageIx);\n\n const feeAmount = BigInt(params.usdcFeeMicroUnits ?? DEFAULT_USDC_FEE_MICRO_UNITS);\n instructions.push(buildSplTransferInstruction(userUsdcAta, feePayerAta, userPubkey, feeAmount));\n\n const solRebate = params.solRebateLamports ?? DEFAULT_SOL_REBATE_LAMPORTS;\n instructions.push(buildSystemTransferInstruction(feePayerPubkey, userPubkey, solRebate));\n\n const normalizedInstructions = instructions.map((ix) => {\n const newKeys = ix.keys.map((meta) => {\n if (meta.pubkey.equals(feePayerPubkey)) {\n return { ...meta, isSigner: true, isWritable: meta.isWritable ?? true };\n }\n if (meta.pubkey.equals(userPubkey)) {\n return { ...meta, isSigner: true };\n }\n return { ...meta, isSigner: false };\n });\n return new TransactionInstruction({ programId: ix.programId, data: ix.data, keys: newKeys });\n });\n\n const lookupTableKey = new PublicKey(params.lookupTableAddress);\n const lookupTableAccount = new AddressLookupTableAccount({\n key: lookupTableKey,\n state: AddressLookupTableAccount.deserialize(\n createLookupTableState(params.lookupTableAddresses.map((a) => new PublicKey(a)))\n ),\n });\n\n const messageV0 = new TransactionMessage({\n payerKey: feePayerPubkey,\n recentBlockhash: params.blockhash,\n instructions: normalizedInstructions,\n }).compileToV0Message([lookupTableAccount]);\n\n return new VersionedTransaction(messageV0);\n};\n"]}
@@ -1 +1,6 @@
1
- export { hashVersionedTransaction } from '@n1xyz/cctp-tx-builder';
1
+ import type { VersionedTransaction } from '@solana/web3.js';
2
+ /**
3
+ * Hashes a VersionedTransaction for signature verification.
4
+ * Local copy to avoid cross-package import that breaks tsc rootDir.
5
+ */
6
+ export declare const hashVersionedTransaction: (tx: VersionedTransaction) => string;
@@ -1,2 +1,11 @@
1
- export { hashVersionedTransaction } from '@n1xyz/cctp-tx-builder';
1
+ import { sha256 } from '@noble/hashes/sha2';
2
+ import { bytesToHex } from '@noble/hashes/utils';
3
+ /**
4
+ * Hashes a VersionedTransaction for signature verification.
5
+ * Local copy to avoid cross-package import that breaks tsc rootDir.
6
+ */
7
+ export var hashVersionedTransaction = function (tx) {
8
+ var serialized = tx.serialize();
9
+ return bytesToHex(sha256(serialized));
10
+ };
2
11
  //# sourceMappingURL=solanaClaim.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"solanaClaim.js","sourceRoot":"","sources":["../../../../src/features/onboarding-flow/cctp/solanaClaim.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,wBAAwB,EAAE,MAAM,wBAAwB,CAAC","sourcesContent":["export { hashVersionedTransaction } from '@n1xyz/cctp-tx-builder';\n"]}
1
+ {"version":3,"file":"solanaClaim.js","sourceRoot":"","sources":["../../../../src/features/onboarding-flow/cctp/solanaClaim.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,MAAM,EAAE,MAAM,oBAAoB,CAAC;AAC5C,OAAO,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAC;AAEjD;;;GAGG;AACH,MAAM,CAAC,IAAM,wBAAwB,GAAG,UAAC,EAAwB;IAC/D,IAAM,UAAU,GAAG,EAAE,CAAC,SAAS,EAAE,CAAC;IAClC,OAAO,UAAU,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC,CAAC;AACxC,CAAC,CAAC","sourcesContent":["import type { VersionedTransaction } from '@solana/web3.js';\nimport { sha256 } from '@noble/hashes/sha2';\nimport { bytesToHex } from '@noble/hashes/utils';\n\n/**\n * Hashes a VersionedTransaction for signature verification.\n * Local copy to avoid cross-package import that breaks tsc rootDir.\n */\nexport const hashVersionedTransaction = (tx: VersionedTransaction): string => {\n const serialized = tx.serialize();\n return bytesToHex(sha256(serialized));\n};\n"]}
@@ -134,11 +134,10 @@ var validateClaimTransaction = function (tx, destinationAddress) {
134
134
  }
135
135
  };
136
136
  var buildSignAndSubmitClaimTx = function (_a) { return __awaiter(void 0, [_a], void 0, function (_b) {
137
- var signer, prepared, tx, buildClaimTx, canonical, txBytes, userKey, preSignAccountKeys, numRequiredSigners, userSignerIndex, signed, accountKeys, sigIndex, sig, userSignatureBase64, txHash, submission;
138
- var _c;
137
+ var signer, prepared, txBytes, tx, userKey, preSignAccountKeys, numRequiredSigners, userSignerIndex, signed, accountKeys, sigIndex, sig, userSignatureBase64, txHash, submission;
139
138
  var depositId = _b.depositId, message = _b.message, attestation = _b.attestation, sourceChain = _b.sourceChain, destinationAddress = _b.destinationAddress, lookupTableAddress = _b.lookupTableAddress, solanaWallet = _b.solanaWallet;
140
- return __generator(this, function (_d) {
141
- switch (_d.label) {
139
+ return __generator(this, function (_c) {
140
+ switch (_c.label) {
142
141
  case 0:
143
142
  if (!lookupTableAddress) {
144
143
  throw new Error('CCTP lookup table not configured (NEXT_PUBLIC_CCTP_LOOKUP_TABLE_ADDRESS)');
@@ -152,7 +151,7 @@ var buildSignAndSubmitClaimTx = function (_a) { return __awaiter(void 0, [_a], v
152
151
  }
153
152
  return [4 /*yield*/, solanaWallet.getSigner()];
154
153
  case 1:
155
- signer = _d.sent();
154
+ signer = _c.sent();
156
155
  if (!(signer === null || signer === void 0 ? void 0 : signer.signTransaction)) {
157
156
  throw new Error('Connected wallet cannot sign transactions');
158
157
  }
@@ -164,28 +163,11 @@ var buildSignAndSubmitClaimTx = function (_a) { return __awaiter(void 0, [_a], v
164
163
  lookupTableAddress: lookupTableAddress,
165
164
  })];
166
165
  case 2:
167
- prepared = _d.sent();
168
- if (!prepared.canonicalParams) return [3 /*break*/, 4];
169
- return [4 /*yield*/, import('@n1xyz/cctp-tx-builder')];
170
- case 3:
171
- buildClaimTx = (_d.sent()).buildClaimTx;
172
- canonical = prepared.canonicalParams;
173
- // Validate canonical params match what the user expects
174
- if (canonical.destinationAddress !== destinationAddress) {
175
- throw new Error('Canonical params destination address mismatch');
176
- }
177
- if (((_c = canonical.sourceChain) === null || _c === void 0 ? void 0 : _c.toLowerCase()) !== sourceChain.toLowerCase()) {
178
- throw new Error('Canonical params source chain mismatch');
179
- }
180
- tx = buildClaimTx(canonical);
181
- return [3 /*break*/, 5];
182
- case 4:
166
+ prepared = _c.sent();
183
167
  txBytes = Buffer.from(prepared.tx, 'base64');
184
168
  tx = VersionedTransaction.deserialize(txBytes);
185
169
  // Validate the transaction only contains expected CCTP instructions and references USDC
186
170
  validateClaimTransaction(tx, destinationAddress);
187
- _d.label = 5;
188
- case 5:
189
171
  userKey = new PublicKey(destinationAddress);
190
172
  preSignAccountKeys = tx.message.staticAccountKeys;
191
173
  numRequiredSigners = tx.message.header.numRequiredSignatures;
@@ -194,8 +176,8 @@ var buildSignAndSubmitClaimTx = function (_a) { return __awaiter(void 0, [_a], v
194
176
  throw new Error('Server-provided transaction does not include the user wallet as a required signer');
195
177
  }
196
178
  return [4 /*yield*/, signer.signTransaction(tx)];
197
- case 6:
198
- signed = _d.sent();
179
+ case 3:
180
+ signed = _c.sent();
199
181
  if (!(signed instanceof VersionedTransaction)) {
200
182
  throw new Error('Lookup-table claims require a VersionedTransaction');
201
183
  }
@@ -214,8 +196,8 @@ var buildSignAndSubmitClaimTx = function (_a) { return __awaiter(void 0, [_a], v
214
196
  userSignature: userSignatureBase64,
215
197
  txHash: txHash,
216
198
  })];
217
- case 7:
218
- submission = _d.sent();
199
+ case 4:
200
+ submission = _c.sent();
219
201
  if (!(submission === null || submission === void 0 ? void 0 : submission.tx)) {
220
202
  throw new Error('Bridge Assist did not return a transaction signature');
221
203
  }
@@ -233,7 +215,7 @@ export var submitClaimWithRetry = function (params) { return __awaiter(void 0, v
233
215
  MAX_RETRIES = 1;
234
216
  retryCount = 0;
235
217
  attemptSubmit = function () { return __awaiter(void 0, void 0, void 0, function () {
236
- var error_1, errorName, isBridgeAssistError, errorStatus, is404Error, status_1, reattestDeposit, _a, retryAfterMs;
218
+ var error_1, errorName, isBridgeAssistError, errorStatus, is404Error, errorMessage, isMessageExpired, status_1, isRetryableError, reattestDeposit, _a, baseDelay, retryAfterMs;
237
219
  var _b, _c;
238
220
  return __generator(this, function (_d) {
239
221
  switch (_d.label) {
@@ -266,11 +248,15 @@ export var submitClaimWithRetry = function (params) { return __awaiter(void 0, v
266
248
  return [4 /*yield*/, attemptSubmit()];
267
249
  case 4: return [2 /*return*/, _d.sent()]; // Recursive retry after creating deposit
268
250
  case 5:
269
- if (!isBridgeAssistError) return [3 /*break*/, 13];
251
+ errorMessage = error_1 instanceof Error ? error_1.message : String(error_1);
252
+ isMessageExpired = /MessageExpired|0x1780/i.test(errorMessage);
270
253
  status_1 = typeof errorStatus === 'number' ? errorStatus : undefined;
271
- if (!((typeof status_1 === 'number' && status_1 >= 500) || status_1 == null)) return [3 /*break*/, 13];
254
+ isRetryableError = isBridgeAssistError && ((typeof status_1 === 'number' && status_1 >= 500) ||
255
+ status_1 == null ||
256
+ isMessageExpired);
257
+ if (!isRetryableError) return [3 /*break*/, 13];
272
258
  if (retryCount >= MAX_RETRIES) {
273
- throw error_1; // Re-throw original error if max retries exceeded
259
+ throw error_1;
274
260
  }
275
261
  _d.label = 6;
276
262
  case 6:
@@ -286,13 +272,14 @@ export var submitClaimWithRetry = function (params) { return __awaiter(void 0, v
286
272
  _a = _d.sent();
287
273
  return [3 /*break*/, 10];
288
274
  case 10:
289
- retryAfterMs = ((_c = error_1.retryAfter) !== null && _c !== void 0 ? _c : 3) * 1000;
275
+ baseDelay = isMessageExpired ? 10 : ((_c = error_1.retryAfter) !== null && _c !== void 0 ? _c : 3);
276
+ retryAfterMs = baseDelay * 1000;
290
277
  return [4 /*yield*/, delay(Math.min(Math.max(retryAfterMs, 1000), 15000))];
291
278
  case 11:
292
279
  _d.sent();
293
280
  retryCount++;
294
281
  return [4 /*yield*/, attemptSubmit()];
295
- case 12: return [2 /*return*/, _d.sent()]; // Recursive retry after server error
282
+ case 12: return [2 /*return*/, _d.sent()];
296
283
  case 13:
297
284
  // For all other errors, throw immediately
298
285
  throw error_1;
@@ -1 +1 @@
1
- {"version":3,"file":"claimSubmission.js","sourceRoot":"","sources":["../../../../../src/features/onboarding-flow/utils/deposit/claimSubmission.ts"],"names":[],"mappings":"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","sourcesContent":["import { Buffer } from 'buffer';\nimport { ComputeBudgetProgram, PublicKey, SystemProgram, VersionedTransaction } from '@solana/web3.js';\nimport { BridgeAssistError } from '../../bridge-assist/types';\nimport { createBridgeDeposit, prepareClaimTx, submitClaimTx } from '../../bridge-assist';\nimport { mapChainToBridgeKit } from '../../cctp/bridgeKitClient';\nimport { hashVersionedTransaction } from '../../cctp/solanaClaim';\nimport { delay } from './solanaUtils';\n\n// Well-known Solana program IDs used in CCTP claim transactions\nconst SPL_TOKEN_PROGRAM_ID = 'TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA';\nconst ASSOCIATED_TOKEN_PROGRAM_ID = 'ATokenGPvbdGVxr1b2hvZbsiqW5xWH25efTNsLJA8knL';\n\n/**\n * Validates that a server-provided claim transaction only contains expected CCTP\n * instructions. This prevents signing a malicious transaction if the Bridge Assist\n * server is compromised or misconfigured.\n *\n * Checks:\n * 1. Every instruction targets a program in the allowlist (CCTP v1/v2, ComputeBudget,\n * SPL Token, Associated Token Account). SystemProgram instructions are validated\n * individually to ensure the user is never the source of a SOL transfer.\n * 2. The Solana USDC mint address appears in the transaction's account keys\n */\nconst validateClaimTransaction = (tx: VersionedTransaction, destinationAddress: string): void => {\n const solanaChain = mapChainToBridgeKit('solana');\n const contracts = solanaChain.cctp?.contracts;\n if (!contracts) {\n throw new Error('Cannot validate claim transaction: CCTP contracts not found for Solana');\n }\n\n // Programs unconditionally allowed (purpose-specific, not exploitable for fund drain)\n const allowedProgramIds = new Set<string>([\n contracts.v1.messageTransmitter,\n contracts.v1.tokenMessenger,\n contracts.v2.messageTransmitter,\n contracts.v2.tokenMessenger,\n ComputeBudgetProgram.programId.toBase58(),\n SPL_TOKEN_PROGRAM_ID, // USDC fee transfer\n ASSOCIATED_TOKEN_PROGRAM_ID, // optional ATA creation\n ]);\n\n const systemProgramId = SystemProgram.programId.toBase58();\n const accountKeys = tx.message.staticAccountKeys;\n const userKey = new PublicKey(destinationAddress);\n\n // Check 1: All instruction program IDs must be in the allowlist.\n // SystemProgram is NOT blanket-allowed — each SystemProgram instruction is validated\n // individually to prevent a malicious SOL transfer from the user's wallet.\n const compiledInstructions = tx.message.compiledInstructions;\n for (const ix of compiledInstructions) {\n const programKey = accountKeys[ix.programIdIndex];\n if (!programKey) {\n throw new Error('Claim transaction contains an instruction with an invalid program ID index');\n }\n const programId = programKey.toBase58();\n\n if (programId === systemProgramId) {\n // Validate SystemProgram instructions: only allow transfer (discriminator = 2)\n // where the user is NOT the source. The legitimate use is a SOL rebate FROM\n // the fee payer TO the user.\n const data = Buffer.from(ix.data);\n if (data.length < 4) {\n throw new Error(\n 'Claim transaction contains a SystemProgram instruction with invalid data. ' +\n 'Transaction rejected to protect your wallet.'\n );\n }\n const discriminator = data.readUInt32LE(0);\n // SystemProgram instruction types: 0=CreateAccount, 2=Transfer, 3=CreateAccountWithSeed, etc.\n if (discriminator !== 2) {\n throw new Error(\n `Claim transaction contains an unexpected SystemProgram instruction (type ${discriminator}). ` +\n 'Transaction rejected to protect your wallet.'\n );\n }\n // For SystemProgram::Transfer: account[0] = from (signer), account[1] = to\n // The 'from' must be a signer, so its index is always within staticAccountKeys.\n const fromAccountIndex = ix.accountKeyIndexes[0];\n const fromKey = fromAccountIndex < accountKeys.length ? accountKeys[fromAccountIndex] : null;\n if (fromKey && fromKey.equals(userKey)) {\n throw new Error(\n 'Claim transaction contains a SOL transfer from the user wallet. ' +\n 'Transaction rejected to protect your wallet.'\n );\n }\n continue;\n }\n\n if (!allowedProgramIds.has(programId)) {\n throw new Error(\n `Claim transaction contains an unexpected program: ${programId}. ` +\n 'Transaction rejected to protect your wallet.'\n );\n }\n }\n\n // Check 2: USDC mint must appear in the transaction's account keys.\n // Skip when address lookup tables are used — the lookup table is controlled by us\n // (NEXT_PUBLIC_CCTP_LOOKUP_TABLE_ADDRESS), so accounts loaded from it are trusted.\n const usesLookupTable = tx.message.addressTableLookups.length > 0;\n if (!usesLookupTable) {\n const usdcMint = solanaChain.usdcAddress;\n if (!usdcMint) {\n throw new Error('Cannot validate claim transaction: USDC address not found for Solana');\n }\n const usdcKey = new PublicKey(usdcMint);\n const hasUsdcMint = accountKeys.some((k) => k.equals(usdcKey));\n if (!hasUsdcMint) {\n throw new Error(\n 'Claim transaction does not reference the expected USDC mint. ' +\n 'Transaction rejected to protect your wallet.'\n );\n }\n }\n};\n\ntype SolanaWalletLike = {\n chain?: string;\n getSigner: () => Promise<{ signTransaction?: (tx: unknown) => Promise<unknown> } | null>;\n};\n\nexport interface SubmitClaimWithRetryParams {\n depositId: string;\n message: string;\n attestation: string;\n sourceChain: string;\n destinationAddress: string;\n lookupTableAddress: string;\n solanaWallet: SolanaWalletLike;\n fallbackWallet: string;\n fallbackAmount: string;\n bridgeTx: string;\n attestationId: string | null;\n}\n\nconst buildSignAndSubmitClaimTx = async ({\n depositId,\n message,\n attestation,\n sourceChain,\n destinationAddress,\n lookupTableAddress,\n solanaWallet,\n}: Omit<SubmitClaimWithRetryParams, 'fallbackWallet' | 'fallbackAmount' | 'bridgeTx' | 'attestationId'>): Promise<string> => {\n if (!lookupTableAddress) {\n throw new Error('CCTP lookup table not configured (NEXT_PUBLIC_CCTP_LOOKUP_TABLE_ADDRESS)');\n }\n if (!depositId) throw new Error('Missing deposit ID for claim transaction');\n if (!solanaWallet) throw new Error('Solana wallet not connected. Please connect your wallet to finish the claim.');\n if (solanaWallet.chain && solanaWallet.chain !== 'SOL') {\n throw new Error('Connected wallet is not a Solana wallet');\n }\n\n const signer = await solanaWallet.getSigner();\n if (!signer?.signTransaction) {\n throw new Error('Connected wallet cannot sign transactions');\n }\n\n // Phase 1: Server builds the unsigned claim tx and returns canonical params\n const prepared = await prepareClaimTx(depositId, {\n message,\n attestation,\n sourceChain,\n destinationAddress,\n lookupTableAddress,\n });\n\n let tx: VersionedTransaction;\n\n if (prepared.canonicalParams) {\n // Canonical rebuild path: build tx locally from canonical params.\n // The widget never signs raw bytes from the server.\n const { buildClaimTx } = await import('@n1xyz/cctp-tx-builder');\n const canonical = prepared.canonicalParams;\n\n // Validate canonical params match what the user expects\n if (canonical.destinationAddress !== destinationAddress) {\n throw new Error('Canonical params destination address mismatch');\n }\n if (canonical.sourceChain?.toLowerCase() !== sourceChain.toLowerCase()) {\n throw new Error('Canonical params source chain mismatch');\n }\n\n tx = buildClaimTx(canonical);\n } else {\n // Legacy fallback: server didn't return canonical params, use serialized tx\n // with allowlist validation (pre-canonical security model)\n const txBytes = Buffer.from(prepared.tx, 'base64');\n tx = VersionedTransaction.deserialize(txBytes);\n\n // Validate the transaction only contains expected CCTP instructions and references USDC\n validateClaimTransaction(tx, destinationAddress);\n }\n\n // Verify the user's public key is a REQUIRED signer (index < numRequiredSignatures)\n // before signing. This prevents signing a tx where the user is just a non-signer account.\n const userKey = new PublicKey(destinationAddress);\n const preSignAccountKeys = tx.message.staticAccountKeys;\n const numRequiredSigners = tx.message.header.numRequiredSignatures;\n const userSignerIndex = preSignAccountKeys.findIndex((k) => k.equals(userKey));\n if (userSignerIndex < 0 || userSignerIndex >= numRequiredSigners) {\n throw new Error('Server-provided transaction does not include the user wallet as a required signer');\n }\n\n // Phase 2: Client signs with wallet\n const signed = await signer.signTransaction(tx as any);\n if (!(signed instanceof VersionedTransaction)) {\n throw new Error('Lookup-table claims require a VersionedTransaction');\n }\n\n // Extract user signature (reuse userKey from pre-sign validation above)\n const accountKeys = signed.message.staticAccountKeys;\n const sigIndex = accountKeys.findIndex((k) => k.equals(userKey));\n if (sigIndex < 0) {\n throw new Error('User pubkey not found in transaction account keys');\n }\n const sig = signed.signatures[sigIndex];\n if (!sig) {\n throw new Error('User signature missing after signing');\n }\n\n const userSignatureBase64 = Buffer.from(sig).toString('base64');\n const txHash = hashVersionedTransaction(signed as any);\n\n // Phase 3: Server adds fee payer signature and broadcasts\n const submission = await submitClaimTx(depositId, {\n userSignature: userSignatureBase64,\n txHash,\n });\n\n if (!submission?.tx) {\n throw new Error('Bridge Assist did not return a transaction signature');\n }\n\n return submission.tx;\n};\n\n/**\n * Submits a claim to Bridge Assist. If the deposit does not exist on the server (404),\n * it will create it and retry once. Implements retry limits to prevent infinite loops.\n */\nexport const submitClaimWithRetry = async (params: SubmitClaimWithRetryParams): Promise<string> => {\n const MAX_RETRIES = 1;\n let retryCount = 0;\n\n const attemptSubmit = async (): Promise<string> => {\n try {\n return await buildSignAndSubmitClaimTx(params);\n } catch (error) {\n // Check if this is a BridgeAssistError by name (more reliable across module boundaries)\n const errorName = error instanceof Error ? error.name : 'unknown';\n const isBridgeAssistError = error instanceof BridgeAssistError || errorName === 'BridgeAssistError';\n const errorStatus = isBridgeAssistError ? (error as any).status : undefined;\n\n // Check for 404 first (deposit doesn't exist) - this takes precedence\n const is404Error = isBridgeAssistError && errorStatus === 404;\n if (is404Error) {\n if (retryCount >= MAX_RETRIES) {\n throw new Error('Max retries exceeded: Unable to create deposit on Bridge Assist server');\n }\n\n await createBridgeDeposit({\n wallet: params.fallbackWallet,\n chain: params.sourceChain,\n solanaAddress: params.destinationAddress,\n amount: params.fallbackAmount,\n bridgeTx: params.bridgeTx,\n depositId: params.depositId,\n attestationId: params.attestationId ?? undefined,\n });\n\n retryCount++;\n return await attemptSubmit(); // Recursive retry after creating deposit\n }\n\n // If Bridge Assist temporarily unavailable, retry once with backoff\n if (isBridgeAssistError) {\n const status = typeof errorStatus === 'number' ? errorStatus : undefined;\n if ((typeof status === 'number' && status >= 500) || status == null) {\n if (retryCount >= MAX_RETRIES) {\n throw error; // Re-throw original error if max retries exceeded\n }\n\n // Attempt to refresh attestation via reattest before retrying.\n // If the claim failed due to an expired attestation, this will trigger\n // Circle's reattest API. The retry's prepareClaimTx will then pick up\n // the fresh attestation via tryRehydrateAttestation on the server.\n try {\n const { reattestDeposit } = await import('../../bridge-assist/client');\n await reattestDeposit(params.depositId);\n } catch {\n // Non-fatal — retry anyway with existing attestation\n }\n\n const retryAfterMs = ((error as any).retryAfter ?? 3) * 1000;\n await delay(Math.min(Math.max(retryAfterMs, 1000), 15_000));\n retryCount++;\n return await attemptSubmit(); // Recursive retry after server error\n }\n }\n\n // For all other errors, throw immediately\n throw error;\n }\n };\n\n return attemptSubmit();\n};\n"]}
1
+ {"version":3,"file":"claimSubmission.js","sourceRoot":"","sources":["../../../../../src/features/onboarding-flow/utils/deposit/claimSubmission.ts"],"names":[],"mappings":"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","sourcesContent":["import { Buffer } from 'buffer';\nimport { ComputeBudgetProgram, PublicKey, SystemProgram, VersionedTransaction } from '@solana/web3.js';\nimport { BridgeAssistError } from '../../bridge-assist/types';\nimport { createBridgeDeposit, prepareClaimTx, submitClaimTx } from '../../bridge-assist';\nimport { mapChainToBridgeKit } from '../../cctp/bridgeKitClient';\nimport { hashVersionedTransaction } from '../../cctp/solanaClaim';\nimport { delay } from './solanaUtils';\n\n// Well-known Solana program IDs used in CCTP claim transactions\nconst SPL_TOKEN_PROGRAM_ID = 'TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA';\nconst ASSOCIATED_TOKEN_PROGRAM_ID = 'ATokenGPvbdGVxr1b2hvZbsiqW5xWH25efTNsLJA8knL';\n\n/**\n * Validates that a server-provided claim transaction only contains expected CCTP\n * instructions. This prevents signing a malicious transaction if the Bridge Assist\n * server is compromised or misconfigured.\n *\n * Checks:\n * 1. Every instruction targets a program in the allowlist (CCTP v1/v2, ComputeBudget,\n * SPL Token, Associated Token Account). SystemProgram instructions are validated\n * individually to ensure the user is never the source of a SOL transfer.\n * 2. The Solana USDC mint address appears in the transaction's account keys\n */\nconst validateClaimTransaction = (tx: VersionedTransaction, destinationAddress: string): void => {\n const solanaChain = mapChainToBridgeKit('solana');\n const contracts = solanaChain.cctp?.contracts;\n if (!contracts) {\n throw new Error('Cannot validate claim transaction: CCTP contracts not found for Solana');\n }\n\n // Programs unconditionally allowed (purpose-specific, not exploitable for fund drain)\n const allowedProgramIds = new Set<string>([\n contracts.v1.messageTransmitter,\n contracts.v1.tokenMessenger,\n contracts.v2.messageTransmitter,\n contracts.v2.tokenMessenger,\n ComputeBudgetProgram.programId.toBase58(),\n SPL_TOKEN_PROGRAM_ID, // USDC fee transfer\n ASSOCIATED_TOKEN_PROGRAM_ID, // optional ATA creation\n ]);\n\n const systemProgramId = SystemProgram.programId.toBase58();\n const accountKeys = tx.message.staticAccountKeys;\n const userKey = new PublicKey(destinationAddress);\n\n // Check 1: All instruction program IDs must be in the allowlist.\n // SystemProgram is NOT blanket-allowed — each SystemProgram instruction is validated\n // individually to prevent a malicious SOL transfer from the user's wallet.\n const compiledInstructions = tx.message.compiledInstructions;\n for (const ix of compiledInstructions) {\n const programKey = accountKeys[ix.programIdIndex];\n if (!programKey) {\n throw new Error('Claim transaction contains an instruction with an invalid program ID index');\n }\n const programId = programKey.toBase58();\n\n if (programId === systemProgramId) {\n // Validate SystemProgram instructions: only allow transfer (discriminator = 2)\n // where the user is NOT the source. The legitimate use is a SOL rebate FROM\n // the fee payer TO the user.\n const data = Buffer.from(ix.data);\n if (data.length < 4) {\n throw new Error(\n 'Claim transaction contains a SystemProgram instruction with invalid data. ' +\n 'Transaction rejected to protect your wallet.'\n );\n }\n const discriminator = data.readUInt32LE(0);\n // SystemProgram instruction types: 0=CreateAccount, 2=Transfer, 3=CreateAccountWithSeed, etc.\n if (discriminator !== 2) {\n throw new Error(\n `Claim transaction contains an unexpected SystemProgram instruction (type ${discriminator}). ` +\n 'Transaction rejected to protect your wallet.'\n );\n }\n // For SystemProgram::Transfer: account[0] = from (signer), account[1] = to\n // The 'from' must be a signer, so its index is always within staticAccountKeys.\n const fromAccountIndex = ix.accountKeyIndexes[0];\n const fromKey = fromAccountIndex < accountKeys.length ? accountKeys[fromAccountIndex] : null;\n if (fromKey && fromKey.equals(userKey)) {\n throw new Error(\n 'Claim transaction contains a SOL transfer from the user wallet. ' +\n 'Transaction rejected to protect your wallet.'\n );\n }\n continue;\n }\n\n if (!allowedProgramIds.has(programId)) {\n throw new Error(\n `Claim transaction contains an unexpected program: ${programId}. ` +\n 'Transaction rejected to protect your wallet.'\n );\n }\n }\n\n // Check 2: USDC mint must appear in the transaction's account keys.\n // Skip when address lookup tables are used — the lookup table is controlled by us\n // (NEXT_PUBLIC_CCTP_LOOKUP_TABLE_ADDRESS), so accounts loaded from it are trusted.\n const usesLookupTable = tx.message.addressTableLookups.length > 0;\n if (!usesLookupTable) {\n const usdcMint = solanaChain.usdcAddress;\n if (!usdcMint) {\n throw new Error('Cannot validate claim transaction: USDC address not found for Solana');\n }\n const usdcKey = new PublicKey(usdcMint);\n const hasUsdcMint = accountKeys.some((k) => k.equals(usdcKey));\n if (!hasUsdcMint) {\n throw new Error(\n 'Claim transaction does not reference the expected USDC mint. ' +\n 'Transaction rejected to protect your wallet.'\n );\n }\n }\n};\n\ntype SolanaWalletLike = {\n chain?: string;\n getSigner: () => Promise<{ signTransaction?: (tx: unknown) => Promise<unknown> } | null>;\n};\n\nexport interface SubmitClaimWithRetryParams {\n depositId: string;\n message: string;\n attestation: string;\n sourceChain: string;\n destinationAddress: string;\n lookupTableAddress: string;\n solanaWallet: SolanaWalletLike;\n fallbackWallet: string;\n fallbackAmount: string;\n bridgeTx: string;\n attestationId: string | null;\n}\n\nconst buildSignAndSubmitClaimTx = async ({\n depositId,\n message,\n attestation,\n sourceChain,\n destinationAddress,\n lookupTableAddress,\n solanaWallet,\n}: Omit<SubmitClaimWithRetryParams, 'fallbackWallet' | 'fallbackAmount' | 'bridgeTx' | 'attestationId'>): Promise<string> => {\n if (!lookupTableAddress) {\n throw new Error('CCTP lookup table not configured (NEXT_PUBLIC_CCTP_LOOKUP_TABLE_ADDRESS)');\n }\n if (!depositId) throw new Error('Missing deposit ID for claim transaction');\n if (!solanaWallet) throw new Error('Solana wallet not connected. Please connect your wallet to finish the claim.');\n if (solanaWallet.chain && solanaWallet.chain !== 'SOL') {\n throw new Error('Connected wallet is not a Solana wallet');\n }\n\n const signer = await solanaWallet.getSigner();\n if (!signer?.signTransaction) {\n throw new Error('Connected wallet cannot sign transactions');\n }\n\n // Phase 1: Server builds the unsigned claim tx\n const prepared = await prepareClaimTx(depositId, {\n message,\n attestation,\n sourceChain,\n destinationAddress,\n lookupTableAddress,\n });\n\n // Deserialize the unsigned tx from the server\n const txBytes = Buffer.from(prepared.tx, 'base64');\n const tx = VersionedTransaction.deserialize(txBytes);\n\n // Validate the transaction only contains expected CCTP instructions and references USDC\n validateClaimTransaction(tx, destinationAddress);\n\n // Verify the user's public key is a REQUIRED signer (index < numRequiredSignatures)\n // before signing. This prevents signing a tx where the user is just a non-signer account.\n const userKey = new PublicKey(destinationAddress);\n const preSignAccountKeys = tx.message.staticAccountKeys;\n const numRequiredSigners = tx.message.header.numRequiredSignatures;\n const userSignerIndex = preSignAccountKeys.findIndex((k) => k.equals(userKey));\n if (userSignerIndex < 0 || userSignerIndex >= numRequiredSigners) {\n throw new Error('Server-provided transaction does not include the user wallet as a required signer');\n }\n\n // Phase 2: Client signs with wallet\n const signed = await signer.signTransaction(tx as any);\n if (!(signed instanceof VersionedTransaction)) {\n throw new Error('Lookup-table claims require a VersionedTransaction');\n }\n\n // Extract user signature (reuse userKey from pre-sign validation above)\n const accountKeys = signed.message.staticAccountKeys;\n const sigIndex = accountKeys.findIndex((k) => k.equals(userKey));\n if (sigIndex < 0) {\n throw new Error('User pubkey not found in transaction account keys');\n }\n const sig = signed.signatures[sigIndex];\n if (!sig) {\n throw new Error('User signature missing after signing');\n }\n\n const userSignatureBase64 = Buffer.from(sig).toString('base64');\n const txHash = hashVersionedTransaction(signed as any);\n\n // Phase 3: Server adds fee payer signature and broadcasts\n const submission = await submitClaimTx(depositId, {\n userSignature: userSignatureBase64,\n txHash,\n });\n\n if (!submission?.tx) {\n throw new Error('Bridge Assist did not return a transaction signature');\n }\n\n return submission.tx;\n};\n\n/**\n * Submits a claim to Bridge Assist. If the deposit does not exist on the server (404),\n * it will create it and retry once. Implements retry limits to prevent infinite loops.\n */\nexport const submitClaimWithRetry = async (params: SubmitClaimWithRetryParams): Promise<string> => {\n const MAX_RETRIES = 1;\n let retryCount = 0;\n\n const attemptSubmit = async (): Promise<string> => {\n try {\n return await buildSignAndSubmitClaimTx(params);\n } catch (error) {\n // Check if this is a BridgeAssistError by name (more reliable across module boundaries)\n const errorName = error instanceof Error ? error.name : 'unknown';\n const isBridgeAssistError = error instanceof BridgeAssistError || errorName === 'BridgeAssistError';\n const errorStatus = isBridgeAssistError ? (error as any).status : undefined;\n\n // Check for 404 first (deposit doesn't exist) - this takes precedence\n const is404Error = isBridgeAssistError && errorStatus === 404;\n if (is404Error) {\n if (retryCount >= MAX_RETRIES) {\n throw new Error('Max retries exceeded: Unable to create deposit on Bridge Assist server');\n }\n\n await createBridgeDeposit({\n wallet: params.fallbackWallet,\n chain: params.sourceChain,\n solanaAddress: params.destinationAddress,\n amount: params.fallbackAmount,\n bridgeTx: params.bridgeTx,\n depositId: params.depositId,\n attestationId: params.attestationId ?? undefined,\n });\n\n retryCount++;\n return await attemptSubmit(); // Recursive retry after creating deposit\n }\n\n // Check if this is a CCTP MessageExpired error (0x1780) — needs reattest\n const errorMessage = error instanceof Error ? error.message : String(error);\n const isMessageExpired = /MessageExpired|0x1780/i.test(errorMessage);\n\n // Retry with reattest on: server errors (5xx), missing status, or MessageExpired\n const status = typeof errorStatus === 'number' ? errorStatus : undefined;\n const isRetryableError = isBridgeAssistError && (\n (typeof status === 'number' && status >= 500) ||\n status == null ||\n isMessageExpired\n );\n\n if (isRetryableError) {\n if (retryCount >= MAX_RETRIES) {\n throw error;\n }\n\n // Trigger Circle's reattest API to get a fresh attestation.\n // For MessageExpired errors, the on-chain message's attestation has passed\n // its ~24h validity window and must be re-signed before the claim can succeed.\n try {\n const { reattestDeposit } = await import('../../bridge-assist/client');\n await reattestDeposit(params.depositId);\n } catch {\n // Non-fatal — retry anyway with existing attestation\n }\n\n // Wait longer for MessageExpired to give reattest time to propagate\n const baseDelay = isMessageExpired ? 10 : ((error as any).retryAfter ?? 3);\n const retryAfterMs = baseDelay * 1000;\n await delay(Math.min(Math.max(retryAfterMs, 1000), 15_000));\n retryCount++;\n return await attemptSubmit();\n }\n\n // For all other errors, throw immediately\n throw error;\n }\n };\n\n return attemptSubmit();\n};\n"]}
@@ -162,10 +162,9 @@ var validateBurnTransaction = function (tx, params) {
162
162
  * This avoids the Turnkey wallet needing SOL for gas fees.
163
163
  */
164
164
  export var sponsoredBurnUsdcOnSolana = function (params) { return __awaiter(void 0, void 0, void 0, function () {
165
- var withdrawalId, amount, destinationChain, destinationAddress, solanaWallet, signer_1, _a, prepareBurnTx, submitBurnTx, hashVersionedTransaction, prepared, txToSign, buildBurnTx, canonical, txBytes, txAccountKeys, numRequiredSigners, userSignerIndex, signedTx, userKey_1, accountKeys, sigIndex, sig, userSignatureBase64, txHash, result, error_1, message;
166
- var _b, _c;
167
- return __generator(this, function (_d) {
168
- switch (_d.label) {
165
+ var withdrawalId, amount, destinationChain, destinationAddress, solanaWallet, signer_1, _a, prepareBurnTx, submitBurnTx, hashVersionedTransaction, prepared, txBytes, deserializedTx, txAccountKeys, numRequiredSigners, userSignerIndex, signedTx, userKey_1, accountKeys, sigIndex, sig, userSignatureBase64, txHash, result, error_1, message;
166
+ return __generator(this, function (_b) {
167
+ switch (_b.label) {
169
168
  case 0:
170
169
  withdrawalId = params.withdrawalId, amount = params.amount, destinationChain = params.destinationChain, destinationAddress = params.destinationAddress, solanaWallet = params.solanaWallet;
171
170
  logger.info('[SolanaBurn] Starting sponsored burn', {
@@ -175,9 +174,9 @@ export var sponsoredBurnUsdcOnSolana = function (params) { return __awaiter(void
175
174
  destinationAddress: destinationAddress,
176
175
  walletAddress: solanaWallet.address,
177
176
  });
178
- _d.label = 1;
177
+ _b.label = 1;
179
178
  case 1:
180
- _d.trys.push([1, 11, , 12]);
179
+ _b.trys.push([1, 8, , 9]);
181
180
  if (!amount || parseFloat(amount) <= 0) {
182
181
  throw new Error('Invalid burn amount');
183
182
  }
@@ -189,17 +188,17 @@ export var sponsoredBurnUsdcOnSolana = function (params) { return __awaiter(void
189
188
  }
190
189
  return [4 /*yield*/, solanaWallet.getSigner()];
191
190
  case 2:
192
- signer_1 = _d.sent();
191
+ signer_1 = _b.sent();
193
192
  if (!signer_1 || !signer_1.signTransaction) {
194
193
  throw new Error('Wallet does not support transaction signing');
195
194
  }
196
195
  logger.info('[SolanaBurn] Requesting server to prepare burn tx');
197
196
  return [4 /*yield*/, import('../../bridge-assist/client')];
198
197
  case 3:
199
- _a = _d.sent(), prepareBurnTx = _a.prepareBurnTx, submitBurnTx = _a.submitBurnTx;
198
+ _a = _b.sent(), prepareBurnTx = _a.prepareBurnTx, submitBurnTx = _a.submitBurnTx;
200
199
  return [4 /*yield*/, import('../../cctp/solanaClaim')];
201
200
  case 4:
202
- hashVersionedTransaction = (_d.sent()).hashVersionedTransaction;
201
+ hashVersionedTransaction = (_b.sent()).hashVersionedTransaction;
203
202
  return [4 /*yield*/, prepareBurnTx(withdrawalId, {
204
203
  userAddress: signer_1.publicKey.toBase58(),
205
204
  amount: amount,
@@ -207,55 +206,30 @@ export var sponsoredBurnUsdcOnSolana = function (params) { return __awaiter(void
207
206
  destinationAddress: destinationAddress,
208
207
  })];
209
208
  case 5:
210
- prepared = _d.sent();
209
+ prepared = _b.sent();
211
210
  logger.info('[SolanaBurn] Server prepared burn tx', {
212
211
  blockhash: prepared.blockhash,
213
212
  lastValidBlockHeight: prepared.lastValidBlockHeight,
214
- hasCanonicalParams: !!prepared.canonicalParams,
215
213
  });
216
- txToSign = void 0;
217
- if (!prepared.canonicalParams) return [3 /*break*/, 7];
218
- return [4 /*yield*/, import('@n1xyz/cctp-tx-builder')];
219
- case 6:
220
- buildBurnTx = (_d.sent()).buildBurnTx;
221
- canonical = prepared.canonicalParams;
222
- // Validate canonical params match what user requested
223
- if (String(canonical.amount) !== String(amount)) {
224
- throw new Error("Canonical params amount mismatch: server=".concat(canonical.amount, ", expected=").concat(amount));
225
- }
226
- if (((_b = canonical.destinationAddress) === null || _b === void 0 ? void 0 : _b.toLowerCase()) !== destinationAddress.toLowerCase()) {
227
- throw new Error('Canonical params destination address mismatch');
228
- }
229
- if (((_c = canonical.destinationChain) === null || _c === void 0 ? void 0 : _c.toLowerCase()) !== destinationChain.toLowerCase()) {
230
- throw new Error('Canonical params destination chain mismatch');
231
- }
232
- if (canonical.userAddress !== signer_1.publicKey.toBase58()) {
233
- throw new Error('Canonical params user address mismatch');
234
- }
235
- txToSign = buildBurnTx(canonical);
236
- logger.info('[SolanaBurn] Rebuilt burn tx from canonical params');
237
- return [3 /*break*/, 8];
238
- case 7:
239
214
  txBytes = Buffer.from(prepared.tx, 'base64');
240
- txToSign = VersionedTransaction.deserialize(txBytes);
241
- validateBurnTransaction(txToSign, {
215
+ deserializedTx = VersionedTransaction.deserialize(txBytes);
216
+ // Validate the transaction only contains expected CCTP burn instructions,
217
+ // references the correct USDC mint, and encodes the expected amount/destination/recipient
218
+ validateBurnTransaction(deserializedTx, {
242
219
  amount: amount,
243
220
  destinationChain: destinationChain,
244
221
  destinationAddress: destinationAddress,
245
222
  });
246
- logger.info('[SolanaBurn] Using legacy tx validation (no canonical params)');
247
- _d.label = 8;
248
- case 8:
249
- txAccountKeys = txToSign.message.staticAccountKeys;
250
- numRequiredSigners = txToSign.message.header.numRequiredSignatures;
223
+ txAccountKeys = deserializedTx.message.staticAccountKeys;
224
+ numRequiredSigners = deserializedTx.message.header.numRequiredSignatures;
251
225
  userSignerIndex = txAccountKeys.findIndex(function (k) { return k.equals(signer_1.publicKey); });
252
226
  if (userSignerIndex < 0 || userSignerIndex >= numRequiredSigners) {
253
- throw new Error('Transaction does not include the user wallet as a required signer');
227
+ throw new Error('Server-provided transaction does not include the user wallet as a required signer');
254
228
  }
255
229
  logger.info('[SolanaBurn] Signing with Turnkey wallet');
256
- return [4 /*yield*/, signer_1.signTransaction(txToSign)];
257
- case 9:
258
- signedTx = _d.sent();
230
+ return [4 /*yield*/, signer_1.signTransaction(deserializedTx)];
231
+ case 6:
232
+ signedTx = _b.sent();
259
233
  if (!(signedTx instanceof VersionedTransaction)) {
260
234
  throw new Error('Expected VersionedTransaction after signing');
261
235
  }
@@ -276,8 +250,8 @@ export var sponsoredBurnUsdcOnSolana = function (params) { return __awaiter(void
276
250
  userSignature: userSignatureBase64,
277
251
  txHash: txHash,
278
252
  })];
279
- case 10:
280
- result = _d.sent();
253
+ case 7:
254
+ result = _b.sent();
281
255
  logger.info('[SolanaBurn] Sponsored burn completed', {
282
256
  txHash: result.burnTx,
283
257
  explorerUrl: result.explorerUrl,
@@ -286,8 +260,8 @@ export var sponsoredBurnUsdcOnSolana = function (params) { return __awaiter(void
286
260
  txHash: result.burnTx,
287
261
  explorerUrl: result.explorerUrl,
288
262
  }];
289
- case 11:
290
- error_1 = _d.sent();
263
+ case 8:
264
+ error_1 = _b.sent();
291
265
  logger.error('[SolanaBurn] Sponsored burn failed', {
292
266
  error: error_1,
293
267
  errorMessage: error_1 instanceof Error ? error_1.message : String(error_1),
@@ -301,7 +275,7 @@ export var sponsoredBurnUsdcOnSolana = function (params) { return __awaiter(void
301
275
  cause: error_1 instanceof Error ? error_1 : undefined,
302
276
  context: { amount: amount, destinationChain: destinationChain, destinationAddress: destinationAddress },
303
277
  });
304
- case 12: return [2 /*return*/];
278
+ case 9: return [2 /*return*/];
305
279
  }
306
280
  });
307
281
  }); };
@@ -1 +1 @@
1
- {"version":3,"file":"solanaBurnUtils.js","sourceRoot":"","sources":["../../../../../src/features/onboarding-flow/utils/withdrawal/solanaBurnUtils.ts"],"names":[],"mappings":"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","sourcesContent":["import { Buffer } from 'buffer';\nimport { ComputeBudgetProgram, PublicKey, SystemProgram, Transaction, VersionedTransaction } from '@solana/web3.js';\nimport { logger } from '../../../../utils/logger';\nimport { createWithdrawalError } from './errors';\nimport { BridgeKitClient, getDomain, mapChainToBridgeKit } from '../../cctp/bridgeKitClient';\nimport {\n SOLANA_ATTESTATION_TIMEOUT_MS,\n SOLANA_ATTESTATION_RETRY_BACKOFF_MS,\n} from '../../constants/withdrawal';\n\n/**\n * Validates a server-provided burn transaction before the user signs it.\n * Prevents a compromised Bridge Assist server from tricking the user into\n * signing a malicious transaction (e.g., token drain, wrong recipient).\n *\n * Checks:\n * 1. All instruction program IDs are in the expected allowlist\n * 2. The Solana USDC mint appears in the transaction's account keys\n * 3. The burn instruction targets a CCTP TokenMessenger program\n * 4. The burn amount, destination domain, and mint recipient in instruction\n * data match what the user requested\n */\nconst validateBurnTransaction = (\n tx: VersionedTransaction,\n params: {\n amount: string;\n destinationChain: string;\n destinationAddress: string;\n }\n): void => {\n const solanaChain = mapChainToBridgeKit('solana');\n const contracts = solanaChain.cctp?.contracts;\n if (!contracts) {\n throw new Error('Cannot validate burn transaction: CCTP contracts not found for Solana');\n }\n\n // Build program ID allowlist from BridgeKit chain config + well-known Solana programs\n const allowedProgramIds = new Set<string>([\n contracts.v1.messageTransmitter,\n contracts.v1.tokenMessenger,\n contracts.v2.messageTransmitter,\n contracts.v2.tokenMessenger,\n ComputeBudgetProgram.programId.toBase58(),\n SystemProgram.programId.toBase58(),\n ]);\n\n const accountKeys = tx.message.staticAccountKeys;\n const compiledInstructions = tx.message.compiledInstructions;\n\n // Check 1: All instruction program IDs must be in the allowlist\n for (const ix of compiledInstructions) {\n const programKey = accountKeys[ix.programIdIndex];\n if (!programKey) {\n throw new Error('Burn transaction contains an instruction with an invalid program ID index');\n }\n const programId = programKey.toBase58();\n if (!allowedProgramIds.has(programId)) {\n throw new Error(\n `Burn transaction contains an unexpected program: ${programId}. ` +\n 'Transaction rejected to protect your wallet.'\n );\n }\n }\n\n // Check 2: USDC mint must appear in account keys\n const usdcMint = solanaChain.usdcAddress;\n if (!usdcMint) {\n throw new Error('Cannot validate burn transaction: USDC address not found for Solana');\n }\n const usdcKey = new PublicKey(usdcMint);\n if (!accountKeys.some((k) => k.equals(usdcKey))) {\n throw new Error(\n 'Burn transaction does not reference the expected USDC mint. ' +\n 'Transaction rejected to protect your wallet.'\n );\n }\n\n // Check 3: Find the burn instruction (targeting CCTP TokenMessenger)\n const tokenMessengerIds = new Set<string>([\n contracts.v1.tokenMessenger,\n contracts.v2.tokenMessenger,\n ]);\n\n const burnIx = compiledInstructions.find((ix) => {\n const programKey = accountKeys[ix.programIdIndex];\n return programKey && tokenMessengerIds.has(programKey.toBase58());\n });\n\n if (!burnIx) {\n throw new Error(\n 'Burn transaction does not contain a CCTP TokenMessenger instruction. ' +\n 'Transaction rejected to protect your wallet.'\n );\n }\n\n // Check 4: Validate instruction data encodes expected parameters\n // Layout: discriminator(8) + amount(8) + destDomain(4) + mintRecipient(32) + ...\n const data = Buffer.from(burnIx.data);\n if (data.length < 52) {\n throw new Error('Burn instruction data is too short to contain expected parameters');\n }\n\n // Validate amount (bytes 8-15, u64 LE)\n const expectedAmountBaseUnits = BigInt(Math.round(parseFloat(params.amount) * 1e6));\n // Read u64 LE manually for cross-environment compatibility\n const amountLo = data.readUInt32LE(8);\n const amountHi = data.readUInt32LE(12);\n // eslint-disable-next-line no-bitwise\n const txAmount = BigInt(amountLo) + (BigInt(amountHi) << BigInt(32));\n if (txAmount !== expectedAmountBaseUnits) {\n throw new Error(\n `Burn amount mismatch: transaction contains ${txAmount} base units, ` +\n `expected ${expectedAmountBaseUnits}. Transaction rejected to protect your wallet.`\n );\n }\n\n // Validate destination domain (bytes 16-19, u32 LE)\n const destChain = mapChainToBridgeKit(params.destinationChain);\n const expectedDomain = getDomain(destChain);\n if (expectedDomain === undefined) {\n throw new Error(`Cannot validate burn: no CCTP domain for chain \"${params.destinationChain}\"`);\n }\n const txDomain = data.readUInt32LE(16);\n if (txDomain !== expectedDomain) {\n throw new Error(\n `Burn destination domain mismatch: transaction targets domain ${txDomain}, ` +\n `expected ${expectedDomain}. Transaction rejected to protect your wallet.`\n );\n }\n\n // Validate mint recipient (bytes 20-51, 32 bytes = zero-padded EVM address)\n const txMintRecipient = data.subarray(20, 52);\n const evmHex = params.destinationAddress.replace(/^0x/i, '').toLowerCase();\n const expectedRecipientHex = '0'.repeat(24) + evmHex;\n const expectedRecipientBuf = Buffer.from(expectedRecipientHex, 'hex');\n if (!txMintRecipient.equals(expectedRecipientBuf)) {\n throw new Error(\n 'Burn recipient mismatch: transaction sends to a different address than expected. ' +\n 'Transaction rejected to protect your wallet.'\n );\n }\n};\n\n/**\n * Parameters for burning USDC on Solana via CCTP\n */\nexport interface SolanaBurnParams {\n amount: string;\n destinationChain: string;\n destinationAddress: string;\n solanaWallet: {\n address?: string;\n chain?: string;\n getSigner: () => Promise<{\n signTransaction: <T extends Transaction | VersionedTransaction>(tx: T) => Promise<T>;\n publicKey: PublicKey;\n }>;\n };\n rpcUrl?: string;\n}\n\n/**\n * Result of burning USDC on Solana\n */\nexport interface SolanaBurnResult {\n txHash: string;\n attestationId?: string;\n explorerUrl?: string;\n}\n\n/**\n * Burns USDC on Solana using a server-sponsored transaction.\n * The server builds the CCTP depositForBurn tx, signs it with the fee payer and\n * message account keypair, then the Turnkey wallet adds the user signature.\n * Finally the fully-signed tx is submitted back to the server for broadcast.\n *\n * This avoids the Turnkey wallet needing SOL for gas fees.\n */\nexport const sponsoredBurnUsdcOnSolana = async (params: {\n withdrawalId: string;\n amount: string;\n destinationChain: string;\n destinationAddress: string;\n solanaWallet: SolanaBurnParams['solanaWallet'];\n}): Promise<SolanaBurnResult> => {\n const {\n withdrawalId,\n amount,\n destinationChain,\n destinationAddress,\n solanaWallet,\n } = params;\n\n logger.info('[SolanaBurn] Starting sponsored burn', {\n withdrawalId,\n amount,\n destinationChain,\n destinationAddress,\n walletAddress: solanaWallet.address,\n });\n\n try {\n if (!amount || parseFloat(amount) <= 0) {\n throw new Error('Invalid burn amount');\n }\n if (!destinationAddress) {\n throw new Error('Destination address is required');\n }\n if (!solanaWallet.address) {\n throw new Error('Solana wallet not connected');\n }\n\n // Get signer from wallet\n const signer = await solanaWallet.getSigner();\n if (!signer || !signer.signTransaction) {\n throw new Error('Wallet does not support transaction signing');\n }\n\n logger.info('[SolanaBurn] Requesting server to prepare burn tx');\n\n const { prepareBurnTx, submitBurnTx } = await import('../../bridge-assist/client');\n const { hashVersionedTransaction } = await import('../../cctp/solanaClaim');\n\n // Step 1: Get canonical params from server\n const prepared = await prepareBurnTx(withdrawalId, {\n userAddress: signer.publicKey.toBase58(),\n amount,\n destinationChain,\n destinationAddress,\n });\n\n logger.info('[SolanaBurn] Server prepared burn tx', {\n blockhash: prepared.blockhash,\n lastValidBlockHeight: prepared.lastValidBlockHeight,\n hasCanonicalParams: !!prepared.canonicalParams,\n });\n\n let txToSign: VersionedTransaction;\n\n if (prepared.canonicalParams) {\n // Canonical rebuild path: build tx locally from canonical params.\n // The widget never signs raw bytes from the server.\n const { buildBurnTx } = await import('@n1xyz/cctp-tx-builder');\n const canonical = prepared.canonicalParams;\n\n // Validate canonical params match what user requested\n if (String(canonical.amount) !== String(amount)) {\n throw new Error(`Canonical params amount mismatch: server=${canonical.amount}, expected=${amount}`);\n }\n if (canonical.destinationAddress?.toLowerCase() !== destinationAddress.toLowerCase()) {\n throw new Error('Canonical params destination address mismatch');\n }\n if (canonical.destinationChain?.toLowerCase() !== destinationChain.toLowerCase()) {\n throw new Error('Canonical params destination chain mismatch');\n }\n if (canonical.userAddress !== signer.publicKey.toBase58()) {\n throw new Error('Canonical params user address mismatch');\n }\n\n txToSign = buildBurnTx(canonical);\n logger.info('[SolanaBurn] Rebuilt burn tx from canonical params');\n } else {\n // Legacy fallback: server didn't return canonical params, use serialized tx\n // with allowlist validation (pre-canonical security model)\n const txBytes = Buffer.from(prepared.tx, 'base64');\n txToSign = VersionedTransaction.deserialize(txBytes);\n\n validateBurnTransaction(txToSign, {\n amount,\n destinationChain,\n destinationAddress,\n });\n logger.info('[SolanaBurn] Using legacy tx validation (no canonical params)');\n }\n\n // Verify the user's public key is a REQUIRED signer\n const txAccountKeys = txToSign.message.staticAccountKeys;\n const numRequiredSigners = txToSign.message.header.numRequiredSignatures;\n const userSignerIndex = txAccountKeys.findIndex((k) => k.equals(signer.publicKey));\n if (userSignerIndex < 0 || userSignerIndex >= numRequiredSigners) {\n throw new Error('Transaction does not include the user wallet as a required signer');\n }\n\n logger.info('[SolanaBurn] Signing with Turnkey wallet');\n const signedTx = await signer.signTransaction(txToSign);\n\n if (!(signedTx instanceof VersionedTransaction)) {\n throw new Error('Expected VersionedTransaction after signing');\n }\n\n // Step 3: Extract user signature from the signed tx (same pattern as claim flow).\n // Turnkey's signTransaction may clear other signatures, so we extract just\n // the user's signature and send it separately. The server adds all 3 signatures.\n const userKey = signer.publicKey;\n const accountKeys = signedTx.message.staticAccountKeys;\n const sigIndex = accountKeys.findIndex((k) => k.equals(userKey));\n if (sigIndex < 0) {\n throw new Error('User pubkey not found in transaction account keys');\n }\n const sig = signedTx.signatures[sigIndex];\n if (!sig || sig.every((b) => b === 0)) {\n throw new Error('User signature missing after signing');\n }\n\n const userSignatureBase64 = Buffer.from(sig).toString('base64');\n const txHash = hashVersionedTransaction(signedTx as any);\n\n logger.info('[SolanaBurn] Submitting user signature to server');\n const result = await submitBurnTx(withdrawalId, {\n userSignature: userSignatureBase64,\n txHash,\n });\n\n logger.info('[SolanaBurn] Sponsored burn completed', {\n txHash: result.burnTx,\n explorerUrl: result.explorerUrl,\n });\n\n return {\n txHash: result.burnTx,\n explorerUrl: result.explorerUrl,\n };\n } catch (error) {\n logger.error('[SolanaBurn] Sponsored burn failed', {\n error,\n errorMessage: error instanceof Error ? error.message : String(error),\n withdrawalId,\n amount,\n destinationChain,\n destinationAddress,\n });\n\n const message = error instanceof Error ? error.message : 'Failed to burn USDC on Solana';\n throw createWithdrawalError('BRIDGE_FAILED', message, {\n cause: error instanceof Error ? error : undefined,\n context: { amount, destinationChain, destinationAddress },\n });\n }\n};\n\n/**\n * Waits for CCTP attestation from Circle's Iris API\n *\n * @param txHash - Solana transaction hash\n * @param timeoutMs - Maximum time to wait for attestation (default: 120 seconds)\n * @param retryBackoffMs - Time between retry attempts (default: 5 seconds)\n * @returns Attestation data including signature and message\n */\nexport const waitForSolanaAttestation = async (\n txHash: string,\n timeoutMs: number = SOLANA_ATTESTATION_TIMEOUT_MS,\n retryBackoffMs: number = SOLANA_ATTESTATION_RETRY_BACKOFF_MS\n): Promise<{\n attestation: string;\n message: string;\n decodedMessage?: any;\n}> => {\n logger.info('[SolanaBurn] Waiting for attestation', {\n txHash,\n timeoutMs,\n retryBackoffMs,\n });\n\n const client = new BridgeKitClient();\n const startTime = Date.now();\n let attempt = 0;\n let lastError: unknown = null;\n\n while (Date.now() - startTime < timeoutMs) {\n attempt++;\n\n try {\n logger.debug('[SolanaBurn] Fetching attestation attempt', {\n attempt,\n elapsed: Date.now() - startTime,\n txHash,\n });\n\n // Use BridgeKitClient's getAttestation method\n const attestationData = await client.getAttestation(txHash, 'solana');\n\n if (attestationData && attestationData.attestation && attestationData.message) {\n logger.info('[SolanaBurn] Attestation received', {\n txHash,\n attempt,\n elapsed: Date.now() - startTime,\n hasDecodedMessage: !!attestationData.decodedMessage,\n });\n\n return attestationData;\n }\n\n logger.debug('[SolanaBurn] Attestation not ready yet', {\n attempt,\n hasData: !!attestationData,\n hasAttestation: !!attestationData?.attestation,\n hasMessage: !!attestationData?.message,\n });\n } catch (error) {\n lastError = error;\n logger.warn('[SolanaBurn] Error fetching attestation', {\n attempt,\n error: error instanceof Error ? error.message : String(error),\n });\n }\n\n // Wait before next attempt\n await new Promise((resolve) => setTimeout(resolve, retryBackoffMs));\n }\n\n // Timeout reached\n const errorMessage = lastError instanceof Error\n ? lastError.message\n : lastError\n ? String(lastError)\n : 'unknown error';\n\n logger.error('[SolanaBurn] Attestation timeout', {\n txHash,\n elapsed: Date.now() - startTime,\n attempts: attempt,\n lastError: errorMessage,\n });\n\n throw new Error(`Attestation timeout after ${timeoutMs}ms (${errorMessage})`);\n};\n\n/**\n * Gets the CCTP domain for a destination chain\n */\nexport const getDestinationDomain = (chainName: string): number => {\n try {\n const chain = mapChainToBridgeKit(chainName);\n const domain = getDomain(chain);\n\n if (domain === undefined) {\n throw new Error(`No CCTP domain found for chain: ${chainName}`);\n }\n\n logger.debug('[SolanaBurn] Resolved destination domain', {\n chain: chainName,\n domain,\n });\n\n return domain;\n } catch (error) {\n logger.error('[SolanaBurn] Failed to get destination domain', {\n chain: chainName,\n error,\n });\n throw error;\n }\n};\n"]}
1
+ {"version":3,"file":"solanaBurnUtils.js","sourceRoot":"","sources":["../../../../../src/features/onboarding-flow/utils/withdrawal/solanaBurnUtils.ts"],"names":[],"mappings":"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","sourcesContent":["import { Buffer } from 'buffer';\nimport { ComputeBudgetProgram, PublicKey, SystemProgram, Transaction, VersionedTransaction } from '@solana/web3.js';\nimport { logger } from '../../../../utils/logger';\nimport { createWithdrawalError } from './errors';\nimport { BridgeKitClient, getDomain, mapChainToBridgeKit } from '../../cctp/bridgeKitClient';\nimport {\n SOLANA_ATTESTATION_TIMEOUT_MS,\n SOLANA_ATTESTATION_RETRY_BACKOFF_MS,\n} from '../../constants/withdrawal';\n\n/**\n * Validates a server-provided burn transaction before the user signs it.\n * Prevents a compromised Bridge Assist server from tricking the user into\n * signing a malicious transaction (e.g., token drain, wrong recipient).\n *\n * Checks:\n * 1. All instruction program IDs are in the expected allowlist\n * 2. The Solana USDC mint appears in the transaction's account keys\n * 3. The burn instruction targets a CCTP TokenMessenger program\n * 4. The burn amount, destination domain, and mint recipient in instruction\n * data match what the user requested\n */\nconst validateBurnTransaction = (\n tx: VersionedTransaction,\n params: {\n amount: string;\n destinationChain: string;\n destinationAddress: string;\n }\n): void => {\n const solanaChain = mapChainToBridgeKit('solana');\n const contracts = solanaChain.cctp?.contracts;\n if (!contracts) {\n throw new Error('Cannot validate burn transaction: CCTP contracts not found for Solana');\n }\n\n // Build program ID allowlist from BridgeKit chain config + well-known Solana programs\n const allowedProgramIds = new Set<string>([\n contracts.v1.messageTransmitter,\n contracts.v1.tokenMessenger,\n contracts.v2.messageTransmitter,\n contracts.v2.tokenMessenger,\n ComputeBudgetProgram.programId.toBase58(),\n SystemProgram.programId.toBase58(),\n ]);\n\n const accountKeys = tx.message.staticAccountKeys;\n const compiledInstructions = tx.message.compiledInstructions;\n\n // Check 1: All instruction program IDs must be in the allowlist\n for (const ix of compiledInstructions) {\n const programKey = accountKeys[ix.programIdIndex];\n if (!programKey) {\n throw new Error('Burn transaction contains an instruction with an invalid program ID index');\n }\n const programId = programKey.toBase58();\n if (!allowedProgramIds.has(programId)) {\n throw new Error(\n `Burn transaction contains an unexpected program: ${programId}. ` +\n 'Transaction rejected to protect your wallet.'\n );\n }\n }\n\n // Check 2: USDC mint must appear in account keys\n const usdcMint = solanaChain.usdcAddress;\n if (!usdcMint) {\n throw new Error('Cannot validate burn transaction: USDC address not found for Solana');\n }\n const usdcKey = new PublicKey(usdcMint);\n if (!accountKeys.some((k) => k.equals(usdcKey))) {\n throw new Error(\n 'Burn transaction does not reference the expected USDC mint. ' +\n 'Transaction rejected to protect your wallet.'\n );\n }\n\n // Check 3: Find the burn instruction (targeting CCTP TokenMessenger)\n const tokenMessengerIds = new Set<string>([\n contracts.v1.tokenMessenger,\n contracts.v2.tokenMessenger,\n ]);\n\n const burnIx = compiledInstructions.find((ix) => {\n const programKey = accountKeys[ix.programIdIndex];\n return programKey && tokenMessengerIds.has(programKey.toBase58());\n });\n\n if (!burnIx) {\n throw new Error(\n 'Burn transaction does not contain a CCTP TokenMessenger instruction. ' +\n 'Transaction rejected to protect your wallet.'\n );\n }\n\n // Check 4: Validate instruction data encodes expected parameters\n // Layout: discriminator(8) + amount(8) + destDomain(4) + mintRecipient(32) + ...\n const data = Buffer.from(burnIx.data);\n if (data.length < 52) {\n throw new Error('Burn instruction data is too short to contain expected parameters');\n }\n\n // Validate amount (bytes 8-15, u64 LE)\n const expectedAmountBaseUnits = BigInt(Math.round(parseFloat(params.amount) * 1e6));\n // Read u64 LE manually for cross-environment compatibility\n const amountLo = data.readUInt32LE(8);\n const amountHi = data.readUInt32LE(12);\n // eslint-disable-next-line no-bitwise\n const txAmount = BigInt(amountLo) + (BigInt(amountHi) << BigInt(32));\n if (txAmount !== expectedAmountBaseUnits) {\n throw new Error(\n `Burn amount mismatch: transaction contains ${txAmount} base units, ` +\n `expected ${expectedAmountBaseUnits}. Transaction rejected to protect your wallet.`\n );\n }\n\n // Validate destination domain (bytes 16-19, u32 LE)\n const destChain = mapChainToBridgeKit(params.destinationChain);\n const expectedDomain = getDomain(destChain);\n if (expectedDomain === undefined) {\n throw new Error(`Cannot validate burn: no CCTP domain for chain \"${params.destinationChain}\"`);\n }\n const txDomain = data.readUInt32LE(16);\n if (txDomain !== expectedDomain) {\n throw new Error(\n `Burn destination domain mismatch: transaction targets domain ${txDomain}, ` +\n `expected ${expectedDomain}. Transaction rejected to protect your wallet.`\n );\n }\n\n // Validate mint recipient (bytes 20-51, 32 bytes = zero-padded EVM address)\n const txMintRecipient = data.subarray(20, 52);\n const evmHex = params.destinationAddress.replace(/^0x/i, '').toLowerCase();\n const expectedRecipientHex = '0'.repeat(24) + evmHex;\n const expectedRecipientBuf = Buffer.from(expectedRecipientHex, 'hex');\n if (!txMintRecipient.equals(expectedRecipientBuf)) {\n throw new Error(\n 'Burn recipient mismatch: transaction sends to a different address than expected. ' +\n 'Transaction rejected to protect your wallet.'\n );\n }\n};\n\n/**\n * Parameters for burning USDC on Solana via CCTP\n */\nexport interface SolanaBurnParams {\n amount: string;\n destinationChain: string;\n destinationAddress: string;\n solanaWallet: {\n address?: string;\n chain?: string;\n getSigner: () => Promise<{\n signTransaction: <T extends Transaction | VersionedTransaction>(tx: T) => Promise<T>;\n publicKey: PublicKey;\n }>;\n };\n rpcUrl?: string;\n}\n\n/**\n * Result of burning USDC on Solana\n */\nexport interface SolanaBurnResult {\n txHash: string;\n attestationId?: string;\n explorerUrl?: string;\n}\n\n/**\n * Burns USDC on Solana using a server-sponsored transaction.\n * The server builds the CCTP depositForBurn tx, signs it with the fee payer and\n * message account keypair, then the Turnkey wallet adds the user signature.\n * Finally the fully-signed tx is submitted back to the server for broadcast.\n *\n * This avoids the Turnkey wallet needing SOL for gas fees.\n */\nexport const sponsoredBurnUsdcOnSolana = async (params: {\n withdrawalId: string;\n amount: string;\n destinationChain: string;\n destinationAddress: string;\n solanaWallet: SolanaBurnParams['solanaWallet'];\n}): Promise<SolanaBurnResult> => {\n const {\n withdrawalId,\n amount,\n destinationChain,\n destinationAddress,\n solanaWallet,\n } = params;\n\n logger.info('[SolanaBurn] Starting sponsored burn', {\n withdrawalId,\n amount,\n destinationChain,\n destinationAddress,\n walletAddress: solanaWallet.address,\n });\n\n try {\n if (!amount || parseFloat(amount) <= 0) {\n throw new Error('Invalid burn amount');\n }\n if (!destinationAddress) {\n throw new Error('Destination address is required');\n }\n if (!solanaWallet.address) {\n throw new Error('Solana wallet not connected');\n }\n\n // Get signer from wallet\n const signer = await solanaWallet.getSigner();\n if (!signer || !signer.signTransaction) {\n throw new Error('Wallet does not support transaction signing');\n }\n\n logger.info('[SolanaBurn] Requesting server to prepare burn tx');\n\n const { prepareBurnTx, submitBurnTx } = await import('../../bridge-assist/client');\n const { hashVersionedTransaction } = await import('../../cctp/solanaClaim');\n\n // Step 1: Get unsigned tx from server\n const prepared = await prepareBurnTx(withdrawalId, {\n userAddress: signer.publicKey.toBase58(),\n amount,\n destinationChain,\n destinationAddress,\n });\n\n logger.info('[SolanaBurn] Server prepared burn tx', {\n blockhash: prepared.blockhash,\n lastValidBlockHeight: prepared.lastValidBlockHeight,\n });\n\n // Step 2: Deserialize and verify the server-provided transaction\n const txBytes = Buffer.from(prepared.tx, 'base64');\n const deserializedTx = VersionedTransaction.deserialize(txBytes);\n\n // Validate the transaction only contains expected CCTP burn instructions,\n // references the correct USDC mint, and encodes the expected amount/destination/recipient\n validateBurnTransaction(deserializedTx, {\n amount,\n destinationChain,\n destinationAddress,\n });\n\n // Verify the user's public key is a REQUIRED signer in the transaction\n // (index < numRequiredSignatures), not just present somewhere in the account list.\n const txAccountKeys = deserializedTx.message.staticAccountKeys;\n const numRequiredSigners = deserializedTx.message.header.numRequiredSignatures;\n const userSignerIndex = txAccountKeys.findIndex((k) => k.equals(signer.publicKey));\n if (userSignerIndex < 0 || userSignerIndex >= numRequiredSigners) {\n throw new Error('Server-provided transaction does not include the user wallet as a required signer');\n }\n\n logger.info('[SolanaBurn] Signing with Turnkey wallet');\n const signedTx = await signer.signTransaction(deserializedTx);\n\n if (!(signedTx instanceof VersionedTransaction)) {\n throw new Error('Expected VersionedTransaction after signing');\n }\n\n // Step 3: Extract user signature from the signed tx (same pattern as claim flow).\n // Turnkey's signTransaction may clear other signatures, so we extract just\n // the user's signature and send it separately. The server adds all 3 signatures.\n const userKey = signer.publicKey;\n const accountKeys = signedTx.message.staticAccountKeys;\n const sigIndex = accountKeys.findIndex((k) => k.equals(userKey));\n if (sigIndex < 0) {\n throw new Error('User pubkey not found in transaction account keys');\n }\n const sig = signedTx.signatures[sigIndex];\n if (!sig || sig.every((b) => b === 0)) {\n throw new Error('User signature missing after signing');\n }\n\n const userSignatureBase64 = Buffer.from(sig).toString('base64');\n const txHash = hashVersionedTransaction(signedTx as any);\n\n logger.info('[SolanaBurn] Submitting user signature to server');\n const result = await submitBurnTx(withdrawalId, {\n userSignature: userSignatureBase64,\n txHash,\n });\n\n logger.info('[SolanaBurn] Sponsored burn completed', {\n txHash: result.burnTx,\n explorerUrl: result.explorerUrl,\n });\n\n return {\n txHash: result.burnTx,\n explorerUrl: result.explorerUrl,\n };\n } catch (error) {\n logger.error('[SolanaBurn] Sponsored burn failed', {\n error,\n errorMessage: error instanceof Error ? error.message : String(error),\n withdrawalId,\n amount,\n destinationChain,\n destinationAddress,\n });\n\n const message = error instanceof Error ? error.message : 'Failed to burn USDC on Solana';\n throw createWithdrawalError('BRIDGE_FAILED', message, {\n cause: error instanceof Error ? error : undefined,\n context: { amount, destinationChain, destinationAddress },\n });\n }\n};\n\n/**\n * Waits for CCTP attestation from Circle's Iris API\n *\n * @param txHash - Solana transaction hash\n * @param timeoutMs - Maximum time to wait for attestation (default: 120 seconds)\n * @param retryBackoffMs - Time between retry attempts (default: 5 seconds)\n * @returns Attestation data including signature and message\n */\nexport const waitForSolanaAttestation = async (\n txHash: string,\n timeoutMs: number = SOLANA_ATTESTATION_TIMEOUT_MS,\n retryBackoffMs: number = SOLANA_ATTESTATION_RETRY_BACKOFF_MS\n): Promise<{\n attestation: string;\n message: string;\n decodedMessage?: any;\n}> => {\n logger.info('[SolanaBurn] Waiting for attestation', {\n txHash,\n timeoutMs,\n retryBackoffMs,\n });\n\n const client = new BridgeKitClient();\n const startTime = Date.now();\n let attempt = 0;\n let lastError: unknown = null;\n\n while (Date.now() - startTime < timeoutMs) {\n attempt++;\n\n try {\n logger.debug('[SolanaBurn] Fetching attestation attempt', {\n attempt,\n elapsed: Date.now() - startTime,\n txHash,\n });\n\n // Use BridgeKitClient's getAttestation method\n const attestationData = await client.getAttestation(txHash, 'solana');\n\n if (attestationData && attestationData.attestation && attestationData.message) {\n logger.info('[SolanaBurn] Attestation received', {\n txHash,\n attempt,\n elapsed: Date.now() - startTime,\n hasDecodedMessage: !!attestationData.decodedMessage,\n });\n\n return attestationData;\n }\n\n logger.debug('[SolanaBurn] Attestation not ready yet', {\n attempt,\n hasData: !!attestationData,\n hasAttestation: !!attestationData?.attestation,\n hasMessage: !!attestationData?.message,\n });\n } catch (error) {\n lastError = error;\n logger.warn('[SolanaBurn] Error fetching attestation', {\n attempt,\n error: error instanceof Error ? error.message : String(error),\n });\n }\n\n // Wait before next attempt\n await new Promise((resolve) => setTimeout(resolve, retryBackoffMs));\n }\n\n // Timeout reached\n const errorMessage = lastError instanceof Error\n ? lastError.message\n : lastError\n ? String(lastError)\n : 'unknown error';\n\n logger.error('[SolanaBurn] Attestation timeout', {\n txHash,\n elapsed: Date.now() - startTime,\n attempts: attempt,\n lastError: errorMessage,\n });\n\n throw new Error(`Attestation timeout after ${timeoutMs}ms (${errorMessage})`);\n};\n\n/**\n * Gets the CCTP domain for a destination chain\n */\nexport const getDestinationDomain = (chainName: string): number => {\n try {\n const chain = mapChainToBridgeKit(chainName);\n const domain = getDomain(chain);\n\n if (domain === undefined) {\n throw new Error(`No CCTP domain found for chain: ${chainName}`);\n }\n\n logger.debug('[SolanaBurn] Resolved destination domain', {\n chain: chainName,\n domain,\n });\n\n return domain;\n } catch (error) {\n logger.error('[SolanaBurn] Failed to get destination domain', {\n chain: chainName,\n error,\n });\n throw error;\n }\n};\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@n1xyz/wallet-widget",
3
- "version": "0.0.35-alpha.43",
3
+ "version": "0.0.35-alpha.45",
4
4
  "description": "React wallet widget component for N1 applications",
5
5
  "main": "dist/index.js",
6
6
  "module": "dist/index.mjs",