@gvnrdao/dh-sdk 0.0.307 → 0.0.308

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.js CHANGED
@@ -1508,6 +1508,19 @@ var require_pkg_src = __commonJS({
1508
1508
  publicKey: "0x046da0ad6da7dd4a0063cbeac6f2bdb6a9889c2178b23470833356a8ee5630f7f0eee0db348d9d9aaaadd23eccf0063c8f68ee5e446abe30b882bf1de4c932bc21",
1509
1509
  ethAddress: "0xc7e1588Db94Bbe92Ab209B833235144Fc5b97607"
1510
1510
  }
1511
+ },
1512
+ btcUtxoInvalidator: {
1513
+ cid: "QmRue1EAjuJwCDTtTH4czdkkmDEfNpT7iudvwtjaRs6AdA",
1514
+ authorizedCidHex: cidToHex(
1515
+ "QmRue1EAjuJwCDTtTH4czdkkmDEfNpT7iudvwtjaRs6AdA"
1516
+ ),
1517
+ name: "Btc Utxo Invalidator",
1518
+ description: "Production Btc Utxo Invalidator",
1519
+ version: "1.0.0",
1520
+ deployed: true,
1521
+ deployedAt: 1784801043540,
1522
+ size: 60717,
1523
+ hash: "2ca9736edf3d54bba7445491920cba28429029c32a2f2830cad831a37a3cb310"
1511
1524
  }
1512
1525
  };
1513
1526
  function getDeploymentsForNetwork(network) {
@@ -2253,7 +2266,7 @@ ${errorReport}`);
2253
2266
  }
2254
2267
  init_debug_logger();
2255
2268
  init_session_signature_cache();
2256
- var import_ethers16 = require("ethers");
2269
+ var import_ethers17 = require("ethers");
2257
2270
  var EXPIRED_LOAN_MIN_LIQUIDATION_THRESHOLD_BPS = 11e3;
2258
2271
  var GRACE_PERIOD_DAYS = 30;
2259
2272
  var SATOSHIS_PER_BITCOIN = 100000000n;
@@ -5083,12 +5096,12 @@ ${auth.clientId}`;
5083
5096
  }
