@cloak.dev/sdk 0.2.3-staging.f2d7f2a → 0.2.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.cjs +15 -847
- package/dist/index.d.cts +1 -678
- package/dist/index.d.ts +1 -678
- package/dist/index.js +14 -832
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -542,10 +542,8 @@ var init_utxo = __esm({
|
|
|
542
542
|
// src/index.ts
|
|
543
543
|
var index_exports = {};
|
|
544
544
|
__export(index_exports, {
|
|
545
|
-
BRIDGE_ESCROW_LABEL: () => BRIDGE_ESCROW_LABEL,
|
|
546
545
|
BUILD_ALLOWS_LOCAL_ENDPOINTS: () => BUILD_ALLOWS_LOCAL_ENDPOINTS,
|
|
547
546
|
CHAIN_NOTE_SALT_BITS: () => CHAIN_NOTE_SALT_BITS,
|
|
548
|
-
CLEANUP_FEE_BUDGET: () => CLEANUP_FEE_BUDGET,
|
|
549
547
|
CLOAK_PRODUCTION_RELAY_URL: () => CLOAK_PRODUCTION_RELAY_URL,
|
|
550
548
|
CLOAK_PROGRAM_ID: () => CLOAK_PROGRAM_ID,
|
|
551
549
|
CloakError: () => CloakError,
|
|
@@ -553,25 +551,16 @@ __export(index_exports, {
|
|
|
553
551
|
DEFAULT_TRANSACTION_CIRCUITS_URL: () => DEFAULT_TRANSACTION_CIRCUITS_URL,
|
|
554
552
|
DELIVERY_MEMO_TAG: () => DELIVERY_MEMO_TAG,
|
|
555
553
|
DELIVERY_REGISTRY_SEED: () => DELIVERY_REGISTRY_SEED,
|
|
556
|
-
DepositError: () => DepositError,
|
|
557
|
-
DoNotRetry: () => DoNotRetry,
|
|
558
|
-
ECONOMIC_MINIMUM: () => ECONOMIC_MINIMUM,
|
|
559
554
|
EXPECTED_CIRCUIT_HASHES: () => EXPECTED_CIRCUIT_HASHES,
|
|
560
|
-
FEE_BUDGET: () => FEE_BUDGET,
|
|
561
555
|
FIXED_FEE_LAMPORTS: () => FIXED_FEE_LAMPORTS,
|
|
562
556
|
InsecureRandomnessError: () => InsecureRandomnessError,
|
|
563
557
|
LAMPORTS_PER_SOL: () => LAMPORTS_PER_SOL,
|
|
564
558
|
LocalStorageAdapter: () => LocalStorageAdapter,
|
|
565
|
-
MAINNET_RENT_0: () => MAINNET_RENT_0,
|
|
566
|
-
MAINNET_RENT_1: () => MAINNET_RENT_1,
|
|
567
|
-
MAX_RECEIVER_INDEX: () => MAX_RECEIVER_INDEX,
|
|
568
559
|
MERKLE_TREE_HEIGHT: () => MERKLE_TREE_HEIGHT2,
|
|
569
560
|
MIN_DEPOSIT_LAMPORTS: () => MIN_DEPOSIT_LAMPORTS,
|
|
570
|
-
MIN_DEPOSIT_SPL_BASE_UNITS: () => MIN_DEPOSIT_SPL_BASE_UNITS,
|
|
571
561
|
MemoryStorageAdapter: () => MemoryStorageAdapter,
|
|
572
562
|
MerkleTree: () => MerkleTree,
|
|
573
563
|
NATIVE_SOL_MINT: () => NATIVE_SOL_MINT,
|
|
574
|
-
ONECLICK_PUBKEY_B58: () => ONECLICK_PUBKEY_B58,
|
|
575
564
|
RECIPIENT_DELIVERY_CIPHERTEXT_LEN: () => RECIPIENT_DELIVERY_CIPHERTEXT_LEN,
|
|
576
565
|
RECIPIENT_DELIVERY_EPHEMERAL_PK_LEN: () => RECIPIENT_DELIVERY_EPHEMERAL_PK_LEN,
|
|
577
566
|
RECIPIENT_DELIVERY_NONCE_LEN: () => RECIPIENT_DELIVERY_NONCE_LEN,
|
|
@@ -590,7 +579,6 @@ __export(index_exports, {
|
|
|
590
579
|
SettlementVerificationError: () => SettlementVerificationError,
|
|
591
580
|
ShieldPoolErrors: () => ShieldPoolErrors,
|
|
592
581
|
SimpleWallet: () => SimpleWallet,
|
|
593
|
-
TERMINAL_FAILURE: () => TERMINAL_FAILURE,
|
|
594
582
|
TRANSACTION_CIRCUITS_VERSION: () => TRANSACTION_CIRCUITS_VERSION,
|
|
595
583
|
TRANSACT_AUTH_FIELDS: () => TRANSACT_AUTH_FIELDS,
|
|
596
584
|
TRANSACT_SWAP_AUTH_FIELDS: () => TRANSACT_SWAP_AUTH_FIELDS,
|
|
@@ -600,12 +588,9 @@ __export(index_exports, {
|
|
|
600
588
|
VARIABLE_FEE_NUMERATOR: () => VARIABLE_FEE_NUMERATOR,
|
|
601
589
|
VARIABLE_FEE_RATE: () => VARIABLE_FEE_RATE,
|
|
602
590
|
VERSION: () => VERSION,
|
|
603
|
-
WITHDRAW_FEE_BPS: () => WITHDRAW_FEE_BPS,
|
|
604
|
-
WITHDRAW_FIXED_FEE: () => WITHDRAW_FIXED_FEE,
|
|
605
591
|
assertDirectSubmissionLanded: () => assertDirectSubmissionLanded,
|
|
606
592
|
assertInputMints: () => assertInputMints,
|
|
607
593
|
assertTransactionCircuitIntegrity: () => assertTransactionCircuitIntegrity,
|
|
608
|
-
assessBridgeQuote: () => assessBridgeQuote,
|
|
609
594
|
bigintToBytes32: () => bigintToBytes32,
|
|
610
595
|
bigintToHex: () => bigintToHex,
|
|
611
596
|
buildMerkleTree: () => buildMerkleTree,
|
|
@@ -620,16 +605,12 @@ __export(index_exports, {
|
|
|
620
605
|
calculateRelayFee: () => calculateRelayFee,
|
|
621
606
|
canRebuildMerkleTreeFromChain: () => canRebuildMerkleTreeFromChain,
|
|
622
607
|
canonicalJson: () => canonicalJson,
|
|
623
|
-
canonicalPayloadString: () => canonicalPayloadString,
|
|
624
608
|
chainNoteFromBase64: () => chainNoteFromBase64,
|
|
625
609
|
chainNoteToBase64: () => chainNoteToBase64,
|
|
626
|
-
classifyPostFailure: () => classifyPostFailure,
|
|
627
610
|
classifyRelayError: () => classifyRelayError,
|
|
628
|
-
cleanupReceivingAddress: () => cleanupReceivingAddress,
|
|
629
611
|
cleanupStalePendingOperations: () => cleanupStalePendingOperations,
|
|
630
612
|
clearPendingDeposits: () => clearPendingDeposits,
|
|
631
613
|
clearPendingWithdrawals: () => clearPendingWithdrawals,
|
|
632
|
-
cloakBridgeRail: () => cloakBridgeRail,
|
|
633
614
|
computeChainNoteHash: () => computeChainNoteHash,
|
|
634
615
|
computeExtDataHash: () => computeExtDataHash,
|
|
635
616
|
computeMerkleRoot: () => computeMerkleRoot,
|
|
@@ -651,13 +632,10 @@ __export(index_exports, {
|
|
|
651
632
|
decryptCompactChainNote: () => decryptCompactChainNote,
|
|
652
633
|
decryptComplianceMetadataWithMasterKey: () => decryptComplianceMetadataWithMasterKey,
|
|
653
634
|
decryptTransactionMetadata: () => decryptTransactionMetadata,
|
|
654
|
-
depositFromDerivedKey: () => depositFromDerivedKey,
|
|
655
|
-
deriveBridgeReceiver: () => deriveBridgeReceiver,
|
|
656
635
|
deriveChangeNoteBlinding: () => deriveChangeNoteBlinding,
|
|
657
636
|
deriveDepositNoteSecrets: () => deriveDepositNoteSecrets,
|
|
658
637
|
deriveDiversifiedViewingKey: () => deriveDiversifiedViewingKey,
|
|
659
638
|
deriveDiversifier: () => deriveDiversifier,
|
|
660
|
-
deriveFundingTargets: () => deriveFundingTargets,
|
|
661
639
|
deriveInputNullifierPdas: () => deriveInputNullifierPdas,
|
|
662
640
|
derivePublicKey: () => derivePublicKey,
|
|
663
641
|
deriveSpendKey: () => deriveSpendKey,
|
|
@@ -696,7 +674,6 @@ __export(index_exports, {
|
|
|
696
674
|
formatErrorForLogging: () => formatErrorForLogging,
|
|
697
675
|
formatSol: () => formatSol,
|
|
698
676
|
fullWithdraw: () => fullWithdraw,
|
|
699
|
-
fundReceiverViaPaymaster: () => fundReceiverViaPaymaster,
|
|
700
677
|
generateCloakKeys: () => generateCloakKeys,
|
|
701
678
|
generateCommitmentAsync: () => generateCommitmentAsync,
|
|
702
679
|
generateMasterSeed: () => generateMasterSeed,
|
|
@@ -732,21 +709,18 @@ __export(index_exports, {
|
|
|
732
709
|
isReactNative: () => isReactNative,
|
|
733
710
|
isRootNotFoundError: () => isRootNotFoundError,
|
|
734
711
|
isSubmissionOutcomeUnknownResponse: () => isSubmissionOutcomeUnknownResponse,
|
|
735
|
-
isTerminalFailure: () => isTerminalFailure,
|
|
736
712
|
isValidHex: () => isValidHex,
|
|
737
713
|
isValidRpcUrl: () => isValidRpcUrl,
|
|
738
714
|
isValidSolanaAddress: () => isValidSolanaAddress,
|
|
739
715
|
isWithdrawAmountSufficient: () => isWithdrawAmountSufficient,
|
|
740
716
|
isWithdrawable: () => isWithdrawable,
|
|
741
717
|
keypairToAdapter: () => keypairToAdapter,
|
|
742
|
-
listBridgeDeposits: () => listBridgeDeposits,
|
|
743
718
|
loadPendingDeposits: () => loadPendingDeposits,
|
|
744
719
|
loadPendingWithdrawals: () => loadPendingWithdrawals,
|
|
745
720
|
loadVerifiedCircuitArtifacts: () => loadVerifiedCircuitArtifacts,
|
|
746
721
|
matchChangeNote: () => matchChangeNote,
|
|
747
722
|
matchDepositNote: () => matchDepositNote,
|
|
748
723
|
matchSwapRefundLeaf: () => matchSwapRefundLeaf,
|
|
749
|
-
mayRetry: () => mayRetry,
|
|
750
724
|
openRecipientDeliveryNote: () => openRecipientDeliveryNote,
|
|
751
725
|
parseAmount: () => parseAmount,
|
|
752
726
|
parseDeliveryCarrierMemo: () => parseDeliveryCarrierMemo,
|
|
@@ -769,14 +743,11 @@ __export(index_exports, {
|
|
|
769
743
|
randomDepositNoteSalt: () => randomDepositNoteSalt,
|
|
770
744
|
randomFieldElement: () => randomFieldElement,
|
|
771
745
|
readMerkleTreeState: () => readMerkleTreeState,
|
|
772
|
-
readRent: () => readRent,
|
|
773
746
|
recipientDeliveryNoteToBase64: () => recipientDeliveryNoteToBase64,
|
|
774
747
|
registerViewingKey: () => registerViewingKey,
|
|
775
748
|
removePendingDeposit: () => removePendingDeposit,
|
|
776
749
|
removePendingWithdrawal: () => removePendingWithdrawal,
|
|
777
|
-
renderAssessment: () => renderAssessment,
|
|
778
750
|
resolveCircuitsBase: () => resolveCircuitsBase,
|
|
779
|
-
retryDelayMs: () => retryDelayMs,
|
|
780
751
|
savePendingDeposit: () => savePendingDeposit,
|
|
781
752
|
savePendingWithdrawal: () => savePendingWithdrawal,
|
|
782
753
|
scanNotesForWallet: () => scanNotesForWallet,
|
|
@@ -809,19 +780,15 @@ __export(index_exports, {
|
|
|
809
780
|
validateDepositParams: () => validateDepositParams,
|
|
810
781
|
validateNote: () => validateNote,
|
|
811
782
|
validateOutputsSum: () => validateOutputsSum,
|
|
812
|
-
validatePaymasterTopUpTransaction: () => validatePaymasterTopUpTransaction,
|
|
813
783
|
validateRoot: () => validateRoot,
|
|
814
784
|
validateTransfers: () => validateTransfers,
|
|
815
785
|
validateWalletConnected: () => validateWalletConnected,
|
|
816
786
|
validateWithdrawableNote: () => validateWithdrawableNote,
|
|
817
787
|
verifyAllCircuits: () => verifyAllCircuits,
|
|
818
788
|
verifyCircuitIntegrity: () => verifyCircuitIntegrity,
|
|
819
|
-
verifyQuoteSignature: () => verifyQuoteSignature,
|
|
820
789
|
verifyUtxos: () => verifyUtxos,
|
|
821
790
|
waitForRoot: () => waitForRoot,
|
|
822
|
-
|
|
823
|
-
withTiming: () => withTiming,
|
|
824
|
-
withdrawFeeFor: () => withdrawFeeFor
|
|
791
|
+
withTiming: () => withTiming
|
|
825
792
|
});
|
|
826
793
|
module.exports = __toCommonJS(index_exports);
|
|
827
794
|
|
|
@@ -1425,7 +1392,7 @@ function parseStrictViewingKeyChallenge(response, userPubkey, viewingKeyHex) {
|
|
|
1425
1392
|
|
|
1426
1393
|
// src/config/relay.ts
|
|
1427
1394
|
var CLOAK_PRODUCTION_RELAY_URL = "https://api.cloak.ag";
|
|
1428
|
-
var RELAY_ORIGIN_ALLOWLIST = [
|
|
1395
|
+
var RELAY_ORIGIN_ALLOWLIST = [CLOAK_PRODUCTION_RELAY_URL];
|
|
1429
1396
|
var ABSOLUTE_URL = /^[a-z][a-z0-9+.-]*:\/\//i;
|
|
1430
1397
|
var LOOPBACK_IPV4 = /^127\.\d{1,3}\.\d{1,3}\.\d{1,3}$/;
|
|
1431
1398
|
var THIS_NETWORK_IPV4 = /^0\.\d{1,3}\.\d{1,3}\.\d{1,3}$/;
|
|
@@ -2963,8 +2930,8 @@ async function verifyUtxos(utxos, connection, programId, commitment = "confirmed
|
|
|
2963
2930
|
const nullifierHex = nullifierBig.toString(16).padStart(64, "0");
|
|
2964
2931
|
const nullifierBytes = Buffer.from(nullifierHex, "hex");
|
|
2965
2932
|
const { pool } = getShieldPoolPDAs(programId, utxo.mintAddress);
|
|
2966
|
-
const [
|
|
2967
|
-
checkable.push({ utxo, pda
|
|
2933
|
+
const [pda] = getNullifierPDA(pool, nullifierBytes, programId);
|
|
2934
|
+
checkable.push({ utxo, pda });
|
|
2968
2935
|
} catch {
|
|
2969
2936
|
skipped.push(utxo);
|
|
2970
2937
|
}
|
|
@@ -3034,8 +3001,8 @@ function deriveInputNullifierPdas(programId, mint, inputNullifiers) {
|
|
|
3034
3001
|
const pdas = [];
|
|
3035
3002
|
for (const nullifier of inputNullifiers) {
|
|
3036
3003
|
if (nullifier === BigInt(0)) continue;
|
|
3037
|
-
const [
|
|
3038
|
-
pdas.push(
|
|
3004
|
+
const [pda] = getNullifierPDA(pool, bigintToBytes324(nullifier), programId);
|
|
3005
|
+
pdas.push(pda);
|
|
3039
3006
|
}
|
|
3040
3007
|
return pdas;
|
|
3041
3008
|
}
|
|
@@ -4354,7 +4321,7 @@ async function fetchWithRetry(url, options = {}) {
|
|
|
4354
4321
|
const {
|
|
4355
4322
|
timeoutMs = DEFAULT_TIMEOUT_MS,
|
|
4356
4323
|
maxRetries = DEFAULT_MAX_RETRIES,
|
|
4357
|
-
retryDelayMs
|
|
4324
|
+
retryDelayMs = 1e3
|
|
4358
4325
|
} = options;
|
|
4359
4326
|
assertAllowedRelayOrigin(url);
|
|
4360
4327
|
let lastError = null;
|
|
@@ -4378,7 +4345,7 @@ async function fetchWithRetry(url, options = {}) {
|
|
|
4378
4345
|
`Relay request failed after ${attempt + 1} attempts: ${lastError.message}`
|
|
4379
4346
|
);
|
|
4380
4347
|
}
|
|
4381
|
-
const delay =
|
|
4348
|
+
const delay = retryDelayMs * Math.pow(2, attempt) + Math.random() * 500;
|
|
4382
4349
|
await new Promise((resolve) => setTimeout(resolve, delay));
|
|
4383
4350
|
}
|
|
4384
4351
|
}
|
|
@@ -7882,7 +7849,7 @@ async function transact(params, options) {
|
|
|
7882
7849
|
// names is refused.
|
|
7883
7850
|
maxRootRetries = 40,
|
|
7884
7851
|
// Increased to handle prolonged relay sync recovery under high concurrency
|
|
7885
|
-
retryDelayMs
|
|
7852
|
+
retryDelayMs = 500,
|
|
7886
7853
|
// Start with short delay, will exponentially back off
|
|
7887
7854
|
riskOracleQueue,
|
|
7888
7855
|
riskQuoteUrl: riskQuoteUrlOption,
|
|
@@ -8304,7 +8271,7 @@ async function transact(params, options) {
|
|
|
8304
8271
|
while (submissionAttempts <= maxRootRetries) {
|
|
8305
8272
|
const isRetry = submissionAttempts > 0;
|
|
8306
8273
|
if (isRetry) {
|
|
8307
|
-
const exponentialDelay = Math.min(
|
|
8274
|
+
const exponentialDelay = Math.min(retryDelayMs * Math.pow(1.5, submissionAttempts - 1), 5e3);
|
|
8308
8275
|
const jitter = Math.random() * 500;
|
|
8309
8276
|
const totalDelay = Math.floor(exponentialDelay + jitter);
|
|
8310
8277
|
await sleep2(totalDelay);
|
|
@@ -8467,7 +8434,7 @@ async function transact(params, options) {
|
|
|
8467
8434
|
}
|
|
8468
8435
|
treeState = null;
|
|
8469
8436
|
useSiblingInfo = false;
|
|
8470
|
-
const waitMs = Math.min(
|
|
8437
|
+
const waitMs = Math.min(retryDelayMs * Math.pow(2, Math.min(submissionAttempts, 4)), 5e3);
|
|
8471
8438
|
if (waitMs > 0) {
|
|
8472
8439
|
onProgress?.(`Waiting ${waitMs}ms for relay sync before retry...`);
|
|
8473
8440
|
await new Promise((r) => setTimeout(r, waitMs));
|
|
@@ -9161,7 +9128,7 @@ async function swapUtxo(params, options) {
|
|
|
9161
9128
|
riskQuoteUrl: riskQuoteUrlOption,
|
|
9162
9129
|
maxRootRetries = 40,
|
|
9163
9130
|
// Increased to handle prolonged relay sync recovery under high concurrency
|
|
9164
|
-
retryDelayMs
|
|
9131
|
+
retryDelayMs = 500,
|
|
9165
9132
|
// Start with short delay, will exponentially back off
|
|
9166
9133
|
useUniqueNullifiers,
|
|
9167
9134
|
useChainRootForProof = true
|
|
@@ -9572,7 +9539,7 @@ async function swapUtxo(params, options) {
|
|
|
9572
9539
|
let walletApprovals = 0;
|
|
9573
9540
|
for (let attempt = 0; attempt <= maxRootRetries; attempt++) {
|
|
9574
9541
|
if (attempt > 0) {
|
|
9575
|
-
const exponentialDelay = Math.min(
|
|
9542
|
+
const exponentialDelay = Math.min(retryDelayMs * Math.pow(1.5, attempt - 1), 5e3);
|
|
9576
9543
|
const jitter = Math.random() * 500;
|
|
9577
9544
|
const totalDelay = Math.floor(exponentialDelay + jitter);
|
|
9578
9545
|
await sleep2(totalDelay);
|
|
@@ -9710,7 +9677,7 @@ async function swapUtxo(params, options) {
|
|
|
9710
9677
|
}
|
|
9711
9678
|
merkleState = null;
|
|
9712
9679
|
useSiblingInfo = false;
|
|
9713
|
-
const waitMs = Math.min(
|
|
9680
|
+
const waitMs = Math.min(retryDelayMs * Math.pow(2, Math.min(attempt, 4)), 5e3);
|
|
9714
9681
|
if (waitMs > 0) {
|
|
9715
9682
|
onProgress?.(`Waiting ${waitMs}ms for relay sync before retry...`);
|
|
9716
9683
|
await new Promise((r) => setTimeout(r, waitMs));
|
|
@@ -11690,781 +11657,13 @@ var SimpleWallet = class {
|
|
|
11690
11657
|
}
|
|
11691
11658
|
};
|
|
11692
11659
|
|
|
11693
|
-
// src/bridge/rail-verify.ts
|
|
11694
|
-
var import_tweetnacl7 = __toESM(require("tweetnacl"), 1);
|
|
11695
|
-
var import_sha256 = require("@noble/hashes/sha256");
|
|
11696
|
-
var ONECLICK_PUBKEY_B58 = "reYaWhvwu8Jzo3WUM3zhn6VrhuMEF4eADL17qtRVifc";
|
|
11697
|
-
var b58 = /* @__PURE__ */ (() => {
|
|
11698
|
-
const A = "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz";
|
|
11699
|
-
return {
|
|
11700
|
-
decode(s) {
|
|
11701
|
-
let n = 0n;
|
|
11702
|
-
for (const c of s) {
|
|
11703
|
-
const i = A.indexOf(c);
|
|
11704
|
-
if (i < 0) throw new Error("bad base58");
|
|
11705
|
-
n = n * 58n + BigInt(i);
|
|
11706
|
-
}
|
|
11707
|
-
const bytes = [];
|
|
11708
|
-
while (n > 0n) {
|
|
11709
|
-
bytes.unshift(Number(n & 255n));
|
|
11710
|
-
n >>= 8n;
|
|
11711
|
-
}
|
|
11712
|
-
for (const c of s) {
|
|
11713
|
-
if (c === "1") bytes.unshift(0);
|
|
11714
|
-
else break;
|
|
11715
|
-
}
|
|
11716
|
-
return Uint8Array.from(bytes);
|
|
11717
|
-
},
|
|
11718
|
-
encode(b) {
|
|
11719
|
-
let n = 0n;
|
|
11720
|
-
for (const x of b) n = n * 256n + BigInt(x);
|
|
11721
|
-
let s = "";
|
|
11722
|
-
while (n > 0n) {
|
|
11723
|
-
s = A[Number(n % 58n)] + s;
|
|
11724
|
-
n /= 58n;
|
|
11725
|
-
}
|
|
11726
|
-
for (const x of b) {
|
|
11727
|
-
if (x === 0) s = "1" + s;
|
|
11728
|
-
else break;
|
|
11729
|
-
}
|
|
11730
|
-
return s;
|
|
11731
|
-
}
|
|
11732
|
-
};
|
|
11733
|
-
})();
|
|
11734
|
-
function stable(v) {
|
|
11735
|
-
if (v === null || typeof v !== "object") return JSON.stringify(v) ?? "null";
|
|
11736
|
-
if (Array.isArray(v)) return `[${v.map(stable).join(",")}]`;
|
|
11737
|
-
const o = v;
|
|
11738
|
-
const parts = Object.keys(o).sort().filter((k) => o[k] !== void 0).map((k) => `${JSON.stringify(k)}:${stable(o[k])}`);
|
|
11739
|
-
return `{${parts.join(",")}}`;
|
|
11740
|
-
}
|
|
11741
|
-
function signedRequest(r) {
|
|
11742
|
-
const q = r.quoteRequest ?? {};
|
|
11743
|
-
return {
|
|
11744
|
-
dry: q.dry,
|
|
11745
|
-
swapType: q.swapType,
|
|
11746
|
-
slippageTolerance: q.slippageTolerance,
|
|
11747
|
-
originAsset: q.originAsset,
|
|
11748
|
-
depositType: q.depositType,
|
|
11749
|
-
destinationAsset: q.destinationAsset,
|
|
11750
|
-
amount: q.amount,
|
|
11751
|
-
refundTo: q.refundTo,
|
|
11752
|
-
refundType: q.refundType,
|
|
11753
|
-
recipient: q.recipient,
|
|
11754
|
-
recipientType: q.recipientType,
|
|
11755
|
-
deadline: q.deadline,
|
|
11756
|
-
quoteWaitingTimeMs: q.quoteWaitingTimeMs || void 0,
|
|
11757
|
-
referral: q.referral || void 0,
|
|
11758
|
-
virtualChainRecipient: q.virtualChainRecipient || void 0,
|
|
11759
|
-
virtualChainRefundRecipient: q.virtualChainRefundRecipient || void 0,
|
|
11760
|
-
customRecipientMsg: q.customRecipientMsg || void 0
|
|
11761
|
-
// Deliberately unsigned by the rail: sessionId, connectedWallets, correlationId, appFees,
|
|
11762
|
-
// partnerId, userAccountId, depositMode. APP FEES ARE NOT AUTHENTICATED — never display a fee
|
|
11763
|
-
// caption as if the signature vouched for it.
|
|
11764
|
-
};
|
|
11765
|
-
}
|
|
11766
|
-
function signedQuote(r) {
|
|
11767
|
-
const q = r.quote ?? {};
|
|
11768
|
-
const base = {
|
|
11769
|
-
amountIn: q.amountIn,
|
|
11770
|
-
amountInFormatted: q.amountInFormatted,
|
|
11771
|
-
amountInUsd: q.amountInUsd,
|
|
11772
|
-
minAmountIn: q.minAmountIn,
|
|
11773
|
-
amountOut: q.amountOut,
|
|
11774
|
-
amountOutFormatted: q.amountOutFormatted,
|
|
11775
|
-
amountOutUsd: q.amountOutUsd,
|
|
11776
|
-
minAmountOut: q.minAmountOut
|
|
11777
|
-
};
|
|
11778
|
-
if (r.quoteRequest?.dry) return base;
|
|
11779
|
-
return {
|
|
11780
|
-
...base,
|
|
11781
|
-
depositAddress: q.depositAddress || void 0,
|
|
11782
|
-
// <- the field that makes substitution detectable
|
|
11783
|
-
depositMemo: q.depositMemo || void 0,
|
|
11784
|
-
deadline: q.deadline || void 0,
|
|
11785
|
-
// <- a real, SIGNED expiry
|
|
11786
|
-
timeWhenInactive: q.timeWhenInactive || void 0,
|
|
11787
|
-
timeEstimate: q.timeEstimate || void 0,
|
|
11788
|
-
virtualChainRecipient: q.virtualChainRecipient || void 0,
|
|
11789
|
-
virtualChainRefundRecipient: q.virtualChainRefundRecipient || void 0,
|
|
11790
|
-
customRecipientMsg: q.customRecipientMsg || void 0,
|
|
11791
|
-
refundFee: q.refundFee || void 0,
|
|
11792
|
-
withdrawFee: q.withdrawFee || void 0
|
|
11793
|
-
};
|
|
11794
|
-
}
|
|
11795
|
-
function canonicalPayloadString(resp) {
|
|
11796
|
-
return stable({ ...signedRequest(resp), ...signedQuote(resp), timestamp: resp.timestamp });
|
|
11797
|
-
}
|
|
11798
|
-
function verifyQuoteSignature(resp) {
|
|
11799
|
-
if (!resp?.signature) return { valid: false, reason: "no signature on the response" };
|
|
11800
|
-
const payload = { ...signedRequest(resp), ...signedQuote(resp), timestamp: resp.timestamp };
|
|
11801
|
-
const digest = (0, import_sha256.sha256)(new TextEncoder().encode(stable(payload)));
|
|
11802
|
-
const message = new TextEncoder().encode(b58.encode(new Uint8Array(digest)));
|
|
11803
|
-
const sig = resp.signature.replace(/^ed25519:/, "");
|
|
11804
|
-
try {
|
|
11805
|
-
return { valid: import_tweetnacl7.default.sign.detached.verify(message, b58.decode(sig), b58.decode(ONECLICK_PUBKEY_B58)) };
|
|
11806
|
-
} catch (e) {
|
|
11807
|
-
return { valid: false, reason: e instanceof Error ? e.message : String(e) };
|
|
11808
|
-
}
|
|
11809
|
-
}
|
|
11810
|
-
|
|
11811
|
-
// src/bridge/rails.ts
|
|
11812
|
-
async function parseBridgeResponse(res, what) {
|
|
11813
|
-
let body;
|
|
11814
|
-
try {
|
|
11815
|
-
body = await res.json();
|
|
11816
|
-
} catch {
|
|
11817
|
-
throw new Error(`${what} failed: ${res.status} ${res.statusText} (response body was not JSON)`);
|
|
11818
|
-
}
|
|
11819
|
-
if (!res.ok) {
|
|
11820
|
-
const b = body ?? {};
|
|
11821
|
-
throw new Error(
|
|
11822
|
-
`${what} failed: ${b.message ?? res.statusText} (${b.code ?? res.status}${b.retryable ? ", retryable" : ""})`
|
|
11823
|
-
);
|
|
11824
|
-
}
|
|
11825
|
-
return body;
|
|
11826
|
-
}
|
|
11827
|
-
function toAttestation(raw) {
|
|
11828
|
-
if (raw.kind === "ed25519") {
|
|
11829
|
-
return { kind: "ed25519", verified: raw.verified ?? false, signer: raw.signer ?? "" };
|
|
11830
|
-
}
|
|
11831
|
-
return { kind: "none", checks: raw.checks ?? [], note: raw.note ?? "" };
|
|
11832
|
-
}
|
|
11833
|
-
async function fetchBridgeQuote(relayUrl, req) {
|
|
11834
|
-
const body = {
|
|
11835
|
-
recipient: req.recipient,
|
|
11836
|
-
origin_chain: req.originChain,
|
|
11837
|
-
amount_base_units: req.amountBaseUnits.toString(),
|
|
11838
|
-
allocate: req.allocate ?? false
|
|
11839
|
-
};
|
|
11840
|
-
if (req.refundTo !== void 0) body.refund_to = req.refundTo;
|
|
11841
|
-
if (req.rails !== void 0) body.rails = req.rails;
|
|
11842
|
-
const res = await relayFetch(`${relayUrl}/bridge/quote`, {
|
|
11843
|
-
method: "POST",
|
|
11844
|
-
headers: { "Content-Type": "application/json" },
|
|
11845
|
-
body: JSON.stringify(body)
|
|
11846
|
-
});
|
|
11847
|
-
const raw = await parseBridgeResponse(res, "bridge quote");
|
|
11848
|
-
const options = [];
|
|
11849
|
-
const unavailable = (raw.unavailable ?? []).map((p) => ({
|
|
11850
|
-
rail: p.rail,
|
|
11851
|
-
reason: p.reason
|
|
11852
|
-
}));
|
|
11853
|
-
for (const opt of raw.options) {
|
|
11854
|
-
const attestation = toAttestation(opt.attestation);
|
|
11855
|
-
if (attestation.kind === "ed25519") {
|
|
11856
|
-
const verdict = opt.rail_response ? verifyQuoteSignature(opt.rail_response) : { valid: false, reason: "no rail_response to verify against" };
|
|
11857
|
-
if (!verdict.valid) {
|
|
11858
|
-
unavailable.push({
|
|
11859
|
-
rail: opt.rail,
|
|
11860
|
-
reason: `deposit address failed independent signature verification, refusing to display it (${verdict.reason ?? "signature did not verify"})`
|
|
11861
|
-
});
|
|
11862
|
-
continue;
|
|
11863
|
-
}
|
|
11864
|
-
}
|
|
11865
|
-
options.push({
|
|
11866
|
-
rail: opt.rail,
|
|
11867
|
-
refunds: opt.refunds,
|
|
11868
|
-
addressLifetime: opt.address_lifetime,
|
|
11869
|
-
amountOut: BigInt(opt.amount_out),
|
|
11870
|
-
minAmountOut: BigInt(opt.min_amount_out),
|
|
11871
|
-
timeEstimateSeconds: opt.time_estimate_s,
|
|
11872
|
-
expiresAt: opt.expires_at,
|
|
11873
|
-
depositAddress: opt.deposit_address,
|
|
11874
|
-
attestation
|
|
11875
|
-
});
|
|
11876
|
-
}
|
|
11877
|
-
return { options, unavailable };
|
|
11878
|
-
}
|
|
11879
|
-
var STATUS_STATES = [
|
|
11880
|
-
"pending",
|
|
11881
|
-
"delivered",
|
|
11882
|
-
"refunded",
|
|
11883
|
-
"expired",
|
|
11884
|
-
"unknown"
|
|
11885
|
-
];
|
|
11886
|
-
async function fetchBridgeStatus(relayUrl, depositAddress, rail) {
|
|
11887
|
-
const qs = new URLSearchParams({ deposit_address: depositAddress, rail });
|
|
11888
|
-
const res = await relayFetch(`${relayUrl}/bridge/status?${qs.toString()}`);
|
|
11889
|
-
const raw = await parseBridgeResponse(res, "bridge status");
|
|
11890
|
-
const state = STATUS_STATES.includes(raw.state ?? "") ? raw.state : "unknown";
|
|
11891
|
-
return { rail: raw.rail ?? rail, state, detail: raw.detail ?? "" };
|
|
11892
|
-
}
|
|
11893
|
-
function cloakBridgeRail(relayUrl) {
|
|
11894
|
-
assertAllowedRelayOrigin(relayUrl);
|
|
11895
|
-
return {
|
|
11896
|
-
id: "cloak-bridge",
|
|
11897
|
-
quote: (req) => fetchBridgeQuote(relayUrl, req),
|
|
11898
|
-
status: (depositAddress, rail) => fetchBridgeStatus(relayUrl, depositAddress, rail)
|
|
11899
|
-
};
|
|
11900
|
-
}
|
|
11901
|
-
|
|
11902
|
-
// src/bridge/paymaster-client.ts
|
|
11903
|
-
var import_web312 = require("@solana/web3.js");
|
|
11904
|
-
var import_spl_token3 = require("@solana/spl-token");
|
|
11905
|
-
function validatePaymasterTopUpTransaction(tx, expect) {
|
|
11906
|
-
const ixs = tx.instructions;
|
|
11907
|
-
if (ixs.length !== 1 && ixs.length !== 2) {
|
|
11908
|
-
throw new Error(
|
|
11909
|
-
`paymaster top-up must be exactly 1 or 2 instructions, got ${ixs.length} \u2014 refusing to sign a transaction whose shape does not match the documented top-up contract`
|
|
11910
|
-
);
|
|
11911
|
-
}
|
|
11912
|
-
const ix0 = ixs[0];
|
|
11913
|
-
if (!ix0.programId.equals(import_web312.SystemProgram.programId)) {
|
|
11914
|
-
throw new Error(
|
|
11915
|
-
`paymaster top-up instruction 0 is owned by ${ix0.programId.toBase58()}, not the System Program \u2014 refusing to sign an unrecognised first instruction`
|
|
11916
|
-
);
|
|
11917
|
-
}
|
|
11918
|
-
const transfer2 = import_web312.SystemInstruction.decodeTransfer(ix0);
|
|
11919
|
-
if (!transfer2.toPubkey.equals(expect.recipient)) {
|
|
11920
|
-
throw new Error(
|
|
11921
|
-
`paymaster top-up sends SOL to ${transfer2.toPubkey.toBase58()}, which is not our recipient ${expect.recipient.toBase58()} \u2014 refusing to sign a transaction that funds a key we do not control`
|
|
11922
|
-
);
|
|
11923
|
-
}
|
|
11924
|
-
if (BigInt(transfer2.lamports) > expect.maxGrantLamports) {
|
|
11925
|
-
throw new Error(
|
|
11926
|
-
`paymaster top-up grants ${transfer2.lamports} lamports, more than the ${expect.maxGrantLamports} we asked for \u2014 refusing a transaction that funds beyond our own request`
|
|
11927
|
-
);
|
|
11928
|
-
}
|
|
11929
|
-
if (ixs.length === 1) return;
|
|
11930
|
-
const ix1 = ixs[1];
|
|
11931
|
-
if (!ix1.programId.equals(import_spl_token3.TOKEN_PROGRAM_ID)) {
|
|
11932
|
-
throw new Error(
|
|
11933
|
-
`paymaster top-up instruction 1 is owned by ${ix1.programId.toBase58()}, not the SPL Token program \u2014 refusing to sign an unrecognised second instruction`
|
|
11934
|
-
);
|
|
11935
|
-
}
|
|
11936
|
-
const spl = (0, import_spl_token3.decodeTransferInstruction)(ix1, import_spl_token3.TOKEN_PROGRAM_ID);
|
|
11937
|
-
const authority = spl.keys.owner.pubkey;
|
|
11938
|
-
if (!authority.equals(expect.recipient)) {
|
|
11939
|
-
throw new Error(
|
|
11940
|
-
`paymaster top-up's fee transfer is authorised by ${authority.toBase58()}, not our recipient ${expect.recipient.toBase58()} \u2014 refusing to sign away tokens from an account we do not control`
|
|
11941
|
-
);
|
|
11942
|
-
}
|
|
11943
|
-
const expectedDestination = (0, import_spl_token3.getAssociatedTokenAddressSync)(
|
|
11944
|
-
expect.feeMint,
|
|
11945
|
-
expect.paymentAddress,
|
|
11946
|
-
false
|
|
11947
|
-
);
|
|
11948
|
-
const destination = spl.keys.destination.pubkey;
|
|
11949
|
-
if (!destination.equals(expectedDestination)) {
|
|
11950
|
-
throw new Error(
|
|
11951
|
-
`paymaster top-up's fee transfer is addressed to ${destination.toBase58()}, not the paymaster's own payment ATA ${expectedDestination.toBase58()} \u2014 refusing to sign a payment to an unverified destination`
|
|
11952
|
-
);
|
|
11953
|
-
}
|
|
11954
|
-
const paidAmount = BigInt(spl.data.amount);
|
|
11955
|
-
if (paidAmount !== expect.feeTokenAmount) {
|
|
11956
|
-
throw new Error(
|
|
11957
|
-
`paymaster top-up's fee amount is ${paidAmount}, not the ${expect.feeTokenAmount} Kora quoted at prepare time \u2014 refusing to sign a payment that does not match the quote`
|
|
11958
|
-
);
|
|
11959
|
-
}
|
|
11960
|
-
}
|
|
11961
|
-
async function parseBridgeResponse2(res, what) {
|
|
11962
|
-
let body;
|
|
11963
|
-
try {
|
|
11964
|
-
body = await res.json();
|
|
11965
|
-
} catch {
|
|
11966
|
-
throw new Error(`${what} failed: ${res.status} ${res.statusText} (response body was not JSON)`);
|
|
11967
|
-
}
|
|
11968
|
-
if (!res.ok) {
|
|
11969
|
-
const b = body ?? {};
|
|
11970
|
-
throw new Error(
|
|
11971
|
-
`${what} failed: ${b.message ?? res.statusText} (${b.code ?? res.status}${b.retryable ? ", retryable" : ""})`
|
|
11972
|
-
);
|
|
11973
|
-
}
|
|
11974
|
-
return body;
|
|
11975
|
-
}
|
|
11976
|
-
async function fundReceiverViaPaymaster(relayUrl, receiver, grantLamports) {
|
|
11977
|
-
assertAllowedRelayOrigin(relayUrl);
|
|
11978
|
-
if (grantLamports <= 0n || grantLamports > BigInt(Number.MAX_SAFE_INTEGER)) {
|
|
11979
|
-
throw new Error(
|
|
11980
|
-
`grantLamports must be a positive value representable as a JS number, got ${grantLamports}`
|
|
11981
|
-
);
|
|
11982
|
-
}
|
|
11983
|
-
const prepareRes = await relayFetch(`${relayUrl}/bridge/paymaster/prepare`, {
|
|
11984
|
-
method: "POST",
|
|
11985
|
-
headers: { "Content-Type": "application/json" },
|
|
11986
|
-
body: JSON.stringify({
|
|
11987
|
-
recipient: receiver.publicKey.toBase58(),
|
|
11988
|
-
grant_lamports: Number(grantLamports)
|
|
11989
|
-
})
|
|
11990
|
-
});
|
|
11991
|
-
const prepared = await parseBridgeResponse2(prepareRes, "paymaster prepare");
|
|
11992
|
-
if (Math.floor(Date.now() / 1e3) >= prepared.expires_at_unix) {
|
|
11993
|
-
throw new Error(
|
|
11994
|
-
"paymaster prepare returned a voucher that is already expired \u2014 refusing to sign a stale top-up rather than fail confusingly at cosign"
|
|
11995
|
-
);
|
|
11996
|
-
}
|
|
11997
|
-
const feeMint = new import_web312.PublicKey(prepared.fee_mint);
|
|
11998
|
-
const paymentAddress = new import_web312.PublicKey(prepared.payment_address);
|
|
11999
|
-
const feeTokenAmount = BigInt(prepared.fee_token_amount);
|
|
12000
|
-
const tx = import_web312.Transaction.from(Buffer.from(prepared.transaction, "base64"));
|
|
12001
|
-
validatePaymasterTopUpTransaction(tx, {
|
|
12002
|
-
recipient: receiver.publicKey,
|
|
12003
|
-
maxGrantLamports: grantLamports,
|
|
12004
|
-
feeMint,
|
|
12005
|
-
feeTokenAmount,
|
|
12006
|
-
paymentAddress
|
|
12007
|
-
});
|
|
12008
|
-
tx.partialSign(receiver);
|
|
12009
|
-
const cosignRes = await relayFetch(`${relayUrl}/bridge/paymaster/cosign`, {
|
|
12010
|
-
method: "POST",
|
|
12011
|
-
headers: { "Content-Type": "application/json" },
|
|
12012
|
-
body: JSON.stringify({
|
|
12013
|
-
transaction: tx.serialize({ requireAllSignatures: false, verifySignatures: false }).toString("base64"),
|
|
12014
|
-
voucher: prepared.voucher
|
|
12015
|
-
})
|
|
12016
|
-
});
|
|
12017
|
-
const cosigned = await parseBridgeResponse2(cosignRes, "paymaster cosign");
|
|
12018
|
-
return {
|
|
12019
|
-
transaction: import_web312.Transaction.from(Buffer.from(cosigned.transaction, "base64")),
|
|
12020
|
-
feeTokenAmount,
|
|
12021
|
-
feeMint: prepared.fee_mint,
|
|
12022
|
-
paymentAddress: prepared.payment_address
|
|
12023
|
-
};
|
|
12024
|
-
}
|
|
12025
|
-
|
|
12026
|
-
// src/bridge/derive.ts
|
|
12027
|
-
var import_web313 = require("@solana/web3.js");
|
|
12028
|
-
var import_hmac = require("@noble/hashes/hmac");
|
|
12029
|
-
var import_sha512 = require("@noble/hashes/sha512");
|
|
12030
|
-
var BRIDGE_ESCROW_LABEL = "cloak_bridge_escrow";
|
|
12031
|
-
var MAX_RECEIVER_INDEX = 1e4;
|
|
12032
|
-
function deriveBridgeReceiver(nk, index) {
|
|
12033
|
-
if (!Number.isInteger(index) || index < 0) {
|
|
12034
|
-
throw new Error(`index must be a non-negative integer, got ${index}`);
|
|
12035
|
-
}
|
|
12036
|
-
if (index > MAX_RECEIVER_INDEX) {
|
|
12037
|
-
throw new Error(
|
|
12038
|
-
`index ${index} exceeds MAX_RECEIVER_INDEX (${MAX_RECEIVER_INDEX}). Indices must be a small sequential counter \u2014 discovery derives 0\u2026N and reads each on chain, so a timestamp index is unreachable by any scan and the deposit would be invisible to every device but this one.`
|
|
12039
|
-
);
|
|
12040
|
-
}
|
|
12041
|
-
const h = (0, import_hmac.hmac)(import_sha512.sha512, new Uint8Array(nk), new TextEncoder().encode(`${BRIDGE_ESCROW_LABEL}:${index}`));
|
|
12042
|
-
return import_web313.Keypair.fromSeed(h.slice(0, 32));
|
|
12043
|
-
}
|
|
12044
|
-
|
|
12045
|
-
// src/bridge/discover.ts
|
|
12046
|
-
var import_web314 = require("@solana/web3.js");
|
|
12047
|
-
var import_spl_token4 = require("@solana/spl-token");
|
|
12048
|
-
function describeError(err) {
|
|
12049
|
-
return err instanceof Error ? err.message : String(err);
|
|
12050
|
-
}
|
|
12051
|
-
async function listBridgeDeposits(conn, nk, opts) {
|
|
12052
|
-
const scanDepth = Math.min(opts.scanDepth ?? 20, MAX_RECEIVER_INDEX + 1);
|
|
12053
|
-
const stopAfterUnused = opts.stopAfterUnused ?? 5;
|
|
12054
|
-
const out = [];
|
|
12055
|
-
let consecutiveUnused = 0;
|
|
12056
|
-
for (let index = 0; index < scanDepth; index++) {
|
|
12057
|
-
const kp = deriveBridgeReceiver(nk, index);
|
|
12058
|
-
const receiver = kp.publicKey;
|
|
12059
|
-
const tokenAccount = (0, import_spl_token4.getAssociatedTokenAddressSync)(opts.mint, receiver, false);
|
|
12060
|
-
try {
|
|
12061
|
-
const [recvInfo, ataInfo] = await conn.getMultipleAccountsInfo([receiver, tokenAccount]);
|
|
12062
|
-
const lamports = recvInfo?.lamports ?? 0;
|
|
12063
|
-
let tokenBalance = 0n;
|
|
12064
|
-
if (ataInfo) {
|
|
12065
|
-
try {
|
|
12066
|
-
tokenBalance = BigInt((await conn.getTokenAccountBalance(tokenAccount)).value.amount);
|
|
12067
|
-
} catch (err) {
|
|
12068
|
-
if (!(err instanceof import_web314.SolanaJSONRPCError && /could not find account/i.test(err.message))) {
|
|
12069
|
-
throw err;
|
|
12070
|
-
}
|
|
12071
|
-
}
|
|
12072
|
-
}
|
|
12073
|
-
if (lamports === 0 && !ataInfo) {
|
|
12074
|
-
consecutiveUnused++;
|
|
12075
|
-
if (consecutiveUnused >= stopAfterUnused) break;
|
|
12076
|
-
continue;
|
|
12077
|
-
}
|
|
12078
|
-
consecutiveUnused = 0;
|
|
12079
|
-
const shieldSignatures = [];
|
|
12080
|
-
const sigs = await conn.getSignaturesForAddress(receiver, { limit: 20 });
|
|
12081
|
-
for (const s of sigs) {
|
|
12082
|
-
if (s.err) continue;
|
|
12083
|
-
const tx = await conn.getTransaction(s.signature, { maxSupportedTransactionVersion: 0 });
|
|
12084
|
-
const keys = tx?.transaction.message.getAccountKeys({
|
|
12085
|
-
accountKeysFromLookups: tx.meta?.loadedAddresses
|
|
12086
|
-
});
|
|
12087
|
-
if (keys && [...Array(keys.length).keys()].some((i) => keys.get(i)?.equals(opts.programId))) {
|
|
12088
|
-
shieldSignatures.push(s.signature);
|
|
12089
|
-
}
|
|
12090
|
-
}
|
|
12091
|
-
const shieldSignature = shieldSignatures[0];
|
|
12092
|
-
const indexReused = shieldSignatures.length > 1;
|
|
12093
|
-
let state;
|
|
12094
|
-
if (tokenBalance > 0n) state = shieldSignature ? "needs-cleanup" : "arrived";
|
|
12095
|
-
else if (shieldSignature) state = ataInfo ? "needs-cleanup" : "complete";
|
|
12096
|
-
else state = "awaiting";
|
|
12097
|
-
out.push({
|
|
12098
|
-
index,
|
|
12099
|
-
receiver,
|
|
12100
|
-
tokenAccount,
|
|
12101
|
-
state,
|
|
12102
|
-
tokenBalance,
|
|
12103
|
-
lamports,
|
|
12104
|
-
shieldSignature,
|
|
12105
|
-
...indexReused ? { indexReused, shieldSignatures } : {}
|
|
12106
|
-
});
|
|
12107
|
-
} catch (err) {
|
|
12108
|
-
out.push({
|
|
12109
|
-
index,
|
|
12110
|
-
receiver,
|
|
12111
|
-
tokenAccount,
|
|
12112
|
-
state: "unknown",
|
|
12113
|
-
tokenBalance: 0n,
|
|
12114
|
-
lamports: 0,
|
|
12115
|
-
error: describeError(err)
|
|
12116
|
-
});
|
|
12117
|
-
}
|
|
12118
|
-
}
|
|
12119
|
-
return out;
|
|
12120
|
-
}
|
|
12121
|
-
|
|
12122
|
-
// src/bridge/deposit-core.ts
|
|
12123
|
-
var import_web316 = require("@solana/web3.js");
|
|
12124
|
-
var import_tweetnacl8 = __toESM(require("tweetnacl"), 1);
|
|
12125
|
-
init_utxo();
|
|
12126
|
-
|
|
12127
|
-
// src/bridge/funder.ts
|
|
12128
|
-
var import_web315 = require("@solana/web3.js");
|
|
12129
|
-
var import_spl_token5 = require("@solana/spl-token");
|
|
12130
|
-
var MAINNET_RENT_0 = 890880;
|
|
12131
|
-
var MAINNET_RENT_1 = 897840;
|
|
12132
|
-
var FEE_BUDGET = 13e4;
|
|
12133
|
-
var CLEANUP_FEE_BUDGET = 5e3;
|
|
12134
|
-
var pda = (seeds, programId) => import_web315.PublicKey.findProgramAddressSync(seeds.map((s) => Buffer.from(s)), programId)[0];
|
|
12135
|
-
function deriveFundingTargets(d) {
|
|
12136
|
-
const pool = pda([Buffer.from("pool"), d.mint.toBuffer()], d.programId);
|
|
12137
|
-
return {
|
|
12138
|
-
pool,
|
|
12139
|
-
// program: NullifierAccount::derive_pda_with_pool -> [b"nullifier", pool, nullifier]
|
|
12140
|
-
nullifier0: pda([Buffer.from("nullifier"), pool.toBuffer(), d.nullifiers[0]], d.programId),
|
|
12141
|
-
nullifier1: pda([Buffer.from("nullifier"), pool.toBuffer(), d.nullifiers[1]], d.programId),
|
|
12142
|
-
// relay: derive_risk_nonce_pda -> [b"risk_nonce", bind0]
|
|
12143
|
-
riskNonce: pda([Buffer.from("risk_nonce"), d.bind0], d.programId),
|
|
12144
|
-
depositorAta: (0, import_spl_token5.getAssociatedTokenAddressSync)(d.mint, d.depositor, false)
|
|
12145
|
-
};
|
|
12146
|
-
}
|
|
12147
|
-
async function readRent(conn) {
|
|
12148
|
-
const [zero, one] = await Promise.all([
|
|
12149
|
-
conn.getMinimumBalanceForRentExemption(0),
|
|
12150
|
-
conn.getMinimumBalanceForRentExemption(1)
|
|
12151
|
-
]);
|
|
12152
|
-
return { zero, one };
|
|
12153
|
-
}
|
|
12154
|
-
|
|
12155
|
-
// src/bridge/deposit-core.ts
|
|
12156
|
-
var DepositError = class extends Error {
|
|
12157
|
-
constructor(message, fundedAccounts, measuredTxSize) {
|
|
12158
|
-
super(message);
|
|
12159
|
-
this.fundedAccounts = fundedAccounts;
|
|
12160
|
-
this.measuredTxSize = measuredTxSize;
|
|
12161
|
-
this.name = "DepositError";
|
|
12162
|
-
}
|
|
12163
|
-
};
|
|
12164
|
-
async function depositFromDerivedKey(conn, R, funder, amount, log = console.log, grantOverride, opts) {
|
|
12165
|
-
if (!opts.noteSpendKey || opts.noteSpendKey.length !== 32) {
|
|
12166
|
-
throw new Error(
|
|
12167
|
-
"opts.noteSpendKey (32 bytes) is required. It derives the note's spending key, and a note whose key is not derived from something you can reproduce is unspendable forever. Pass the same Cloak seed you derived the receiving address from."
|
|
12168
|
-
);
|
|
12169
|
-
}
|
|
12170
|
-
if (!opts.relayUrl) {
|
|
12171
|
-
throw new Error(
|
|
12172
|
-
"opts.relayUrl is required. There is no default: a missing relay used to resolve silently to the local stack, which is how a live run built a deposit against infrastructure that only existed on someone's laptop. Say which relay, every call."
|
|
12173
|
-
);
|
|
12174
|
-
}
|
|
12175
|
-
if (!opts.programId) {
|
|
12176
|
-
throw new Error(
|
|
12177
|
-
"opts.programId is required. There is no default: this is the exact field a live mainnet run once inherited from this module's local-stack constant, built a deposit against a program that does not exist on mainnet, and failed hunting a merkle tree that was never there."
|
|
12178
|
-
);
|
|
12179
|
-
}
|
|
12180
|
-
if (!opts.mint) {
|
|
12181
|
-
throw new Error(
|
|
12182
|
-
"opts.mint is required. There is no default: a deposit built for the wrong mint produces a note for an asset that never arrived at R, and there is nothing to silently fall back to."
|
|
12183
|
-
);
|
|
12184
|
-
}
|
|
12185
|
-
assertAllowedRpcConnection(conn);
|
|
12186
|
-
const relayUrl = opts.relayUrl;
|
|
12187
|
-
const programId = opts.programId;
|
|
12188
|
-
const mint = opts.mint;
|
|
12189
|
-
setCircuitsPath(resolveCircuitsBase());
|
|
12190
|
-
const grantR = grantOverride ?? MAINNET_RENT_0 + FEE_BUDGET + CLEANUP_FEE_BUDGET;
|
|
12191
|
-
const heldByR = await conn.getBalance(R.publicKey);
|
|
12192
|
-
if (heldByR >= grantR) {
|
|
12193
|
-
log(` R already holds ${heldByR} (>= ${grantR}) \u2014 no top-up needed`);
|
|
12194
|
-
} else {
|
|
12195
|
-
await (0, import_web316.sendAndConfirmTransaction)(conn, new import_web316.Transaction().add(
|
|
12196
|
-
import_web316.SystemProgram.transfer({ fromPubkey: funder.publicKey, toPubkey: R.publicKey, lamports: grantR - heldByR })
|
|
12197
|
-
), [funder]);
|
|
12198
|
-
log(` funder topped R up by ${grantR - heldByR} to ${grantR}${grantOverride !== void 0 ? " (OVERRIDDEN for a deliberate test)" : " \u2014 floor + deposit fee + cleanup fee, no rent"}`);
|
|
12199
|
-
}
|
|
12200
|
-
let measuredSize = -1;
|
|
12201
|
-
let fundedAccounts = [];
|
|
12202
|
-
const signTransaction2 = async (tx) => {
|
|
12203
|
-
if (tx instanceof import_web316.VersionedTransaction) {
|
|
12204
|
-
measuredSize = tx.serialize().length;
|
|
12205
|
-
const alts = await Promise.all(
|
|
12206
|
-
tx.message.addressTableLookups.map(async (l) => (await conn.getAddressLookupTable(l.accountKey)).value)
|
|
12207
|
-
);
|
|
12208
|
-
const keys = tx.message.getAccountKeys({ addressLookupTableAccounts: alts });
|
|
12209
|
-
const ix = tx.message.compiledInstructions.find((i) => keys.get(i.programIdIndex).equals(programId));
|
|
12210
|
-
const at = (n) => keys.get(ix.accountKeyIndexes[n]);
|
|
12211
|
-
const targets = [
|
|
12212
|
-
{ a: at(12), need: MAINNET_RENT_0, name: "risk_nonce" },
|
|
12213
|
-
{ a: at(4), need: MAINNET_RENT_1, name: "nullifier_0" },
|
|
12214
|
-
{ a: at(5), need: MAINNET_RENT_1, name: "nullifier_1" }
|
|
12215
|
-
];
|
|
12216
|
-
const infos = await conn.getMultipleAccountsInfo(targets.map((t) => t.a));
|
|
12217
|
-
fundedAccounts = targets.map((t, i) => ({
|
|
12218
|
-
name: t.name,
|
|
12219
|
-
address: t.a.toBase58(),
|
|
12220
|
-
lamportsSent: Math.max(0, t.need - (infos[i]?.lamports ?? 0))
|
|
12221
|
-
}));
|
|
12222
|
-
const ixs = targets.flatMap((t, i) => (infos[i]?.lamports ?? 0) >= t.need ? [] : [import_web316.SystemProgram.transfer({
|
|
12223
|
-
fromPubkey: funder.publicKey,
|
|
12224
|
-
toPubkey: t.a,
|
|
12225
|
-
lamports: t.need - (infos[i]?.lamports ?? 0)
|
|
12226
|
-
})]);
|
|
12227
|
-
if (ixs.length) {
|
|
12228
|
-
const sig = await (0, import_web316.sendAndConfirmTransaction)(conn, new import_web316.Transaction().add(...ixs), [funder]);
|
|
12229
|
-
log(` seam: funded ${ixs.length} program accounts read off the built tx \u2014 ${sig.slice(0, 16)}\u2026`);
|
|
12230
|
-
}
|
|
12231
|
-
tx.sign([R]);
|
|
12232
|
-
return tx;
|
|
12233
|
-
}
|
|
12234
|
-
tx.partialSign(R);
|
|
12235
|
-
return tx;
|
|
12236
|
-
};
|
|
12237
|
-
const signMessage = async (m) => import_tweetnacl8.default.sign.detached(m, R.secretKey);
|
|
12238
|
-
const utxoKeypair = await deriveUtxoKeypairFromSpendKey(opts.noteSpendKey);
|
|
12239
|
-
const nk = getNkFromUtxoPrivateKey(utxoKeypair.privateKey);
|
|
12240
|
-
const { utxo, noteSalt } = await createRecoverableDepositUtxo(amount, nk, mint);
|
|
12241
|
-
const zeroInput = await createZeroUtxo(mint);
|
|
12242
|
-
const rBefore = await conn.getBalance(R.publicKey);
|
|
12243
|
-
let result;
|
|
12244
|
-
try {
|
|
12245
|
-
result = await transact(
|
|
12246
|
-
{ inputUtxos: [zeroInput], outputUtxos: [utxo], externalAmount: amount, depositor: R.publicKey },
|
|
12247
|
-
{
|
|
12248
|
-
connection: conn,
|
|
12249
|
-
programId,
|
|
12250
|
-
relayUrl,
|
|
12251
|
-
// NO depositorKeypair: the SDK branches `if (keypair) … else if (signTransaction)`
|
|
12252
|
-
// (transact.ts:2786, :2936), so passing one silently skips the funding seam.
|
|
12253
|
-
depositorPublicKey: R.publicKey,
|
|
12254
|
-
walletPublicKey: R.publicKey,
|
|
12255
|
-
signTransaction: signTransaction2,
|
|
12256
|
-
signMessage,
|
|
12257
|
-
chainNoteViewingKeyNk: nk,
|
|
12258
|
-
chainNoteSalt: noteSalt,
|
|
12259
|
-
relaySupplementalAlt: true,
|
|
12260
|
-
onProgress: (s) => log(` \xB7 ${s}`)
|
|
12261
|
-
}
|
|
12262
|
-
);
|
|
12263
|
-
} catch (e) {
|
|
12264
|
-
const msg = e instanceof Error ? e.message : String(e);
|
|
12265
|
-
throw new DepositError(msg, fundedAccounts, measuredSize);
|
|
12266
|
-
}
|
|
12267
|
-
const rAfter = await conn.getBalance(R.publicKey);
|
|
12268
|
-
const noteIndex = result.outputUtxos[0].index;
|
|
12269
|
-
if (noteIndex === void 0) throw new Error("deposit landed but the note has no index \u2014 it cannot be discovered later");
|
|
12270
|
-
return {
|
|
12271
|
-
signature: result.signature,
|
|
12272
|
-
noteIndex,
|
|
12273
|
-
amount: result.outputUtxos[0].amount,
|
|
12274
|
-
txSize: measuredSize,
|
|
12275
|
-
rBefore,
|
|
12276
|
-
rAfter,
|
|
12277
|
-
rentExempt: rAfter >= MAINNET_RENT_0,
|
|
12278
|
-
inputNullifiers: result.inputNullifiers,
|
|
12279
|
-
fundedAccounts
|
|
12280
|
-
};
|
|
12281
|
-
}
|
|
12282
|
-
|
|
12283
|
-
// src/bridge/cleanup.ts
|
|
12284
|
-
var import_web317 = require("@solana/web3.js");
|
|
12285
|
-
var import_spl_token6 = require("@solana/spl-token");
|
|
12286
|
-
var DEFAULT_MINT = new import_web317.PublicKey("EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v");
|
|
12287
|
-
async function cleanupReceivingAddress(conn, R, dustDestination, mint = DEFAULT_MINT) {
|
|
12288
|
-
assertAllowedRpcConnection(conn);
|
|
12289
|
-
const rAta = (0, import_spl_token6.getAssociatedTokenAddressSync)(mint, R.publicKey);
|
|
12290
|
-
const info = await conn.getAccountInfo(rAta);
|
|
12291
|
-
if (!info) {
|
|
12292
|
-
return {
|
|
12293
|
-
closed: false,
|
|
12294
|
-
dustSwept: 0n,
|
|
12295
|
-
rentReturned: 0,
|
|
12296
|
-
destination: null,
|
|
12297
|
-
signature: null,
|
|
12298
|
-
note: "no token account \u2014 nothing to recover"
|
|
12299
|
-
};
|
|
12300
|
-
}
|
|
12301
|
-
const bal = BigInt((await conn.getTokenAccountBalance(rAta)).value.amount);
|
|
12302
|
-
const rentHeld = info.lamports;
|
|
12303
|
-
const before = await conn.getBalance(R.publicKey);
|
|
12304
|
-
const ixs = [];
|
|
12305
|
-
let destination = null;
|
|
12306
|
-
if (bal > 0n && !dustDestination) {
|
|
12307
|
-
return {
|
|
12308
|
-
closed: false,
|
|
12309
|
-
dustSwept: 0n,
|
|
12310
|
-
rentReturned: 0,
|
|
12311
|
-
destination: null,
|
|
12312
|
-
signature: null,
|
|
12313
|
-
note: `dusted with ${bal} base units after the deposit; leaving the account open and ${rentHeld.toLocaleString()} lamports of rent unrecovered, because sweeping it would publish a link from this deposit to whoever receives it`
|
|
12314
|
-
};
|
|
12315
|
-
}
|
|
12316
|
-
if (bal > 0n && dustDestination) {
|
|
12317
|
-
const destAta = (0, import_spl_token6.getAssociatedTokenAddressSync)(mint, dustDestination);
|
|
12318
|
-
const destInfo = await conn.getAccountInfo(destAta);
|
|
12319
|
-
if (!destInfo) {
|
|
12320
|
-
const ataRent = await (0, import_spl_token6.getMinimumBalanceForRentExemptAccount)(conn);
|
|
12321
|
-
if (before < ataRent + CLEANUP_FEE_BUDGET) {
|
|
12322
|
-
throw new Error(
|
|
12323
|
-
`dustDestination ${dustDestination.toBase58()} has no token account for mint ${mint.toBase58()}, and creating one costs ${ataRent} lamports of rent that R does not have: R holds ${before}, which deposit-core.ts reserved only for this transaction's own fee (CLEANUP_FEE_BUDGET = ${CLEANUP_FEE_BUDGET} in funder.ts), not for a fresh account's rent. Fund R with at least ${ataRent + CLEANUP_FEE_BUDGET - before} more lamports first, or choose a destination that already has a token account for this mint.`
|
|
12324
|
-
);
|
|
12325
|
-
}
|
|
12326
|
-
ixs.push((0, import_spl_token6.createAssociatedTokenAccountIdempotentInstruction)(R.publicKey, destAta, dustDestination, mint));
|
|
12327
|
-
}
|
|
12328
|
-
ixs.push((0, import_spl_token6.createTransferInstruction)(rAta, destAta, R.publicKey, bal));
|
|
12329
|
-
destination = destAta.toBase58();
|
|
12330
|
-
}
|
|
12331
|
-
ixs.push((0, import_spl_token6.createCloseAccountInstruction)(rAta, R.publicKey, R.publicKey));
|
|
12332
|
-
const signature = await (0, import_web317.sendAndConfirmTransaction)(conn, new import_web317.Transaction().add(...ixs), [R], {
|
|
12333
|
-
commitment: "confirmed"
|
|
12334
|
-
});
|
|
12335
|
-
const after = await conn.getBalance(R.publicKey);
|
|
12336
|
-
const gone = await conn.getAccountInfo(rAta) === null;
|
|
12337
|
-
return {
|
|
12338
|
-
closed: gone,
|
|
12339
|
-
dustSwept: bal,
|
|
12340
|
-
rentReturned: after - before,
|
|
12341
|
-
destination,
|
|
12342
|
-
signature,
|
|
12343
|
-
note: bal > 0n ? `swept ${bal} base units of dust to the caller-chosen destination and closed, in one transaction \u2014 note this publishes a link from the deposit to that destination` : `closed cleanly, nothing to sweep`
|
|
12344
|
-
};
|
|
12345
|
-
}
|
|
12346
|
-
|
|
12347
|
-
// src/bridge/quote.ts
|
|
12348
|
-
var MIN_DEPOSIT_SPL_BASE_UNITS = 1000000n;
|
|
12349
|
-
var WITHDRAW_FIXED_FEE = 450000n;
|
|
12350
|
-
var WITHDRAW_FEE_BPS = 30n;
|
|
12351
|
-
function withdrawFeeAt(amount, fixedFee, feeBps) {
|
|
12352
|
-
return fixedFee + amount * feeBps / 10000n;
|
|
12353
|
-
}
|
|
12354
|
-
var MAX_FEE_FRACTION = 0.063;
|
|
12355
|
-
var FIXED_ROUND_TRIP = 903000n;
|
|
12356
|
-
var ECONOMIC_MINIMUM = FIXED_ROUND_TRIP * 1000000n / BigInt(Math.round((MAX_FEE_FRACTION - 3e-3) * 1e6));
|
|
12357
|
-
function withdrawFeeFor(amount) {
|
|
12358
|
-
return withdrawFeeAt(amount, WITHDRAW_FIXED_FEE, WITHDRAW_FEE_BPS);
|
|
12359
|
-
}
|
|
12360
|
-
function assessBridgeQuote(q) {
|
|
12361
|
-
if (q.sent < 0n) {
|
|
12362
|
-
throw new Error(`assessBridgeQuote: sent must not be negative (got ${q.sent}).`);
|
|
12363
|
-
}
|
|
12364
|
-
if (q.arrivesMin > q.sent) {
|
|
12365
|
-
throw new Error(
|
|
12366
|
-
`assessBridgeQuote: arrivesMin (${q.arrivesMin}) exceeds sent (${q.sent}) \u2014 no rail returns more than it was given, so this input did not come from a real quote.`
|
|
12367
|
-
);
|
|
12368
|
-
}
|
|
12369
|
-
const shieldedMinRaw = q.arrivesMin - q.paymasterFee;
|
|
12370
|
-
const shieldedTargetRaw = q.arrivesTarget - q.paymasterFee;
|
|
12371
|
-
const shieldedMin = shieldedMinRaw > 0n ? shieldedMinRaw : 0n;
|
|
12372
|
-
const shieldedTarget = shieldedTargetRaw > 0n ? shieldedTargetRaw : 0n;
|
|
12373
|
-
const viable = shieldedMinRaw >= MIN_DEPOSIT_SPL_BASE_UNITS;
|
|
12374
|
-
const economic = q.sent >= ECONOMIC_MINIMUM;
|
|
12375
|
-
const withdrawFee = shieldedMin > 0n ? withdrawFeeAt(shieldedMin, q.liveWithdrawFixedFee ?? WITHDRAW_FIXED_FEE, q.liveWithdrawFeeBps ?? WITHDRAW_FEE_BPS) : 0n;
|
|
12376
|
-
const roundTripCost = q.sent - (shieldedMin > withdrawFee ? shieldedMin - withdrawFee : 0n);
|
|
12377
|
-
const roundTripFraction = q.sent > 0n ? Number(roundTripCost) / Number(q.sent) : 0;
|
|
12378
|
-
const reasons = [];
|
|
12379
|
-
if (!viable) {
|
|
12380
|
-
const short = MIN_DEPOSIT_SPL_BASE_UNITS - shieldedMinRaw;
|
|
12381
|
-
reasons.push(
|
|
12382
|
-
(shieldedMinRaw <= 0n ? `The ${fmt(q.paymasterFee)} paymaster fee alone is ${shieldedMinRaw < 0n ? `${fmt(-shieldedMinRaw)} more than` : "all of"} the ${fmt(q.arrivesMin)} the rail guarantees, so nothing would be left to shield.` : `Only ${fmt(shieldedMinRaw)} would be left to shield after the ${fmt(q.paymasterFee)} paymaster fee.`) + ` The program's minimum deposit is ${fmt(MIN_DEPOSIT_SPL_BASE_UNITS)}. Send at least ${fmt(q.sent + short)} to clear it.`
|
|
12383
|
-
);
|
|
12384
|
-
}
|
|
12385
|
-
if (viable && !economic) {
|
|
12386
|
-
reasons.push(
|
|
12387
|
-
`This works, but ${fmt(roundTripCost)} of ${fmt(q.sent)} goes to fees (${(roundTripFraction * 100).toFixed(0)}%). The costs are almost all fixed, so bridging ${fmt(ECONOMIC_MINIMUM)} or more spreads them much further.`
|
|
12388
|
-
);
|
|
12389
|
-
}
|
|
12390
|
-
return {
|
|
12391
|
-
...q,
|
|
12392
|
-
shieldedMin,
|
|
12393
|
-
shieldedTarget,
|
|
12394
|
-
viable,
|
|
12395
|
-
economic,
|
|
12396
|
-
withdrawFee,
|
|
12397
|
-
roundTripCost,
|
|
12398
|
-
roundTripFraction,
|
|
12399
|
-
reasons
|
|
12400
|
-
};
|
|
12401
|
-
}
|
|
12402
|
-
var fmt = (v) => `${(Number(v) / 1e6).toFixed(6)} USDC`;
|
|
12403
|
-
function renderAssessment(a) {
|
|
12404
|
-
const L = [];
|
|
12405
|
-
L.push(` you send ${fmt(a.sent)}`);
|
|
12406
|
-
L.push(` arrives at least ${fmt(a.arrivesMin)} (target ${fmt(a.arrivesTarget)}, not a promise)`);
|
|
12407
|
-
L.push(` paymaster fee ${fmt(a.paymasterFee)} buys the receiver its SOL, so your wallet stays off chain`);
|
|
12408
|
-
L.push(` SHIELDED ${fmt(a.shieldedMin)} at least \u2014 this is what you end up with`);
|
|
12409
|
-
L.push(` to withdraw later ${fmt(a.withdrawFee)} the program's fee, whenever you take it out`);
|
|
12410
|
-
for (const r of a.reasons) L.push(`
|
|
12411
|
-
${a.viable ? "NOTE" : "REFUSED"}: ${r}`);
|
|
12412
|
-
return L.join("\n");
|
|
12413
|
-
}
|
|
12414
|
-
|
|
12415
|
-
// src/bridge/retry.ts
|
|
12416
|
-
var TERMINAL_FAILURE = /DepositTooSmall|minimum is 1\.000000|insufficient|holds only|below the program|kora wants|over the .* ceiling/i;
|
|
12417
|
-
function isTerminalFailure(message) {
|
|
12418
|
-
return TERMINAL_FAILURE.test(message);
|
|
12419
|
-
}
|
|
12420
|
-
function classifyPostFailure(attempted, after) {
|
|
12421
|
-
if (after === null) return "unknown";
|
|
12422
|
-
if (after === 0n) return "landed";
|
|
12423
|
-
if (after >= attempted) return "did-not-land";
|
|
12424
|
-
return "unknown";
|
|
12425
|
-
}
|
|
12426
|
-
function mayRetry(verdict, message) {
|
|
12427
|
-
return verdict === "did-not-land" && !isTerminalFailure(message);
|
|
12428
|
-
}
|
|
12429
|
-
function retryDelayMs(attempt) {
|
|
12430
|
-
return 15e3 * Math.max(0, attempt - 1);
|
|
12431
|
-
}
|
|
12432
|
-
var DoNotRetry = class extends Error {
|
|
12433
|
-
constructor(message) {
|
|
12434
|
-
super(message);
|
|
12435
|
-
this.name = "DoNotRetry";
|
|
12436
|
-
}
|
|
12437
|
-
};
|
|
12438
|
-
async function withShieldRetries(attempt, hooks = {}) {
|
|
12439
|
-
const attempts = hooks.attempts ?? 3;
|
|
12440
|
-
const sleep4 = hooks.sleep ?? ((ms) => new Promise((r) => setTimeout(r, ms)));
|
|
12441
|
-
let last = "";
|
|
12442
|
-
for (let n = 1; n <= attempts; n++) {
|
|
12443
|
-
if (n > 1) {
|
|
12444
|
-
const delay = retryDelayMs(n);
|
|
12445
|
-
hooks.onRetry?.(n, delay, last);
|
|
12446
|
-
await sleep4(delay);
|
|
12447
|
-
}
|
|
12448
|
-
try {
|
|
12449
|
-
return await attempt(n);
|
|
12450
|
-
} catch (e) {
|
|
12451
|
-
if (e instanceof DoNotRetry) throw e;
|
|
12452
|
-
last = e instanceof Error ? e.message : String(e);
|
|
12453
|
-
if (isTerminalFailure(last) || n === attempts) throw e;
|
|
12454
|
-
}
|
|
12455
|
-
}
|
|
12456
|
-
throw new Error("unreachable");
|
|
12457
|
-
}
|
|
12458
|
-
|
|
12459
11660
|
// src/index.ts
|
|
12460
11661
|
var VERSION = "0.2.3";
|
|
12461
11662
|
var SCANNER_SUPPORTS_TRANSACT_SWAP = true;
|
|
12462
11663
|
// Annotate the CommonJS export names for ESM import in node:
|
|
12463
11664
|
0 && (module.exports = {
|
|
12464
|
-
BRIDGE_ESCROW_LABEL,
|
|
12465
11665
|
BUILD_ALLOWS_LOCAL_ENDPOINTS,
|
|
12466
11666
|
CHAIN_NOTE_SALT_BITS,
|
|
12467
|
-
CLEANUP_FEE_BUDGET,
|
|
12468
11667
|
CLOAK_PRODUCTION_RELAY_URL,
|
|
12469
11668
|
CLOAK_PROGRAM_ID,
|
|
12470
11669
|
CloakError,
|
|
@@ -12472,25 +11671,16 @@ var SCANNER_SUPPORTS_TRANSACT_SWAP = true;
|
|
|
12472
11671
|
DEFAULT_TRANSACTION_CIRCUITS_URL,
|
|
12473
11672
|
DELIVERY_MEMO_TAG,
|
|
12474
11673
|
DELIVERY_REGISTRY_SEED,
|
|
12475
|
-
DepositError,
|
|
12476
|
-
DoNotRetry,
|
|
12477
|
-
ECONOMIC_MINIMUM,
|
|
12478
11674
|
EXPECTED_CIRCUIT_HASHES,
|
|
12479
|
-
FEE_BUDGET,
|
|
12480
11675
|
FIXED_FEE_LAMPORTS,
|
|
12481
11676
|
InsecureRandomnessError,
|
|
12482
11677
|
LAMPORTS_PER_SOL,
|
|
12483
11678
|
LocalStorageAdapter,
|
|
12484
|
-
MAINNET_RENT_0,
|
|
12485
|
-
MAINNET_RENT_1,
|
|
12486
|
-
MAX_RECEIVER_INDEX,
|
|
12487
11679
|
MERKLE_TREE_HEIGHT,
|
|
12488
11680
|
MIN_DEPOSIT_LAMPORTS,
|
|
12489
|
-
MIN_DEPOSIT_SPL_BASE_UNITS,
|
|
12490
11681
|
MemoryStorageAdapter,
|
|
12491
11682
|
MerkleTree,
|
|
12492
11683
|
NATIVE_SOL_MINT,
|
|
12493
|
-
ONECLICK_PUBKEY_B58,
|
|
12494
11684
|
RECIPIENT_DELIVERY_CIPHERTEXT_LEN,
|
|
12495
11685
|
RECIPIENT_DELIVERY_EPHEMERAL_PK_LEN,
|
|
12496
11686
|
RECIPIENT_DELIVERY_NONCE_LEN,
|
|
@@ -12509,7 +11699,6 @@ var SCANNER_SUPPORTS_TRANSACT_SWAP = true;
|
|
|
12509
11699
|
SettlementVerificationError,
|
|
12510
11700
|
ShieldPoolErrors,
|
|
12511
11701
|
SimpleWallet,
|
|
12512
|
-
TERMINAL_FAILURE,
|
|
12513
11702
|
TRANSACTION_CIRCUITS_VERSION,
|
|
12514
11703
|
TRANSACT_AUTH_FIELDS,
|
|
12515
11704
|
TRANSACT_SWAP_AUTH_FIELDS,
|
|
@@ -12519,12 +11708,9 @@ var SCANNER_SUPPORTS_TRANSACT_SWAP = true;
|
|
|
12519
11708
|
VARIABLE_FEE_NUMERATOR,
|
|
12520
11709
|
VARIABLE_FEE_RATE,
|
|
12521
11710
|
VERSION,
|
|
12522
|
-
WITHDRAW_FEE_BPS,
|
|
12523
|
-
WITHDRAW_FIXED_FEE,
|
|
12524
11711
|
assertDirectSubmissionLanded,
|
|
12525
11712
|
assertInputMints,
|
|
12526
11713
|
assertTransactionCircuitIntegrity,
|
|
12527
|
-
assessBridgeQuote,
|
|
12528
11714
|
bigintToBytes32,
|
|
12529
11715
|
bigintToHex,
|
|
12530
11716
|
buildMerkleTree,
|
|
@@ -12539,16 +11725,12 @@ var SCANNER_SUPPORTS_TRANSACT_SWAP = true;
|
|
|
12539
11725
|
calculateRelayFee,
|
|
12540
11726
|
canRebuildMerkleTreeFromChain,
|
|
12541
11727
|
canonicalJson,
|
|
12542
|
-
canonicalPayloadString,
|
|
12543
11728
|
chainNoteFromBase64,
|
|
12544
11729
|
chainNoteToBase64,
|
|
12545
|
-
classifyPostFailure,
|
|
12546
11730
|
classifyRelayError,
|
|
12547
|
-
cleanupReceivingAddress,
|
|
12548
11731
|
cleanupStalePendingOperations,
|
|
12549
11732
|
clearPendingDeposits,
|
|
12550
11733
|
clearPendingWithdrawals,
|
|
12551
|
-
cloakBridgeRail,
|
|
12552
11734
|
computeChainNoteHash,
|
|
12553
11735
|
computeExtDataHash,
|
|
12554
11736
|
computeMerkleRoot,
|
|
@@ -12570,13 +11752,10 @@ var SCANNER_SUPPORTS_TRANSACT_SWAP = true;
|
|
|
12570
11752
|
decryptCompactChainNote,
|
|
12571
11753
|
decryptComplianceMetadataWithMasterKey,
|
|
12572
11754
|
decryptTransactionMetadata,
|
|
12573
|
-
depositFromDerivedKey,
|
|
12574
|
-
deriveBridgeReceiver,
|
|
12575
11755
|
deriveChangeNoteBlinding,
|
|
12576
11756
|
deriveDepositNoteSecrets,
|
|
12577
11757
|
deriveDiversifiedViewingKey,
|
|
12578
11758
|
deriveDiversifier,
|
|
12579
|
-
deriveFundingTargets,
|
|
12580
11759
|
deriveInputNullifierPdas,
|
|
12581
11760
|
derivePublicKey,
|
|
12582
11761
|
deriveSpendKey,
|
|
@@ -12615,7 +11794,6 @@ var SCANNER_SUPPORTS_TRANSACT_SWAP = true;
|
|
|
12615
11794
|
formatErrorForLogging,
|
|
12616
11795
|
formatSol,
|
|
12617
11796
|
fullWithdraw,
|
|
12618
|
-
fundReceiverViaPaymaster,
|
|
12619
11797
|
generateCloakKeys,
|
|
12620
11798
|
generateCommitmentAsync,
|
|
12621
11799
|
generateMasterSeed,
|
|
@@ -12651,21 +11829,18 @@ var SCANNER_SUPPORTS_TRANSACT_SWAP = true;
|
|
|
12651
11829
|
isReactNative,
|
|
12652
11830
|
isRootNotFoundError,
|
|
12653
11831
|
isSubmissionOutcomeUnknownResponse,
|
|
12654
|
-
isTerminalFailure,
|
|
12655
11832
|
isValidHex,
|
|
12656
11833
|
isValidRpcUrl,
|
|
12657
11834
|
isValidSolanaAddress,
|
|
12658
11835
|
isWithdrawAmountSufficient,
|
|
12659
11836
|
isWithdrawable,
|
|
12660
11837
|
keypairToAdapter,
|
|
12661
|
-
listBridgeDeposits,
|
|
12662
11838
|
loadPendingDeposits,
|
|
12663
11839
|
loadPendingWithdrawals,
|
|
12664
11840
|
loadVerifiedCircuitArtifacts,
|
|
12665
11841
|
matchChangeNote,
|
|
12666
11842
|
matchDepositNote,
|
|
12667
11843
|
matchSwapRefundLeaf,
|
|
12668
|
-
mayRetry,
|
|
12669
11844
|
openRecipientDeliveryNote,
|
|
12670
11845
|
parseAmount,
|
|
12671
11846
|
parseDeliveryCarrierMemo,
|
|
@@ -12688,14 +11863,11 @@ var SCANNER_SUPPORTS_TRANSACT_SWAP = true;
|
|
|
12688
11863
|
randomDepositNoteSalt,
|
|
12689
11864
|
randomFieldElement,
|
|
12690
11865
|
readMerkleTreeState,
|
|
12691
|
-
readRent,
|
|
12692
11866
|
recipientDeliveryNoteToBase64,
|
|
12693
11867
|
registerViewingKey,
|
|
12694
11868
|
removePendingDeposit,
|
|
12695
11869
|
removePendingWithdrawal,
|
|
12696
|
-
renderAssessment,
|
|
12697
11870
|
resolveCircuitsBase,
|
|
12698
|
-
retryDelayMs,
|
|
12699
11871
|
savePendingDeposit,
|
|
12700
11872
|
savePendingWithdrawal,
|
|
12701
11873
|
scanNotesForWallet,
|
|
@@ -12728,17 +11900,13 @@ var SCANNER_SUPPORTS_TRANSACT_SWAP = true;
|
|
|
12728
11900
|
validateDepositParams,
|
|
12729
11901
|
validateNote,
|
|
12730
11902
|
validateOutputsSum,
|
|
12731
|
-
validatePaymasterTopUpTransaction,
|
|
12732
11903
|
validateRoot,
|
|
12733
11904
|
validateTransfers,
|
|
12734
11905
|
validateWalletConnected,
|
|
12735
11906
|
validateWithdrawableNote,
|
|
12736
11907
|
verifyAllCircuits,
|
|
12737
11908
|
verifyCircuitIntegrity,
|
|
12738
|
-
verifyQuoteSignature,
|
|
12739
11909
|
verifyUtxos,
|
|
12740
11910
|
waitForRoot,
|
|
12741
|
-
|
|
12742
|
-
withTiming,
|
|
12743
|
-
withdrawFeeFor
|
|
11911
|
+
withTiming
|
|
12744
11912
|
});
|