@gvnrdao/dh-sdk 0.0.323 → 0.0.324
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/browser/dist/browser.js +1 -1
- package/dist/index.js +186 -43
- package/dist/index.mjs +186 -43
- package/dist/modules/diamond-hands-sdk.d.ts +18 -0
- package/dist/utils/quantum-revert.utils.d.ts +21 -0
- package/dist/utils/quantum-submission.utils.d.ts +23 -3
- package/dist/utils/quantum-timing.d.ts +49 -2
- package/package.json +3 -3
package/dist/index.js
CHANGED
|
@@ -1379,30 +1379,30 @@ var require_pkg_src = __commonJS({
|
|
|
1379
1379
|
}
|
|
1380
1380
|
},
|
|
1381
1381
|
btcTransactionSigner: {
|
|
1382
|
-
cid: "
|
|
1382
|
+
cid: "QmakWzTce8NH1Jkgv1xwg83Bg9WmF2UG1Mq76pDYDSwwUp",
|
|
1383
1383
|
authorizedCidHex: cidToHex(
|
|
1384
|
-
"
|
|
1384
|
+
"QmakWzTce8NH1Jkgv1xwg83Bg9WmF2UG1Mq76pDYDSwwUp"
|
|
1385
1385
|
),
|
|
1386
1386
|
name: "Btc Transaction Signer",
|
|
1387
1387
|
description: "Production Btc Transaction Signer",
|
|
1388
1388
|
version: "1.1.1",
|
|
1389
1389
|
deployed: true,
|
|
1390
|
-
deployedAt:
|
|
1391
|
-
size:
|
|
1392
|
-
hash: "
|
|
1390
|
+
deployedAt: 1786113907707,
|
|
1391
|
+
size: 67999,
|
|
1392
|
+
hash: "83f3644c68819215e05ba8db3225571354a009458fc1437f606df6cb9142d3f9"
|
|
1393
1393
|
},
|
|
1394
1394
|
ucdMintValidator: {
|
|
1395
|
-
cid: "
|
|
1395
|
+
cid: "Qmd8jgKRceLvf5aoTtwdXG2JqMoBK5cRJwrvEtQkgvbFbx",
|
|
1396
1396
|
authorizedCidHex: cidToHex(
|
|
1397
|
-
"
|
|
1397
|
+
"Qmd8jgKRceLvf5aoTtwdXG2JqMoBK5cRJwrvEtQkgvbFbx"
|
|
1398
1398
|
),
|
|
1399
1399
|
name: "Ucd Mint Validator",
|
|
1400
1400
|
description: "Production Ucd Mint Validator",
|
|
1401
1401
|
version: "1.2.1",
|
|
1402
1402
|
deployed: true,
|
|
1403
|
-
deployedAt:
|
|
1404
|
-
size:
|
|
1405
|
-
hash: "
|
|
1403
|
+
deployedAt: 1786113908489,
|
|
1404
|
+
size: 82739,
|
|
1405
|
+
hash: "2bdd9aebdaad58a43a4731d5b7284f2531b7a9caaf8caf5719d891c4ed33cb2e",
|
|
1406
1406
|
validatorWalletAddress: "0x82DB9F515957aA380B596C6eA2Bd30CEF181f236",
|
|
1407
1407
|
pkp: {
|
|
1408
1408
|
publicKey: "0x041ab17cd91fc5c0b761eea6092d032807561b621b82c488826776e04a9158d61ba64d809a4729f0501289d980732cb06d8dfd06999dd9c8efd2f495dad78b31bb",
|
|
@@ -1410,17 +1410,17 @@ var require_pkg_src = __commonJS({
|
|
|
1410
1410
|
}
|
|
1411
1411
|
},
|
|
1412
1412
|
processPaymentValidator: {
|
|
1413
|
-
cid: "
|
|
1413
|
+
cid: "QmNXVdysXDhCaQ1uNE2Vgjbuzy6yUEnnVgHzmDfNKXMU6z",
|
|
1414
1414
|
authorizedCidHex: cidToHex(
|
|
1415
|
-
"
|
|
1415
|
+
"QmNXVdysXDhCaQ1uNE2Vgjbuzy6yUEnnVgHzmDfNKXMU6z"
|
|
1416
1416
|
),
|
|
1417
1417
|
name: "Process Payment Validator",
|
|
1418
1418
|
description: "Production Process Payment Validator",
|
|
1419
1419
|
version: "1.2.1",
|
|
1420
1420
|
deployed: true,
|
|
1421
|
-
deployedAt:
|
|
1422
|
-
size:
|
|
1423
|
-
hash: "
|
|
1421
|
+
deployedAt: 1786113909138,
|
|
1422
|
+
size: 78736,
|
|
1423
|
+
hash: "17191ecc9c009e0fa5ab52c876330beb2a9a75d30cccb92e7c0c04f169df088b",
|
|
1424
1424
|
validatorWalletAddress: "0x82DB9F515957aA380B596C6eA2Bd30CEF181f236",
|
|
1425
1425
|
pkp: {
|
|
1426
1426
|
publicKey: "0x04cfccb9b6c7addc79469c0e9fafebef4c70801302c62cdb26b610723a9b8527d23f98a40158c7340d83fd0e62d02b5ec74c12f7a86d98e8c6973b4811110f19ad",
|
|
@@ -1428,17 +1428,17 @@ var require_pkg_src = __commonJS({
|
|
|
1428
1428
|
}
|
|
1429
1429
|
},
|
|
1430
1430
|
extendPositionValidator: {
|
|
1431
|
-
cid: "
|
|
1431
|
+
cid: "QmYwBsyrhGfHWyRKx549G4tKHxsBLAuRUHcecigeUCkFav",
|
|
1432
1432
|
authorizedCidHex: cidToHex(
|
|
1433
|
-
"
|
|
1433
|
+
"QmYwBsyrhGfHWyRKx549G4tKHxsBLAuRUHcecigeUCkFav"
|
|
1434
1434
|
),
|
|
1435
1435
|
name: "Extend Position Validator",
|
|
1436
1436
|
description: "Production Extend Position Validator",
|
|
1437
1437
|
version: "1.2.1",
|
|
1438
1438
|
deployed: true,
|
|
1439
|
-
deployedAt:
|
|
1440
|
-
size:
|
|
1441
|
-
hash: "
|
|
1439
|
+
deployedAt: 1786113909872,
|
|
1440
|
+
size: 76515,
|
|
1441
|
+
hash: "1d4e085335af80f194a663a577876902c83015177e95906a0b461fa93bd5da08",
|
|
1442
1442
|
validatorWalletAddress: "0x82DB9F515957aA380B596C6eA2Bd30CEF181f236",
|
|
1443
1443
|
pkp: {
|
|
1444
1444
|
publicKey: "0x04e52338f6a0c3362800f1a94c4c8f08be5030dde0fa217388c53d1c1a4790f4443c9f2886b2d2d8f4b75a9a156e9b028011b1a1cf7648da0e556aa980ec692836",
|
|
@@ -1446,9 +1446,9 @@ var require_pkg_src = __commonJS({
|
|
|
1446
1446
|
}
|
|
1447
1447
|
},
|
|
1448
1448
|
btcWithdrawal: {
|
|
1449
|
-
cid: "
|
|
1449
|
+
cid: "QmZuR3qSBajutXfRd91ffpyFrRMgmaMh7fDEHRiQQF8Ljp",
|
|
1450
1450
|
authorizedCidHex: cidToHex(
|
|
1451
|
-
"
|
|
1451
|
+
"QmZuR3qSBajutXfRd91ffpyFrRMgmaMh7fDEHRiQQF8Ljp"
|
|
1452
1452
|
),
|
|
1453
1453
|
name: "Btc Withdrawal",
|
|
1454
1454
|
description: "Production Btc Withdrawal",
|
|
@@ -1458,9 +1458,9 @@ var require_pkg_src = __commonJS({
|
|
|
1458
1458
|
// than the one it replaced, which a rotation ceremony would treat as a rollback.
|
|
1459
1459
|
version: "1.2.4",
|
|
1460
1460
|
deployed: true,
|
|
1461
|
-
deployedAt:
|
|
1462
|
-
size:
|
|
1463
|
-
hash: "
|
|
1461
|
+
deployedAt: 1786113910531,
|
|
1462
|
+
size: 95313,
|
|
1463
|
+
hash: "ce12f11e3b5469953bc919586e4f3b8b5d594224b58b799dd9a3b60e3749559c",
|
|
1464
1464
|
validatorWalletAddress: "0x82DB9F515957aA380B596C6eA2Bd30CEF181f236",
|
|
1465
1465
|
pkp: {
|
|
1466
1466
|
publicKey: "0x043616787c5432415c24378c4ef48de2bcd6bb7b575b837e3cff09171802662da7105d79586c7659677a0ecbaddac4cce06cb2a11f69a16fa0c4d7002ac7d51a4d",
|
|
@@ -1571,6 +1571,21 @@ var require_pkg_src = __commonJS({
|
|
|
1571
1571
|
size: 1046,
|
|
1572
1572
|
hash: "03ee5be239c91c735d2c95db89a0d1b77e602cfc18af8eb64b3281fddcd90a72"
|
|
1573
1573
|
},
|
|
1574
|
+
agentModuleExecutor: {
|
|
1575
|
+
// Bound to the isolated Sepolia agent group 7 ("DH-Agent-Sepolia"), which
|
|
1576
|
+
// holds this action and no PKPs until an agent is minted into it. NOT yet
|
|
1577
|
+
// bound on mainnet — the Base `DH-Agent-Mainnet` group is created at rollout.
|
|
1578
|
+
cid: "QmVgjGXUuxoGf8XyddW8a7btaazT9yEotpKoBgb65oPvcF",
|
|
1579
|
+
authorizedCidHex: cidToHex(
|
|
1580
|
+
"QmVgjGXUuxoGf8XyddW8a7btaazT9yEotpKoBgb65oPvcF"
|
|
1581
|
+
),
|
|
1582
|
+
name: "Agent Module Executor",
|
|
1583
|
+
description: "Capability gate for multi-sig Safe agent delegation: binds the agent PKP to the AgentDelegationRegistry record before signing (authorize | execute modes)",
|
|
1584
|
+
version: "1.0.0",
|
|
1585
|
+
deployed: true,
|
|
1586
|
+
size: 11785,
|
|
1587
|
+
hash: "fa294e164273c2158f9ef11a0ccfd735c343c0e3759fcb4b37e0f8a5d1ab0d29"
|
|
1588
|
+
},
|
|
1574
1589
|
staleSpendRecoveryValidator: {
|
|
1575
1590
|
cid: "QmXQWT8V4wjuvH8BbC7xrkYxsVu5AKfvfWcS7jnYfrexYm",
|
|
1576
1591
|
authorizedCidHex: cidToHex(
|
|
@@ -1590,17 +1605,17 @@ var require_pkg_src = __commonJS({
|
|
|
1590
1605
|
}
|
|
1591
1606
|
},
|
|
1592
1607
|
btcUtxoInvalidator: {
|
|
1593
|
-
cid: "
|
|
1608
|
+
cid: "Qmf4Ze8yhnQhHbnX5RPgJrC7Jw1aA3gbpfpd52kFg7fd1m",
|
|
1594
1609
|
authorizedCidHex: cidToHex(
|
|
1595
|
-
"
|
|
1610
|
+
"Qmf4Ze8yhnQhHbnX5RPgJrC7Jw1aA3gbpfpd52kFg7fd1m"
|
|
1596
1611
|
),
|
|
1597
1612
|
name: "Btc Utxo Invalidator",
|
|
1598
1613
|
description: "Production Btc Utxo Invalidator",
|
|
1599
1614
|
version: "1.0.0",
|
|
1600
1615
|
deployed: true,
|
|
1601
|
-
deployedAt:
|
|
1602
|
-
size:
|
|
1603
|
-
hash: "
|
|
1616
|
+
deployedAt: 1786113911948,
|
|
1617
|
+
size: 62553,
|
|
1618
|
+
hash: "1dcea2b49e545c423195be22e072dc5e3039ed1c95a8490b23505956029f5b33"
|
|
1604
1619
|
}
|
|
1605
1620
|
};
|
|
1606
1621
|
function getDeploymentsForNetwork(network) {
|
|
@@ -6253,7 +6268,10 @@ var import_ethers2 = require("ethers");
|
|
|
6253
6268
|
// src/utils/quantum-timing.ts
|
|
6254
6269
|
var QUANTUM_WINDOW_SECONDS = 60;
|
|
6255
6270
|
var DEAD_ZONE_SECONDS = 8;
|
|
6256
|
-
var
|
|
6271
|
+
var SLOT_SECONDS = 12;
|
|
6272
|
+
var INCLUSION_SLOT_TOLERANCE = 3;
|
|
6273
|
+
var INCLUSION_LATENCY_BUDGET = SLOT_SECONDS * INCLUSION_SLOT_TOLERANCE;
|
|
6274
|
+
var MAX_GATE_POLLS = 12;
|
|
6257
6275
|
var POST_BOUNDARY_SKEW_MARGIN = 3;
|
|
6258
6276
|
function calculateNextQuantumTimestamp() {
|
|
6259
6277
|
const now = Math.floor(Date.now() / 1e3);
|
|
@@ -6286,8 +6304,17 @@ function validateQuantumTiming(signedTimestamp, _bufferSeconds = 30) {
|
|
|
6286
6304
|
async function awaitSafeSubmissionWindow(quantumTimestamp, opts = {}) {
|
|
6287
6305
|
const now = opts.now ?? (() => Math.floor(Date.now() / 1e3));
|
|
6288
6306
|
const sleep = opts.sleep ?? ((ms) => new Promise((r) => setTimeout(r, ms)));
|
|
6289
|
-
const nowSec = now();
|
|
6290
6307
|
const signatureQuantum = Math.floor(quantumTimestamp / QUANTUM_WINDOW_SECONDS) * QUANTUM_WINDOW_SECONDS;
|
|
6308
|
+
if (opts.chainNow) {
|
|
6309
|
+
const chainResult = await awaitSafeSubmissionWindowOnChain(
|
|
6310
|
+
signatureQuantum,
|
|
6311
|
+
opts.chainNow,
|
|
6312
|
+
sleep
|
|
6313
|
+
);
|
|
6314
|
+
if (chainResult)
|
|
6315
|
+
return chainResult;
|
|
6316
|
+
}
|
|
6317
|
+
const nowSec = now();
|
|
6291
6318
|
const currentQuantum = Math.floor(nowSec / QUANTUM_WINDOW_SECONDS) * QUANTUM_WINDOW_SECONDS;
|
|
6292
6319
|
const secsToBoundary = QUANTUM_WINDOW_SECONDS - nowSec % QUANTUM_WINDOW_SECONDS;
|
|
6293
6320
|
const isNextQuantumSig = signatureQuantum === currentQuantum + QUANTUM_WINDOW_SECONDS;
|
|
@@ -6304,6 +6331,44 @@ async function awaitSafeSubmissionWindow(quantumTimestamp, opts = {}) {
|
|
|
6304
6331
|
}
|
|
6305
6332
|
return { waited: false, waitedSeconds: 0 };
|
|
6306
6333
|
}
|
|
6334
|
+
async function awaitSafeSubmissionWindowOnChain(signatureQuantum, chainNow, sleep) {
|
|
6335
|
+
let waitedSeconds = 0;
|
|
6336
|
+
for (let poll = 0; poll < MAX_GATE_POLLS; poll++) {
|
|
6337
|
+
let head;
|
|
6338
|
+
try {
|
|
6339
|
+
head = await chainNow();
|
|
6340
|
+
} catch {
|
|
6341
|
+
head = null;
|
|
6342
|
+
}
|
|
6343
|
+
if (head === null || !Number.isFinite(head)) {
|
|
6344
|
+
return waitedSeconds > 0 ? { waited: true, waitedSeconds } : null;
|
|
6345
|
+
}
|
|
6346
|
+
const chainQuantum = Math.floor(head / QUANTUM_WINDOW_SECONDS) * QUANTUM_WINDOW_SECONDS;
|
|
6347
|
+
if (signatureQuantum <= chainQuantum) {
|
|
6348
|
+
return { waited: waitedSeconds > 0, waitedSeconds };
|
|
6349
|
+
}
|
|
6350
|
+
const earliestMine = head + SLOT_SECONDS;
|
|
6351
|
+
const latestMine = head + SLOT_SECONDS * INCLUSION_SLOT_TOLERANCE;
|
|
6352
|
+
const safeBeforeDeadZone = latestMine < signatureQuantum - DEAD_ZONE_SECONDS;
|
|
6353
|
+
const safeAfterBoundary = earliestMine >= signatureQuantum;
|
|
6354
|
+
if (safeBeforeDeadZone || safeAfterBoundary) {
|
|
6355
|
+
return { waited: waitedSeconds > 0, waitedSeconds };
|
|
6356
|
+
}
|
|
6357
|
+
const sleepSeconds = Math.max(
|
|
6358
|
+
1,
|
|
6359
|
+
Math.min(SLOT_SECONDS, signatureQuantum - head)
|
|
6360
|
+
);
|
|
6361
|
+
log.debug(
|
|
6362
|
+
`[Quantum Timing] \u23F3 Deferring send ${sleepSeconds}s to clear the quantum dead zone (sig quantum ${signatureQuantum}, chain head ${head}, insured mine window [${earliestMine}, ${latestMine}])`
|
|
6363
|
+
);
|
|
6364
|
+
await sleep(sleepSeconds * 1e3);
|
|
6365
|
+
waitedSeconds += sleepSeconds;
|
|
6366
|
+
}
|
|
6367
|
+
log.debug(
|
|
6368
|
+
`[Quantum Timing] \u26A0\uFE0F Dead-zone gate exhausted ${MAX_GATE_POLLS} chain polls (sig quantum ${signatureQuantum}) \u2014 proceeding`
|
|
6369
|
+
);
|
|
6370
|
+
return { waited: waitedSeconds > 0, waitedSeconds };
|
|
6371
|
+
}
|
|
6307
6372
|
|
|
6308
6373
|
// src/utils/mint-authorization.utils.ts
|
|
6309
6374
|
var PKP_NFT_ABI = [
|
|
@@ -7260,6 +7325,20 @@ function decodeQuantumRevert(e) {
|
|
|
7260
7325
|
}
|
|
7261
7326
|
return { data, selector, name };
|
|
7262
7327
|
}
|
|
7328
|
+
var RETRYABLE_QUANTUM_ERROR_NAMES = [
|
|
7329
|
+
"DeadZoneViolation",
|
|
7330
|
+
"QuantumOutsideWindow",
|
|
7331
|
+
"QuantumAlreadyUsed",
|
|
7332
|
+
"QuantumExpired"
|
|
7333
|
+
];
|
|
7334
|
+
function isRetryableQuantumFailure(message) {
|
|
7335
|
+
if (!message)
|
|
7336
|
+
return false;
|
|
7337
|
+
if (message.includes("Transaction timeout") || message.includes("Transaction confirmation failed") || message.includes("Transaction receipt not found")) {
|
|
7338
|
+
return false;
|
|
7339
|
+
}
|
|
7340
|
+
return RETRYABLE_QUANTUM_ERROR_NAMES.some((name) => message.includes(name)) || message.includes("Transaction reverted");
|
|
7341
|
+
}
|
|
7263
7342
|
|
|
7264
7343
|
// src/utils/quantum-submission.utils.ts
|
|
7265
7344
|
var MAX_DEADZONE_RESIMULATIONS = 3;
|
|
@@ -7281,9 +7360,14 @@ async function assertSafeQuantumSubmission(opts) {
|
|
|
7281
7360
|
const now = opts.now ?? (() => Math.floor(Date.now() / 1e3));
|
|
7282
7361
|
const onDebug = opts.onDebug ?? (() => {
|
|
7283
7362
|
});
|
|
7363
|
+
const chainNow = opts.chainNow ?? (typeof provider.getBlock === "function" ? async () => {
|
|
7364
|
+
const block = await provider.getBlock("latest");
|
|
7365
|
+
return typeof block?.timestamp === "number" ? block.timestamp : null;
|
|
7366
|
+
} : void 0);
|
|
7284
7367
|
const gateOpts = {
|
|
7285
7368
|
now,
|
|
7286
|
-
...opts.sleep ? { sleep: opts.sleep } : {}
|
|
7369
|
+
...opts.sleep ? { sleep: opts.sleep } : {},
|
|
7370
|
+
...chainNow ? { chainNow } : {}
|
|
7287
7371
|
};
|
|
7288
7372
|
await awaitSafeSubmissionWindow(quantumTimestamp, gateOpts);
|
|
7289
7373
|
const SAME_BLOCK_INTERACTION_SELECTOR = "0x3b53d1db";
|
|
@@ -22293,10 +22377,7 @@ Message: ${causeMessage}${quantumContext}${mintDebtDiagnostics}`
|
|
|
22293
22377
|
isRetryablePaymentQuantumFailure(result) {
|
|
22294
22378
|
if (result.success || !result.error)
|
|
22295
22379
|
return false;
|
|
22296
|
-
|
|
22297
|
-
if (e.includes("Transaction timeout"))
|
|
22298
|
-
return false;
|
|
22299
|
-
return e.includes("DeadZoneViolation") || e.includes("QuantumOutsideWindow") || e.includes("QuantumAlreadyUsed") || e.includes("QuantumExpired") || e === "Transaction reverted";
|
|
22380
|
+
return isRetryableQuantumFailure(result.error);
|
|
22300
22381
|
}
|
|
22301
22382
|
/**
|
|
22302
22383
|
* One payment attempt: user auth → Lit Action authorization → dead-zone gate →
|
|
@@ -22935,6 +23016,37 @@ Message: ${causeMessage}${quantumContext}${mintDebtDiagnostics}`
|
|
|
22935
23016
|
}
|
|
22936
23017
|
return this.withdrawalAddressModule.getEntries(target);
|
|
22937
23018
|
}
|
|
23019
|
+
/**
|
|
23020
|
+
* Recover the revert reason of an already-mined, already-reverted transaction.
|
|
23021
|
+
*
|
|
23022
|
+
* A status-0 receipt carries no revert data, and ethers does not re-fetch it, so
|
|
23023
|
+
* the reason has to be recovered by replaying the exact calldata as an `eth_call`
|
|
23024
|
+
* pinned to the block that mined it — the only block whose `block.timestamp`
|
|
23025
|
+
* reproduces a timing-dependent revert such as `DeadZoneViolation()`.
|
|
23026
|
+
*
|
|
23027
|
+
* Caveat: the replay runs against end-of-block state rather than the state at the
|
|
23028
|
+
* transaction's own index, so for a state-dependent revert the recovered name is
|
|
23029
|
+
* diagnostic, not proof. Timing reverts (the case this exists for) are unaffected —
|
|
23030
|
+
* they depend only on the block timestamp.
|
|
23031
|
+
*
|
|
23032
|
+
* @returns the decoded error name, its raw selector if unknown, or `null` when the
|
|
23033
|
+
* replay yields no revert data at all (never throws — a failed diagnosis
|
|
23034
|
+
* must not mask the underlying failure).
|
|
23035
|
+
*/
|
|
23036
|
+
async decodeMinedRevert(params) {
|
|
23037
|
+
try {
|
|
23038
|
+
await this.getProviderOrThrow().call({
|
|
23039
|
+
to: params.to,
|
|
23040
|
+
from: params.from,
|
|
23041
|
+
data: params.data,
|
|
23042
|
+
blockTag: params.blockNumber
|
|
23043
|
+
});
|
|
23044
|
+
return null;
|
|
23045
|
+
} catch (replayError) {
|
|
23046
|
+
const decoded = decodeQuantumRevert(replayError);
|
|
23047
|
+
return decoded.name ?? decoded.selector ?? null;
|
|
23048
|
+
}
|
|
23049
|
+
}
|
|
22938
23050
|
/**
|
|
22939
23051
|
* Withdraw Bitcoin from a position
|
|
22940
23052
|
*
|
|
@@ -23508,9 +23620,23 @@ Message: ${causeMessage}${quantumContext}${mintDebtDiagnostics}`
|
|
|
23508
23620
|
txHash: tx.hash
|
|
23509
23621
|
});
|
|
23510
23622
|
}
|
|
23623
|
+
const withdrawProvider = this.getProviderOrThrow();
|
|
23624
|
+
const withdrawTimeoutMs = this.config.transactionTimeoutMs || 3e5;
|
|
23511
23625
|
let receipt;
|
|
23512
23626
|
try {
|
|
23513
|
-
receipt = await
|
|
23627
|
+
receipt = await Promise.race([
|
|
23628
|
+
withdrawProvider.waitForTransaction(tx.hash, 1),
|
|
23629
|
+
new Promise(
|
|
23630
|
+
(_, reject) => setTimeout(
|
|
23631
|
+
() => reject(
|
|
23632
|
+
new Error(
|
|
23633
|
+
`Transaction timeout after ${withdrawTimeoutMs}ms. Hash: ${tx.hash}`
|
|
23634
|
+
)
|
|
23635
|
+
),
|
|
23636
|
+
withdrawTimeoutMs
|
|
23637
|
+
)
|
|
23638
|
+
)
|
|
23639
|
+
]);
|
|
23514
23640
|
} catch (waitError) {
|
|
23515
23641
|
const waitErrorMsg = waitError instanceof Error ? waitError.message : String(waitError);
|
|
23516
23642
|
if (this.config.debug) {
|
|
@@ -23527,7 +23653,26 @@ Message: ${causeMessage}${quantumContext}${mintDebtDiagnostics}`
|
|
|
23527
23653
|
if (!receipt) {
|
|
23528
23654
|
return {
|
|
23529
23655
|
success: false,
|
|
23530
|
-
error: `Transaction
|
|
23656
|
+
error: `Transaction receipt not found for hash: ${tx.hash}`
|
|
23657
|
+
};
|
|
23658
|
+
}
|
|
23659
|
+
if (receipt.status === 0) {
|
|
23660
|
+
const revertName = await this.decodeMinedRevert({
|
|
23661
|
+
to: positionManagerAddress,
|
|
23662
|
+
from: await withdrawSigner.getAddress(),
|
|
23663
|
+
data: withdrawCalldata,
|
|
23664
|
+
blockNumber: receipt.blockNumber
|
|
23665
|
+
});
|
|
23666
|
+
if (this.config.debug) {
|
|
23667
|
+
log.error("\u274C withdrawBTC reverted on-chain", {
|
|
23668
|
+
txHash: receipt.hash,
|
|
23669
|
+
blockNumber: receipt.blockNumber,
|
|
23670
|
+
revert: revertName ?? "undecodable"
|
|
23671
|
+
});
|
|
23672
|
+
}
|
|
23673
|
+
return {
|
|
23674
|
+
success: false,
|
|
23675
|
+
error: `Transaction reverted: ${revertName ?? "unknown reason"} (tx: ${receipt.hash})`
|
|
23531
23676
|
};
|
|
23532
23677
|
}
|
|
23533
23678
|
if (this.config.debug) {
|
|
@@ -24655,13 +24800,11 @@ Message: ${causeMessage}${quantumContext}${mintDebtDiagnostics}`
|
|
|
24655
24800
|
if (authResult.success) {
|
|
24656
24801
|
break;
|
|
24657
24802
|
}
|
|
24658
|
-
const isQuantumError = authResult.error
|
|
24659
|
-
"QuantumOutsideWindow"
|
|
24660
|
-
);
|
|
24803
|
+
const isQuantumError = isRetryableQuantumFailure(authResult.error);
|
|
24661
24804
|
if (isQuantumError && wAttempt < MAX_WITHDRAWAL_QUANTUM_RETRIES) {
|
|
24662
24805
|
if (this.config.debug) {
|
|
24663
24806
|
log.warn(
|
|
24664
|
-
`\u26A0\uFE0F Phase 1
|
|
24807
|
+
`\u26A0\uFE0F Phase 1 quantum-timing failure (attempt ${wAttempt}/${MAX_WITHDRAWAL_QUANTUM_RETRIES}): ${authResult.error}. Retrying with a fresh quantum...`
|
|
24665
24808
|
);
|
|
24666
24809
|
}
|
|
24667
24810
|
await new Promise((resolve) => setTimeout(resolve, 2e3));
|