5084
5097
  async function executeVaultSnapshot(params) {
5085
5098
  global.ethers = {
5086
- ...import_ethers16.ethers,
5099
+ ...import_ethers17.ethers,
5087
5100
  providers: {
5088
- StaticJsonRpcProvider: import_ethers16.ethers.JsonRpcProvider
5101
+ StaticJsonRpcProvider: import_ethers17.ethers.JsonRpcProvider
5089
5102
  },
5090
- Contract: import_ethers16.ethers.Contract,
5091
- utils: import_ethers16.ethers
5103
+ Contract: import_ethers17.ethers.Contract,
5104
+ utils: import_ethers17.ethers
5092
5105
  // v6 moved utils to top level
5093
5106
  };
5094
5107
  global.Lit = {
@@ -5568,6 +5581,7 @@ __export(src_exports, {
5568
5581
  PKPManager: () => PKPManager,
5569
5582
  PaymentType: () => PaymentType,
5570
5583
  PositionStatus: () => PositionStatus,
5584
+ RECOVERY_INVALIDATE_ACTION: () => RECOVERY_INVALIDATE_ACTION,
5571
5585
  SDKError: () => SDKError,
5572
5586
  SDK_DEFAULTS: () => SDK_DEFAULTS,
5573
5587
  SEPOLIA_CONTRACTS: () => SEPOLIA_CONTRACTS,
@@ -5580,6 +5594,8 @@ __export(src_exports, {
5580
5594
  assertProtocolNotPaused: () => assertProtocolNotPaused,
5581
5595
  assertSafeServiceEndpoint: () => assertSafeServiceEndpoint,
5582
5596
  buildBtcExecuteEnvelope: () => buildBtcExecuteEnvelope,
5597
+ buildInvalidateMessageHash: () => buildInvalidateMessageHash,
5598
+ buildInvalidateStaleSpendEnvelope: () => buildInvalidateStaleSpendEnvelope,
5583
5599
  collectFailures: () => collectFailures,
5584
5600
  collectSuccesses: () => collectSuccesses,
5585
5601
  combine: () => combine,
@@ -5630,7 +5646,7 @@ __export(src_exports, {
5630
5646
  module.exports = __toCommonJS(src_exports);
5631
5647
 
5632
5648
  // src/modules/diamond-hands-sdk.ts
5633
- var import_ethers14 = require("ethers");
5649
+ var import_ethers15 = require("ethers");
5634
5650
 
5635
5651
  // src/types/result.ts
5636
5652
  function success(value) {
@@ -7146,10 +7162,81 @@ async function reconcileAuthorizedSpend(spend, esploraBaseUrl, httpGetJson = def
7146
7162
  };
7147
7163
  }
7148
7164
 
7149
- // src/utils/btc-withdrawal-message.ts
7165
+ // src/utils/stale-spend-invalidate-message.ts
7150
7166
  var import_ethers6 = require("ethers");
7167
+ var RECOVERY_INVALIDATE_ACTION = "btc-utxo-invalidator";
7151
7168
  var QUANTUM_SECONDS = 60;
7152
7169
  var QUANTUM_SAFE_THRESHOLD = 40;
7170
+ function buildInvalidateMessageHash(params) {
7171
+ const positionIdBytes32 = (0, import_ethers6.zeroPadValue)(
7172
+ params.positionId.startsWith("0x") ? params.positionId : `0x${params.positionId}`,
7173
+ 32
7174
+ );
7175
+ const actionHash = (0, import_ethers6.keccak256)((0, import_ethers6.toUtf8Bytes)(RECOVERY_INVALIDATE_ACTION));
7176
+ return (0, import_ethers6.solidityPackedKeccak256)(
7177
+ [
7178
+ "bytes32",
7179
+ // positionId
7180
+ "uint256",
7181
+ // timestamp
7182
+ "uint256",
7183
+ // chainId
7184
+ "string",
7185
+ // utxoTxid (display order)
7186
+ "uint32",
7187
+ // utxoVout
7188
+ "bytes32"
7189
+ // actionHash
7190
+ ],
7191
+ [
7192
+ positionIdBytes32,
7193
+ params.timestamp,
7194
+ params.chainId,
7195
+ params.utxoTxid,
7196
+ params.utxoVout,
7197
+ actionHash
7198
+ ]
7199
+ );
7200
+ }
7201
+ async function buildInvalidateStaleSpendEnvelope(params) {
7202
+ const { positionId, utxoTxid, utxoVout, chainId, signer } = params;
7203
+ const nowSec = Date.now() / 1e3;
7204
+ const currentQuantumStart = Math.floor(nowSec / QUANTUM_SECONDS) * QUANTUM_SECONDS;
7205
+ const secsIntoQuantum = nowSec - currentQuantumStart;
7206
+ let timestamp;
7207
+ if (secsIntoQuantum > QUANTUM_SAFE_THRESHOLD) {
7208
+ const nextQuantumStart = currentQuantumStart + QUANTUM_SECONDS;
7209
+ const waitMs = Math.max(0, (nextQuantumStart - nowSec) * 1e3 + 500);
7210
+ await new Promise((r) => setTimeout(r, waitMs));
7211
+ timestamp = nextQuantumStart;
7212
+ } else {
7213
+ timestamp = currentQuantumStart;
7214
+ }
7215
+ const messageHash = buildInvalidateMessageHash({
7216
+ positionId,
7217
+ timestamp,
7218
+ chainId,
7219
+ utxoTxid,
7220
+ utxoVout
7221
+ });
7222
+ const signature = await signer.signMessage((0, import_ethers6.getBytes)(messageHash));
7223
+ const borrowerAddress = await signer.getAddress();
7224
+ return {
7225
+ positionId,
7226
+ utxoTxid,
7227
+ utxoVout,
7228
+ timestamp,
7229
+ chainId,
7230
+ action: RECOVERY_INVALIDATE_ACTION,
7231
+ signature,
7232
+ borrowerAddress
7233
+ };
7234
+ }
7235
+
7236
+ // src/utils/btc-withdrawal-message.ts
7237
+ var import_ethers7 = require("ethers");
7238
+ var QUANTUM_SECONDS2 = 60;
7239
+ var QUANTUM_SAFE_THRESHOLD2 = 40;
7153
7240
  function hashBtcInputSet(utxos) {
7154
7241
  if (!Array.isArray(utxos) || utxos.length === 0) {
7155
7242
  throw new Error("hashBtcInputSet: at least one input is required");
@@ -7178,7 +7265,7 @@ function hashBtcInputSet(utxos) {
7178
7265
  seen.add(key);
7179
7266
  }
7180
7267
  const canonical = normalized.sort((a, b) => a.txid < b.txid ? -1 : a.txid > b.txid ? 1 : a.vout - b.vout).map((u) => `${u.txid}:${u.vout}:${u.value}`).join("|");
7181
- return (0, import_ethers6.keccak256)((0, import_ethers6.toUtf8Bytes)(canonical));
7268
+ return (0, import_ethers7.keccak256)((0, import_ethers7.toUtf8Bytes)(canonical));
7182
7269
  }
7183
7270
  async function buildBtcExecuteEnvelope(params) {
7184
7271
  const {
@@ -7212,26 +7299,26 @@ async function buildBtcExecuteEnvelope(params) {
7212
7299
  }
7213
7300
  const utxosHash = hashBtcInputSet(utxos);
7214
7301
  const nowSec = Date.now() / 1e3;
7215
- const currentQuantumStart = Math.floor(nowSec / QUANTUM_SECONDS) * QUANTUM_SECONDS;
7302
+ const currentQuantumStart = Math.floor(nowSec / QUANTUM_SECONDS2) * QUANTUM_SECONDS2;
7216
7303
  const secsIntoQuantum = nowSec - currentQuantumStart;
7217
7304
  let timestamp;
7218
- if (secsIntoQuantum > QUANTUM_SAFE_THRESHOLD) {
7219
- const nextQuantumStart = currentQuantumStart + QUANTUM_SECONDS;
7305
+ if (secsIntoQuantum > QUANTUM_SAFE_THRESHOLD2) {
7306
+ const nextQuantumStart = currentQuantumStart + QUANTUM_SECONDS2;
7220
7307
  const waitMs = Math.max(0, (nextQuantumStart - nowSec) * 1e3 + 500);
7221
7308
  await new Promise((r) => setTimeout(r, waitMs));
7222
7309
  timestamp = nextQuantumStart;
7223
7310
  } else {
7224
7311
  timestamp = currentQuantumStart;
7225
7312
  }
7226
- const actionHash = (0, import_ethers6.keccak256)(
7227
- (0, import_ethers6.toUtf8Bytes)("execute-btc-withdrawal")
7313
+ const actionHash = (0, import_ethers7.keccak256)(
7314
+ (0, import_ethers7.toUtf8Bytes)("execute-btc-withdrawal")
7228
7315
  );
7229
7316
  const utxoIdentifier = `${txid}:${vout}`;
7230
- const positionIdBytes32 = (0, import_ethers6.zeroPadValue)(
7317
+ const positionIdBytes32 = (0, import_ethers7.zeroPadValue)(
7231
7318
  positionId.startsWith("0x") ? positionId : `0x${positionId}`,
7232
7319
  32
7233
7320
  );
7234
- const messageHash = (0, import_ethers6.solidityPackedKeccak256)(
7321
+ const messageHash = (0, import_ethers7.solidityPackedKeccak256)(
7235
7322
  [
7236
7323
  "bytes32",
7237
7324
  // positionId
@@ -7264,7 +7351,7 @@ async function buildBtcExecuteEnvelope(params) {
7264
7351
  actionHash
7265
7352
  ]
7266
7353
  );
7267
- const userSignature = await signer.signMessage((0, import_ethers6.getBytes)(messageHash));
7354
+ const userSignature = await signer.signMessage((0, import_ethers7.getBytes)(messageHash));
7268
7355
  const borrowerAddress = await signer.getAddress();
7269
7356
  return {
7270
7357
  positionId,
@@ -7328,7 +7415,7 @@ function maybeTemperSignature(signature, shouldTemper, operationName) {
7328
7415
  }
7329
7416
 
7330
7417
  // src/utils/address-conversion.utils.ts
7331
- var import_ethers7 = require("ethers");
7418
+ var import_ethers8 = require("ethers");
7332
7419
 
7333
7420
  // src/utils/chunks/bitcoin-utils.ts
7334
7421
  var import_sha256 = require("@noble/hashes/sha256");
@@ -7612,7 +7699,7 @@ function normalizeBitcoinAddress(address) {
7612
7699
  }
7613
7700
 
7614
7701
  // src/protocol/protocol-pause.ts
7615
- var import_ethers8 = require("ethers");
7702
+ var import_ethers9 = require("ethers");
7616
7703
  var GET_PROTOCOL_PAUSE_STATUS_ABI = [
7617
7704
  "function getProtocolPauseStatus() view returns (tuple(bool positionManagerPaused, bool positionManagerLiquidationsPaused, bool positionManagerCorePaused, bool loanOperationsPaused, bool collateralManagerPaused, bool liquidationManagerPaused, bool circuitBreakerPaused, bool ucdControllerPaused, bool ucdTokenPaused, bool simplePsmPaused))"
7618
7705
  ];
@@ -7634,7 +7721,7 @@ function rowToStatus(row) {
7634
7721
  return row;
7635
7722
  }
7636
7723
  async function fetchProtocolPauseStatus(provider, positionManagerAddress) {
7637
- const iface = new import_ethers8.Interface(GET_PROTOCOL_PAUSE_STATUS_ABI);
7724
+ const iface = new import_ethers9.Interface(GET_PROTOCOL_PAUSE_STATUS_ABI);
7638
7725
  const data = iface.encodeFunctionData("getProtocolPauseStatus", []);
7639
7726
  const raw = await provider.call({ to: positionManagerAddress, data });
7640
7727
  const decoded = iface.decodeFunctionResult("getProtocolPauseStatus", raw);
@@ -7767,7 +7854,7 @@ function extractOptionalLitSignature(raw) {
7767
7854
  }
7768
7855
 
7769
7856
  // src/modules/contract/contract-manager.module.ts
7770
- var import_ethers9 = require("ethers");
7857
+ var import_ethers10 = require("ethers");
7771
7858
  init_deployment_addresses();
7772
7859
  var POSITION_MANAGER_ABI = [
7773
7860
  "function createPosition(bytes32 pkpId, bytes calldata validatorSignature, string mainnetVaultAddress, string regtestVaultAddress, uint256 selectedTermMonths, uint256 validatorVersion, bytes calldata pkpPublicKey) external returns (bytes32 positionId)",
@@ -7844,43 +7931,43 @@ var ContractManager = class {
7844
7931
  }
7845
7932
  const contractRunner = runner;
7846
7933
  const contracts = {
7847
- positionManager: new import_ethers9.Contract(
7934
+ positionManager: new import_ethers10.Contract(
7848
7935
  contractAddresses.positionManager,
7849
7936
  POSITION_MANAGER_ABI,
7850
7937
  contractRunner
7851
7938
  ),
7852
- loanOperationsManager: new import_ethers9.Contract(
7853
- contractAddresses.loanOperationsManager || import_ethers9.ZeroAddress,
7939
+ loanOperationsManager: new import_ethers10.Contract(
7940
+ contractAddresses.loanOperationsManager || import_ethers10.ZeroAddress,
7854
7941
  LOAN_OPS_ABI,
7855
7942
  contractRunner
7856
7943
  ),
7857
- ucdController: new import_ethers9.Contract(
7944
+ ucdController: new import_ethers10.Contract(
7858
7945
  contractAddresses.ucdToken,
7859
7946
  UCD_CONTROLLER_ABI,
7860
7947
  contractRunner
7861
7948
  ),
7862
- priceFeed: new import_ethers9.Contract(
7863
- contractAddresses.priceFeedConsumer || import_ethers9.ZeroAddress,
7949
+ priceFeed: new import_ethers10.Contract(
7950
+ contractAddresses.priceFeedConsumer || import_ethers10.ZeroAddress,
7864
7951
  PRICE_FEED_ABI,
7865
7952
  contractRunner
7866
7953
  ),
7867
- termManager: new import_ethers9.Contract(
7868
- contractAddresses.termManager || import_ethers9.ZeroAddress,
7954
+ termManager: new import_ethers10.Contract(
7955
+ contractAddresses.termManager || import_ethers10.ZeroAddress,
7869
7956
  TERM_MANAGER_ABI,
7870
7957
  contractRunner
7871
7958
  ),
7872
- circuitBreaker: new import_ethers9.Contract(
7873
- contractAddresses.circuitBreaker || import_ethers9.ZeroAddress,
7959
+ circuitBreaker: new import_ethers10.Contract(
7960
+ contractAddresses.circuitBreaker || import_ethers10.ZeroAddress,
7874
7961
  CIRCUIT_BREAKER_ABI,
7875
7962
  contractRunner
7876
7963
  ),
7877
- liquidationManager: new import_ethers9.Contract(
7878
- contractAddresses.liquidationManager || import_ethers9.ZeroAddress,
7964
+ liquidationManager: new import_ethers10.Contract(
7965
+ contractAddresses.liquidationManager || import_ethers10.ZeroAddress,
7879
7966
  LIQUIDATION_MANAGER_ABI,
7880
7967
  contractRunner
7881
7968
  ),
7882
- bitcoinWithdrawalAddressRegistry: new import_ethers9.Contract(
7883
- contractAddresses.bitcoinWithdrawalAddressRegistry || import_ethers9.ZeroAddress,
7969
+ bitcoinWithdrawalAddressRegistry: new import_ethers10.Contract(
7970
+ contractAddresses.bitcoinWithdrawalAddressRegistry || import_ethers10.ZeroAddress,
7884
7971
  BITCOIN_WITHDRAWAL_ADDRESS_REGISTRY_ABI,
7885
7972
  contractRunner
7886
7973
  )
@@ -7930,13 +8017,13 @@ var ContractManager = class {
7930
8017
  const address = addresses[key];
7931
8018
  if (!address) {
7932
8019
  missing.push(String(key));
7933
- } else if (!(0, import_ethers9.isAddress)(address)) {
8020
+ } else if (!(0, import_ethers10.isAddress)(address)) {
7934
8021
  invalid.push(String(key));
7935
8022
  }
7936
8023
  }
7937
8024
  for (const key of optionalAddresses) {
7938
8025
  const address = addresses[key];
7939
- if (address && !(0, import_ethers9.isAddress)(address)) {
8026
+ if (address && !(0, import_ethers10.isAddress)(address)) {
7940
8027
  invalid.push(String(key));
7941
8028
  }
7942
8029
  }
@@ -8912,7 +8999,7 @@ function createPKPManager(config) {
8912
8999
  }
8913
9000
 
8914
9001
  // src/modules/loan/loan-creator.module.ts
8915
- var import_ethers10 = require("ethers");
9002
+ var import_ethers11 = require("ethers");
8916
9003
  var import_dh_lit_actions = __toESM(require_pkg_src());
8917
9004
  var LoanCreator = class {
8918
9005
  config;
@@ -9242,11 +9329,11 @@ var LoanCreator = class {
9242
9329
  try {
9243
9330
  const mainnetVaultAddress = bitcoinAddresses.mainnet;
9244
9331
  const regtestVaultAddress = bitcoinAddresses.regtest;
9245
- const pkpIdBytes32 = (0, import_ethers10.zeroPadValue)(
9246
- (0, import_ethers10.toBeHex)(BigInt(pkpData.tokenId)),
9332
+ const pkpIdBytes32 = (0, import_ethers11.zeroPadValue)(
9333
+ (0, import_ethers11.toBeHex)(BigInt(pkpData.tokenId)),
9247
9334
  32
9248
9335
  );
9249
- const pkpPublicKeyUncompressed = import_ethers10.SigningKey.computePublicKey(
9336
+ const pkpPublicKeyUncompressed = import_ethers11.SigningKey.computePublicKey(
9250
9337
  pkpData.publicKey,
9251
9338
  false
9252
9339
  );
@@ -9259,7 +9346,7 @@ var LoanCreator = class {
9259
9346
  );
9260
9347
  log.debug(`BigInt conversion: ${BigInt(pkpData.tokenId).toString()}`);
9261
9348
  log.debug(
9262
- `Hex from BigInt: ${(0, import_ethers10.toBeHex)(BigInt(pkpData.tokenId))}`
9349
+ `Hex from BigInt: ${(0, import_ethers11.toBeHex)(BigInt(pkpData.tokenId))}`
9263
9350
  );
9264
9351
  log.debug(`Final bytes32 (zero-padded): ${pkpIdBytes32}`);
9265
9352
  log.debug(
@@ -9423,8 +9510,8 @@ var LoanCreator = class {
9423
9510
  }
9424
9511
  }
9425
9512
  if (this.config.debug) {
9426
- const pkpIdBytes32Check = (0, import_ethers10.zeroPadValue)(
9427
- (0, import_ethers10.toBeHex)(BigInt(pkpData.tokenId)),
9513
+ const pkpIdBytes32Check = (0, import_ethers11.zeroPadValue)(
9514
+ (0, import_ethers11.toBeHex)(BigInt(pkpData.tokenId)),
9428
9515
  32
9429
9516
  );
9430
9517
  log.error("\u274C Loan creation transaction failed", {
@@ -9470,8 +9557,8 @@ var LoanCreator = class {
9470
9557
  const newEventAbi = [
9471
9558
  "event PositionCreated(bytes32 indexed positionId, bytes32 indexed pkpId, address indexed borrower, uint256 requestedCollateralRatio, uint256 selectedTerm, uint256 expiryAt)"
9472
9559
  ];
9473
- const oldIface = new import_ethers10.Interface(oldEventAbi);
9474
- const newIface = new import_ethers10.Interface(newEventAbi);
9560
+ const oldIface = new import_ethers11.Interface(oldEventAbi);
9561
+ const newIface = new import_ethers11.Interface(newEventAbi);
9475
9562
  let positionId;
9476
9563
  if (this.config.debug) {
9477
9564
  log.info("\u{1F50D} Parsing transaction receipt logs", {
@@ -9565,7 +9652,7 @@ var LoanStatus = /* @__PURE__ */ ((LoanStatus2) => {
9565
9652
  })(LoanStatus || {});
9566
9653
 
9567
9654
  // src/modules/loan/loan-query.module.ts
9568
- var import_ethers11 = require("ethers");
9655
+ var import_ethers12 = require("ethers");
9569
9656
  var POSITION_CORE_ABI = [
9570
9657
  "function getPositionDetails(bytes32) view returns (tuple(bytes32 positionId, bytes32 pkpId, uint256 ucdDebt, string vaultAddress, address borrower, uint40 createdAt, uint40 lastUpdated, uint16 selectedTerm, uint40 expiryAt, uint8 status, uint40 previousExpiryAt, uint16 totalTerm))"
9571
9658
  ];
@@ -9863,7 +9950,7 @@ var LoanQuery = class {
9863
9950
  const isChipotlePkpId2 = typeof rawId === "string" && rawId.length === 40 && !rawId.toLowerCase().startsWith("04");
9864
9951
  if (isChipotlePkpId2) {
9865
9952
  if (this.config.positionManagerCoreAddress && this.config.provider) {
9866
- const pmContract = new import_ethers11.Contract(
9953
+ const pmContract = new import_ethers12.Contract(
9867
9954
  this.config.positionManagerCoreAddress,
9868
9955
  POSITION_CORE_ABI,
9869
9956
  this.config.provider
@@ -10186,7 +10273,7 @@ function createLoanQuery(config) {
10186
10273
  }
10187
10274
 
10188
10275
  // src/modules/withdrawal-address/withdrawal-address.module.ts
10189
- var import_ethers12 = require("ethers");
10276
+ var import_ethers13 = require("ethers");
10190
10277
  var WithdrawalAddressModule = class {
10191
10278
  config;
10192
10279
  graphClient;
@@ -10203,7 +10290,7 @@ var WithdrawalAddressModule = class {
10203
10290
  if (!res.success)
10204
10291
  return res;
10205
10292
  const target = res.value.target;
10206
- if (!target || target === import_ethers12.ZeroAddress) {
10293
+ if (!target || target === import_ethers13.ZeroAddress) {
10207
10294
  return failure(
10208
10295
  new SDKError({
10209
10296
  code: "SDK_WITHDRAWAL_REGISTRY_NOT_CONFIGURED",
@@ -10221,7 +10308,7 @@ var WithdrawalAddressModule = class {
10221
10308
  }
10222
10309
  /** keccak256 of the canonicalized address — matches the on-chain key. */
10223
10310
  static addressHash(btcAddress) {
10224
- return (0, import_ethers12.keccak256)((0, import_ethers12.toUtf8Bytes)(normalizeBitcoinAddress(btcAddress)));
10311
+ return (0, import_ethers13.keccak256)((0, import_ethers13.toUtf8Bytes)(normalizeBitcoinAddress(btcAddress)));
10225
10312
  }
10226
10313
  /**
10227
10314
  * Add a Bitcoin address to the caller's allowlist. It becomes usable only
@@ -13267,7 +13354,7 @@ var DiamondHandsGraph = class {
13267
13354
  };
13268
13355
 
13269
13356
  // src/contracts/typechain-contracts/factories/src/psm/SimplePSMV2__factory.ts
13270
- var import_ethers13 = require("ethers");
13357
+ var import_ethers14 = require("ethers");
13271
13358
  var _abi = [
13272
13359
  {
13273
13360
  inputs: [],
@@ -15835,7 +15922,7 @@ var _abi = [
15835
15922
  ];
15836
15923
  var _bytecode = "0x60a080604052346100ea57306080527ff0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a005460ff8160401c166100d9576002600160401b03196001600160401b03821601610073575b60405161485a90816100f0823960805181818161278e01526128870152f35b6001600160401b0319166001600160401b039081177ff0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a005581527fc7f505b2f371ae2175ee4913f4499e1f2633a7b5936321eed1cdaeb6115181d290602090a13880610054565b63f92ee8a960e01b60005260046000fd5b600080fdfe6080604052600436101561001257600080fd5b6000803560e01c8062f7fce91461384657806301ffc9a7146137d5578063021d28931461377c5780630871b20614613743578063114249d214610f6157806311d954f81461371a57806313da3166146136e15780631d44a904146136385780631f77bf65146135ff578063248a9ca3146135e05780632b83cccd146131205780632f2ff15d146130ee57806334bac370146130b557806334e181251461307c57806336568abe14613037578063373c86b614612ffe5780633f4ba83a14612f375780634373b57214612f0e5780634451e89b14612b3a5780634ebd25a514612b015780634f1ef2861461280c5780635273b6f6146127e357806352d1902d1461277b578063568fafca146126ed57806359d5d02a146124205780635bc26aea146123eb5780635c975abb146123bb5780635ecc27081461229d5780638456cb59146121a257806385c15d9a1461216957806389d3ad00146120a25780638bff608e146120695780639010d07c1461201657806390ad8b4014611ffa57806391d1485414611fa15780639b759bf714611f5e5780639baf58d214611f415780639f1d0f59146118a8578063a217fddf1461188c578063a3246ad3146117cf578063ad3cb1cc14611788578063b492fc691461168e578063b9f637af14611463578063bf7d911914611424578063c4c5f62414611371578063c55f15ea1461134e578063ca15c87314611317578063ca2ce65d146112de578063cc1f8ffa146112ac578063cf46075e146111a2578063d21a74ff14611165578063d2f8253614611142578063d547741f14611107578063d5d3f78b14610f9a578063d66bd52414610f61578063e1f1c4a714610f44578063e1f3962c14610f18578063ec2f96fe14610ef4578063eda5a26a14610af7578063f1a1eb8414610ab4578063f385116d14610a7b578063f77c479114610a54578063f8c8765e14610661578063faaebd2114610628578063facdfb5e14610488578063fc99bd9a14610377578063fe32e7281461033e5763ffa1ad741461030857600080fd5b3461033b578060031936011261033b57610337610323613a68565b604051918291602083526020830190613a17565b0390f35b80fd5b503461033b57602036600319011261033b576020906040906001600160a01b0361036661392e565b168152601283522054604051908152f35b503461033b57604036600319011261033b5761039161392e565b6010546024359291906001600160a01b03163303610479576001600160a01b03168082526002602052604082205490929060ff16156104665780156104575782825260076020526040822054926103e88285613cb0565b848110610448576001600160ff1b0381116104395760008051602061482e833981519152604085968493846104369852600760205280838a205582519182526020820152a23090339061421c565b80f35b630700fcb360e11b8452600484fd5b63446c8cc960e01b8452600484fd5b63162908e360e11b8252600482fd5b506024916374ed46ad60e01b8252600452fd5b6349db3bd360e01b8252600482fd5b503461033b57602036600319011261033b576104a261392e565b6104aa613f12565b6010546001600160a01b03163303610479576001600160a01b03168082526002602052604082205460ff161561061657808252600760205260408220546040516370a0823160e01b8152306004820152602081602481865afa90811561060b5784916105d4575b50818111156105c5576105248282613b6c565b8215908115610570575b505060008051602061482e833981519152916040918486526007602052808387205582519182526020820152a260016000805160206147ce8339815191525580f35b61271081029080820461271014901517156105b157606484029184830460641417156105b157116105a257388061052e565b63a73af74d60e01b8452600484fd5b634e487b7160e01b86526011600452602486fd5b6105cf8183613b6c565b610524565b90506020813d602011610603575b816105ef602093836139c3565b810103126105fe575138610511565b600080fd5b3d91506105e2565b6040513d86823e3d90fd5b6374ed46ad60e01b8252600452602490fd5b503461033b57602036600319011261033b576020906040906001600160a01b0361065061392e565b168152600483522054604051908152f35b503461033b57608036600319011261033b5761067b61392e565b610683613944565b6044356001600160a01b03811690818103610a50576064356001600160a01b0381169390849003610a4c5760008051602061480e83398151915254604081901c60ff161595906001600160401b031680159081610a44575b6001149081610a3a575b159081610a31575b50610a225760008051602061480e83398151915280546001600160401b0319166001179055856109fd575b6001600160a01b03169081156109ee576001600160a01b03169081156109df5783156109d05761074661448a565b61074e61448a565b61075661448a565b61075e61448a565b60016000805160206147ce8339815191525561077861448a565b61078061448a565b86546001600160a01b0319908116919091178755600180549182168317905560405163313ce56760e01b8152909190602081600481855afa88918161099f575b506107d457633a24e95b60e11b8852600488fd5b6001600160a81b03199092161760a091821b60ff60a01b16176001819055901c60ff16601119810161098d575061080b8186614348565b80610965575b156109205761082e816000805160206147ee833981519152614348565b8061092f575b15610920576108519060008051602061470e833981519152614348565b90816108e9575b50156108da57806108af575b5061086c5780f35b60ff60401b1960008051602061480e833981519152541660008051602061480e833981519152556000805160206146ee833981519152602060405160018152a180f35b601080546001600160a01b031916821790558260008051602061474e8339815191528180a338610864565b63cf5a8e3360e01b8352600483fd5b6109199060008051602061470e83398151915286526000805160206146ae833981519152602052604086206144d0565b5038610858565b63cf5a8e3360e01b8552600485fd5b6000805160206147ee83398151915286526000805160206146ae83398151915260205261095f83604088206144d0565b50610834565b8580526000805160206146ae83398151915260205261098783604088206144d0565b50610811565b63167738cf60e21b8652600452602485fd5b6109c291925060203d6020116109c9575b6109ba81836139c3565b810190613ba9565b90386107c0565b503d6109b0565b630b5eba9f60e41b8752600487fd5b63c1ab6dc160e01b8752600487fd5b6336abb4df60e11b8752600487fd5b60008051602061480e833981519152805460ff60401b1916600160401b179055610718565b63f92ee8a960e01b8752600487fd5b905015386106ed565b303b1591506106e5565b8791506106db565b8580fd5b8480fd5b503461033b578060031936011261033b57546040516001600160a01b039091168152602090f35b503461033b57602036600319011261033b576020906040906001600160a01b03610aa361392e565b168152600a83522054604051908152f35b503461033b57604036600319011261033b576020906040906001600160a01b03610adc61392e565b16815260158352818120602435825283522054604051908152f35b503461033b5761016036600319011261033b57610b1261392e565b90606435604435602435610b24613a58565b9160a4359160c43560e43561010435916101243595610144359760018060a01b03601054163303610ee5576001600160a01b038c16808c52600260205260408c2054909a9060ff16610ed1578a15610ec2578615610eb3576127108811610e99576103e88111610e815760ff82169c60128e118e8115610e76575b50610e6257803b15610e4e578915610e3a578a15610e265782610bc191614260565b84151580610e1d575b610e065785151580610dfd575b610de6578b9c602460208d9e9d604051928380926370a0823160e01b82523060048301525afa9c8d15610dda579c610da6575b506001600160ff1b038c11610d97578a8d8f9760408f97838f918f8f8f8f90859f988f99879f9660008051602061476e8339815191529f978b9f988f8d6000805160206146ce8339815191529f988e8e610d4f9b60008051602061468e8339815191529f8f8f8487526002602052878720600160ff198254161790558487526003602052878720558386526004602052868620558285526006602052878686205582855260056020528585209060ff19825416179055818452600c6020528885852055818452600d6020528985852055818452600e6020528a85852055818452600f6020528b8585205581845260076020528484205582526012602052828220558d8152601360205220558a7f991d1ef1b5c0820d213328cba6682059e00a50e49c469a454eb3557e78eaf6668e80518b81528c6020820152a28c5198899889613cbd565b0390a28151908b82526020820152a28151908782526020820152a280610d73578280f35b604060008051602061482e833981519152918151908582526020820152a281808280f35b63556e7a8160e01b8e5260048efd5b909b506020813d602011610dd2575b81610dc2602093836139c3565b810103126105fe57519a38610c0a565b3d9150610db5565b604051903d90823e3d90fd5b60448c858863dd85772b60e01b8352600452602452fd5b50838610610bd7565b60448c8487637449915760e01b8352600452602452fd5b50828510610bca565b636835314760e11b8d52600160045260248dfd5b636835314760e11b8d5260048d905260248dfd5b63377e3f9960e21b8d5260048c905260248dfd5b63ca95039160e01b8d5260048e905260248dfd5b60069150108e610b9f565b631051834f60e11b8c526004526103e860245260448bfd5b63c1e9a14160e01b8c52600488905261271060245260448cfd5b63a2ec3a5560e01b8c5260048cfd5b63df407ac560e01b8c5260048cfd5b6317f4215b60e21b8c5260048b905260248cfd5b6349db3bd360e01b8b5260048bfd5b503461033b578060031936011261033b57602060ff60015460a01c16604051908152f35b503461033b57602036600319011261033b576020610f3c610f3761392e565b613df5565b604051908152f35b503461033b578060031936011261033b5760206040516127108152f35b503461033b57602036600319011261033b576020906040906001600160a01b03610f8961392e565b168152600783522054604051908152f35b503461033b57602036600319011261033b57610fb461392e565b6010546001600160a01b03163303610479576001600160a01b03168082526002602052604082205460ff16156106165780825260076020526040822054806110f1575080825260026020526040822060ff1981541690558082526003602052816040812055808252600460205281604081205580825260056020526040822060ff198154169055808252600c602052816040812055808252600d602052816040812055808252600e602052816040812055808252600f602052816040812055808252600660205281604081205580825260076020526040822054818352600760205282604081205560405190827f3302a1b37f04242bb55603f5449e7ecd690a35eef08ba1353c48c20e2aae9cda8580a2806110ce578380f35b8160409160008051602061482e8339815191529352846020820152a23880808380f35b604492916376bc059760e11b8352600452602452fd5b503461033b57604036600319011261033b5761113e600435611127613944565b9061113961113482613b79565b614088565b61411a565b5080f35b503461033b578060031936011261033b57602060ff600854166040519015158152f35b503461033b57602036600319011261033b5760209060ff906040906001600160a01b0361119061392e565b16815260058452205416604051908152f35b503461033b57602036600319011261033b576111bc61392e565b6111c4613f12565b6010546001600160a01b03163303610479576001600160a01b03168082526002602052604082205460ff161561061657808252600760205260408220546040516370a0823160e01b8152306004820152602081602481865afa90811561060b57849161126c575b5060008051602061482e833981519152916040918486526007602052808387205582519182526020820152a260016000805160206147ce8339815191525580f35b90506020813d6020116112a4575b81611287602093836139c3565b810103126105fe575160008051602061482e83398151915261122b565b3d915061127a565b503461033b57604036600319011261033b5760206112d46112cb61392e565b60243590613cf6565b6040519015158152f35b503461033b57602036600319011261033b576020906040906001600160a01b0361130661392e565b168152601383522054604051908152f35b503461033b57602036600319011261033b57604060209160043581526000805160206146ae83398151915283522054604051908152f35b503461033b578060031936011261033b576020604051670de0b6b3a76400008152f35b503461033b57604036600319011261033b5761138b61392e565b6010546024359291906001600160a01b03163303610479576001600160a01b031680825260076020526040822054929081841061140d578060008051602061482e8339815191526040866113e3866104369899613b6c565b84895260076020528289205583885260076020528188205482519182526020820152a2339061404c565b5091604492633cb8e07360e01b8352600452602452fd5b503461033b57602036600319011261033b5760209060ff906040906001600160a01b0361144f61392e565b168152600284522054166040519015158152f35b503461033b5761012036600319011261033b5761147e61392e565b6064359190604435602435611491613a58565b601054610104359660e4359260c4359260a43592906001600160a01b0316330361167f576001600160a01b038816808a52600260205260408a205490989060ff161561166b57861561165c576127108811611642576103e882116116285760ff83169060128211801561161e575b61160a578361150d91614260565b85151580611601575b6115ea578a1515806115e1575b6115ca579260008051602061468e83398151915297969592828c956115c4979460408e8e80825260036020528c8383205580825260046020528d838320558152600660205220558b8d52600560205260408d209060ff198254161790558a8c52600c6020528260408d20558a8c52600d6020528360408d20558a8c52600e6020528460408d20558a8c52600f6020528560408d205560405198899889613cbd565b0390a280f35b60448a868d63dd85772b60e01b8352600452602452fd5b50848b10611523565b60448a8588637449915760e01b8352600452602452fd5b50838610611516565b63ca95039160e01b8b52600482905260248bfd5b50600682106114ff565b631051834f60e11b8a5260048290526103e860245260448afd5b63c1e9a14160e01b8a52600488905261271060245260448afd5b63a2ec3a5560e01b8a5260048afd5b6374ed46ad60e01b8a52600489905260248afd5b6349db3bd360e01b8952600489fd5b503461033b57604036600319011261033b576116a861392e565b6001600160a01b0316808252600260205260408220546024359060ff16156117745780156117655761271061172a604085670de0b6b3a76400006117196117329688859a52600560205260ff85852054169080916012811061173f575b505088845260036020528484205490613a8b565b049581526004602052205484613a8b565b048092613b6c565b9082519182526020820152f35b61175e925060ff61175261175892613ad4565b16613ae5565b90613a8b565b3880611705565b63162908e360e11b8352600483fd5b6374ed46ad60e01b83526004829052602483fd5b503461033b578060031936011261033b5761033760408051906117ab81836139c3565b60058252640352e302e360dc1b602083015251918291602083526020830190613a17565b503461033b57602036600319011261033b5760043581526000805160206146ae83398151915260205260408120604051908160208254918281520190819285526020852090855b818110611876575050508261182c9103836139c3565b604051928392602084019060208552518091526040840192915b818110611854575050500390f35b82516001600160a01b0316845285945060209384019390920191600101611846565b8254845260209093019260019283019201611816565b503461033b578060031936011261033b57602090604051908152f35b503461033b576118b736613969565b9190926118c2613f12565b6118ca613f4e565b338152600960205260408120544303611f1f57338152600a602052600360408220541015611f1057338152600a602052604081206119088154613b9a565b90555b6001600160a01b0382168082526002602052604082205490929060ff16611e6f575b828252600260205260ff60408320541615610466578415610457578315611e6057828252600c60205260408220548510611e3b57828252600e60205260408220548015611e2c57808611611e155750846119869161415e565b6040516370a0823160e01b8152306004820152602081602481865afa908115611e0a578291611dd8575b506119bd8530338661421c565b6040516370a0823160e01b8152306004820152602081602481875afa908115611cef57908692918491611d9f575b50906119f691613b6c565b10611d905781815260076020526040812054611a128582613cb0565b818110611d81576001600160ff1b038111611d72576040849260008051602061482e833981519152928486526007602052808387205582519182526020820152a2818152600560205260ff604082205416849060128110611d11575b50611a8f670de0b6b3a7640000918484526003602052604084205490613a8b565b04908281526004602052612710611aaa604083205484613a8b565b0491611ab68382613b6c565b94808610611cfa57506001546040516318160ddd60e01b815290602090829060049082906001600160a01b03165afa908115611cef578391611cbd575b5082546001600160a01b0316803b15611ca45783809160846040518094819363ae494fa160e01b83523360048401528c60248401528b60448401528d60648401525af1801561060b57908491611ca8575b505083611c34575b6001546040516318160ddd60e01b81529190602090839060049082906001600160a01b03165afa801561060b578490611c00575b611b8a9250613b6c565b90808203611bea575050507fb3e2773606abfd36b5bd91394b3a54d1398336c65005baf7bf7a05efeffaf75b611bcd602095604051918291339588429285613bdd565b0390a360016000805160206147ce83398151915255604051908152f35b632d8562a360e11b835260045260245260449150fd5b506020823d602011611c2c575b81611c1a602093836139c3565b810103126105fe57611b8a9151611b80565b3d9150611c0d565b82546001600160a01b0316803b15611ca45783809160846040518094819363ae494fa160e01b83523060048401528a60248401528b60448401528160648401525af1801561060b57908491611c8b575b5050611b4c565b81611c95916139c3565b611ca0578238611c84565b8280fd5b8380fd5b81611cb2916139c3565b611ca0578238611b44565b90506020813d602011611ce7575b81611cd8602093836139c3565b810103126105fe575138611af3565b3d9150611ccb565b6040513d85823e3d90fd5b6371c4efed60e01b83526004869052602452604482fd5b611d21915061175260ff91613ad4565b8015611d5e5780600019048511611d4f57611a8f611d48670de0b6b3a76400009287613a8b565b9150611a6e565b63035fc53d60e41b8252600482fd5b634e487b7160e01b82526012600452602482fd5b630700fcb360e11b8352600483fd5b63446c8cc960e01b8352600483fd5b639bfa3c1760e01b8152600490fd5b919250506020813d602011611dd0575b81611dbc602093836139c3565b810103126105fe57518591906119f66119eb565b3d9150611daf565b90506020813d602011611e02575b81611df3602093836139c3565b810103126105fe5751386119b0565b3d9150611de6565b6040513d84823e3d90fd5b631d7f2ac360e01b83526004869052602452604482fd5b633b5db2f360e11b8352600483fd5b50908152600c6020526040812054630d54e9e160e01b82526004849052602452604490fd5b632cd84af360e01b8252600482fd5b60405163313ce56760e01b815291939291602081600481865afa859181611eef575b50611ea55763105482c760e21b8552600485fd5b93919293838352600560205260ff806040852054169116908103611ec9575061192d565b90506044928252600560205260ff604083205416631e43476360e11b8352600452602452fd5b611f0991925060203d6020116109c9576109ba81836139c3565b9038611e91565b63a74c1c5f60e01b8152600490fd5b3381526009602052436040822055338152600a6020526001604082205561190b565b503461033b578060031936011261033b5760206040516103e88152f35b503461033b57604036600319011261033b576020906040906001600160a01b03611f8661392e565b16815260148352818120602435825283522054604051908152f35b503461033b57604036600319011261033b576040611fbd613944565b91600435815260008051602061478e833981519152602052209060018060a01b0316600052602052602060ff604060002054166040519015158152f35b503461033b578060031936011261033b57602060405160648152f35b503461033b57604036600319011261033b5761205060209160043581526000805160206146ae8339815191528352604060243591206144b8565b905460405160039290921b1c6001600160a01b03168152f35b503461033b57602036600319011261033b576020906040906001600160a01b0361209161392e565b168152600983522054604051908152f35b503461033b57604036600319011261033b576120bc61392e565b60105460243591906001600160a01b0316330361215a576001600160a01b031690811561214b57604060008051602061476e8339815191529183855260136020528185205490848652601360205280838720558486526015602052828620438752602052828620548587526019602052838720558486526017602052438387205582519182526020820152a280f35b63df407ac560e01b8352600483fd5b6349db3bd360e01b8352600483fd5b503461033b57602036600319011261033b576020906040906001600160a01b0361219161392e565b168152600383522054604051908152f35b503461033b578060031936011261033b5760008051602061470e833981519152815260008051602061478e83398151915260209081526040808320336000908152925290205460ff1615612278576121f8613f4e565b600160ff196000805160206147ae8339815191525416176000805160206147ae833981519152557f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a2586020604051338152a16040514281527f80170b5fcdd2bf1e0660ef4b8851f86685f64d41b1a19de1471947ece8725aac60203392a280f35b63e2517d3f60e01b81523360045260008051602061470e833981519152602452604490fd5b503461033b57602036600319011261033b576122b761392e565b60008051602061480e8339815191525460ff8160401c169081156123a3575b506123945760008051602061480e83398151915280546001600160481b0319166003600160401b0117905581805260008051602061478e83398151915260209081526040808420336000908152925290205460ff161561237c5761233990613c5e565b60ff60401b1960008051602061480e833981519152541660008051602061480e833981519152556000805160206146ee833981519152602060405160038152a180f35b63e2517d3f60e01b8252336004526024829052604482fd5b63f92ee8a960e01b8252600482fd5b60036001600160401b039190911610159050386122d6565b503461033b578060031936011261033b57602060ff6000805160206147ae83398151915254166040519015158152f35b503461033b57602036600319011261033b5761240561392e565b6010546001600160a01b031633036104795761043690613c5e565b503461033b57606036600319011261033b5761243a61392e565b612442613944565b60105490926044359290916001600160a01b0316330361047957612464613f4e565b6011546001600160a01b03169182156126de5760405163babcc53960e01b81526001600160a01b0386166004820181905293602090829060249082905afa908115611e0a57829161269f575b5015612690578215612681576001546001600160a01b03928316921682036125d1576040516370a0823160e01b8152306004820152602081602481865afa908115611e0a57829161259f575b50935b841561259057600019810361258a5750835b841561257b5780851161256357505061252d836020958361404c565b7f0bf519e4b3821615dbdd874fa1a5fbb4bb651b4e6beabedd4ac318e770233b2c604080518581524287820152a3604051908152f35b630555ed4f60e31b8252600485905260245260449150fd5b632e11316f60e11b8252600482fd5b93612511565b63f09872eb60e01b8252600482fd5b90506020813d6020116125c9575b816125ba602093836139c3565b810103126105fe5751386124fc565b3d91506125ad565b8181526002602052604081205460ff161561266f576040516370a0823160e01b8152306004820152602081602481865afa908115611e0a57829161263d575b5082825260076020526040822054808211156126355761262f91613b6c565b936124ff565b50508061262f565b90506020813d602011612667575b81612658602093836139c3565b810103126105fe575138612610565b3d915061264b565b60249163eef7849760e01b8252600452fd5b634e46966960e11b8152600490fd5b63133307bb60e21b8152600490fd5b90506020813d6020116126d6575b816126ba602093836139c3565b810103126126d2575180151581036126d257386124b0565b5080fd5b3d91506126ad565b630e048e7160e41b8152600490fd5b503461033b57602036600319011261033b5761270761392e565b6010546001600160a01b03163303610479576001600160a01b0316801561276c57601180546001600160a01b0319811683179091556001600160a01b03167f1e9c406f2707909cfd9f61e744f73bcab77e5997d063276f67883c5257d51cf08380a380f35b634e46966960e11b8252600482fd5b503461033b578060031936011261033b577f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031630036127d457602060405160008051602061472e8339815191528152f35b63703e46dd60e11b8152600490fd5b503461033b578060031936011261033b576010546040516001600160a01b039091168152602090f35b50604036600319011261033b5761282161392e565b602435906001600160401b038211611ca05736602383011215611ca0578160040135908361284e836139fc565b9361285c60405195866139c3565b83855260208501933660248284010111611ca057806024602093018637850101526001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016308114908115612ade575b50612acf576010546001600160a01b03163303612ac0576001600160a01b038116928315612ab157813b15612aa25760008051602061472e83398151915254846128fa613a68565b7f6ea8b34d59b2818d3f37a08dddaa06f5886b9c20c907b36f03ca6528e106e86f61293060405192604084526040840190613a17565b4260208401526001600160a01b038516929081900390a36040516352d1902d60e01b8152602081600481895afa879181612a6a575b5061297e57634c9c8ce360e01b87526004869052602487fd5b908160008051602061472e83398151915288979303612a585750833b15612a44576001600160a01b031916811760008051602061472e833981519152558491907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b8380a2805115612a295761113e9382915190845af43d15612a21573d91612a05836139fc565b92612a1360405194856139c3565b83523d85602085013e61460c565b60609161460c565b5050505034612a355780f35b63b398979f60e01b8152600490fd5b634c9c8ce360e01b86526004829052602486fd5b632a87526960e21b8752600452602486fd5b9091506020813d602011612a9a575b81612a86602093836139c3565b81010312612a9657519038612965565b8780fd5b3d9150612a79565b636f7c43f160e01b8552600485fd5b63e6c4247b60e01b8552600485fd5b6349db3bd360e01b8452600484fd5b63703e46dd60e11b8452600484fd5b60008051602061472e833981519152546001600160a01b031614159050386128b2565b503461033b57602036600319011261033b576020906040906001600160a01b03612b2961392e565b168152600e83522054604051908152f35b503461033b57606036600319011261033b57612b5461395a565b6024356001600160401b038111611ca057612b73903690600401613993565b916044356001600160401b038111610a5057612b93903690600401613993565b60008051602061480e8339815191529291925460ff8160401c16908115612ef6575b50612ee75760008051602061480e83398151915280546001600160481b0319166002600160401b011790556000805160206147ee833981519152865260008051602061478e83398151915260209081526040808820336000908152925290205460ff1615612ec257612c2561448a565b612c2d61448a565b60016000805160206147ce83398151915255600b549160ff8316612eb357818603612ea457612c5b86613bf9565b92612c6960405194856139c3565b868452601f19612c7888613bf9565b01366020860137875b878110612daf575060019060ff191617600b5515159460ff196008541660ff871617600855865b818110612d0c578760008051602061466e833981519152602089604051908152a160ff60401b1960008051602061480e833981519152541660008051602061480e833981519152556000805160206146ee833981519152602060405160028152a180f35b808860008051602061482e8339815191526040612d34612d2f600196888d613c10565b613c36565b612d3f85898c613c10565b357f8f955fa878b4aae8b1ac37b1ab715307470f2822ceff87e23d33ef1e044814a783612d6c888d613c4a565b5193898060a01b0316968793848252600660205280838320558482526007602052858383205582519182526020820152a28151908d82526020820152a201612ca8565b612dbd612d2f828a8a613c10565b612dc8828689613c10565b6001600160a01b03909116808b52600260205260408b20549091359060ff1615612e90576103e88111612e785750906020602492604051938480926370a0823160e01b82523060048301525afa8015612e6d578a90612e37575b60019250612e308288613c4a565b5201612c81565b509060203d8111612e66575b612e4d81836139c3565b6020826000928101031261033b57509060019151612e22565b503d612e43565b6040513d8c823e3d90fd5b631051834f60e11b8b526004526103e860245260448afd5b6351104c5960e01b8b52600482905260248bfd5b63512509d360e11b8752600487fd5b6324d0d1fd60e01b8752600487fd5b63e2517d3f60e01b8652336004526000805160206147ee833981519152602452604486fd5b63f92ee8a960e01b8652600486fd5b60026001600160401b03919091161015905038612bb5565b503461033b578060031936011261033b576011546040516001600160a01b039091168152602090f35b503461033b578060031936011261033b576010546001600160a01b03163303612fef576000805160206147ae8339815191525460ff811615612fe05760ff19166000805160206147ae833981519152557f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa6020604051338152a16040514281527f107553d8191d85b405879cf752997865edd48d94e20bda4dd27223c94b31a7cc60203392a280f35b638dfc202b60e01b8252600482fd5b6349db3bd360e01b8152600490fd5b503461033b57602036600319011261033b576020906040906001600160a01b0361302661392e565b168152601683522054604051908152f35b503461033b57604036600319011261033b57613051613944565b336001600160a01b0382160361306d5761113e9060043561411a565b63334bd91960e11b8252600482fd5b503461033b57602036600319011261033b576020906040906001600160a01b036130a461392e565b168152600c83522054604051908152f35b503461033b57602036600319011261033b576020906040906001600160a01b036130dd61392e565b168152601783522054604051908152f35b503461033b57604036600319011261033b5761113e60043561310e613944565b9061311b61113482613b79565b6140d2565b503461033b5761312f36613969565b91909261313a613f12565b613142613f4e565b3381526009602052604081205443036135be57338152600a602052600360408220541015611f1057338152600a602052604081206131808154613b9a565b90555b6001600160a01b0382168082526002602052604082205490929060ff16613543575b828252600260205260ff604083205416156104665760ff6008541615613534578415610457578315611e6057828252600d602052604082205480861061351d5750828252600f6020526040822054801561350e578086116134f857508461320b91613f78565b670de0b6b3a76400008402848104670de0b6b3a7640000036134e4578282526003602052604082205461323d91613ab4565b90828152600560205260ff604082205416601281106134c4575b50828152600660205261327c612710613274604084205485613a8b565b048093613b6c565b938085106134ac575082815260076020528360408220541061348857828152600760205260408120548481106134795760008051602061482e8339815191526040826132c9888895613b6c565b8486526007602052808387205582519182526020820152a26001546040516318160ddd60e01b815290602090829060049082906001600160a01b03165afa908115611e0a578291613447575b5081546001600160a01b0316803b15611ca057826040518092633a52b90760e11b82528183816133498d3360048401613bc2565b03925af18015611cef57613432575b506001546040516318160ddd60e01b81529190602090839060049082906001600160a01b03165afa908115611cef5783916133fc575b6133989250613b6c565b8581036133e45750507f8caf04742286d017f9ac3924388e188c73e6e5094311c5e59a61a7ef86dda8bf611bcd6020956133d386338761404c565b604051918291339588429285613bdd565b635ab6e2db60e01b8252600486905260245260449150fd5b90506020823d60201161342a575b81613417602093836139c3565b810103126105fe5761339891519061338e565b3d915061340a565b9161344081600493946139c3565b9190613358565b90506020813d602011613471575b81613462602093836139c3565b810103126126d2575138613315565b3d9150613455565b6308aed4ef60e31b8252600482fd5b82815260076020526040812054635960d22160e01b82526004526024849052604490fd5b6371c4efed60e01b8252600485905260245260449150fd5b916134d760ff6117526134dd9495613ad4565b90613ab4565b9038613257565b634e487b7160e01b82526011600452602482fd5b625502a360e91b83526004869052602452604482fd5b636c6ff70d60e11b8352600483fd5b6361767b8560e01b83526004869052602452604482fd5b630df65d9f60e01b8252600482fd5b60405163313ce56760e01b815291939291602081600481865afa85918161359d575b506135795763105482c760e21b8552600485fd5b93919293838352600560205260ff806040852054169116908103611ec957506131a5565b6135b791925060203d6020116109c9576109ba81836139c3565b9038613565565b3381526009602052436040822055338152600a60205260016040822055613183565b503461033b57602036600319011261033b576020610f3c600435613b79565b503461033b57602036600319011261033b576020906040906001600160a01b0361362761392e565b168152600f83522054604051908152f35b503461033b57604036600319011261033b5761365261392e565b60105460243591906001600160a01b0316330361215a576001600160a01b031690811561214b5760406000805160206146ce8339815191529183855260126020528185205490848652601260205280838720558486526014602052828620438752602052828620548587526018602052838720558486526016602052438387205582519182526020820152a280f35b503461033b57602036600319011261033b576020906040906001600160a01b0361370961392e565b168152600683522054604051908152f35b503461033b578060031936011261033b576001546040516001600160a01b039091168152602090f35b503461033b57602036600319011261033b576020906040906001600160a01b0361376b61392e565b168152600d83522054604051908152f35b503461033b57602036600319011261033b5761379661395a565b6010546001600160a01b0316330361047957602060008051602061466e83398151915291151560ff196008541660ff821617600855604051908152a180f35b503461033b57602036600319011261033b5760043563ffffffff60e01b81168091036126d257602090635a05180f60e01b811490811561381b575b506040519015158152f35b637965db0b60e01b811491508115613835575b5082613810565b6301ffc9a760e01b1490508261382e565b503461033b57604036600319011261033b5761386061392e565b6001600160a01b0316808252600260205260408220546024359060ff161561177457670de0b6b3a7640000810290808204670de0b6b3a7640000149015171561391a57916138bc60409383835260036020528483205490613ab4565b91808252600560205260ff8483205416601281106138f1575b5061172a84836127109361173295526006602052205484613a8b565b846117329361390f61271094966134d760ff61175261172a97613ad4565b9593509350506138d5565b634e487b7160e01b83526011600452602483fd5b600435906001600160a01b03821682036105fe57565b602435906001600160a01b03821682036105fe57565b6004359081151582036105fe57565b60609060031901126105fe576004356001600160a01b03811681036105fe57906024359060443590565b9181601f840112156105fe578235916001600160401b0383116105fe576020808501948460051b0101116105fe57565b601f909101601f19168101906001600160401b038211908210176139e657604052565b634e487b7160e01b600052604160045260246000fd5b6001600160401b0381116139e657601f01601f191660200190565b919082519283825260005b848110613a43575050826000602080949584010152601f8019910116010190565b80602080928401015182828601015201613a22565b6084359060ff821682036105fe57565b60405190613a776040836139c3565b6005825264322e332e3360d81b6020830152565b81810292918115918404141715613a9e57565b634e487b7160e01b600052601160045260246000fd5b8115613abe570490565b634e487b7160e01b600052601260045260246000fd5b60ff166012039060ff8211613a9e57565b8015613b665760009060208110600116604e821060011617613b5e57600a916001915b60018111613b35575082600019048211613b2157500290565b634e487b7160e01b81526011600452602490fd5b92806000190481116134e45760018416613b55575b80029260011c613b08565b80920291613b4a565b9050600a0a90565b50600190565b91908203918211613a9e57565b60005260008051602061478e83398151915260205260016040600020015490565b6000198114613a9e5760010190565b908160209103126105fe575160ff811681036105fe5790565b6001600160a01b039091168152602081019190915260400190565b9094939260609260808301968352602083015260408201520152565b6001600160401b0381116139e65760051b60200190565b9190811015613c205760051b0190565b634e487b7160e01b600052603260045260246000fd5b356001600160a01b03811681036105fe5790565b8051821015613c205760209160051b010190565b6001600160a01b03168015613c9f57601080546001600160a01b0319811683179091556001600160a01b031660008051602061474e833981519152600080a3565b63e6c4247b60e01b60005260046000fd5b91908201809211613a9e57565b94919360e0969360ff929a99989561010088019b885260208801526040870152166060850152608084015260a083015260c08201520152565b6001600160a01b03811660008181526002602052604090205490919060ff16158015613de8575b8015613de0575b613dce5781600052600f6020526040600020548015908115613dd6575b50613dce57613d66926040918251948592839262f7fce960e01b845260048401613bc2565b0381305afa918215613dc257600092613d8e575b506000526007602052604060002054101590565b9091506040813d604011613dba575b81613daa604093836139c3565b810103126105fe57519038613d7a565b3d9150613d9d565b6040513d6000823e3d90fd5b505050600090565b9050831138613d41565b508215613d24565b5060ff6008541615613d1d565b6001546001600160a01b0391821691168103613e6a576020602491604051928380926370a0823160e01b82523060048301525afa908115613dc257600091613e3b575090565b90506020813d602011613e62575b81613e56602093836139c3565b810103126105fe575190565b3d9150613e49565b80600052600260205260ff60406000205416613e865750600090565b6040516370a0823160e01b815230600482015290602082602481845afa918215613dc257600092613ede575b506000526007602052604060002054808211600014613ed757613ed491613b6c565b90565b5050600090565b90916020823d602011613f0a575b81613ef9602093836139c3565b8101031261033b5750519038613eb2565b3d9150613eec565b60026000805160206147ce8339815191525414613f3d5760026000805160206147ce83398151915255565b633ee5aeb560e01b60005260046000fd5b60ff6000805160206147ae8339815191525416613f6757565b63d93c066560e01b60005260046000fd5b6001600160a01b0316600081815260136020526040902054801561404757816000526015602052604060002043600052602052613fbb6040600020549384613cb0565b92831061403657808260005260176020524360406000205414614018575b8311613ffc57506000526015602052604060002043600052602052604060002055565b925063029359d560e41b60005260045260245260445260646000fd5b5081600052601960205261403160406000205482613cb0565b613fd9565b63446c8cc960e01b60005260046000fd5b505050565b614081614086939261407360405194859263a9059cbb60e01b602085015260248401613bc2565b03601f1981018452836139c3565b6142ed565b565b600081815260008051602061478e8339815191526020908152604080832033845290915290205460ff16156140ba5750565b63e2517d3f60e01b6000523360045260245260446000fd5b6140dc8282614348565b91826140e757505090565b60009182526000805160206146ae8339815191526020526040909120614116916001600160a01b0316906144d0565b5090565b61412482826143ea565b918261412f57505090565b60009182526000805160206146ae8339815191526020526040909120614116916001600160a01b031690614539565b6001600160a01b03166000818152601260205260409020548015614047578160005260146020526040600020436000526020526141a16040600020549384613cb0565b928310614036578082600052601660205243604060002054146141fe575b83116141e257506000526014602052604060002043600052602052604060002055565b92506319a4e2a760e01b60005260045260245260445260646000fd5b5081600052601860205261421760406000205482613cb0565b6141bf565b6040516323b872dd60e01b60208201526001600160a01b039283166024820152929091166044830152606480830193909352918152614086916140816084836139c3565b60405163313ce56760e01b81529190602090839060049082906001600160a01b03165afa600092816142cc575b506142a357631eecbb6560e01b60005260046000fd5b60ff91821691168082036142b5575050565b631e43476360e11b60005260045260245260446000fd5b6142e691935060203d6020116109c9576109ba81836139c3565b913861428d565b906000602091828151910182855af115613dc2576000513d61433f57506001600160a01b0381163b155b61431e5750565b635274afe760e01b60009081526001600160a01b0391909116600452602490fd5b60011415614317565b600081815260008051602061478e833981519152602090815260408083206001600160a01b038616845290915290205460ff16613ed757600081815260008051602061478e833981519152602090815260408083206001600160a01b0395909516808452949091528120805460ff19166001179055339291907f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d9080a4600190565b600081815260008051602061478e833981519152602090815260408083206001600160a01b038616845290915290205460ff1615613ed757600081815260008051602061478e833981519152602090815260408083206001600160a01b0395909516808452949091528120805460ff19169055339291907ff6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b9080a4600190565b60ff60008051602061480e8339815191525460401c16156144a757565b631afcd79f60e31b60005260046000fd5b8054821015613c205760005260206000200190600090565b6001810190826000528160205260406000205415600014613dce578054600160401b8110156139e65761452461450d8260018794018555846144b8565b819391549060031b91821b91600019901b19161790565b90555491600052602052604060002055600190565b9060018201918160005282602052604060002054801515600014614603576000198101818111613a9e578254600019810191908211613a9e578181036145cc575b505050805480156145b657600019019061459482826144b8565b8154906000199060031b1b191690555560005260205260006040812055600190565b634e487b7160e01b600052603160045260246000fd5b6145ec6145dc61450d93866144b8565b90549060031b1c928392866144b8565b90556000528360205260406000205538808061457a565b50505050600090565b90614632575080511561462157602081519101fd5b63d6bda27560e01b60005260046000fd5b81511580614664575b614643575090565b639996b31560e01b60009081526001600160a01b0391909116600452602490fd5b50803b1561463b56fe2c0a5f5ab0ba371221bb3612c2d2f90d36566279309f526000c5b354efd1b0658c67aaac7f77de07240e5a9b36dfdccb2a89c438635abbb27a73142d2aa0f629c1f6fe24621ce81ec5827caf0253cadb74709b061630e6b55e8237170593200048b07fab687f450848f1df8a96db08fef7840f53415f18fdc2ec8e9f810f0930c7f505b2f371ae2175ee4913f4499e1f2633a7b5936321eed1cdaeb6115181d275027301df982f5215b4963a854cf9c73219df80cb6acd8f098189c9480c7bbc360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc17dc5b1290f7495d7f8cc68476e6941aaf510598fa925d0d2720edc8805a846c4460507c21097c15f6883572ebd157a9ee4b1d989a312314e93afd9d2ecd494002dd7bc7dec4dceedda775e58dd541e08a116c6c53815c0bd028192f7b626800cd5ed15c6e187e77e9aee88184c21f4f2182ab5827cb3b7e07fbedcd63f033009b779b17422d0df92223018b32b4d1fa46e071723d6817e2486d003becc55f00a49807205ce4d355092ef5a8a18f56e8913cf4a201fbe287825b095693c21775f0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a006d129bd71f2401cbe77f49f546d7d5f58992faecfca6e51ba06b50b261e83331a164736f6c6343000822000a";
15837
15924
  var isSuperArgs = (xs) => xs.length > 1;
15838
- var SimplePSMV2__factory = class extends import_ethers13.ContractFactory {
15925
+ var SimplePSMV2__factory = class extends import_ethers14.ContractFactory {
15839
15926
  constructor(...args) {
15840
15927
  if (isSuperArgs(args)) {
15841
15928
  super(...args);
@@ -15855,10 +15942,10 @@ var SimplePSMV2__factory = class extends import_ethers13.ContractFactory {
15855
15942
  static bytecode = _bytecode;
15856
15943
  static abi = _abi;
15857
15944
  static createInterface() {
15858
- return new import_ethers13.Interface(_abi);
15945
+ return new import_ethers14.Interface(_abi);
15859
15946
  }
15860
15947
  static connect(address, runner) {
15861
- return new import_ethers13.Contract(address, _abi, runner);
15948
+ return new import_ethers14.Contract(address, _abi, runner);
15862
15949
  }
15863
15950
  };
15864
15951
 
@@ -16446,7 +16533,7 @@ var DiamondHandsSDK = class _DiamondHandsSDK {
16446
16533
  */
16447
16534
  constructor(config) {
16448
16535
  if (!config.provider && config.ethRpcUrl) {
16449
- config.provider = new import_ethers14.JsonRpcProvider(config.ethRpcUrl);
16536
+ config.provider = new import_ethers15.JsonRpcProvider(config.ethRpcUrl);
16450
16537
  }
16451
16538
  this.config = config;
16452
16539
  if (config.debug) {
@@ -16719,7 +16806,7 @@ var DiamondHandsSDK = class _DiamondHandsSDK {
16719
16806
  const network = await config.provider.getNetwork();
16720
16807
  chainId = Number(network.chainId);
16721
16808
  } else if (config.ethRpcUrl) {
16722
- const tempProvider = new import_ethers14.JsonRpcProvider(
16809
+ const tempProvider = new import_ethers15.JsonRpcProvider(
16723
16810
  config.ethRpcUrl
16724
16811
  );
16725
16812
  const network = await tempProvider.getNetwork();
@@ -17255,7 +17342,7 @@ var DiamondHandsSDK = class _DiamondHandsSDK {
17255
17342
  }
17256
17343
  const loanOps = this.loanOps();
17257
17344
  const protocolConfig = await loanOps.getProtocolConfig();
17258
- const requestAmountWei = (0, import_ethers14.parseEther)(
17345
+ const requestAmountWei = (0, import_ethers15.parseEther)(
17259
17346
  request.amount.toString()
17260
17347
  );
17261
17348
  const minLoanValueWei = BigInt(protocolConfig.minimumLoanValueWei);
@@ -17337,7 +17424,7 @@ var DiamondHandsSDK = class _DiamondHandsSDK {
17337
17424
  pkpNftAddress,
17338
17425
  this.getChipotlePublicKeyFallback()
17339
17426
  );
17340
- pkpEthAddress = (0, import_ethers14.computeAddress)(pkpPublicKey);
17427
+ pkpEthAddress = (0, import_ethers15.computeAddress)(pkpPublicKey);
17341
17428
  pkpCache.set(request.positionId, {
17342
17429
  publicKey: pkpPublicKey,
17343
17430
  ethAddress: pkpEthAddress,
@@ -17666,8 +17753,8 @@ var DiamondHandsSDK = class _DiamondHandsSDK {
17666
17753
  throw new Error(`Position not found: ${request.positionId}`);
17667
17754
  }
17668
17755
  const currentDebt = position.ucdDebt.toString();
17669
- const ucdDebtHash = (0, import_ethers14.keccak256)(import_ethers14.AbiCoder.defaultAbiCoder().encode(["uint256"], [currentDebt]));
17670
- const contractHash = (0, import_ethers14.keccak256)(import_ethers14.AbiCoder.defaultAbiCoder().encode(
17756
+ const ucdDebtHash = (0, import_ethers15.keccak256)(import_ethers15.AbiCoder.defaultAbiCoder().encode(["uint256"], [currentDebt]));
17757
+ const contractHash = (0, import_ethers15.keccak256)(import_ethers15.AbiCoder.defaultAbiCoder().encode(
17671
17758
  ["address", "address", "address", "address"],
17672
17759
  [
17673
17760
  positionManagerAddress,
@@ -17736,7 +17823,7 @@ var DiamondHandsSDK = class _DiamondHandsSDK {
17736
17823
  const coreAbi = [
17737
17824
  "function getPositionDetails(bytes32) view returns (tuple(bytes32 positionId, bytes32 pkpId, uint256 ucdDebt, string vaultAddress, address borrower, uint40 createdAt, uint40 lastUpdated, uint16 selectedTerm, uint40 expiryAt, uint8 status, uint40 previousExpiryAt, uint16 totalTerm))"
17738
17825
  ];
17739
- const positionCore = new import_ethers14.Contract(
17826
+ const positionCore = new import_ethers15.Contract(
17740
17827
  coreAddress,
17741
17828
  coreAbi,
17742
17829
  this.getSignerOrThrow().provider
@@ -17744,8 +17831,8 @@ var DiamondHandsSDK = class _DiamondHandsSDK {
17744
17831
  const currentPosition = await positionCore["getPositionDetails"](
17745
17832
  positionIdBytes32
17746
17833
  );
17747
- const currentDebtHash = (0, import_ethers14.keccak256)(
17748
- import_ethers14.AbiCoder.defaultAbiCoder().encode(
17834
+ const currentDebtHash = (0, import_ethers15.keccak256)(
17835
+ import_ethers15.AbiCoder.defaultAbiCoder().encode(
17749
17836
  ["uint256"],
17750
17837
  [currentPosition.ucdDebt]
17751
17838
  )
@@ -17792,7 +17879,7 @@ var DiamondHandsSDK = class _DiamondHandsSDK {
17792
17879
  "function getCurrentQuantum() view returns (uint256)",
17793
17880
  "function isQuantumValid(bytes32,uint256) view returns (bool)"
17794
17881
  ];
17795
- const registry = new import_ethers14.Contract(
17882
+ const registry = new import_ethers15.Contract(
17796
17883
  registryAddress,
17797
17884
  registryAbi,
17798
17885
  this.getSignerOrThrow().provider
@@ -17908,7 +17995,7 @@ var DiamondHandsSDK = class _DiamondHandsSDK {
17908
17995
  });
17909
17996
  }
17910
17997
  const signatureHexMint = finalSignature.startsWith("0x") ? finalSignature : "0x" + finalSignature;
17911
- const mintIface = new import_ethers14.Interface(positionManagerAbi);
17998
+ const mintIface = new import_ethers15.Interface(positionManagerAbi);
17912
17999
  const mintCalldata = mintIface.encodeFunctionData("mintUCD", [
17913
18000
  positionIdBytes32,
17914
18001
  validationResponse.mintAmount,
@@ -17944,7 +18031,7 @@ var DiamondHandsSDK = class _DiamondHandsSDK {
17944
18031
  if (viewsAddress) {
17945
18032
  let diagnosis = null;
17946
18033
  try {
17947
- const views = new import_ethers14.Contract(
18034
+ const views = new import_ethers15.Contract(
17948
18035
  viewsAddress,
17949
18036
  [
17950
18037
  "function diagnoseMintUCD(bytes32,uint256,uint256,uint256,uint256,uint256,bytes32,bytes32,bytes32,uint256,bytes) view returns (string)"
@@ -18054,7 +18141,7 @@ Message: ${causeMessage}${quantumContext}${mintDebtDiagnostics}`
18054
18141
  if (receipt.logs && receipt.logs.length > 0) {
18055
18142
  for (const receiptLog of receipt.logs) {
18056
18143
  if (receiptLog.topics && receiptLog.topics[0] === "0x08c379a0") {
18057
- const iface = new import_ethers14.Interface([
18144
+ const iface = new import_ethers15.Interface([
18058
18145
  "error Error(string)"
18059
18146
  ]);
18060
18147
  const decoded = iface.decodeErrorResult("Error", receiptLog.data);
@@ -18071,7 +18158,7 @@ Message: ${causeMessage}${quantumContext}${mintDebtDiagnostics}`
18071
18158
  const minimalAbi = [
18072
18159
  "event UCDMintedWithAuthorization(bytes32 indexed positionId, address indexed borrower, uint256 mintAmount, uint256 mintFee, uint256 newDebt, uint256 newCollateral, uint256 btcPrice, uint256 quantumTimestamp, bytes32 authorizedSpendsHash)"
18073
18160
  ];
18074
- const iface = new import_ethers14.Interface(minimalAbi);
18161
+ const iface = new import_ethers15.Interface(minimalAbi);
18075
18162
  for (const receiptLog of receipt.logs) {
18076
18163
  const parsed = (() => {
18077
18164
  const logIface = iface;
@@ -18258,7 +18345,7 @@ Message: ${causeMessage}${quantumContext}${mintDebtDiagnostics}`
18258
18345
  pkpNftAddress,
18259
18346
  this.getChipotlePublicKeyFallback()
18260
18347
  );
18261
- const pkpEthAddress = (0, import_ethers14.computeAddress)(pkpPublicKey);
18348
+ const pkpEthAddress = (0, import_ethers15.computeAddress)(pkpPublicKey);
18262
18349
  pkpData = {
18263
18350
  publicKey: pkpPublicKey,
18264
18351
  ethAddress: pkpEthAddress,
@@ -18660,7 +18747,7 @@ Message: ${causeMessage}${quantumContext}${mintDebtDiagnostics}`
18660
18747
  }
18661
18748
  const loanOpsForUcd = loanOpsForUcdResult.value;
18662
18749
  const ucdTokenAddress = await loanOpsForUcd.ucdToken();
18663
- const ucdToken = new import_ethers14.Contract(
18750
+ const ucdToken = new import_ethers15.Contract(
18664
18751
  ucdTokenAddress,
18665
18752
  [
18666
18753
  "function balanceOf(address) view returns (uint256)",
@@ -18676,9 +18763,9 @@ Message: ${causeMessage}${quantumContext}${mintDebtDiagnostics}`
18676
18763
  if (ucdBalance < debtWei) {
18677
18764
  return {
18678
18765
  success: false,
18679
- error: `Insufficient UCD balance for liquidation: ${(0, import_ethers14.formatEther)(
18766
+ error: `Insufficient UCD balance for liquidation: ${(0, import_ethers15.formatEther)(
18680
18767
  ucdBalance
18681
- )} UCD (need ${(0, import_ethers14.formatEther)(debtWei)} UCD)`,
18768
+ )} UCD (need ${(0, import_ethers15.formatEther)(debtWei)} UCD)`,
18682
18769
  positionId: request.positionId,
18683
18770
  wasLiquidated: false
18684
18771
  };
@@ -18687,7 +18774,7 @@ Message: ${causeMessage}${quantumContext}${mintDebtDiagnostics}`
18687
18774
  if (request.skipUcdApproval) {
18688
18775
  return {
18689
18776
  success: false,
18690
- error: `Insufficient UCD allowance for UCDController: need at least ${(0, import_ethers14.formatEther)(
18777
+ error: `Insufficient UCD allowance for UCDController: need at least ${(0, import_ethers15.formatEther)(
18691
18778
  debtWei
18692
18779
  )} UCD, or omit skipUcdApproval to let the SDK submit approve`,
18693
18780
  positionId: request.positionId,
@@ -19194,7 +19281,7 @@ Message: ${causeMessage}${quantumContext}${mintDebtDiagnostics}`
19194
19281
  if (typeof signatureBytes === "string" && signatureBytes.startsWith("{")) {
19195
19282
  try {
19196
19283
  const parsed = JSON.parse(signatureBytes);
19197
- signatureBytes = parsed.signature ?? (parsed.r && parsed.s && parsed.v ? import_ethers14.Signature.from({
19284
+ signatureBytes = parsed.signature ?? (parsed.r && parsed.s && parsed.v ? import_ethers15.Signature.from({
19198
19285
  r: parsed.r,
19199
19286
  s: parsed.s,
19200
19287
  v: parsed.v
@@ -19205,7 +19292,7 @@ Message: ${causeMessage}${quantumContext}${mintDebtDiagnostics}`
19205
19292
  if (!signatureBytes.startsWith("0x")) {
19206
19293
  signatureBytes = "0x" + signatureBytes;
19207
19294
  }
19208
- const extendIface = new import_ethers14.Interface([
19295
+ const extendIface = new import_ethers15.Interface([
19209
19296
  "function extendPosition(bytes32 positionId, uint256 selectedTerm, uint256 quantumTimestamp, uint256 btcPrice, uint256 availableBTCBalance, uint256 proRataRenewalFee, bytes calldata extensionValidatorSignature) external returns (bool)"
19210
19297
  ]);
19211
19298
  const extendCalldata = extendIface.encodeFunctionData("extendPosition", [
@@ -19755,7 +19842,7 @@ Message: ${causeMessage}${quantumContext}${mintDebtDiagnostics}`
19755
19842
  ` Converting payment amount: ${request.paymentAmount} (type: ${typeof request.paymentAmount})`
19756
19843
  );
19757
19844
  }
19758
- const paymentAmountWei = (0, import_ethers14.parseEther)(
19845
+ const paymentAmountWei = (0, import_ethers15.parseEther)(
19759
19846
  request.paymentAmount.toString()
19760
19847
  );
19761
19848
  if (this.config.debug) {
@@ -19817,7 +19904,7 @@ Message: ${causeMessage}${quantumContext}${mintDebtDiagnostics}`
19817
19904
  };
19818
19905
  }
19819
19906
  const ucdTokenAddress = await loanOps.ucdToken();
19820
- const ucdToken = new import_ethers14.Contract(
19907
+ const ucdToken = new import_ethers15.Contract(
19821
19908
  ucdTokenAddress,
19822
19909
  [
19823
19910
  "function balanceOf(address) view returns (uint256)",
@@ -19832,16 +19919,16 @@ Message: ${causeMessage}${quantumContext}${mintDebtDiagnostics}`
19832
19919
  ucdToken["allowance"](signerAddress, positionManagerAddress)
19833
19920
  ]);
19834
19921
  if (this.config.debug) {
19835
- log.info(` UCD Balance: ${(0, import_ethers14.formatEther)(balance)} UCD`);
19922
+ log.info(` UCD Balance: ${(0, import_ethers15.formatEther)(balance)} UCD`);
19836
19923
  log.info(
19837
- ` UCD Allowance: ${(0, import_ethers14.formatEther)(allowance)} UCD`
19924
+ ` UCD Allowance: ${(0, import_ethers15.formatEther)(allowance)} UCD`
19838
19925
  );
19839
19926
  log.info(` Required: ${request.paymentAmount} UCD`);
19840
19927
  }
19841
19928
  if (balance < paymentAmountWei) {
19842
19929
  return {
19843
19930
  success: false,
19844
- error: `Insufficient UCD balance: ${(0, import_ethers14.formatEther)(
19931
+ error: `Insufficient UCD balance: ${(0, import_ethers15.formatEther)(
19845
19932
  balance
19846
19933
  )} UCD (need ${request.paymentAmount} UCD)`
19847
19934
  };
@@ -20110,7 +20197,7 @@ Message: ${causeMessage}${quantumContext}${mintDebtDiagnostics}`
20110
20197
  const paymentSigner = this.getSignerOrThrow();
20111
20198
  const paymentFrom = await paymentSigner.getAddress();
20112
20199
  const paymentProvider = contractManager.getProvider();
20113
- const paymentIface = new import_ethers14.Interface([
20200
+ const paymentIface = new import_ethers15.Interface([
20114
20201
  "function makePayment(bytes32 positionId, uint256 paymentAmount, uint256 quantumTimestamp, uint256 btcPrice, bytes calldata paymentValidatorSignature) external returns (bool)"
20115
20202
  ]);
20116
20203
  const paymentCalldata = paymentIface.encodeFunctionData("makePayment", [
@@ -20427,7 +20514,7 @@ Message: ${causeMessage}${quantumContext}${mintDebtDiagnostics}`
20427
20514
  const pkpId = position.pkpId;
20428
20515
  if (litValidatorAddr && pkpId) {
20429
20516
  try {
20430
- const litValidator = new import_ethers14.Contract(
20517
+ const litValidator = new import_ethers15.Contract(
20431
20518
  litValidatorAddr,
20432
20519
  ["function pkpOwners(bytes32) view returns (address)"],
20433
20520
  this.getProviderOrThrow()
@@ -20435,7 +20522,7 @@ Message: ${causeMessage}${quantumContext}${mintDebtDiagnostics}`
20435
20522
  const owner = await litValidator.pkpOwners(
20436
20523
  pkpId
20437
20524
  );
20438
- if (owner && owner !== import_ethers14.ZeroAddress) {
20525
+ if (owner && owner !== import_ethers15.ZeroAddress) {
20439
20526
  controller = owner;
20440
20527
  }
20441
20528
  } catch {
@@ -20487,7 +20574,7 @@ Message: ${causeMessage}${quantumContext}${mintDebtDiagnostics}`
20487
20574
  pkpNftAddress,
20488
20575
  this.getChipotlePublicKeyFallback()
20489
20576
  );
20490
- pkpEthAddress = (0, import_ethers14.computeAddress)(pkpPublicKey);
20577
+ pkpEthAddress = (0, import_ethers15.computeAddress)(pkpPublicKey);
20491
20578
  pkpCache.set(positionId, {
20492
20579
  publicKey: pkpPublicKey,
20493
20580
  ethAddress: pkpEthAddress,
@@ -20850,7 +20937,7 @@ Message: ${causeMessage}${quantumContext}${mintDebtDiagnostics}`
20850
20937
  utxoVout: withdrawalParams.utxoVout
20851
20938
  });
20852
20939
  }
20853
- const withdrawIface = new import_ethers14.Interface([
20940
+ const withdrawIface = new import_ethers15.Interface([
20854
20941
  "function withdrawBTC((bytes32 positionId, bytes32 actionHash, bytes32 authorizedSpendsHash, bytes32 ucdDebtHash, bytes32 contractBundleHash, string withdrawalAddress, uint256 totalDeduction, uint256 newCollateral, uint256 quantumTimestamp, uint256 btcPrice, string utxoTxid, uint32 utxoVout) params, bytes withdrawalValidatorSignature, bytes btcSpendAuthSignature) external returns (bool)"
20855
20942
  ]);
20856
20943
  const withdrawCalldata = withdrawIface.encodeFunctionData("withdrawBTC", [
@@ -21042,7 +21129,7 @@ Message: ${causeMessage}${quantumContext}${mintDebtDiagnostics}`
21042
21129
  }
21043
21130
  const pkpId = positionDetails.pkpId;
21044
21131
  const vaultAddress = positionDetails.vaultAddress;
21045
- if (!pkpId || pkpId === import_ethers14.ZeroHash) {
21132
+ if (!pkpId || pkpId === import_ethers15.ZeroHash) {
21046
21133
  return { success: false, error: "Position has no PKP" };
21047
21134
  }
21048
21135
  if (!vaultAddress) {
@@ -21062,7 +21149,7 @@ Message: ${causeMessage}${quantumContext}${mintDebtDiagnostics}`
21062
21149
  if (!publicKey) {
21063
21150
  return { success: false, error: "Failed to resolve PKP public key" };
21064
21151
  }
21065
- const chipotlePkpAddress = (0, import_ethers14.computeAddress)(publicKey);
21152
+ const chipotlePkpAddress = (0, import_ethers15.computeAddress)(publicKey);
21066
21153
  const STANDALONE_CHAIN_NAMES = {
21067
21154
  1: "ethereum",
21068
21155
  11155111: "sepolia",
@@ -21412,7 +21499,7 @@ Message: ${causeMessage}${quantumContext}${mintDebtDiagnostics}`
21412
21499
  const btcSpendAuthorizerAbi = [
21413
21500
  "function getAuthorizedSpends(bytes32) view returns (tuple(string txid, uint32 vout, uint256 satoshis, string targetAddress, uint256 targetAmount, uint256 authorizedAt)[])"
21414
21501
  ];
21415
- const btcSpendAuthorizer = new import_ethers14.Contract(
21502
+ const btcSpendAuthorizer = new import_ethers15.Contract(
21416
21503
  btcSpendAuthorizerAddress,
21417
21504
  btcSpendAuthorizerAbi,
21418
21505
  this.getProviderOrThrow()
@@ -21480,7 +21567,7 @@ Message: ${causeMessage}${quantumContext}${mintDebtDiagnostics}`
21480
21567
  * been broadcast to the Bitcoin network. An empty array means no pending withdrawals.
21481
21568
  *
21482
21569
  * @param positionId - Position identifier
21483
- * @returns Array of pending withdrawals, each including a pre-computed utxoKey for use with cancelPendingWithdrawal
21570
+ * @returns Array of pending withdrawals, each including a pre-computed utxoKey (the key recoverStaleSpend and the admin clearing path operate on)
21484
21571
  */
21485
21572
  async getPendingWithdrawals(positionId) {
21486
21573
  this.ensureInitialized();
@@ -21498,7 +21585,7 @@ Message: ${causeMessage}${quantumContext}${mintDebtDiagnostics}`
21498
21585
  const abi = [
21499
21586
  "function getAuthorizedSpends(bytes32) view returns (tuple(string txid, uint32 vout, uint256 satoshis, string targetAddress, uint256 targetAmount, uint256 authorizedAt)[])"
21500
21587
  ];
21501
- const contract = new import_ethers14.Contract(
21588
+ const contract = new import_ethers15.Contract(
21502
21589
  btcSpendAuthorizerAddress,
21503
21590
  abi,
21504
21591
  this.getProviderOrThrow()
@@ -21512,7 +21599,7 @@ Message: ${causeMessage}${quantumContext}${mintDebtDiagnostics}`
21512
21599
  targetAddress: spend.targetAddress,
21513
21600
  targetAmount: Number(spend.targetAmount),
21514
21601
  authorizedAt: Number(spend.authorizedAt),
21515
- utxoKey: (0, import_ethers14.solidityPackedKeccak256)(
21602
+ utxoKey: (0, import_ethers15.solidityPackedKeccak256)(
21516
21603
  ["string", "uint32"],
21517
21604
  [spend.txid, Number(spend.vout)]
21518
21605
  )
@@ -21525,11 +21612,15 @@ Message: ${causeMessage}${quantumContext}${mintDebtDiagnostics}`
21525
21612
  * broadcast happened. Callers MUST use the returned `status` to decide what
21526
21613
  * to offer:
21527
21614
  * - EXECUTABLE → offer Execute (the only status that may).
21528
- * - EXECUTED → auto-clear; `spendingTxid` is the completion proof.
21529
- * - SPENT_MISMATCH → unexecutable; offer cancelPendingWithdrawal.
21615
+ * - EXECUTED → auto-clear; `spendingTxid` is the completion proof
21616
+ * feed it to recoverStaleSpend to clear the reservation.
21617
+ * - SPENT_MISMATCH → unexecutable; recoverStaleSpend with the spending txid
21618
+ * as invalidator clears the reservation.
21530
21619
  * - CORRUPT → authorization contradicts the chain (e.g. declared
21531
- * satoshis ≠ real output value); offer Cancel &
21532
- * re-request Execute can only die at the signer guard.
21620
+ * satoshis ≠ real output value); Execute can only die at
21621
+ * the signer guard, and no borrower-side cancel exists
21622
+ * (audit #62210) — clearing needs the AdminModule
21623
+ * cancelStaleSpendByAdmin operator override.
21533
21624
  * - UNFUNDED → funding tx unknown/unconfirmed; wait.
21534
21625
  *
21535
21626
  * @param opts.esploraBaseUrl Esplora API base (e.g. the api proxy
@@ -21553,18 +21644,13 @@ Message: ${causeMessage}${quantumContext}${mintDebtDiagnostics}`
21553
21644
  spends.map((spend) => reconcileAuthorizedSpend(spend, esploraBaseUrl))
21554
21645
  );
21555
21646
  }
21556
- /**
21557
- * Cancel a pending BTC withdrawal
21558
- *
21559
- * Removes a stale authorized spend from BTCSpendAuthorizer, unlocking the UTXO
21560
- * and allowing the borrower to retry the withdrawal from scratch.
21561
- * Only the position's borrower may call this requires a connected signer.
21562
- *
21563
- * @param positionId - Position identifier
21564
- * @param txid - Bitcoin UTXO transaction ID (from getPendingWithdrawals)
21565
- * @param vout - Output index (from getPendingWithdrawals)
21566
- * @returns Transaction hash of the cancellation EVM transaction
21567
- */
21647
+ // NOTE: there is deliberately no cancelPendingWithdrawal. Borrower-callable
21648
+ // cleanup was permanently disabled by audit #62210 (markSpentByOwner /
21649
+ // cancelStaleSpendByOwner revert with BorrowerBTCSpendMutationDisabled — a
21650
+ // borrower cancel could be replayed to mint UCD against the same UTXO).
21651
+ // Reservations clear via recoverStaleSpend below (trustless attestation once
21652
+ // the UTXO is provably consumed) or the AdminModule-timelocked
21653
+ // cancelStaleSpendByAdmin operator override.
21568
21654
  /**
21569
21655
  * Recover (clear) a stale BTC reservation via LIT-attested proof.
21570
21656
  *
@@ -21686,7 +21772,7 @@ Message: ${causeMessage}${quantumContext}${mintDebtDiagnostics}`
21686
21772
  error: attRes.error ?? attRes.reason ?? `LIT recovery attestation rejected${attRes.failedStep ? ` at step ${attRes.failedStep}` : ""}`
21687
21773
  };
21688
21774
  }
21689
- const btcSpendAuthorizer = new import_ethers14.Contract(
21775
+ const btcSpendAuthorizer = new import_ethers15.Contract(
21690
21776
  btcSpendAuthorizerAddress,
21691
21777
  [
21692
21778
  "function cancelStaleSpendWithProof(bytes32 positionId, bytes32 utxoKey, uint256 authorizedAt, string calldata invalidatorTxid, uint256 attestationTimestamp, bytes calldata litSignature) external"
@@ -21716,6 +21802,256 @@ Message: ${causeMessage}${quantumContext}${mintDebtDiagnostics}`
21716
21802
  };
21717
21803
  }
21718
21804
  }
21805
+ /**
21806
+ * Sign + broadcast the PKP vault→vault self-spend that invalidates one
21807
+ * stuck authorized outpoint (btc-utxo-invalidator 1.0.0). Once the returned
21808
+ * `invalidatorTxid` reaches >=6 Bitcoin confirmations, `recoverStaleSpend`
21809
+ * clears the on-chain reservation — the trustless replacement for the
21810
+ * AdminModule cancelStaleSpendByAdmin path on unspent stuck/corrupt
21811
+ * reservations (incident 2026-07-22). Requires the borrower (or position
21812
+ * delegate) signer; the signature is scoped to exactly this outpoint.
21813
+ */
21814
+ async invalidateStaleSpend(params) {
21815
+ this.ensureInitialized();
21816
+ const chainId = this.config.chainId ?? this.config.networkOverride?.chainId;
21817
+ if (!chainId) {
21818
+ return {
21819
+ success: false,
21820
+ failedStep: "config",
21821
+ error: "chainId required for invalidateStaleSpend"
21822
+ };
21823
+ }
21824
+ const signer = this.getSignerOrThrow();
21825
+ const envelope = await buildInvalidateStaleSpendEnvelope({
21826
+ positionId: params.positionId,
21827
+ utxoTxid: params.utxoTxid,
21828
+ utxoVout: params.utxoVout,
21829
+ chainId,
21830
+ signer
21831
+ });
21832
+ if (this.config.mode === "service" && this.config.serviceEndpoint) {
21833
+ const headers = {
21834
+ "Content-Type": "application/json",
21835
+ ...await this.getAuthHeader()
21836
+ };
21837
+ const resp = await fetch(
21838
+ `${this.config.serviceEndpoint}/api/lit/stale-spend/invalidate`,
21839
+ {
21840
+ method: "POST",
21841
+ headers,
21842
+ body: JSON.stringify({
21843
+ positionId: this.toBytes32(params.positionId),
21844
+ utxoTxid: params.utxoTxid,
21845
+ utxoVout: params.utxoVout,
21846
+ chainId,
21847
+ auth: {
21848
+ timestamp: envelope.timestamp,
21849
+ action: envelope.action,
21850
+ signature: envelope.signature
21851
+ }
21852
+ })
21853
+ }
21854
+ );
21855
+ const json = await resp.json();
21856
+ return json.data ?? {
21857
+ success: false,
21858
+ error: json.error ?? "stale-spend invalidate request failed"
21859
+ };
21860
+ }
21861
+ const rpcUrl = params.rpcUrl ?? this.config.ethRpcUrl;
21862
+ if (!rpcUrl) {
21863
+ return {
21864
+ success: false,
21865
+ failedStep: "config",
21866
+ error: "ethRpcUrl required for invalidateStaleSpend \u2014 set DiamondHandsSDKConfig.ethRpcUrl or pass rpcUrl"
21867
+ };
21868
+ }
21869
+ const positionDetails = await this.getPositionDetailsView(
21870
+ params.positionId
21871
+ );
21872
+ if (!positionDetails?.pkpId || positionDetails.pkpId === import_ethers15.ZeroHash) {
21873
+ return { success: false, error: "Position has no PKP" };
21874
+ }
21875
+ const pkpCache = this.cacheManager.getCache("pkp-data", {
21876
+ maxSize: 500,
21877
+ ttlMs: 24 * 60 * 60 * 1e3
21878
+ });
21879
+ let publicKey = pkpCache.get(params.positionId)?.publicKey;
21880
+ if (!publicKey) {
21881
+ const derived = await this.litOps.deriveDiamondHandsLoanPkpPublicKey({
21882
+ pkpId: positionDetails.pkpId
21883
+ });
21884
+ publicKey = derived.publicKey;
21885
+ }
21886
+ if (!publicKey) {
21887
+ return { success: false, error: "Failed to resolve PKP public key" };
21888
+ }
21889
+ const chipotlePkpAddress = (0, import_ethers15.computeAddress)(publicKey);
21890
+ const dc = this.config.contractAddresses || {};
21891
+ const chainName = chainId === 1 ? "ethereum" : chainId === 11155111 ? "sepolia" : chainId === 1337 || chainId === 31337 ? "hardhat" : void 0;
21892
+ if (!chainName) {
21893
+ return {
21894
+ success: false,
21895
+ error: `Unsupported chainId ${chainId} for invalidateStaleSpend (supported: 1, 11155111, 1337, 31337)`
21896
+ };
21897
+ }
21898
+ const signResult = await this.litOps.signBtcUtxoInvalidator({
21899
+ auth: {
21900
+ positionId: this.toBytes32(params.positionId),
21901
+ utxoTxid: params.utxoTxid,
21902
+ utxoVout: params.utxoVout,
21903
+ timestamp: envelope.timestamp,
21904
+ chainId,
21905
+ action: envelope.action,
21906
+ signature: envelope.signature
21907
+ },
21908
+ publicKey,
21909
+ pkpId: chipotlePkpAddress,
21910
+ chain: chainName,
21911
+ rpcUrl,
21912
+ ...this.config.bitcoinProviders?.[0]?.url && (chainId === 1337 || chainId === 31337) ? { devBitcoinProviderUrl: this.config.bitcoinProviders[0].url } : {},
21913
+ contractAddresses: {
21914
+ PositionManager: dc.positionManager ?? "",
21915
+ BTCSpendAuthorizer: dc.btcSpendAuthorizer ?? "",
21916
+ ...dc.bitcoinProviderRegistry ? { BitcoinProviderRegistry: dc.bitcoinProviderRegistry } : {},
21917
+ ...dc.positionDelegateRegistry ? { PositionDelegateRegistry: dc.positionDelegateRegistry } : {}
21918
+ }
21919
+ });
21920
+ if (!signResult.success) {
21921
+ return {
21922
+ success: false,
21923
+ error: signResult.error ?? "btc-utxo-invalidator signing failed",
21924
+ failedStep: signResult.failedStep
21925
+ };
21926
+ }
21927
+ if (signResult.alreadySpent && typeof signResult.alreadySpent === "object") {
21928
+ return {
21929
+ success: true,
21930
+ alreadySpent: { spendingTxid: signResult.alreadySpent.spendingTxid }
21931
+ };
21932
+ }
21933
+ if (!signResult.signatures?.length || !signResult.utxo || !signResult.pkpBtcAddress || typeof signResult.invalidatorAmount !== "number") {
21934
+ return {
21935
+ success: false,
21936
+ error: "btc-utxo-invalidator returned incomplete data (signatures/utxo/pkpBtcAddress/invalidatorAmount)"
21937
+ };
21938
+ }
21939
+ const broadcastUrl = this.config.bitcoinProviders?.[0]?.url;
21940
+ if (!broadcastUrl) {
21941
+ return {
21942
+ success: false,
21943
+ error: "invalidateStaleSpend broadcast requires config.bitcoinProviders[0].url (esplora base)"
21944
+ };
21945
+ }
21946
+ const { txid: invalidatorTxid } = await (0, import_dh_lit_ops.broadcastSignedBitcoinTransaction)({
21947
+ signatures: signResult.signatures,
21948
+ utxos: [signResult.utxo],
21949
+ pkpPublicKey: signResult.pkpPublicKey ?? publicKey,
21950
+ destination: signResult.pkpBtcAddress,
21951
+ userReceivesAmount: signResult.invalidatorAmount,
21952
+ changeAmount: 0,
21953
+ pkpBtcAddress: signResult.pkpBtcAddress,
21954
+ bitcoinNetwork: chainId === 1 ? "mainnet" : "regtest",
21955
+ bitcoinRpcUrl: broadcastUrl
21956
+ });
21957
+ return {
21958
+ success: true,
21959
+ invalidatorTxid,
21960
+ invalidatorAmount: signResult.invalidatorAmount,
21961
+ networkFee: signResult.networkFee,
21962
+ valueMismatch: signResult.valueMismatch
21963
+ };
21964
+ }
21965
+ /**
21966
+ * Resumable, stateless clearing state machine for one stuck reservation —
21967
+ * Bitcoin itself is the state store, so every call either advances the flow
21968
+ * one step or reports where it stands (survives reloads and the multi-day
21969
+ * 6-confirmation wait; no internal polling).
21970
+ *
21971
+ * (a) reservation gone → phase "cleared"
21972
+ * (b) outpoint spent, >=6 confs → recoverStaleSpend → "cleared"/"failed"
21973
+ * outpoint spent, <6 confs → "awaiting-confirmations" (x/6)
21974
+ * (c) outpoint unspent → invalidateStaleSpend → "invalidator-broadcast"
21975
+ */
21976
+ async clearStuckReservation(params) {
21977
+ this.ensureInitialized();
21978
+ const REQUIRED_CONFS = 6;
21979
+ const esploraBaseUrl = params.esploraBaseUrl ?? this.config.bitcoinProviders?.[0]?.url;
21980
+ const reconciled = await this.reconcilePendingWithdrawals(
21981
+ params.positionId,
21982
+ esploraBaseUrl ? { esploraBaseUrl } : void 0
21983
+ );
21984
+ const row = reconciled.find(
21985
+ (r) => r.spend.txid.toLowerCase() === params.utxoTxid.toLowerCase() && r.spend.vout === params.utxoVout
21986
+ );
21987
+ if (!row) {
21988
+ return { phase: "cleared" };
21989
+ }
21990
+ if (row.spendingTxid && esploraBaseUrl) {
21991
+ const base = esploraBaseUrl.replace(/\/+$/, "");
21992
+ const txRes = await fetch(`${base}/tx/${row.spendingTxid}`);
21993
+ const tipRes = await fetch(`${base}/blocks/tip/height`);
21994
+ let confirmations = 0;
21995
+ if (txRes.ok && tipRes.ok) {
21996
+ const tx = await txRes.json();
21997
+ const tip = Number(await tipRes.text());
21998
+ if (tx.status?.confirmed && typeof tx.status.block_height === "number" && Number.isFinite(tip)) {
21999
+ confirmations = Math.max(0, tip - tx.status.block_height + 1);
22000
+ }
22001
+ }
22002
+ if (confirmations < REQUIRED_CONFS) {
22003
+ return {
22004
+ phase: "awaiting-confirmations",
22005
+ invalidatorTxid: row.spendingTxid,
22006
+ confirmations,
22007
+ required: REQUIRED_CONFS
22008
+ };
22009
+ }
22010
+ const recovery = await this.recoverStaleSpend({
22011
+ positionId: params.positionId,
22012
+ utxoTxid: params.utxoTxid,
22013
+ utxoVout: params.utxoVout,
22014
+ invalidatorTxid: row.spendingTxid
22015
+ });
22016
+ if (recovery.success) {
22017
+ return {
22018
+ phase: "cleared",
22019
+ invalidatorTxid: row.spendingTxid,
22020
+ transactionHash: recovery.transactionHash,
22021
+ classification: recovery.classification
22022
+ };
22023
+ }
22024
+ return {
22025
+ phase: "failed",
22026
+ invalidatorTxid: row.spendingTxid,
22027
+ error: recovery.error ?? "stale-spend recovery failed"
22028
+ };
22029
+ }
22030
+ const invalidation = await this.invalidateStaleSpend({
22031
+ positionId: params.positionId,
22032
+ utxoTxid: params.utxoTxid,
22033
+ utxoVout: params.utxoVout
22034
+ });
22035
+ if (!invalidation.success) {
22036
+ return {
22037
+ phase: "failed",
22038
+ error: invalidation.error ?? "invalidator signing/broadcast failed"
22039
+ };
22040
+ }
22041
+ if (invalidation.alreadySpent) {
22042
+ return {
22043
+ phase: "awaiting-confirmations",
22044
+ invalidatorTxid: invalidation.alreadySpent.spendingTxid,
22045
+ confirmations: 0,
22046
+ required: REQUIRED_CONFS
22047
+ };
22048
+ }
22049
+ return {
22050
+ phase: "invalidator-broadcast",
22051
+ invalidatorTxid: invalidation.invalidatorTxid,
22052
+ valueMismatch: invalidation.valueMismatch
22053
+ };
22054
+ }
21719
22055
  /**
21720
22056
  * Withdraw BTC and execute transfer (Complete Flow)
21721
22057
  *
@@ -22126,10 +22462,10 @@ Message: ${causeMessage}${quantumContext}${mintDebtDiagnostics}`
22126
22462
  "function allowance(address owner, address spender) view returns (uint256)",
22127
22463
  "function approve(address spender, uint256 amount) returns (bool)"
22128
22464
  ];
22129
- const stablecoin = new import_ethers14.Contract(params.stablecoinAddress, erc20Abi, params.signer);
22465
+ const stablecoin = new import_ethers15.Contract(params.stablecoinAddress, erc20Abi, params.signer);
22130
22466
  const allowance = await stablecoin.allowance(signerAddress, psmAddress);
22131
22467
  if (allowance < params.amountWei) {
22132
- const approveTx = await stablecoin.approve(psmAddress, import_ethers14.MaxUint256);
22468
+ const approveTx = await stablecoin.approve(psmAddress, import_ethers15.MaxUint256);
22133
22469
  await approveTx.wait();
22134
22470
  }
22135
22471
  const psm = SimplePSMV2__factory.connect(psmAddress, params.signer);
@@ -22164,10 +22500,10 @@ Message: ${causeMessage}${quantumContext}${mintDebtDiagnostics}`
22164
22500
  "function allowance(address owner, address spender) view returns (uint256)",
22165
22501
  "function approve(address spender, uint256 amount) returns (bool)"
22166
22502
  ];
22167
- const ucdToken = new import_ethers14.Contract(ucdAddress, erc20Abi, params.signer);
22503
+ const ucdToken = new import_ethers15.Contract(ucdAddress, erc20Abi, params.signer);
22168
22504
  const allowance = await ucdToken.allowance(signerAddress, ucdControllerAddress);
22169
22505
  if (allowance < params.ucdAmountWei) {
22170
- const approveTx = await ucdToken.approve(ucdControllerAddress, import_ethers14.MaxUint256);
22506
+ const approveTx = await ucdToken.approve(ucdControllerAddress, import_ethers15.MaxUint256);
22171
22507
  await approveTx.wait();
22172
22508
  }
22173
22509
  const psm = SimplePSMV2__factory.connect(psmAddress, params.signer);
@@ -22379,7 +22715,7 @@ Message: ${causeMessage}${quantumContext}${mintDebtDiagnostics}`
22379
22715
  const maxUcdWhole = BigInt(result[3].toString());
22380
22716
  return success({
22381
22717
  liquidationThreshold: result[0].toString(),
22382
- minimumLoanValueUcd: (0, import_ethers14.formatUnits)(result[2], 18),
22718
+ minimumLoanValueUcd: (0, import_ethers15.formatUnits)(result[2], 18),
22383
22719
  minimumLoanValueWei: result[2].toString(),
22384
22720
  maxSingleLoanValueUcd: maxUcdWhole.toString(),
22385
22721
  maxSingleLoanValueWei: (maxUcdWhole * 10n ** 18n).toString()
@@ -22416,7 +22752,7 @@ Message: ${causeMessage}${quantumContext}${mintDebtDiagnostics}`
22416
22752
  const balanceWei = await provider.getBalance(address);
22417
22753
  return success({
22418
22754
  balanceWei: balanceWei.toString(),
22419
- balanceEth: (0, import_ethers14.formatEther)(balanceWei)
22755
+ balanceEth: (0, import_ethers15.formatEther)(balanceWei)
22420
22756
  });
22421
22757
  } catch (error) {
22422
22758
  return failure(new SDKError({
@@ -22806,7 +23142,7 @@ Message: ${causeMessage}${quantumContext}${mintDebtDiagnostics}`
22806
23142
  * Convert decimal position ID to bytes32 format
22807
23143
  */
22808
23144
  toBytes32(value) {
22809
- return (0, import_ethers14.zeroPadValue)((0, import_ethers14.toBeHex)(BigInt(value)), 32);
23145
+ return (0, import_ethers15.zeroPadValue)((0, import_ethers15.toBeHex)(BigInt(value)), 32);
22810
23146
  }
22811
23147
  /**
22812
23148
  * Check if an error indicates a technical failure vs business logic rejection
@@ -22847,7 +23183,7 @@ Message: ${causeMessage}${quantumContext}${mintDebtDiagnostics}`
22847
23183
  const coreModuleAbi = [
22848
23184
  "function getPositionDetails(bytes32) view returns (tuple(bytes32 positionId, bytes32 pkpId, uint256 ucdDebt, string vaultAddress, address borrower, uint40 createdAt, uint40 lastUpdated, uint16 selectedTerm, uint40 expiryAt, uint8 status, uint40 previousExpiryAt, uint16 totalTerm))"
22849
23185
  ];
22850
- const coreModule = new import_ethers14.Contract(
23186
+ const coreModule = new import_ethers15.Contract(
22851
23187
  coreModuleAddress,
22852
23188
  coreModuleAbi,
22853
23189
  provider
@@ -22914,7 +23250,7 @@ Message: ${causeMessage}${quantumContext}${mintDebtDiagnostics}`
22914
23250
  const corePositionAbi = [
22915
23251
  "function getPositionDetails(bytes32) view returns (tuple(bytes32 positionId, bytes32 pkpId, uint256 ucdDebt, string vaultAddress, address borrower, uint40 createdAt, uint40 lastUpdated, uint16 selectedTerm, uint40 expiryAt, uint8 status, uint40 previousExpiryAt, uint16 totalTerm))"
22916
23252
  ];
22917
- const corePositionContract = new import_ethers14.Contract(
23253
+ const corePositionContract = new import_ethers15.Contract(
22918
23254
  coreAddress,
22919
23255
  corePositionAbi,
22920
23256
  provider
@@ -22925,7 +23261,7 @@ Message: ${causeMessage}${quantumContext}${mintDebtDiagnostics}`
22925
23261
  positionIdBytes32
22926
23262
  );
22927
23263
  const positionIdFromCore = corePosition?.positionId || corePosition?.[0] || null;
22928
- if (positionIdFromCore && positionIdFromCore !== import_ethers14.ZeroHash && positionIdFromCore !== "0x0000000000000000000000000000000000000000000000000000000000000000") {
23264
+ if (positionIdFromCore && positionIdFromCore !== import_ethers15.ZeroHash && positionIdFromCore !== "0x0000000000000000000000000000000000000000000000000000000000000000") {
22929
23265
  if (this.config.debug) {
22930
23266
  log.info("Position exists in core contract", {
22931
23267
  positionId,
@@ -22993,7 +23329,7 @@ Message: ${causeMessage}${quantumContext}${mintDebtDiagnostics}`
22993
23329
  throw new Error("loanOperationsManager address not configured");
22994
23330
  }
22995
23331
  const runner = this.config.contractSigner || this.getProviderOrThrow();
22996
- const contract = new import_ethers14.Contract(
23332
+ const contract = new import_ethers15.Contract(
22997
23333
  addr.loanOperationsManager,
22998
23334
  [
22999
23335
  "function getProtocolConfig() external view returns (uint256 liquidationThreshold, uint256 minimumLoanValueUcd, uint256 minimumLoanValueWei, uint256 maxSingleLoanValueUcd)"
@@ -23006,7 +23342,7 @@ Message: ${causeMessage}${quantumContext}${mintDebtDiagnostics}`
23006
23342
  const maxUcdWhole = BigInt(result[3].toString());
23007
23343
  return {
23008
23344
  liquidationThreshold: result[0].toString(),
23009
- minimumLoanValueUcd: (0, import_ethers14.formatUnits)(result[2], 18),
23345
+ minimumLoanValueUcd: (0, import_ethers15.formatUnits)(result[2], 18),
23010
23346
  minimumLoanValueWei: result[2].toString(),
23011
23347
  maxSingleLoanValueUcd: maxUcdWhole.toString(),
23012
23348
  maxSingleLoanValueWei: (maxUcdWhole * 10n ** 18n).toString()
@@ -23024,8 +23360,8 @@ Message: ${causeMessage}${quantumContext}${mintDebtDiagnostics}`
23024
23360
  const MIN_REVEAL_DELAY = 60;
23025
23361
  const MAX_RANDOM_DELAY = 240;
23026
23362
  const entropyInput = positionId + quantumTimestamp.toString();
23027
- const hash = (0, import_ethers14.keccak256)(
23028
- (0, import_ethers14.toUtf8Bytes)(entropyInput)
23363
+ const hash = (0, import_ethers15.keccak256)(
23364
+ (0, import_ethers15.toUtf8Bytes)(entropyInput)
23029
23365
  );
23030
23366
  const randomValue = BigInt(hash);
23031
23367
  const randomDelay = Number(randomValue % BigInt(MAX_RANDOM_DELAY));
@@ -23050,12 +23386,12 @@ Message: ${causeMessage}${quantumContext}${mintDebtDiagnostics}`
23050
23386
  const rawPositionId = /^0x/i.test(params.positionId.trim()) ? params.positionId.trim().slice(2) : params.positionId.trim();
23051
23387
  const canonicalPositionId = "0x" + rawPositionId.padStart(64, "0").toLowerCase();
23052
23388
  const intentTimestamp = Math.floor(Date.now() / 1e3);
23053
- const intentActionHash = (0, import_ethers14.keccak256)((0, import_ethers14.toUtf8Bytes)("liquidate-position"));
23054
- const intentHash = (0, import_ethers14.solidityPackedKeccak256)(
23389
+ const intentActionHash = (0, import_ethers15.keccak256)((0, import_ethers15.toUtf8Bytes)("liquidate-position"));
23390
+ const intentHash = (0, import_ethers15.solidityPackedKeccak256)(
23055
23391
  ["bytes32", "uint256", "uint256", "address", "bytes32"],
23056
23392
  [canonicalPositionId, intentTimestamp, chainId, intentSigner, intentActionHash]
23057
23393
  );
23058
- const intentSignature = await signer.signMessage((0, import_ethers14.getBytes)(intentHash));
23394
+ const intentSignature = await signer.signMessage((0, import_ethers15.getBytes)(intentHash));
23059
23395
  const response = await fetch(endpoint, {
23060
23396
  method: "POST",
23061
23397
  headers: { "Content-Type": "application/json" },
@@ -23107,7 +23443,7 @@ Message: ${causeMessage}${quantumContext}${mintDebtDiagnostics}`
23107
23443
  const vrfSeedRaw = await lmResult.value["vrfSeeds"](positionId);
23108
23444
  const vrfSeed = BigInt(vrfSeedRaw.toString());
23109
23445
  if (vrfSeed !== 0n) {
23110
- const finalEntropy = (0, import_ethers14.solidityPackedKeccak256)(
23446
+ const finalEntropy = (0, import_ethers15.solidityPackedKeccak256)(
23111
23447
  ["uint256", "uint256", "bytes32"],
23112
23448
  [vrfSeed, BigInt(quantumTimestamp.toString()), positionId]
23113
23449
  );
@@ -23385,14 +23721,14 @@ var EventHelpers = {
23385
23721
  };
23386
23722
 
23387
23723
  // src/utils/position-delegate.utils.ts
23388
- var import_ethers15 = require("ethers");
23724
+ var import_ethers16 = require("ethers");
23389
23725
  var POSITION_DELEGATE_REGISTRY_ABI = [
23390
23726
  "function positionDelegate(bytes32 positionId) view returns (address)",
23391
23727
  "function setPositionDelegate(bytes32 positionId, address newDelegate) external",
23392
23728
  "event PositionDelegateUpdated(bytes32 indexed positionId, address indexed oldDelegate, address indexed newDelegate)"
23393
23729
  ];
23394
23730
  async function setPositionDelegate(positionId, delegate, signer, registryAddress) {
23395
- const registry = new import_ethers15.Contract(
23731
+ const registry = new import_ethers16.Contract(
23396
23732
  registryAddress,
23397
23733
  POSITION_DELEGATE_REGISTRY_ABI,
23398
23734
  signer
@@ -23400,7 +23736,7 @@ async function setPositionDelegate(positionId, delegate, signer, registryAddress
23400
23736
  return registry["setPositionDelegate"](positionId, delegate);
23401
23737
  }
23402
23738
  async function getPositionDelegate(positionId, provider, registryAddress) {
23403
- const registry = new import_ethers15.Contract(
23739
+ const registry = new import_ethers16.Contract(
23404
23740
  registryAddress,
23405
23741
  POSITION_DELEGATE_REGISTRY_ABI,
23406
23742
  provider
@@ -23429,6 +23765,7 @@ async function getPositionDelegate(positionId, provider, registryAddress) {
23429
23765
  PKPManager,
23430
23766
  PaymentType,
23431
23767
  PositionStatus,
23768
+ RECOVERY_INVALIDATE_ACTION,
23432
23769
  SDKError,
23433
23770
  SDK_DEFAULTS,
23434
23771
  SEPOLIA_CONTRACTS,
@@ -23441,6 +23778,8 @@ async function getPositionDelegate(positionId, provider, registryAddress) {
23441
23778
  assertProtocolNotPaused,
23442
23779
  assertSafeServiceEndpoint,
23443
23780
  buildBtcExecuteEnvelope,
23781
+ buildInvalidateMessageHash,
23782
+ buildInvalidateStaleSpendEnvelope,
23444
23783
  collectFailures,
23445
23784
  collectSuccesses,
23446
23785
  combine,