@gvnrdao/dh-sdk 0.0.307 → 0.0.309

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) {
@@ -6491,7 +6507,7 @@ async function generateExtendAuthorization(positionId, newTerm, chainId, signerO
6491
6507
  var import_ethers4 = require("ethers");
6492
6508
  function buildLoginDomain(chainId) {
6493
6509
  return {
6494
- name: "Diamond Hands lit-ops-server",
6510
+ name: "Diamond Hands",
6495
6511
  version: "1",
6496
6512
  chainId
6497
6513
  };
@@ -6606,6 +6622,8 @@ function createDefaultSessionStore() {
6606
6622
 
6607
6623
  // src/utils/server-session.ts
6608
6624
  var REFRESH_LEEWAY_SECONDS = 30;
6625
+ var LOGIN_RETRY_BASE_MS = 3e4;
6626
+ var LOGIN_RETRY_MAX_MS = 5 * 6e4;
6609
6627
  var ServerLoginError = class extends Error {
6610
6628
  constructor(message, status) {
6611
6629
  super(message);
@@ -6626,6 +6644,11 @@ var ServerSession = class {
6626
6644
  fetchImpl;
6627
6645
  cached = null;
6628
6646
  inFlight = null;
6647
+ /**
6648
+ * Set when a prompted login failed; suppresses further prompts until `until`.
6649
+ * `error` is replayed to callers so they still see the real failure reason.
6650
+ */
6651
+ promptBackoff = null;
6629
6652
  /**
6630
6653
  * Bumped by `clearPersisted()` (logout / disconnect). An in-flight
6631
6654
  * `getOrRefresh()` captures this at start and refuses to write its freshly
@@ -6700,6 +6723,7 @@ var ServerSession = class {
6700
6723
  this.generation += 1;
6701
6724
  this.cached = null;
6702
6725
  this.inFlight = null;
6726
+ this.promptBackoff = null;
6703
6727
  if (!this.store)
6704
6728
  return;
6705
6729
  try {
@@ -6796,19 +6820,39 @@ var ServerSession = class {
6796
6820
  this.inFlight = (async () => {
6797
6821
  try {
6798
6822
  const existing = await this.tryResolveSilently(gen);
6799
- if (existing)
6823
+ if (existing) {
6824
+ this.promptBackoff = null;
6800
6825
  return existing;
6826
+ }
6827
+ if (this.promptBackoff && this.now() * 1e3 < this.promptBackoff.until) {
6828
+ throw this.promptBackoff.error;
6829
+ }
6801
6830
  this.onSignaturePrompt?.();
6802
- const payload = await buildSignedLoginPayload(
6803
- this.signer,
6804
- this.chainId,
6805
- this.serviceEndpoint
6806
- );
6807
- const session = await this.login(payload);
6808
- if (notCleared()) {
6809
- this.persist(payload, session);
6810
- this.cached = session;
6831
+ let session;
6832
+ try {
6833
+ const payload = await buildSignedLoginPayload(
6834
+ this.signer,
6835
+ this.chainId,
6836
+ this.serviceEndpoint
6837
+ );
6838
+ session = await this.login(payload);
6839
+ if (notCleared()) {
6840
+ this.persist(payload, session);
6841
+ this.cached = session;
6842
+ }
6843
+ } catch (error) {
6844
+ const failures = (this.promptBackoff?.failures ?? 0) + 1;
6845
+ this.promptBackoff = {
6846
+ failures,
6847
+ error,
6848
+ until: this.now() * 1e3 + Math.min(
6849
+ LOGIN_RETRY_BASE_MS * 2 ** (failures - 1),
6850
+ LOGIN_RETRY_MAX_MS
6851
+ )
6852
+ };
6853
+ throw error;
6811
6854
  }
6855
+ this.promptBackoff = null;
6812
6856
  return session;
6813
6857
  } finally {
6814
6858
  if (notCleared())
@@ -7146,10 +7190,81 @@ async function reconcileAuthorizedSpend(spend, esploraBaseUrl, httpGetJson = def
7146
7190
  };
7147
7191
  }
7148
7192
 
7149
- // src/utils/btc-withdrawal-message.ts
7193
+ // src/utils/stale-spend-invalidate-message.ts
7150
7194
  var import_ethers6 = require("ethers");
7195
+ var RECOVERY_INVALIDATE_ACTION = "btc-utxo-invalidator";
7151
7196
  var QUANTUM_SECONDS = 60;
7152
7197
  var QUANTUM_SAFE_THRESHOLD = 40;
7198
+ function buildInvalidateMessageHash(params) {
7199
+ const positionIdBytes32 = (0, import_ethers6.zeroPadValue)(
7200
+ params.positionId.startsWith("0x") ? params.positionId : `0x${params.positionId}`,
7201
+ 32
7202
+ );
7203
+ const actionHash = (0, import_ethers6.keccak256)((0, import_ethers6.toUtf8Bytes)(RECOVERY_INVALIDATE_ACTION));
7204
+ return (0, import_ethers6.solidityPackedKeccak256)(
7205
+ [
7206
+ "bytes32",
7207
+ // positionId
7208
+ "uint256",
7209
+ // timestamp
7210
+ "uint256",
7211
+ // chainId
7212
+ "string",
7213
+ // utxoTxid (display order)
7214
+ "uint32",
7215
+ // utxoVout
7216
+ "bytes32"
7217
+ // actionHash
7218
+ ],
7219
+ [
7220
+ positionIdBytes32,
7221
+ params.timestamp,
7222
+ params.chainId,
7223
+ params.utxoTxid,
7224
+ params.utxoVout,
7225
+ actionHash
7226
+ ]
7227
+ );
7228
+ }
7229
+ async function buildInvalidateStaleSpendEnvelope(params) {
7230
+ const { positionId, utxoTxid, utxoVout, chainId, signer } = params;
7231
+ const nowSec = Date.now() / 1e3;
7232
+ const currentQuantumStart = Math.floor(nowSec / QUANTUM_SECONDS) * QUANTUM_SECONDS;
7233
+ const secsIntoQuantum = nowSec - currentQuantumStart;
7234
+ let timestamp;
7235
+ if (secsIntoQuantum > QUANTUM_SAFE_THRESHOLD) {
7236
+ const nextQuantumStart = currentQuantumStart + QUANTUM_SECONDS;
7237
+ const waitMs = Math.max(0, (nextQuantumStart - nowSec) * 1e3 + 500);
7238
+ await new Promise((r) => setTimeout(r, waitMs));
7239
+ timestamp = nextQuantumStart;
7240
+ } else {
7241
+ timestamp = currentQuantumStart;
7242
+ }
7243
+ const messageHash = buildInvalidateMessageHash({
7244
+ positionId,
7245
+ timestamp,
7246
+ chainId,
7247
+ utxoTxid,
7248
+ utxoVout
7249
+ });
7250
+ const signature = await signer.signMessage((0, import_ethers6.getBytes)(messageHash));
7251
+ const borrowerAddress = await signer.getAddress();
7252
+ return {
7253
+ positionId,
7254
+ utxoTxid,
7255
+ utxoVout,
7256
+ timestamp,
7257
+ chainId,
7258
+ action: RECOVERY_INVALIDATE_ACTION,
7259
+ signature,
7260
+ borrowerAddress
7261
+ };
7262
+ }
7263
+
7264
+ // src/utils/btc-withdrawal-message.ts
7265
+ var import_ethers7 = require("ethers");
7266
+ var QUANTUM_SECONDS2 = 60;
7267
+ var QUANTUM_SAFE_THRESHOLD2 = 40;
7153
7268
  function hashBtcInputSet(utxos) {
7154
7269
  if (!Array.isArray(utxos) || utxos.length === 0) {
7155
7270
  throw new Error("hashBtcInputSet: at least one input is required");
@@ -7178,7 +7293,7 @@ function hashBtcInputSet(utxos) {
7178
7293
  seen.add(key);
7179
7294
  }
7180
7295
  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));
7296
+ return (0, import_ethers7.keccak256)((0, import_ethers7.toUtf8Bytes)(canonical));
7182
7297
  }
7183
7298
  async function buildBtcExecuteEnvelope(params) {
7184
7299
  const {
@@ -7212,26 +7327,26 @@ async function buildBtcExecuteEnvelope(params) {
7212
7327
  }
7213
7328
  const utxosHash = hashBtcInputSet(utxos);
7214
7329
  const nowSec = Date.now() / 1e3;
7215
- const currentQuantumStart = Math.floor(nowSec / QUANTUM_SECONDS) * QUANTUM_SECONDS;
7330
+ const currentQuantumStart = Math.floor(nowSec / QUANTUM_SECONDS2) * QUANTUM_SECONDS2;
7216
7331
  const secsIntoQuantum = nowSec - currentQuantumStart;
7217
7332
  let timestamp;
7218
- if (secsIntoQuantum > QUANTUM_SAFE_THRESHOLD) {
7219
- const nextQuantumStart = currentQuantumStart + QUANTUM_SECONDS;
7333
+ if (secsIntoQuantum > QUANTUM_SAFE_THRESHOLD2) {
7334
+ const nextQuantumStart = currentQuantumStart + QUANTUM_SECONDS2;
7220
7335
  const waitMs = Math.max(0, (nextQuantumStart - nowSec) * 1e3 + 500);
7221
7336
  await new Promise((r) => setTimeout(r, waitMs));
7222
7337
  timestamp = nextQuantumStart;
7223
7338
  } else {
7224
7339
  timestamp = currentQuantumStart;
7225
7340
  }
7226
- const actionHash = (0, import_ethers6.keccak256)(
7227
- (0, import_ethers6.toUtf8Bytes)("execute-btc-withdrawal")
7341
+ const actionHash = (0, import_ethers7.keccak256)(
7342
+ (0, import_ethers7.toUtf8Bytes)("execute-btc-withdrawal")
7228
7343
  );
7229
7344
  const utxoIdentifier = `${txid}:${vout}`;
7230
- const positionIdBytes32 = (0, import_ethers6.zeroPadValue)(
7345
+ const positionIdBytes32 = (0, import_ethers7.zeroPadValue)(
7231
7346
  positionId.startsWith("0x") ? positionId : `0x${positionId}`,
7232
7347
  32
7233
7348
  );
7234
- const messageHash = (0, import_ethers6.solidityPackedKeccak256)(
7349
+ const messageHash = (0, import_ethers7.solidityPackedKeccak256)(
7235
7350
  [
7236
7351
  "bytes32",
7237
7352
  // positionId
@@ -7264,7 +7379,7 @@ async function buildBtcExecuteEnvelope(params) {
7264
7379
  actionHash
7265
7380
  ]
7266
7381
  );
7267
- const userSignature = await signer.signMessage((0, import_ethers6.getBytes)(messageHash));
7382
+ const userSignature = await signer.signMessage((0, import_ethers7.getBytes)(messageHash));
7268
7383
  const borrowerAddress = await signer.getAddress();
7269
7384
  return {
7270
7385
  positionId,
@@ -7328,7 +7443,7 @@ function maybeTemperSignature(signature, shouldTemper, operationName) {
7328
7443
  }
7329
7444
 
7330
7445
  // src/utils/address-conversion.utils.ts
7331
- var import_ethers7 = require("ethers");
7446
+ var import_ethers8 = require("ethers");
7332
7447
 
7333
7448
  // src/utils/chunks/bitcoin-utils.ts
7334
7449
  var import_sha256 = require("@noble/hashes/sha256");
@@ -7612,7 +7727,7 @@ function normalizeBitcoinAddress(address) {
7612
7727
  }
7613
7728
 
7614
7729
  // src/protocol/protocol-pause.ts
7615
- var import_ethers8 = require("ethers");
7730
+ var import_ethers9 = require("ethers");
7616
7731
  var GET_PROTOCOL_PAUSE_STATUS_ABI = [
7617
7732
  "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
7733
  ];
@@ -7634,7 +7749,7 @@ function rowToStatus(row) {
7634
7749
  return row;
7635
7750
  }
7636
7751
  async function fetchProtocolPauseStatus(provider, positionManagerAddress) {
7637
- const iface = new import_ethers8.Interface(GET_PROTOCOL_PAUSE_STATUS_ABI);
7752
+ const iface = new import_ethers9.Interface(GET_PROTOCOL_PAUSE_STATUS_ABI);
7638
7753
  const data = iface.encodeFunctionData("getProtocolPauseStatus", []);
7639
7754
  const raw = await provider.call({ to: positionManagerAddress, data });
7640
7755
  const decoded = iface.decodeFunctionResult("getProtocolPauseStatus", raw);
@@ -7767,7 +7882,7 @@ function extractOptionalLitSignature(raw) {
7767
7882
  }
7768
7883
 
7769
7884
  // src/modules/contract/contract-manager.module.ts
7770
- var import_ethers9 = require("ethers");
7885
+ var import_ethers10 = require("ethers");
7771
7886
  init_deployment_addresses();
7772
7887
  var POSITION_MANAGER_ABI = [
7773
7888
  "function createPosition(bytes32 pkpId, bytes calldata validatorSignature, string mainnetVaultAddress, string regtestVaultAddress, uint256 selectedTermMonths, uint256 validatorVersion, bytes calldata pkpPublicKey) external returns (bytes32 positionId)",
@@ -7844,43 +7959,43 @@ var ContractManager = class {
7844
7959
  }
7845
7960
  const contractRunner = runner;
7846
7961
  const contracts = {
7847
- positionManager: new import_ethers9.Contract(
7962
+ positionManager: new import_ethers10.Contract(
7848
7963
  contractAddresses.positionManager,
7849
7964
  POSITION_MANAGER_ABI,
7850
7965
  contractRunner
7851
7966
  ),
7852
- loanOperationsManager: new import_ethers9.Contract(
7853
- contractAddresses.loanOperationsManager || import_ethers9.ZeroAddress,
7967
+ loanOperationsManager: new import_ethers10.Contract(
7968
+ contractAddresses.loanOperationsManager || import_ethers10.ZeroAddress,
7854
7969
  LOAN_OPS_ABI,
7855
7970
  contractRunner
7856
7971
  ),
7857
- ucdController: new import_ethers9.Contract(
7972
+ ucdController: new import_ethers10.Contract(
7858
7973
  contractAddresses.ucdToken,
7859
7974
  UCD_CONTROLLER_ABI,
7860
7975
  contractRunner
7861
7976
  ),
7862
- priceFeed: new import_ethers9.Contract(
7863
- contractAddresses.priceFeedConsumer || import_ethers9.ZeroAddress,
7977
+ priceFeed: new import_ethers10.Contract(
7978
+ contractAddresses.priceFeedConsumer || import_ethers10.ZeroAddress,
7864
7979
  PRICE_FEED_ABI,
7865
7980
  contractRunner
7866
7981
  ),
7867
- termManager: new import_ethers9.Contract(
7868
- contractAddresses.termManager || import_ethers9.ZeroAddress,
7982
+ termManager: new import_ethers10.Contract(
7983
+ contractAddresses.termManager || import_ethers10.ZeroAddress,
7869
7984
  TERM_MANAGER_ABI,
7870
7985
  contractRunner
7871
7986
  ),
7872
- circuitBreaker: new import_ethers9.Contract(
7873
- contractAddresses.circuitBreaker || import_ethers9.ZeroAddress,
7987
+ circuitBreaker: new import_ethers10.Contract(
7988
+ contractAddresses.circuitBreaker || import_ethers10.ZeroAddress,
7874
7989
  CIRCUIT_BREAKER_ABI,
7875
7990
  contractRunner
7876
7991
  ),
7877
- liquidationManager: new import_ethers9.Contract(
7878
- contractAddresses.liquidationManager || import_ethers9.ZeroAddress,
7992
+ liquidationManager: new import_ethers10.Contract(
7993
+ contractAddresses.liquidationManager || import_ethers10.ZeroAddress,
7879
7994
  LIQUIDATION_MANAGER_ABI,
7880
7995
  contractRunner
7881
7996
  ),
7882
- bitcoinWithdrawalAddressRegistry: new import_ethers9.Contract(
7883
- contractAddresses.bitcoinWithdrawalAddressRegistry || import_ethers9.ZeroAddress,
7997
+ bitcoinWithdrawalAddressRegistry: new import_ethers10.Contract(
7998
+ contractAddresses.bitcoinWithdrawalAddressRegistry || import_ethers10.ZeroAddress,
7884
7999
  BITCOIN_WITHDRAWAL_ADDRESS_REGISTRY_ABI,
7885
8000
  contractRunner
7886
8001
  )
@@ -7930,13 +8045,13 @@ var ContractManager = class {
7930
8045
  const address = addresses[key];
7931
8046
  if (!address) {
7932
8047
  missing.push(String(key));
7933
- } else if (!(0, import_ethers9.isAddress)(address)) {
8048
+ } else if (!(0, import_ethers10.isAddress)(address)) {
7934
8049
  invalid.push(String(key));
7935
8050
  }
7936
8051
  }
7937
8052
  for (const key of optionalAddresses) {
7938
8053
  const address = addresses[key];
7939
- if (address && !(0, import_ethers9.isAddress)(address)) {
8054
+ if (address && !(0, import_ethers10.isAddress)(address)) {
7940
8055
  invalid.push(String(key));
7941
8056
  }
7942
8057
  }
@@ -8912,7 +9027,7 @@ function createPKPManager(config) {
8912
9027
  }
8913
9028
 
8914
9029
  // src/modules/loan/loan-creator.module.ts
8915
- var import_ethers10 = require("ethers");
9030
+ var import_ethers11 = require("ethers");
8916
9031
  var import_dh_lit_actions = __toESM(require_pkg_src());
8917
9032
  var LoanCreator = class {
8918
9033
  config;
@@ -9242,11 +9357,11 @@ var LoanCreator = class {
9242
9357
  try {
9243
9358
  const mainnetVaultAddress = bitcoinAddresses.mainnet;
9244
9359
  const regtestVaultAddress = bitcoinAddresses.regtest;
9245
- const pkpIdBytes32 = (0, import_ethers10.zeroPadValue)(
9246
- (0, import_ethers10.toBeHex)(BigInt(pkpData.tokenId)),
9360
+ const pkpIdBytes32 = (0, import_ethers11.zeroPadValue)(
9361
+ (0, import_ethers11.toBeHex)(BigInt(pkpData.tokenId)),
9247
9362
  32
9248
9363
  );
9249
- const pkpPublicKeyUncompressed = import_ethers10.SigningKey.computePublicKey(
9364
+ const pkpPublicKeyUncompressed = import_ethers11.SigningKey.computePublicKey(
9250
9365
  pkpData.publicKey,
9251
9366
  false
9252
9367
  );
@@ -9259,7 +9374,7 @@ var LoanCreator = class {
9259
9374
  );
9260
9375
  log.debug(`BigInt conversion: ${BigInt(pkpData.tokenId).toString()}`);
9261
9376
  log.debug(
9262
- `Hex from BigInt: ${(0, import_ethers10.toBeHex)(BigInt(pkpData.tokenId))}`
9377
+ `Hex from BigInt: ${(0, import_ethers11.toBeHex)(BigInt(pkpData.tokenId))}`
9263
9378
  );
9264
9379
  log.debug(`Final bytes32 (zero-padded): ${pkpIdBytes32}`);
9265
9380
  log.debug(
@@ -9423,8 +9538,8 @@ var LoanCreator = class {
9423
9538
  }
9424
9539
  }
9425
9540
  if (this.config.debug) {
9426
- const pkpIdBytes32Check = (0, import_ethers10.zeroPadValue)(
9427
- (0, import_ethers10.toBeHex)(BigInt(pkpData.tokenId)),
9541
+ const pkpIdBytes32Check = (0, import_ethers11.zeroPadValue)(
9542
+ (0, import_ethers11.toBeHex)(BigInt(pkpData.tokenId)),
9428
9543
  32
9429
9544
  );
9430
9545
  log.error("\u274C Loan creation transaction failed", {
@@ -9470,8 +9585,8 @@ var LoanCreator = class {
9470
9585
  const newEventAbi = [
9471
9586
  "event PositionCreated(bytes32 indexed positionId, bytes32 indexed pkpId, address indexed borrower, uint256 requestedCollateralRatio, uint256 selectedTerm, uint256 expiryAt)"
9472
9587
  ];
9473
- const oldIface = new import_ethers10.Interface(oldEventAbi);
9474
- const newIface = new import_ethers10.Interface(newEventAbi);
9588
+ const oldIface = new import_ethers11.Interface(oldEventAbi);
9589
+ const newIface = new import_ethers11.Interface(newEventAbi);
9475
9590
  let positionId;
9476
9591
  if (this.config.debug) {
9477
9592
  log.info("\u{1F50D} Parsing transaction receipt logs", {
@@ -9565,7 +9680,7 @@ var LoanStatus = /* @__PURE__ */ ((LoanStatus2) => {
9565
9680
  })(LoanStatus || {});
9566
9681
 
9567
9682
  // src/modules/loan/loan-query.module.ts
9568
- var import_ethers11 = require("ethers");
9683
+ var import_ethers12 = require("ethers");
9569
9684
  var POSITION_CORE_ABI = [
9570
9685
  "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
9686
  ];
@@ -9863,7 +9978,7 @@ var LoanQuery = class {
9863
9978
  const isChipotlePkpId2 = typeof rawId === "string" && rawId.length === 40 && !rawId.toLowerCase().startsWith("04");
9864
9979
  if (isChipotlePkpId2) {
9865
9980
  if (this.config.positionManagerCoreAddress && this.config.provider) {
9866
- const pmContract = new import_ethers11.Contract(
9981
+ const pmContract = new import_ethers12.Contract(
9867
9982
  this.config.positionManagerCoreAddress,
9868
9983
  POSITION_CORE_ABI,
9869
9984
  this.config.provider
@@ -10186,7 +10301,7 @@ function createLoanQuery(config) {
10186
10301
  }
10187
10302
 
10188
10303
  // src/modules/withdrawal-address/withdrawal-address.module.ts
10189
- var import_ethers12 = require("ethers");
10304
+ var import_ethers13 = require("ethers");
10190
10305
  var WithdrawalAddressModule = class {
10191
10306
  config;
10192
10307
  graphClient;
@@ -10203,7 +10318,7 @@ var WithdrawalAddressModule = class {
10203
10318
  if (!res.success)
10204
10319
  return res;
10205
10320
  const target = res.value.target;
10206
- if (!target || target === import_ethers12.ZeroAddress) {
10321
+ if (!target || target === import_ethers13.ZeroAddress) {
10207
10322
  return failure(
10208
10323
  new SDKError({
10209
10324
  code: "SDK_WITHDRAWAL_REGISTRY_NOT_CONFIGURED",
@@ -10221,7 +10336,7 @@ var WithdrawalAddressModule = class {
10221
10336
  }
10222
10337
  /** keccak256 of the canonicalized address — matches the on-chain key. */
10223
10338
  static addressHash(btcAddress) {
10224
- return (0, import_ethers12.keccak256)((0, import_ethers12.toUtf8Bytes)(normalizeBitcoinAddress(btcAddress)));
10339
+ return (0, import_ethers13.keccak256)((0, import_ethers13.toUtf8Bytes)(normalizeBitcoinAddress(btcAddress)));
10225
10340
  }
10226
10341
  /**
10227
10342
  * Add a Bitcoin address to the caller's allowlist. It becomes usable only
@@ -13267,7 +13382,7 @@ var DiamondHandsGraph = class {
13267
13382
  };
13268
13383
 
13269
13384
  // src/contracts/typechain-contracts/factories/src/psm/SimplePSMV2__factory.ts
13270
- var import_ethers13 = require("ethers");
13385
+ var import_ethers14 = require("ethers");
13271
13386
  var _abi = [
13272
13387
  {
13273
13388
  inputs: [],
@@ -15835,7 +15950,7 @@ var _abi = [
15835
15950
  ];
15836
15951
  var _bytecode = "0x60a080604052346100ea57306080527ff0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a005460ff8160401c166100d9576002600160401b03196001600160401b03821601610073575b60405161485a90816100f0823960805181818161278e01526128870152f35b6001600160401b0319166001600160401b039081177ff0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a005581527fc7f505b2f371ae2175ee4913f4499e1f2633a7b5936321eed1cdaeb6115181d290602090a13880610054565b63f92ee8a960e01b60005260046000fd5b600080fdfe6080604052600436101561001257600080fd5b6000803560e01c8062f7fce91461384657806301ffc9a7146137d5578063021d28931461377c5780630871b20614613743578063114249d214610f6157806311d954f81461371a57806313da3166146136e15780631d44a904146136385780631f77bf65146135ff578063248a9ca3146135e05780632b83cccd146131205780632f2ff15d146130ee57806334bac370146130b557806334e181251461307c57806336568abe14613037578063373c86b614612ffe5780633f4ba83a14612f375780634373b57214612f0e5780634451e89b14612b3a5780634ebd25a514612b015780634f1ef2861461280c5780635273b6f6146127e357806352d1902d1461277b578063568fafca146126ed57806359d5d02a146124205780635bc26aea146123eb5780635c975abb146123bb5780635ecc27081461229d5780638456cb59146121a257806385c15d9a1461216957806389d3ad00146120a25780638bff608e146120695780639010d07c1461201657806390ad8b4014611ffa57806391d1485414611fa15780639b759bf714611f5e5780639baf58d214611f415780639f1d0f59146118a8578063a217fddf1461188c578063a3246ad3146117cf578063ad3cb1cc14611788578063b492fc691461168e578063b9f637af14611463578063bf7d911914611424578063c4c5f62414611371578063c55f15ea1461134e578063ca15c87314611317578063ca2ce65d146112de578063cc1f8ffa146112ac578063cf46075e146111a2578063d21a74ff14611165578063d2f8253614611142578063d547741f14611107578063d5d3f78b14610f9a578063d66bd52414610f61578063e1f1c4a714610f44578063e1f3962c14610f18578063ec2f96fe14610ef4578063eda5a26a14610af7578063f1a1eb8414610ab4578063f385116d14610a7b578063f77c479114610a54578063f8c8765e14610661578063faaebd2114610628578063facdfb5e14610488578063fc99bd9a14610377578063fe32e7281461033e5763ffa1ad741461030857600080fd5b3461033b578060031936011261033b57610337610323613a68565b604051918291602083526020830190613a17565b0390f35b80fd5b503461033b57602036600319011261033b576020906040906001600160a01b0361036661392e565b168152601283522054604051908152f35b503461033b57604036600319011261033b5761039161392e565b6010546024359291906001600160a01b03163303610479576001600160a01b03168082526002602052604082205490929060ff16156104665780156104575782825260076020526040822054926103e88285613cb0565b848110610448576001600160ff1b0381116104395760008051602061482e833981519152604085968493846104369852600760205280838a205582519182526020820152a23090339061421c565b80f35b630700fcb360e11b8452600484fd5b63446c8cc960e01b8452600484fd5b63162908e360e11b8252600482fd5b506024916374ed46ad60e01b8252600452fd5b6349db3bd360e01b8252600482fd5b503461033b57602036600319011261033b576104a261392e565b6104aa613f12565b6010546001600160a01b03163303610479576001600160a01b03168082526002602052604082205460ff161561061657808252600760205260408220546040516370a0823160e01b8152306004820152602081602481865afa90811561060b5784916105d4575b50818111156105c5576105248282613b6c565b8215908115610570575b505060008051602061482e833981519152916040918486526007602052808387205582519182526020820152a260016000805160206147ce8339815191525580f35b61271081029080820461271014901517156105b157606484029184830460641417156105b157116105a257388061052e565b63a73af74d60e01b8452600484fd5b634e487b7160e01b86526011600452602486fd5b6105cf8183613b6c565b610524565b90506020813d602011610603575b816105ef602093836139c3565b810103126105fe575138610511565b600080fd5b3d91506105e2565b6040513d86823e3d90fd5b6374ed46ad60e01b8252600452602490fd5b503461033b57602036600319011261033b576020906040906001600160a01b0361065061392e565b168152600483522054604051908152f35b503461033b57608036600319011261033b5761067b61392e565b610683613944565b6044356001600160a01b03811690818103610a50576064356001600160a01b0381169390849003610a4c5760008051602061480e83398151915254604081901c60ff161595906001600160401b031680159081610a44575b6001149081610a3a575b159081610a31575b50610a225760008051602061480e83398151915280546001600160401b0319166001179055856109fd575b6001600160a01b03169081156109ee576001600160a01b03169081156109df5783156109d05761074661448a565b61074e61448a565b61075661448a565b61075e61448a565b60016000805160206147ce8339815191525561077861448a565b61078061448a565b86546001600160a01b0319908116919091178755600180549182168317905560405163313ce56760e01b8152909190602081600481855afa88918161099f575b506107d457633a24e95b60e11b8852600488fd5b6001600160a81b03199092161760a091821b60ff60a01b16176001819055901c60ff16601119810161098d575061080b8186614348565b80610965575b156109205761082e816000805160206147ee833981519152614348565b8061092f575b15610920576108519060008051602061470e833981519152614348565b90816108e9575b50156108da57806108af575b5061086c5780f35b60ff60401b1960008051602061480e833981519152541660008051602061480e833981519152556000805160206146ee833981519152602060405160018152a180f35b601080546001600160a01b031916821790558260008051602061474e8339815191528180a338610864565b63cf5a8e3360e01b8352600483fd5b6109199060008051602061470e83398151915286526000805160206146ae833981519152602052604086206144d0565b5038610858565b63cf5a8e3360e01b8552600485fd5b6000805160206147ee83398151915286526000805160206146ae83398151915260205261095f83604088206144d0565b50610834565b8580526000805160206146ae83398151915260205261098783604088206144d0565b50610811565b63167738cf60e21b8652600452602485fd5b6109c291925060203d6020116109c9575b6109ba81836139c3565b810190613ba9565b90386107c0565b503d6109b0565b630b5eba9f60e41b8752600487fd5b63c1ab6dc160e01b8752600487fd5b6336abb4df60e11b8752600487fd5b60008051602061480e833981519152805460ff60401b1916600160401b179055610718565b63f92ee8a960e01b8752600487fd5b905015386106ed565b303b1591506106e5565b8791506106db565b8580fd5b8480fd5b503461033b578060031936011261033b57546040516001600160a01b039091168152602090f35b503461033b57602036600319011261033b576020906040906001600160a01b03610aa361392e565b168152600a83522054604051908152f35b503461033b57604036600319011261033b576020906040906001600160a01b03610adc61392e565b16815260158352818120602435825283522054604051908152f35b503461033b5761016036600319011261033b57610b1261392e565b90606435604435602435610b24613a58565b9160a4359160c43560e43561010435916101243595610144359760018060a01b03601054163303610ee5576001600160a01b038c16808c52600260205260408c2054909a9060ff16610ed1578a15610ec2578615610eb3576127108811610e99576103e88111610e815760ff82169c60128e118e8115610e76575b50610e6257803b15610e4e578915610e3a578a15610e265782610bc191614260565b84151580610e1d575b610e065785151580610dfd575b610de6578b9c602460208d9e9d604051928380926370a0823160e01b82523060048301525afa9c8d15610dda579c610da6575b506001600160ff1b038c11610d97578a8d8f9760408f97838f918f8f8f8f90859f988f99879f9660008051602061476e8339815191529f978b9f988f8d6000805160206146ce8339815191529f988e8e610d4f9b60008051602061468e8339815191529f8f8f8487526002602052878720600160ff198254161790558487526003602052878720558386526004602052868620558285526006602052878686205582855260056020528585209060ff19825416179055818452600c6020528885852055818452600d6020528985852055818452600e6020528a85852055818452600f6020528b8585205581845260076020528484205582526012602052828220558d8152601360205220558a7f991d1ef1b5c0820d213328cba6682059e00a50e49c469a454eb3557e78eaf6668e80518b81528c6020820152a28c5198899889613cbd565b0390a28151908b82526020820152a28151908782526020820152a280610d73578280f35b604060008051602061482e833981519152918151908582526020820152a281808280f35b63556e7a8160e01b8e5260048efd5b909b506020813d602011610dd2575b81610dc2602093836139c3565b810103126105fe57519a38610c0a565b3d9150610db5565b604051903d90823e3d90fd5b60448c858863dd85772b60e01b8352600452602452fd5b50838610610bd7565b60448c8487637449915760e01b8352600452602452fd5b50828510610bca565b636835314760e11b8d52600160045260248dfd5b636835314760e11b8d5260048d905260248dfd5b63377e3f9960e21b8d5260048c905260248dfd5b63ca95039160e01b8d5260048e905260248dfd5b60069150108e610b9f565b631051834f60e11b8c526004526103e860245260448bfd5b63c1e9a14160e01b8c52600488905261271060245260448cfd5b63a2ec3a5560e01b8c5260048cfd5b63df407ac560e01b8c5260048cfd5b6317f4215b60e21b8c5260048b905260248cfd5b6349db3bd360e01b8b5260048bfd5b503461033b578060031936011261033b57602060ff60015460a01c16604051908152f35b503461033b57602036600319011261033b576020610f3c610f3761392e565b613df5565b604051908152f35b503461033b578060031936011261033b5760206040516127108152f35b503461033b57602036600319011261033b576020906040906001600160a01b03610f8961392e565b168152600783522054604051908152f35b503461033b57602036600319011261033b57610fb461392e565b6010546001600160a01b03163303610479576001600160a01b03168082526002602052604082205460ff16156106165780825260076020526040822054806110f1575080825260026020526040822060ff1981541690558082526003602052816040812055808252600460205281604081205580825260056020526040822060ff198154169055808252600c602052816040812055808252600d602052816040812055808252600e602052816040812055808252600f602052816040812055808252600660205281604081205580825260076020526040822054818352600760205282604081205560405190827f3302a1b37f04242bb55603f5449e7ecd690a35eef08ba1353c48c20e2aae9cda8580a2806110ce578380f35b8160409160008051602061482e8339815191529352846020820152a23880808380f35b604492916376bc059760e11b8352600452602452fd5b503461033b57604036600319011261033b5761113e600435611127613944565b9061113961113482613b79565b614088565b61411a565b5080f35b503461033b578060031936011261033b57602060ff600854166040519015158152f35b503461033b57602036600319011261033b5760209060ff906040906001600160a01b0361119061392e565b16815260058452205416604051908152f35b503461033b57602036600319011261033b576111bc61392e565b6111c4613f12565b6010546001600160a01b03163303610479576001600160a01b03168082526002602052604082205460ff161561061657808252600760205260408220546040516370a0823160e01b8152306004820152602081602481865afa90811561060b57849161126c575b5060008051602061482e833981519152916040918486526007602052808387205582519182526020820152a260016000805160206147ce8339815191525580f35b90506020813d6020116112a4575b81611287602093836139c3565b810103126105fe575160008051602061482e83398151915261122b565b3d915061127a565b503461033b57604036600319011261033b5760206112d46112cb61392e565b60243590613cf6565b6040519015158152f35b503461033b57602036600319011261033b576020906040906001600160a01b0361130661392e565b168152601383522054604051908152f35b503461033b57602036600319011261033b57604060209160043581526000805160206146ae83398151915283522054604051908152f35b503461033b578060031936011261033b576020604051670de0b6b3a76400008152f35b503461033b57604036600319011261033b5761138b61392e565b6010546024359291906001600160a01b03163303610479576001600160a01b031680825260076020526040822054929081841061140d578060008051602061482e8339815191526040866113e3866104369899613b6c565b84895260076020528289205583885260076020528188205482519182526020820152a2339061404c565b5091604492633cb8e07360e01b8352600452602452fd5b503461033b57602036600319011261033b5760209060ff906040906001600160a01b0361144f61392e565b168152600284522054166040519015158152f35b503461033b5761012036600319011261033b5761147e61392e565b6064359190604435602435611491613a58565b601054610104359660e4359260c4359260a43592906001600160a01b0316330361167f576001600160a01b038816808a52600260205260408a205490989060ff161561166b57861561165c576127108811611642576103e882116116285760ff83169060128211801561161e575b61160a578361150d91614260565b85151580611601575b6115ea578a1515806115e1575b6115ca579260008051602061468e83398151915297969592828c956115c4979460408e8e80825260036020528c8383205580825260046020528d838320558152600660205220558b8d52600560205260408d209060ff198254161790558a8c52600c6020528260408d20558a8c52600d6020528360408d20558a8c52600e6020528460408d20558a8c52600f6020528560408d205560405198899889613cbd565b0390a280f35b60448a868d63dd85772b60e01b8352600452602452fd5b50848b10611523565b60448a8588637449915760e01b8352600452602452fd5b50838610611516565b63ca95039160e01b8b52600482905260248bfd5b50600682106114ff565b631051834f60e11b8a5260048290526103e860245260448afd5b63c1e9a14160e01b8a52600488905261271060245260448afd5b63a2ec3a5560e01b8a5260048afd5b6374ed46ad60e01b8a52600489905260248afd5b6349db3bd360e01b8952600489fd5b503461033b57604036600319011261033b576116a861392e565b6001600160a01b0316808252600260205260408220546024359060ff16156117745780156117655761271061172a604085670de0b6b3a76400006117196117329688859a52600560205260ff85852054169080916012811061173f575b505088845260036020528484205490613a8b565b049581526004602052205484613a8b565b048092613b6c565b9082519182526020820152f35b61175e925060ff61175261175892613ad4565b16613ae5565b90613a8b565b3880611705565b63162908e360e11b8352600483fd5b6374ed46ad60e01b83526004829052602483fd5b503461033b578060031936011261033b5761033760408051906117ab81836139c3565b60058252640352e302e360dc1b602083015251918291602083526020830190613a17565b503461033b57602036600319011261033b5760043581526000805160206146ae83398151915260205260408120604051908160208254918281520190819285526020852090855b818110611876575050508261182c9103836139c3565b604051928392602084019060208552518091526040840192915b818110611854575050500390f35b82516001600160a01b0316845285945060209384019390920191600101611846565b8254845260209093019260019283019201611816565b503461033b578060031936011261033b57602090604051908152f35b503461033b576118b736613969565b9190926118c2613f12565b6118ca613f4e565b338152600960205260408120544303611f1f57338152600a602052600360408220541015611f1057338152600a602052604081206119088154613b9a565b90555b6001600160a01b0382168082526002602052604082205490929060ff16611e6f575b828252600260205260ff60408320541615610466578415610457578315611e6057828252600c60205260408220548510611e3b57828252600e60205260408220548015611e2c57808611611e155750846119869161415e565b6040516370a0823160e01b8152306004820152602081602481865afa908115611e0a578291611dd8575b506119bd8530338661421c565b6040516370a0823160e01b8152306004820152602081602481875afa908115611cef57908692918491611d9f575b50906119f691613b6c565b10611d905781815260076020526040812054611a128582613cb0565b818110611d81576001600160ff1b038111611d72576040849260008051602061482e833981519152928486526007602052808387205582519182526020820152a2818152600560205260ff604082205416849060128110611d11575b50611a8f670de0b6b3a7640000918484526003602052604084205490613a8b565b04908281526004602052612710611aaa604083205484613a8b565b0491611ab68382613b6c565b94808610611cfa57506001546040516318160ddd60e01b815290602090829060049082906001600160a01b03165afa908115611cef578391611cbd575b5082546001600160a01b0316803b15611ca45783809160846040518094819363ae494fa160e01b83523360048401528c60248401528b60448401528d60648401525af1801561060b57908491611ca8575b505083611c34575b6001546040516318160ddd60e01b81529190602090839060049082906001600160a01b03165afa801561060b578490611c00575b611b8a9250613b6c565b90808203611bea575050507fb3e2773606abfd36b5bd91394b3a54d1398336c65005baf7bf7a05efeffaf75b611bcd602095604051918291339588429285613bdd565b0390a360016000805160206147ce83398151915255604051908152f35b632d8562a360e11b835260045260245260449150fd5b506020823d602011611c2c575b81611c1a602093836139c3565b810103126105fe57611b8a9151611b80565b3d9150611c0d565b82546001600160a01b0316803b15611ca45783809160846040518094819363ae494fa160e01b83523060048401528a60248401528b60448401528160648401525af1801561060b57908491611c8b575b5050611b4c565b81611c95916139c3565b611ca0578238611c84565b8280fd5b8380fd5b81611cb2916139c3565b611ca0578238611b44565b90506020813d602011611ce7575b81611cd8602093836139c3565b810103126105fe575138611af3565b3d9150611ccb565b6040513d85823e3d90fd5b6371c4efed60e01b83526004869052602452604482fd5b611d21915061175260ff91613ad4565b8015611d5e5780600019048511611d4f57611a8f611d48670de0b6b3a76400009287613a8b565b9150611a6e565b63035fc53d60e41b8252600482fd5b634e487b7160e01b82526012600452602482fd5b630700fcb360e11b8352600483fd5b63446c8cc960e01b8352600483fd5b639bfa3c1760e01b8152600490fd5b919250506020813d602011611dd0575b81611dbc602093836139c3565b810103126105fe57518591906119f66119eb565b3d9150611daf565b90506020813d602011611e02575b81611df3602093836139c3565b810103126105fe5751386119b0565b3d9150611de6565b6040513d84823e3d90fd5b631d7f2ac360e01b83526004869052602452604482fd5b633b5db2f360e11b8352600483fd5b50908152600c6020526040812054630d54e9e160e01b82526004849052602452604490fd5b632cd84af360e01b8252600482fd5b60405163313ce56760e01b815291939291602081600481865afa859181611eef575b50611ea55763105482c760e21b8552600485fd5b93919293838352600560205260ff806040852054169116908103611ec9575061192d565b90506044928252600560205260ff604083205416631e43476360e11b8352600452602452fd5b611f0991925060203d6020116109c9576109ba81836139c3565b9038611e91565b63a74c1c5f60e01b8152600490fd5b3381526009602052436040822055338152600a6020526001604082205561190b565b503461033b578060031936011261033b5760206040516103e88152f35b503461033b57604036600319011261033b576020906040906001600160a01b03611f8661392e565b16815260148352818120602435825283522054604051908152f35b503461033b57604036600319011261033b576040611fbd613944565b91600435815260008051602061478e833981519152602052209060018060a01b0316600052602052602060ff604060002054166040519015158152f35b503461033b578060031936011261033b57602060405160648152f35b503461033b57604036600319011261033b5761205060209160043581526000805160206146ae8339815191528352604060243591206144b8565b905460405160039290921b1c6001600160a01b03168152f35b503461033b57602036600319011261033b576020906040906001600160a01b0361209161392e565b168152600983522054604051908152f35b503461033b57604036600319011261033b576120bc61392e565b60105460243591906001600160a01b0316330361215a576001600160a01b031690811561214b57604060008051602061476e8339815191529183855260136020528185205490848652601360205280838720558486526015602052828620438752602052828620548587526019602052838720558486526017602052438387205582519182526020820152a280f35b63df407ac560e01b8352600483fd5b6349db3bd360e01b8352600483fd5b503461033b57602036600319011261033b576020906040906001600160a01b0361219161392e565b168152600383522054604051908152f35b503461033b578060031936011261033b5760008051602061470e833981519152815260008051602061478e83398151915260209081526040808320336000908152925290205460ff1615612278576121f8613f4e565b600160ff196000805160206147ae8339815191525416176000805160206147ae833981519152557f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a2586020604051338152a16040514281527f80170b5fcdd2bf1e0660ef4b8851f86685f64d41b1a19de1471947ece8725aac60203392a280f35b63e2517d3f60e01b81523360045260008051602061470e833981519152602452604490fd5b503461033b57602036600319011261033b576122b761392e565b60008051602061480e8339815191525460ff8160401c169081156123a3575b506123945760008051602061480e83398151915280546001600160481b0319166003600160401b0117905581805260008051602061478e83398151915260209081526040808420336000908152925290205460ff161561237c5761233990613c5e565b60ff60401b1960008051602061480e833981519152541660008051602061480e833981519152556000805160206146ee833981519152602060405160038152a180f35b63e2517d3f60e01b8252336004526024829052604482fd5b63f92ee8a960e01b8252600482fd5b60036001600160401b039190911610159050386122d6565b503461033b578060031936011261033b57602060ff6000805160206147ae83398151915254166040519015158152f35b503461033b57602036600319011261033b5761240561392e565b6010546001600160a01b031633036104795761043690613c5e565b503461033b57606036600319011261033b5761243a61392e565b612442613944565b60105490926044359290916001600160a01b0316330361047957612464613f4e565b6011546001600160a01b03169182156126de5760405163babcc53960e01b81526001600160a01b0386166004820181905293602090829060249082905afa908115611e0a57829161269f575b5015612690578215612681576001546001600160a01b03928316921682036125d1576040516370a0823160e01b8152306004820152602081602481865afa908115611e0a57829161259f575b50935b841561259057600019810361258a5750835b841561257b5780851161256357505061252d836020958361404c565b7f0bf519e4b3821615dbdd874fa1a5fbb4bb651b4e6beabedd4ac318e770233b2c604080518581524287820152a3604051908152f35b630555ed4f60e31b8252600485905260245260449150fd5b632e11316f60e11b8252600482fd5b93612511565b63f09872eb60e01b8252600482fd5b90506020813d6020116125c9575b816125ba602093836139c3565b810103126105fe5751386124fc565b3d91506125ad565b8181526002602052604081205460ff161561266f576040516370a0823160e01b8152306004820152602081602481865afa908115611e0a57829161263d575b5082825260076020526040822054808211156126355761262f91613b6c565b936124ff565b50508061262f565b90506020813d602011612667575b81612658602093836139c3565b810103126105fe575138612610565b3d915061264b565b60249163eef7849760e01b8252600452fd5b634e46966960e11b8152600490fd5b63133307bb60e21b8152600490fd5b90506020813d6020116126d6575b816126ba602093836139c3565b810103126126d2575180151581036126d257386124b0565b5080fd5b3d91506126ad565b630e048e7160e41b8152600490fd5b503461033b57602036600319011261033b5761270761392e565b6010546001600160a01b03163303610479576001600160a01b0316801561276c57601180546001600160a01b0319811683179091556001600160a01b03167f1e9c406f2707909cfd9f61e744f73bcab77e5997d063276f67883c5257d51cf08380a380f35b634e46966960e11b8252600482fd5b503461033b578060031936011261033b577f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031630036127d457602060405160008051602061472e8339815191528152f35b63703e46dd60e11b8152600490fd5b503461033b578060031936011261033b576010546040516001600160a01b039091168152602090f35b50604036600319011261033b5761282161392e565b602435906001600160401b038211611ca05736602383011215611ca0578160040135908361284e836139fc565b9361285c60405195866139c3565b83855260208501933660248284010111611ca057806024602093018637850101526001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016308114908115612ade575b50612acf576010546001600160a01b03163303612ac0576001600160a01b038116928315612ab157813b15612aa25760008051602061472e83398151915254846128fa613a68565b7f6ea8b34d59b2818d3f37a08dddaa06f5886b9c20c907b36f03ca6528e106e86f61293060405192604084526040840190613a17565b4260208401526001600160a01b038516929081900390a36040516352d1902d60e01b8152602081600481895afa879181612a6a575b5061297e57634c9c8ce360e01b87526004869052602487fd5b908160008051602061472e83398151915288979303612a585750833b15612a44576001600160a01b031916811760008051602061472e833981519152558491907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b8380a2805115612a295761113e9382915190845af43d15612a21573d91612a05836139fc565b92612a1360405194856139c3565b83523d85602085013e61460c565b60609161460c565b5050505034612a355780f35b63b398979f60e01b8152600490fd5b634c9c8ce360e01b86526004829052602486fd5b632a87526960e21b8752600452602486fd5b9091506020813d602011612a9a575b81612a86602093836139c3565b81010312612a9657519038612965565b8780fd5b3d9150612a79565b636f7c43f160e01b8552600485fd5b63e6c4247b60e01b8552600485fd5b6349db3bd360e01b8452600484fd5b63703e46dd60e11b8452600484fd5b60008051602061472e833981519152546001600160a01b031614159050386128b2565b503461033b57602036600319011261033b576020906040906001600160a01b03612b2961392e565b168152600e83522054604051908152f35b503461033b57606036600319011261033b57612b5461395a565b6024356001600160401b038111611ca057612b73903690600401613993565b916044356001600160401b038111610a5057612b93903690600401613993565b60008051602061480e8339815191529291925460ff8160401c16908115612ef6575b50612ee75760008051602061480e83398151915280546001600160481b0319166002600160401b011790556000805160206147ee833981519152865260008051602061478e83398151915260209081526040808820336000908152925290205460ff1615612ec257612c2561448a565b612c2d61448a565b60016000805160206147ce83398151915255600b549160ff8316612eb357818603612ea457612c5b86613bf9565b92612c6960405194856139c3565b868452601f19612c7888613bf9565b01366020860137875b878110612daf575060019060ff191617600b5515159460ff196008541660ff871617600855865b818110612d0c578760008051602061466e833981519152602089604051908152a160ff60401b1960008051602061480e833981519152541660008051602061480e833981519152556000805160206146ee833981519152602060405160028152a180f35b808860008051602061482e8339815191526040612d34612d2f600196888d613c10565b613c36565b612d3f85898c613c10565b357f8f955fa878b4aae8b1ac37b1ab715307470f2822ceff87e23d33ef1e044814a783612d6c888d613c4a565b5193898060a01b0316968793848252600660205280838320558482526007602052858383205582519182526020820152a28151908d82526020820152a201612ca8565b612dbd612d2f828a8a613c10565b612dc8828689613c10565b6001600160a01b03909116808b52600260205260408b20549091359060ff1615612e90576103e88111612e785750906020602492604051938480926370a0823160e01b82523060048301525afa8015612e6d578a90612e37575b60019250612e308288613c4a565b5201612c81565b509060203d8111612e66575b612e4d81836139c3565b6020826000928101031261033b57509060019151612e22565b503d612e43565b6040513d8c823e3d90fd5b631051834f60e11b8b526004526103e860245260448afd5b6351104c5960e01b8b52600482905260248bfd5b63512509d360e11b8752600487fd5b6324d0d1fd60e01b8752600487fd5b63e2517d3f60e01b8652336004526000805160206147ee833981519152602452604486fd5b63f92ee8a960e01b8652600486fd5b60026001600160401b03919091161015905038612bb5565b503461033b578060031936011261033b576011546040516001600160a01b039091168152602090f35b503461033b578060031936011261033b576010546001600160a01b03163303612fef576000805160206147ae8339815191525460ff811615612fe05760ff19166000805160206147ae833981519152557f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa6020604051338152a16040514281527f107553d8191d85b405879cf752997865edd48d94e20bda4dd27223c94b31a7cc60203392a280f35b638dfc202b60e01b8252600482fd5b6349db3bd360e01b8152600490fd5b503461033b57602036600319011261033b576020906040906001600160a01b0361302661392e565b168152601683522054604051908152f35b503461033b57604036600319011261033b57613051613944565b336001600160a01b0382160361306d5761113e9060043561411a565b63334bd91960e11b8252600482fd5b503461033b57602036600319011261033b576020906040906001600160a01b036130a461392e565b168152600c83522054604051908152f35b503461033b57602036600319011261033b576020906040906001600160a01b036130dd61392e565b168152601783522054604051908152f35b503461033b57604036600319011261033b5761113e60043561310e613944565b9061311b61113482613b79565b6140d2565b503461033b5761312f36613969565b91909261313a613f12565b613142613f4e565b3381526009602052604081205443036135be57338152600a602052600360408220541015611f1057338152600a602052604081206131808154613b9a565b90555b6001600160a01b0382168082526002602052604082205490929060ff16613543575b828252600260205260ff604083205416156104665760ff6008541615613534578415610457578315611e6057828252600d602052604082205480861061351d5750828252600f6020526040822054801561350e578086116134f857508461320b91613f78565b670de0b6b3a76400008402848104670de0b6b3a7640000036134e4578282526003602052604082205461323d91613ab4565b90828152600560205260ff604082205416601281106134c4575b50828152600660205261327c612710613274604084205485613a8b565b048093613b6c565b938085106134ac575082815260076020528360408220541061348857828152600760205260408120548481106134795760008051602061482e8339815191526040826132c9888895613b6c565b8486526007602052808387205582519182526020820152a26001546040516318160ddd60e01b815290602090829060049082906001600160a01b03165afa908115611e0a578291613447575b5081546001600160a01b0316803b15611ca057826040518092633a52b90760e11b82528183816133498d3360048401613bc2565b03925af18015611cef57613432575b506001546040516318160ddd60e01b81529190602090839060049082906001600160a01b03165afa908115611cef5783916133fc575b6133989250613b6c565b8581036133e45750507f8caf04742286d017f9ac3924388e188c73e6e5094311c5e59a61a7ef86dda8bf611bcd6020956133d386338761404c565b604051918291339588429285613bdd565b635ab6e2db60e01b8252600486905260245260449150fd5b90506020823d60201161342a575b81613417602093836139c3565b810103126105fe5761339891519061338e565b3d915061340a565b9161344081600493946139c3565b9190613358565b90506020813d602011613471575b81613462602093836139c3565b810103126126d2575138613315565b3d9150613455565b6308aed4ef60e31b8252600482fd5b82815260076020526040812054635960d22160e01b82526004526024849052604490fd5b6371c4efed60e01b8252600485905260245260449150fd5b916134d760ff6117526134dd9495613ad4565b90613ab4565b9038613257565b634e487b7160e01b82526011600452602482fd5b625502a360e91b83526004869052602452604482fd5b636c6ff70d60e11b8352600483fd5b6361767b8560e01b83526004869052602452604482fd5b630df65d9f60e01b8252600482fd5b60405163313ce56760e01b815291939291602081600481865afa85918161359d575b506135795763105482c760e21b8552600485fd5b93919293838352600560205260ff806040852054169116908103611ec957506131a5565b6135b791925060203d6020116109c9576109ba81836139c3565b9038613565565b3381526009602052436040822055338152600a60205260016040822055613183565b503461033b57602036600319011261033b576020610f3c600435613b79565b503461033b57602036600319011261033b576020906040906001600160a01b0361362761392e565b168152600f83522054604051908152f35b503461033b57604036600319011261033b5761365261392e565b60105460243591906001600160a01b0316330361215a576001600160a01b031690811561214b5760406000805160206146ce8339815191529183855260126020528185205490848652601260205280838720558486526014602052828620438752602052828620548587526018602052838720558486526016602052438387205582519182526020820152a280f35b503461033b57602036600319011261033b576020906040906001600160a01b0361370961392e565b168152600683522054604051908152f35b503461033b578060031936011261033b576001546040516001600160a01b039091168152602090f35b503461033b57602036600319011261033b576020906040906001600160a01b0361376b61392e565b168152600d83522054604051908152f35b503461033b57602036600319011261033b5761379661395a565b6010546001600160a01b0316330361047957602060008051602061466e83398151915291151560ff196008541660ff821617600855604051908152a180f35b503461033b57602036600319011261033b5760043563ffffffff60e01b81168091036126d257602090635a05180f60e01b811490811561381b575b506040519015158152f35b637965db0b60e01b811491508115613835575b5082613810565b6301ffc9a760e01b1490508261382e565b503461033b57604036600319011261033b5761386061392e565b6001600160a01b0316808252600260205260408220546024359060ff161561177457670de0b6b3a7640000810290808204670de0b6b3a7640000149015171561391a57916138bc60409383835260036020528483205490613ab4565b91808252600560205260ff8483205416601281106138f1575b5061172a84836127109361173295526006602052205484613a8b565b846117329361390f61271094966134d760ff61175261172a97613ad4565b9593509350506138d5565b634e487b7160e01b83526011600452602483fd5b600435906001600160a01b03821682036105fe57565b602435906001600160a01b03821682036105fe57565b6004359081151582036105fe57565b60609060031901126105fe576004356001600160a01b03811681036105fe57906024359060443590565b9181601f840112156105fe578235916001600160401b0383116105fe576020808501948460051b0101116105fe57565b601f909101601f19168101906001600160401b038211908210176139e657604052565b634e487b7160e01b600052604160045260246000fd5b6001600160401b0381116139e657601f01601f191660200190565b919082519283825260005b848110613a43575050826000602080949584010152601f8019910116010190565b80602080928401015182828601015201613a22565b6084359060ff821682036105fe57565b60405190613a776040836139c3565b6005825264322e332e3360d81b6020830152565b81810292918115918404141715613a9e57565b634e487b7160e01b600052601160045260246000fd5b8115613abe570490565b634e487b7160e01b600052601260045260246000fd5b60ff166012039060ff8211613a9e57565b8015613b665760009060208110600116604e821060011617613b5e57600a916001915b60018111613b35575082600019048211613b2157500290565b634e487b7160e01b81526011600452602490fd5b92806000190481116134e45760018416613b55575b80029260011c613b08565b80920291613b4a565b9050600a0a90565b50600190565b91908203918211613a9e57565b60005260008051602061478e83398151915260205260016040600020015490565b6000198114613a9e5760010190565b908160209103126105fe575160ff811681036105fe5790565b6001600160a01b039091168152602081019190915260400190565b9094939260609260808301968352602083015260408201520152565b6001600160401b0381116139e65760051b60200190565b9190811015613c205760051b0190565b634e487b7160e01b600052603260045260246000fd5b356001600160a01b03811681036105fe5790565b8051821015613c205760209160051b010190565b6001600160a01b03168015613c9f57601080546001600160a01b0319811683179091556001600160a01b031660008051602061474e833981519152600080a3565b63e6c4247b60e01b60005260046000fd5b91908201809211613a9e57565b94919360e0969360ff929a99989561010088019b885260208801526040870152166060850152608084015260a083015260c08201520152565b6001600160a01b03811660008181526002602052604090205490919060ff16158015613de8575b8015613de0575b613dce5781600052600f6020526040600020548015908115613dd6575b50613dce57613d66926040918251948592839262f7fce960e01b845260048401613bc2565b0381305afa918215613dc257600092613d8e575b506000526007602052604060002054101590565b9091506040813d604011613dba575b81613daa604093836139c3565b810103126105fe57519038613d7a565b3d9150613d9d565b6040513d6000823e3d90fd5b505050600090565b9050831138613d41565b508215613d24565b5060ff6008541615613d1d565b6001546001600160a01b0391821691168103613e6a576020602491604051928380926370a0823160e01b82523060048301525afa908115613dc257600091613e3b575090565b90506020813d602011613e62575b81613e56602093836139c3565b810103126105fe575190565b3d9150613e49565b80600052600260205260ff60406000205416613e865750600090565b6040516370a0823160e01b815230600482015290602082602481845afa918215613dc257600092613ede575b506000526007602052604060002054808211600014613ed757613ed491613b6c565b90565b5050600090565b90916020823d602011613f0a575b81613ef9602093836139c3565b8101031261033b5750519038613eb2565b3d9150613eec565b60026000805160206147ce8339815191525414613f3d5760026000805160206147ce83398151915255565b633ee5aeb560e01b60005260046000fd5b60ff6000805160206147ae8339815191525416613f6757565b63d93c066560e01b60005260046000fd5b6001600160a01b0316600081815260136020526040902054801561404757816000526015602052604060002043600052602052613fbb6040600020549384613cb0565b92831061403657808260005260176020524360406000205414614018575b8311613ffc57506000526015602052604060002043600052602052604060002055565b925063029359d560e41b60005260045260245260445260646000fd5b5081600052601960205261403160406000205482613cb0565b613fd9565b63446c8cc960e01b60005260046000fd5b505050565b614081614086939261407360405194859263a9059cbb60e01b602085015260248401613bc2565b03601f1981018452836139c3565b6142ed565b565b600081815260008051602061478e8339815191526020908152604080832033845290915290205460ff16156140ba5750565b63e2517d3f60e01b6000523360045260245260446000fd5b6140dc8282614348565b91826140e757505090565b60009182526000805160206146ae8339815191526020526040909120614116916001600160a01b0316906144d0565b5090565b61412482826143ea565b918261412f57505090565b60009182526000805160206146ae8339815191526020526040909120614116916001600160a01b031690614539565b6001600160a01b03166000818152601260205260409020548015614047578160005260146020526040600020436000526020526141a16040600020549384613cb0565b928310614036578082600052601660205243604060002054146141fe575b83116141e257506000526014602052604060002043600052602052604060002055565b92506319a4e2a760e01b60005260045260245260445260646000fd5b5081600052601860205261421760406000205482613cb0565b6141bf565b6040516323b872dd60e01b60208201526001600160a01b039283166024820152929091166044830152606480830193909352918152614086916140816084836139c3565b60405163313ce56760e01b81529190602090839060049082906001600160a01b03165afa600092816142cc575b506142a357631eecbb6560e01b60005260046000fd5b60ff91821691168082036142b5575050565b631e43476360e11b60005260045260245260446000fd5b6142e691935060203d6020116109c9576109ba81836139c3565b913861428d565b906000602091828151910182855af115613dc2576000513d61433f57506001600160a01b0381163b155b61431e5750565b635274afe760e01b60009081526001600160a01b0391909116600452602490fd5b60011415614317565b600081815260008051602061478e833981519152602090815260408083206001600160a01b038616845290915290205460ff16613ed757600081815260008051602061478e833981519152602090815260408083206001600160a01b0395909516808452949091528120805460ff19166001179055339291907f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d9080a4600190565b600081815260008051602061478e833981519152602090815260408083206001600160a01b038616845290915290205460ff1615613ed757600081815260008051602061478e833981519152602090815260408083206001600160a01b0395909516808452949091528120805460ff19169055339291907ff6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b9080a4600190565b60ff60008051602061480e8339815191525460401c16156144a757565b631afcd79f60e31b60005260046000fd5b8054821015613c205760005260206000200190600090565b6001810190826000528160205260406000205415600014613dce578054600160401b8110156139e65761452461450d8260018794018555846144b8565b819391549060031b91821b91600019901b19161790565b90555491600052602052604060002055600190565b9060018201918160005282602052604060002054801515600014614603576000198101818111613a9e578254600019810191908211613a9e578181036145cc575b505050805480156145b657600019019061459482826144b8565b8154906000199060031b1b191690555560005260205260006040812055600190565b634e487b7160e01b600052603160045260246000fd5b6145ec6145dc61450d93866144b8565b90549060031b1c928392866144b8565b90556000528360205260406000205538808061457a565b50505050600090565b90614632575080511561462157602081519101fd5b63d6bda27560e01b60005260046000fd5b81511580614664575b614643575090565b639996b31560e01b60009081526001600160a01b0391909116600452602490fd5b50803b1561463b56fe2c0a5f5ab0ba371221bb3612c2d2f90d36566279309f526000c5b354efd1b0658c67aaac7f77de07240e5a9b36dfdccb2a89c438635abbb27a73142d2aa0f629c1f6fe24621ce81ec5827caf0253cadb74709b061630e6b55e8237170593200048b07fab687f450848f1df8a96db08fef7840f53415f18fdc2ec8e9f810f0930c7f505b2f371ae2175ee4913f4499e1f2633a7b5936321eed1cdaeb6115181d275027301df982f5215b4963a854cf9c73219df80cb6acd8f098189c9480c7bbc360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc17dc5b1290f7495d7f8cc68476e6941aaf510598fa925d0d2720edc8805a846c4460507c21097c15f6883572ebd157a9ee4b1d989a312314e93afd9d2ecd494002dd7bc7dec4dceedda775e58dd541e08a116c6c53815c0bd028192f7b626800cd5ed15c6e187e77e9aee88184c21f4f2182ab5827cb3b7e07fbedcd63f033009b779b17422d0df92223018b32b4d1fa46e071723d6817e2486d003becc55f00a49807205ce4d355092ef5a8a18f56e8913cf4a201fbe287825b095693c21775f0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a006d129bd71f2401cbe77f49f546d7d5f58992faecfca6e51ba06b50b261e83331a164736f6c6343000822000a";
15837
15952
  var isSuperArgs = (xs) => xs.length > 1;
15838
- var SimplePSMV2__factory = class extends import_ethers13.ContractFactory {
15953
+ var SimplePSMV2__factory = class extends import_ethers14.ContractFactory {
15839
15954
  constructor(...args) {
15840
15955
  if (isSuperArgs(args)) {
15841
15956
  super(...args);
@@ -15855,10 +15970,10 @@ var SimplePSMV2__factory = class extends import_ethers13.ContractFactory {
15855
15970
  static bytecode = _bytecode;
15856
15971
  static abi = _abi;
15857
15972
  static createInterface() {
15858
- return new import_ethers13.Interface(_abi);
15973
+ return new import_ethers14.Interface(_abi);
15859
15974
  }
15860
15975
  static connect(address, runner) {
15861
- return new import_ethers13.Contract(address, _abi, runner);
15976
+ return new import_ethers14.Contract(address, _abi, runner);
15862
15977
  }
15863
15978
  };
15864
15979
 
@@ -16446,7 +16561,7 @@ var DiamondHandsSDK = class _DiamondHandsSDK {
16446
16561
  */
16447
16562
  constructor(config) {
16448
16563
  if (!config.provider && config.ethRpcUrl) {
16449
- config.provider = new import_ethers14.JsonRpcProvider(config.ethRpcUrl);
16564
+ config.provider = new import_ethers15.JsonRpcProvider(config.ethRpcUrl);
16450
16565
  }
16451
16566
  this.config = config;
16452
16567
  if (config.debug) {
@@ -16719,7 +16834,7 @@ var DiamondHandsSDK = class _DiamondHandsSDK {
16719
16834
  const network = await config.provider.getNetwork();
16720
16835
  chainId = Number(network.chainId);
16721
16836
  } else if (config.ethRpcUrl) {
16722
- const tempProvider = new import_ethers14.JsonRpcProvider(
16837
+ const tempProvider = new import_ethers15.JsonRpcProvider(
16723
16838
  config.ethRpcUrl
16724
16839
  );
16725
16840
  const network = await tempProvider.getNetwork();
@@ -17255,7 +17370,7 @@ var DiamondHandsSDK = class _DiamondHandsSDK {
17255
17370
  }
17256
17371
  const loanOps = this.loanOps();
17257
17372
  const protocolConfig = await loanOps.getProtocolConfig();
17258
- const requestAmountWei = (0, import_ethers14.parseEther)(
17373
+ const requestAmountWei = (0, import_ethers15.parseEther)(
17259
17374
  request.amount.toString()
17260
17375
  );
17261
17376
  const minLoanValueWei = BigInt(protocolConfig.minimumLoanValueWei);
@@ -17337,7 +17452,7 @@ var DiamondHandsSDK = class _DiamondHandsSDK {
17337
17452
  pkpNftAddress,
17338
17453
  this.getChipotlePublicKeyFallback()
17339
17454
  );
17340
- pkpEthAddress = (0, import_ethers14.computeAddress)(pkpPublicKey);
17455
+ pkpEthAddress = (0, import_ethers15.computeAddress)(pkpPublicKey);
17341
17456
  pkpCache.set(request.positionId, {
17342
17457
  publicKey: pkpPublicKey,
17343
17458
  ethAddress: pkpEthAddress,
@@ -17666,8 +17781,8 @@ var DiamondHandsSDK = class _DiamondHandsSDK {
17666
17781
  throw new Error(`Position not found: ${request.positionId}`);
17667
17782
  }
17668
17783
  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(
17784
+ const ucdDebtHash = (0, import_ethers15.keccak256)(import_ethers15.AbiCoder.defaultAbiCoder().encode(["uint256"], [currentDebt]));
17785
+ const contractHash = (0, import_ethers15.keccak256)(import_ethers15.AbiCoder.defaultAbiCoder().encode(
17671
17786
  ["address", "address", "address", "address"],
17672
17787
  [
17673
17788
  positionManagerAddress,
@@ -17736,7 +17851,7 @@ var DiamondHandsSDK = class _DiamondHandsSDK {
17736
17851
  const coreAbi = [
17737
17852
  "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
17853
  ];
17739
- const positionCore = new import_ethers14.Contract(
17854
+ const positionCore = new import_ethers15.Contract(
17740
17855
  coreAddress,
17741
17856
  coreAbi,
17742
17857
  this.getSignerOrThrow().provider
@@ -17744,8 +17859,8 @@ var DiamondHandsSDK = class _DiamondHandsSDK {
17744
17859
  const currentPosition = await positionCore["getPositionDetails"](
17745
17860
  positionIdBytes32
17746
17861
  );
17747
- const currentDebtHash = (0, import_ethers14.keccak256)(
17748
- import_ethers14.AbiCoder.defaultAbiCoder().encode(
17862
+ const currentDebtHash = (0, import_ethers15.keccak256)(
17863
+ import_ethers15.AbiCoder.defaultAbiCoder().encode(
17749
17864
  ["uint256"],
17750
17865
  [currentPosition.ucdDebt]
17751
17866
  )
@@ -17792,7 +17907,7 @@ var DiamondHandsSDK = class _DiamondHandsSDK {
17792
17907
  "function getCurrentQuantum() view returns (uint256)",
17793
17908
  "function isQuantumValid(bytes32,uint256) view returns (bool)"
17794
17909
  ];
17795
- const registry = new import_ethers14.Contract(
17910
+ const registry = new import_ethers15.Contract(
17796
17911
  registryAddress,
17797
17912
  registryAbi,
17798
17913
  this.getSignerOrThrow().provider
@@ -17908,7 +18023,7 @@ var DiamondHandsSDK = class _DiamondHandsSDK {
17908
18023
  });
17909
18024
  }
17910
18025
  const signatureHexMint = finalSignature.startsWith("0x") ? finalSignature : "0x" + finalSignature;
17911
- const mintIface = new import_ethers14.Interface(positionManagerAbi);
18026
+ const mintIface = new import_ethers15.Interface(positionManagerAbi);
17912
18027
  const mintCalldata = mintIface.encodeFunctionData("mintUCD", [
17913
18028
  positionIdBytes32,
17914
18029
  validationResponse.mintAmount,
@@ -17944,7 +18059,7 @@ var DiamondHandsSDK = class _DiamondHandsSDK {
17944
18059
  if (viewsAddress) {
17945
18060
  let diagnosis = null;
17946
18061
  try {
17947
- const views = new import_ethers14.Contract(
18062
+ const views = new import_ethers15.Contract(
17948
18063
  viewsAddress,
17949
18064
  [
17950
18065
  "function diagnoseMintUCD(bytes32,uint256,uint256,uint256,uint256,uint256,bytes32,bytes32,bytes32,uint256,bytes) view returns (string)"
@@ -18054,7 +18169,7 @@ Message: ${causeMessage}${quantumContext}${mintDebtDiagnostics}`
18054
18169
  if (receipt.logs && receipt.logs.length > 0) {
18055
18170
  for (const receiptLog of receipt.logs) {
18056
18171
  if (receiptLog.topics && receiptLog.topics[0] === "0x08c379a0") {
18057
- const iface = new import_ethers14.Interface([
18172
+ const iface = new import_ethers15.Interface([
18058
18173
  "error Error(string)"
18059
18174
  ]);
18060
18175
  const decoded = iface.decodeErrorResult("Error", receiptLog.data);
@@ -18071,7 +18186,7 @@ Message: ${causeMessage}${quantumContext}${mintDebtDiagnostics}`
18071
18186
  const minimalAbi = [
18072
18187
  "event UCDMintedWithAuthorization(bytes32 indexed positionId, address indexed borrower, uint256 mintAmount, uint256 mintFee, uint256 newDebt, uint256 newCollateral, uint256 btcPrice, uint256 quantumTimestamp, bytes32 authorizedSpendsHash)"
18073
18188
  ];
18074
- const iface = new import_ethers14.Interface(minimalAbi);
18189
+ const iface = new import_ethers15.Interface(minimalAbi);
18075
18190
  for (const receiptLog of receipt.logs) {
18076
18191
  const parsed = (() => {
18077
18192
  const logIface = iface;
@@ -18258,7 +18373,7 @@ Message: ${causeMessage}${quantumContext}${mintDebtDiagnostics}`
18258
18373
  pkpNftAddress,
18259
18374
  this.getChipotlePublicKeyFallback()
18260
18375
  );
18261
- const pkpEthAddress = (0, import_ethers14.computeAddress)(pkpPublicKey);
18376
+ const pkpEthAddress = (0, import_ethers15.computeAddress)(pkpPublicKey);
18262
18377
  pkpData = {
18263
18378
  publicKey: pkpPublicKey,
18264
18379
  ethAddress: pkpEthAddress,
@@ -18660,7 +18775,7 @@ Message: ${causeMessage}${quantumContext}${mintDebtDiagnostics}`
18660
18775
  }
18661
18776
  const loanOpsForUcd = loanOpsForUcdResult.value;
18662
18777
  const ucdTokenAddress = await loanOpsForUcd.ucdToken();
18663
- const ucdToken = new import_ethers14.Contract(
18778
+ const ucdToken = new import_ethers15.Contract(
18664
18779
  ucdTokenAddress,
18665
18780
  [
18666
18781
  "function balanceOf(address) view returns (uint256)",
@@ -18676,9 +18791,9 @@ Message: ${causeMessage}${quantumContext}${mintDebtDiagnostics}`
18676
18791
  if (ucdBalance < debtWei) {
18677
18792
  return {
18678
18793
  success: false,
18679
- error: `Insufficient UCD balance for liquidation: ${(0, import_ethers14.formatEther)(
18794
+ error: `Insufficient UCD balance for liquidation: ${(0, import_ethers15.formatEther)(
18680
18795
  ucdBalance
18681
- )} UCD (need ${(0, import_ethers14.formatEther)(debtWei)} UCD)`,
18796
+ )} UCD (need ${(0, import_ethers15.formatEther)(debtWei)} UCD)`,
18682
18797
  positionId: request.positionId,
18683
18798
  wasLiquidated: false
18684
18799
  };
@@ -18687,7 +18802,7 @@ Message: ${causeMessage}${quantumContext}${mintDebtDiagnostics}`
18687
18802
  if (request.skipUcdApproval) {
18688
18803
  return {
18689
18804
  success: false,
18690
- error: `Insufficient UCD allowance for UCDController: need at least ${(0, import_ethers14.formatEther)(
18805
+ error: `Insufficient UCD allowance for UCDController: need at least ${(0, import_ethers15.formatEther)(
18691
18806
  debtWei
18692
18807
  )} UCD, or omit skipUcdApproval to let the SDK submit approve`,
18693
18808
  positionId: request.positionId,
@@ -19194,7 +19309,7 @@ Message: ${causeMessage}${quantumContext}${mintDebtDiagnostics}`
19194
19309
  if (typeof signatureBytes === "string" && signatureBytes.startsWith("{")) {
19195
19310
  try {
19196
19311
  const parsed = JSON.parse(signatureBytes);
19197
- signatureBytes = parsed.signature ?? (parsed.r && parsed.s && parsed.v ? import_ethers14.Signature.from({
19312
+ signatureBytes = parsed.signature ?? (parsed.r && parsed.s && parsed.v ? import_ethers15.Signature.from({
19198
19313
  r: parsed.r,
19199
19314
  s: parsed.s,
19200
19315
  v: parsed.v
@@ -19205,7 +19320,7 @@ Message: ${causeMessage}${quantumContext}${mintDebtDiagnostics}`
19205
19320
  if (!signatureBytes.startsWith("0x")) {
19206
19321
  signatureBytes = "0x" + signatureBytes;
19207
19322
  }
19208
- const extendIface = new import_ethers14.Interface([
19323
+ const extendIface = new import_ethers15.Interface([
19209
19324
  "function extendPosition(bytes32 positionId, uint256 selectedTerm, uint256 quantumTimestamp, uint256 btcPrice, uint256 availableBTCBalance, uint256 proRataRenewalFee, bytes calldata extensionValidatorSignature) external returns (bool)"
19210
19325
  ]);
19211
19326
  const extendCalldata = extendIface.encodeFunctionData("extendPosition", [
@@ -19755,7 +19870,7 @@ Message: ${causeMessage}${quantumContext}${mintDebtDiagnostics}`
19755
19870
  ` Converting payment amount: ${request.paymentAmount} (type: ${typeof request.paymentAmount})`
19756
19871
  );
19757
19872
  }
19758
- const paymentAmountWei = (0, import_ethers14.parseEther)(
19873
+ const paymentAmountWei = (0, import_ethers15.parseEther)(
19759
19874
  request.paymentAmount.toString()
19760
19875
  );
19761
19876
  if (this.config.debug) {
@@ -19817,7 +19932,7 @@ Message: ${causeMessage}${quantumContext}${mintDebtDiagnostics}`
19817
19932
  };
19818
19933
  }
19819
19934
  const ucdTokenAddress = await loanOps.ucdToken();
19820
- const ucdToken = new import_ethers14.Contract(
19935
+ const ucdToken = new import_ethers15.Contract(
19821
19936
  ucdTokenAddress,
19822
19937
  [
19823
19938
  "function balanceOf(address) view returns (uint256)",
@@ -19832,16 +19947,16 @@ Message: ${causeMessage}${quantumContext}${mintDebtDiagnostics}`
19832
19947
  ucdToken["allowance"](signerAddress, positionManagerAddress)
19833
19948
  ]);
19834
19949
  if (this.config.debug) {
19835
- log.info(` UCD Balance: ${(0, import_ethers14.formatEther)(balance)} UCD`);
19950
+ log.info(` UCD Balance: ${(0, import_ethers15.formatEther)(balance)} UCD`);
19836
19951
  log.info(
19837
- ` UCD Allowance: ${(0, import_ethers14.formatEther)(allowance)} UCD`
19952
+ ` UCD Allowance: ${(0, import_ethers15.formatEther)(allowance)} UCD`
19838
19953
  );
19839
19954
  log.info(` Required: ${request.paymentAmount} UCD`);
19840
19955
  }
19841
19956
  if (balance < paymentAmountWei) {
19842
19957
  return {
19843
19958
  success: false,
19844
- error: `Insufficient UCD balance: ${(0, import_ethers14.formatEther)(
19959
+ error: `Insufficient UCD balance: ${(0, import_ethers15.formatEther)(
19845
19960
  balance
19846
19961
  )} UCD (need ${request.paymentAmount} UCD)`
19847
19962
  };
@@ -20110,7 +20225,7 @@ Message: ${causeMessage}${quantumContext}${mintDebtDiagnostics}`
20110
20225
  const paymentSigner = this.getSignerOrThrow();
20111
20226
  const paymentFrom = await paymentSigner.getAddress();
20112
20227
  const paymentProvider = contractManager.getProvider();
20113
- const paymentIface = new import_ethers14.Interface([
20228
+ const paymentIface = new import_ethers15.Interface([
20114
20229
  "function makePayment(bytes32 positionId, uint256 paymentAmount, uint256 quantumTimestamp, uint256 btcPrice, bytes calldata paymentValidatorSignature) external returns (bool)"
20115
20230
  ]);
20116
20231
  const paymentCalldata = paymentIface.encodeFunctionData("makePayment", [
@@ -20427,7 +20542,7 @@ Message: ${causeMessage}${quantumContext}${mintDebtDiagnostics}`
20427
20542
  const pkpId = position.pkpId;
20428
20543
  if (litValidatorAddr && pkpId) {
20429
20544
  try {
20430
- const litValidator = new import_ethers14.Contract(
20545
+ const litValidator = new import_ethers15.Contract(
20431
20546
  litValidatorAddr,
20432
20547
  ["function pkpOwners(bytes32) view returns (address)"],
20433
20548
  this.getProviderOrThrow()
@@ -20435,7 +20550,7 @@ Message: ${causeMessage}${quantumContext}${mintDebtDiagnostics}`
20435
20550
  const owner = await litValidator.pkpOwners(
20436
20551
  pkpId
20437
20552
  );
20438
- if (owner && owner !== import_ethers14.ZeroAddress) {
20553
+ if (owner && owner !== import_ethers15.ZeroAddress) {
20439
20554
  controller = owner;
20440
20555
  }
20441
20556
  } catch {
@@ -20487,7 +20602,7 @@ Message: ${causeMessage}${quantumContext}${mintDebtDiagnostics}`
20487
20602
  pkpNftAddress,
20488
20603
  this.getChipotlePublicKeyFallback()
20489
20604
  );
20490
- pkpEthAddress = (0, import_ethers14.computeAddress)(pkpPublicKey);
20605
+ pkpEthAddress = (0, import_ethers15.computeAddress)(pkpPublicKey);
20491
20606
  pkpCache.set(positionId, {
20492
20607
  publicKey: pkpPublicKey,
20493
20608
  ethAddress: pkpEthAddress,
@@ -20850,7 +20965,7 @@ Message: ${causeMessage}${quantumContext}${mintDebtDiagnostics}`
20850
20965
  utxoVout: withdrawalParams.utxoVout
20851
20966
  });
20852
20967
  }
20853
- const withdrawIface = new import_ethers14.Interface([
20968
+ const withdrawIface = new import_ethers15.Interface([
20854
20969
  "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
20970
  ]);
20856
20971
  const withdrawCalldata = withdrawIface.encodeFunctionData("withdrawBTC", [
@@ -21042,7 +21157,7 @@ Message: ${causeMessage}${quantumContext}${mintDebtDiagnostics}`
21042
21157
  }
21043
21158
  const pkpId = positionDetails.pkpId;
21044
21159
  const vaultAddress = positionDetails.vaultAddress;
21045
- if (!pkpId || pkpId === import_ethers14.ZeroHash) {
21160
+ if (!pkpId || pkpId === import_ethers15.ZeroHash) {
21046
21161
  return { success: false, error: "Position has no PKP" };
21047
21162
  }
21048
21163
  if (!vaultAddress) {
@@ -21062,7 +21177,7 @@ Message: ${causeMessage}${quantumContext}${mintDebtDiagnostics}`
21062
21177
  if (!publicKey) {
21063
21178
  return { success: false, error: "Failed to resolve PKP public key" };
21064
21179
  }
21065
- const chipotlePkpAddress = (0, import_ethers14.computeAddress)(publicKey);
21180
+ const chipotlePkpAddress = (0, import_ethers15.computeAddress)(publicKey);
21066
21181
  const STANDALONE_CHAIN_NAMES = {
21067
21182
  1: "ethereum",
21068
21183
  11155111: "sepolia",
@@ -21412,7 +21527,7 @@ Message: ${causeMessage}${quantumContext}${mintDebtDiagnostics}`
21412
21527
  const btcSpendAuthorizerAbi = [
21413
21528
  "function getAuthorizedSpends(bytes32) view returns (tuple(string txid, uint32 vout, uint256 satoshis, string targetAddress, uint256 targetAmount, uint256 authorizedAt)[])"
21414
21529
  ];
21415
- const btcSpendAuthorizer = new import_ethers14.Contract(
21530
+ const btcSpendAuthorizer = new import_ethers15.Contract(
21416
21531
  btcSpendAuthorizerAddress,
21417
21532
  btcSpendAuthorizerAbi,
21418
21533
  this.getProviderOrThrow()
@@ -21480,7 +21595,7 @@ Message: ${causeMessage}${quantumContext}${mintDebtDiagnostics}`
21480
21595
  * been broadcast to the Bitcoin network. An empty array means no pending withdrawals.
21481
21596
  *
21482
21597
  * @param positionId - Position identifier
21483
- * @returns Array of pending withdrawals, each including a pre-computed utxoKey for use with cancelPendingWithdrawal
21598
+ * @returns Array of pending withdrawals, each including a pre-computed utxoKey (the key recoverStaleSpend and the admin clearing path operate on)
21484
21599
  */
21485
21600
  async getPendingWithdrawals(positionId) {
21486
21601
  this.ensureInitialized();
@@ -21498,7 +21613,7 @@ Message: ${causeMessage}${quantumContext}${mintDebtDiagnostics}`
21498
21613
  const abi = [
21499
21614
  "function getAuthorizedSpends(bytes32) view returns (tuple(string txid, uint32 vout, uint256 satoshis, string targetAddress, uint256 targetAmount, uint256 authorizedAt)[])"
21500
21615
  ];
21501
- const contract = new import_ethers14.Contract(
21616
+ const contract = new import_ethers15.Contract(
21502
21617
  btcSpendAuthorizerAddress,
21503
21618
  abi,
21504
21619
  this.getProviderOrThrow()
@@ -21512,7 +21627,7 @@ Message: ${causeMessage}${quantumContext}${mintDebtDiagnostics}`
21512
21627
  targetAddress: spend.targetAddress,
21513
21628
  targetAmount: Number(spend.targetAmount),
21514
21629
  authorizedAt: Number(spend.authorizedAt),
21515
- utxoKey: (0, import_ethers14.solidityPackedKeccak256)(
21630
+ utxoKey: (0, import_ethers15.solidityPackedKeccak256)(
21516
21631
  ["string", "uint32"],
21517
21632
  [spend.txid, Number(spend.vout)]
21518
21633
  )
@@ -21525,11 +21640,15 @@ Message: ${causeMessage}${quantumContext}${mintDebtDiagnostics}`
21525
21640
  * broadcast happened. Callers MUST use the returned `status` to decide what
21526
21641
  * to offer:
21527
21642
  * - EXECUTABLE → offer Execute (the only status that may).
21528
- * - EXECUTED → auto-clear; `spendingTxid` is the completion proof.
21529
- * - SPENT_MISMATCH → unexecutable; offer cancelPendingWithdrawal.
21643
+ * - EXECUTED → auto-clear; `spendingTxid` is the completion proof
21644
+ * feed it to recoverStaleSpend to clear the reservation.
21645
+ * - SPENT_MISMATCH → unexecutable; recoverStaleSpend with the spending txid
21646
+ * as invalidator clears the reservation.
21530
21647
  * - 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.
21648
+ * satoshis ≠ real output value); Execute can only die at
21649
+ * the signer guard, and no borrower-side cancel exists
21650
+ * (audit #62210) — clearing needs the AdminModule
21651
+ * cancelStaleSpendByAdmin operator override.
21533
21652
  * - UNFUNDED → funding tx unknown/unconfirmed; wait.
21534
21653
  *
21535
21654
  * @param opts.esploraBaseUrl Esplora API base (e.g. the api proxy
@@ -21553,18 +21672,13 @@ Message: ${causeMessage}${quantumContext}${mintDebtDiagnostics}`
21553
21672
  spends.map((spend) => reconcileAuthorizedSpend(spend, esploraBaseUrl))
21554
21673
  );
21555
21674
  }
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
- */
21675
+ // NOTE: there is deliberately no cancelPendingWithdrawal. Borrower-callable
21676
+ // cleanup was permanently disabled by audit #62210 (markSpentByOwner /
21677
+ // cancelStaleSpendByOwner revert with BorrowerBTCSpendMutationDisabled — a
21678
+ // borrower cancel could be replayed to mint UCD against the same UTXO).
21679
+ // Reservations clear via recoverStaleSpend below (trustless attestation once
21680
+ // the UTXO is provably consumed) or the AdminModule-timelocked
21681
+ // cancelStaleSpendByAdmin operator override.
21568
21682
  /**
21569
21683
  * Recover (clear) a stale BTC reservation via LIT-attested proof.
21570
21684
  *
@@ -21686,7 +21800,7 @@ Message: ${causeMessage}${quantumContext}${mintDebtDiagnostics}`
21686
21800
  error: attRes.error ?? attRes.reason ?? `LIT recovery attestation rejected${attRes.failedStep ? ` at step ${attRes.failedStep}` : ""}`
21687
21801
  };
21688
21802
  }
21689
- const btcSpendAuthorizer = new import_ethers14.Contract(
21803
+ const btcSpendAuthorizer = new import_ethers15.Contract(
21690
21804
  btcSpendAuthorizerAddress,
21691
21805
  [
21692
21806
  "function cancelStaleSpendWithProof(bytes32 positionId, bytes32 utxoKey, uint256 authorizedAt, string calldata invalidatorTxid, uint256 attestationTimestamp, bytes calldata litSignature) external"
@@ -21716,6 +21830,256 @@ Message: ${causeMessage}${quantumContext}${mintDebtDiagnostics}`
21716
21830
  };
21717
21831
  }
21718
21832
  }
21833
+ /**
21834
+ * Sign + broadcast the PKP vault→vault self-spend that invalidates one
21835
+ * stuck authorized outpoint (btc-utxo-invalidator 1.0.0). Once the returned
21836
+ * `invalidatorTxid` reaches >=6 Bitcoin confirmations, `recoverStaleSpend`
21837
+ * clears the on-chain reservation — the trustless replacement for the
21838
+ * AdminModule cancelStaleSpendByAdmin path on unspent stuck/corrupt
21839
+ * reservations (incident 2026-07-22). Requires the borrower (or position
21840
+ * delegate) signer; the signature is scoped to exactly this outpoint.
21841
+ */
21842
+ async invalidateStaleSpend(params) {
21843
+ this.ensureInitialized();
21844
+ const chainId = this.config.chainId ?? this.config.networkOverride?.chainId;
21845
+ if (!chainId) {
21846
+ return {
21847
+ success: false,
21848
+ failedStep: "config",
21849
+ error: "chainId required for invalidateStaleSpend"
21850
+ };
21851
+ }
21852
+ const signer = this.getSignerOrThrow();
21853
+ const envelope = await buildInvalidateStaleSpendEnvelope({
21854
+ positionId: params.positionId,
21855
+ utxoTxid: params.utxoTxid,
21856
+ utxoVout: params.utxoVout,
21857
+ chainId,
21858
+ signer
21859
+ });
21860
+ if (this.config.mode === "service" && this.config.serviceEndpoint) {
21861
+ const headers = {
21862
+ "Content-Type": "application/json",
21863
+ ...await this.getAuthHeader()
21864
+ };
21865
+ const resp = await fetch(
21866
+ `${this.config.serviceEndpoint}/api/lit/stale-spend/invalidate`,
21867
+ {
21868
+ method: "POST",
21869
+ headers,
21870
+ body: JSON.stringify({
21871
+ positionId: this.toBytes32(params.positionId),
21872
+ utxoTxid: params.utxoTxid,
21873
+ utxoVout: params.utxoVout,
21874
+ chainId,
21875
+ auth: {
21876
+ timestamp: envelope.timestamp,
21877
+ action: envelope.action,
21878
+ signature: envelope.signature
21879
+ }
21880
+ })
21881
+ }
21882
+ );
21883
+ const json = await resp.json();
21884
+ return json.data ?? {
21885
+ success: false,
21886
+ error: json.error ?? "stale-spend invalidate request failed"
21887
+ };
21888
+ }
21889
+ const rpcUrl = params.rpcUrl ?? this.config.ethRpcUrl;
21890
+ if (!rpcUrl) {
21891
+ return {
21892
+ success: false,
21893
+ failedStep: "config",
21894
+ error: "ethRpcUrl required for invalidateStaleSpend \u2014 set DiamondHandsSDKConfig.ethRpcUrl or pass rpcUrl"
21895
+ };
21896
+ }
21897
+ const positionDetails = await this.getPositionDetailsView(
21898
+ params.positionId
21899
+ );
21900
+ if (!positionDetails?.pkpId || positionDetails.pkpId === import_ethers15.ZeroHash) {
21901
+ return { success: false, error: "Position has no PKP" };
21902
+ }
21903
+ const pkpCache = this.cacheManager.getCache("pkp-data", {
21904
+ maxSize: 500,
21905
+ ttlMs: 24 * 60 * 60 * 1e3
21906
+ });
21907
+ let publicKey = pkpCache.get(params.positionId)?.publicKey;
21908
+ if (!publicKey) {
21909
+ const derived = await this.litOps.deriveDiamondHandsLoanPkpPublicKey({
21910
+ pkpId: positionDetails.pkpId
21911
+ });
21912
+ publicKey = derived.publicKey;
21913
+ }
21914
+ if (!publicKey) {
21915
+ return { success: false, error: "Failed to resolve PKP public key" };
21916
+ }
21917
+ const chipotlePkpAddress = (0, import_ethers15.computeAddress)(publicKey);
21918
+ const dc = this.config.contractAddresses || {};
21919
+ const chainName = chainId === 1 ? "ethereum" : chainId === 11155111 ? "sepolia" : chainId === 1337 || chainId === 31337 ? "hardhat" : void 0;
21920
+ if (!chainName) {
21921
+ return {
21922
+ success: false,
21923
+ error: `Unsupported chainId ${chainId} for invalidateStaleSpend (supported: 1, 11155111, 1337, 31337)`
21924
+ };
21925
+ }
21926
+ const signResult = await this.litOps.signBtcUtxoInvalidator({
21927
+ auth: {
21928
+ positionId: this.toBytes32(params.positionId),
21929
+ utxoTxid: params.utxoTxid,
21930
+ utxoVout: params.utxoVout,
21931
+ timestamp: envelope.timestamp,
21932
+ chainId,
21933
+ action: envelope.action,
21934
+ signature: envelope.signature
21935
+ },
21936
+ publicKey,
21937
+ pkpId: chipotlePkpAddress,
21938
+ chain: chainName,
21939
+ rpcUrl,
21940
+ ...this.config.bitcoinProviders?.[0]?.url && (chainId === 1337 || chainId === 31337) ? { devBitcoinProviderUrl: this.config.bitcoinProviders[0].url } : {},
21941
+ contractAddresses: {
21942
+ PositionManager: dc.positionManager ?? "",
21943
+ BTCSpendAuthorizer: dc.btcSpendAuthorizer ?? "",
21944
+ ...dc.bitcoinProviderRegistry ? { BitcoinProviderRegistry: dc.bitcoinProviderRegistry } : {},
21945
+ ...dc.positionDelegateRegistry ? { PositionDelegateRegistry: dc.positionDelegateRegistry } : {}
21946
+ }
21947
+ });
21948
+ if (!signResult.success) {
21949
+ return {
21950
+ success: false,
21951
+ error: signResult.error ?? "btc-utxo-invalidator signing failed",
21952
+ failedStep: signResult.failedStep
21953
+ };
21954
+ }
21955
+ if (signResult.alreadySpent && typeof signResult.alreadySpent === "object") {
21956
+ return {
21957
+ success: true,
21958
+ alreadySpent: { spendingTxid: signResult.alreadySpent.spendingTxid }
21959
+ };
21960
+ }
21961
+ if (!signResult.signatures?.length || !signResult.utxo || !signResult.pkpBtcAddress || typeof signResult.invalidatorAmount !== "number") {
21962
+ return {
21963
+ success: false,
21964
+ error: "btc-utxo-invalidator returned incomplete data (signatures/utxo/pkpBtcAddress/invalidatorAmount)"
21965
+ };
21966
+ }
21967
+ const broadcastUrl = this.config.bitcoinProviders?.[0]?.url;
21968
+ if (!broadcastUrl) {
21969
+ return {
21970
+ success: false,
21971
+ error: "invalidateStaleSpend broadcast requires config.bitcoinProviders[0].url (esplora base)"
21972
+ };
21973
+ }
21974
+ const { txid: invalidatorTxid } = await (0, import_dh_lit_ops.broadcastSignedBitcoinTransaction)({
21975
+ signatures: signResult.signatures,
21976
+ utxos: [signResult.utxo],
21977
+ pkpPublicKey: signResult.pkpPublicKey ?? publicKey,
21978
+ destination: signResult.pkpBtcAddress,
21979
+ userReceivesAmount: signResult.invalidatorAmount,
21980
+ changeAmount: 0,
21981
+ pkpBtcAddress: signResult.pkpBtcAddress,
21982
+ bitcoinNetwork: chainId === 1 ? "mainnet" : "regtest",
21983
+ bitcoinRpcUrl: broadcastUrl
21984
+ });
21985
+ return {
21986
+ success: true,
21987
+ invalidatorTxid,
21988
+ invalidatorAmount: signResult.invalidatorAmount,
21989
+ networkFee: signResult.networkFee,
21990
+ valueMismatch: signResult.valueMismatch
21991
+ };
21992
+ }
21993
+ /**
21994
+ * Resumable, stateless clearing state machine for one stuck reservation —
21995
+ * Bitcoin itself is the state store, so every call either advances the flow
21996
+ * one step or reports where it stands (survives reloads and the multi-day
21997
+ * 6-confirmation wait; no internal polling).
21998
+ *
21999
+ * (a) reservation gone → phase "cleared"
22000
+ * (b) outpoint spent, >=6 confs → recoverStaleSpend → "cleared"/"failed"
22001
+ * outpoint spent, <6 confs → "awaiting-confirmations" (x/6)
22002
+ * (c) outpoint unspent → invalidateStaleSpend → "invalidator-broadcast"
22003
+ */
22004
+ async clearStuckReservation(params) {
22005
+ this.ensureInitialized();
22006
+ const REQUIRED_CONFS = 6;
22007
+ const esploraBaseUrl = params.esploraBaseUrl ?? this.config.bitcoinProviders?.[0]?.url;
22008
+ const reconciled = await this.reconcilePendingWithdrawals(
22009
+ params.positionId,
22010
+ esploraBaseUrl ? { esploraBaseUrl } : void 0
22011
+ );
22012
+ const row = reconciled.find(
22013
+ (r) => r.spend.txid.toLowerCase() === params.utxoTxid.toLowerCase() && r.spend.vout === params.utxoVout
22014
+ );
22015
+ if (!row) {
22016
+ return { phase: "cleared" };
22017
+ }
22018
+ if (row.spendingTxid && esploraBaseUrl) {
22019
+ const base = esploraBaseUrl.replace(/\/+$/, "");
22020
+ const txRes = await fetch(`${base}/tx/${row.spendingTxid}`);
22021
+ const tipRes = await fetch(`${base}/blocks/tip/height`);
22022
+ let confirmations = 0;
22023
+ if (txRes.ok && tipRes.ok) {
22024
+ const tx = await txRes.json();
22025
+ const tip = Number(await tipRes.text());
22026
+ if (tx.status?.confirmed && typeof tx.status.block_height === "number" && Number.isFinite(tip)) {
22027
+ confirmations = Math.max(0, tip - tx.status.block_height + 1);
22028
+ }
22029
+ }
22030
+ if (confirmations < REQUIRED_CONFS) {
22031
+ return {
22032
+ phase: "awaiting-confirmations",
22033
+ invalidatorTxid: row.spendingTxid,
22034
+ confirmations,
22035
+ required: REQUIRED_CONFS
22036
+ };
22037
+ }
22038
+ const recovery = await this.recoverStaleSpend({
22039
+ positionId: params.positionId,
22040
+ utxoTxid: params.utxoTxid,
22041
+ utxoVout: params.utxoVout,
22042
+ invalidatorTxid: row.spendingTxid
22043
+ });
22044
+ if (recovery.success) {
22045
+ return {
22046
+ phase: "cleared",
22047
+ invalidatorTxid: row.spendingTxid,
22048
+ transactionHash: recovery.transactionHash,
22049
+ classification: recovery.classification
22050
+ };
22051
+ }
22052
+ return {
22053
+ phase: "failed",
22054
+ invalidatorTxid: row.spendingTxid,
22055
+ error: recovery.error ?? "stale-spend recovery failed"
22056
+ };
22057
+ }
22058
+ const invalidation = await this.invalidateStaleSpend({
22059
+ positionId: params.positionId,
22060
+ utxoTxid: params.utxoTxid,
22061
+ utxoVout: params.utxoVout
22062
+ });
22063
+ if (!invalidation.success) {
22064
+ return {
22065
+ phase: "failed",
22066
+ error: invalidation.error ?? "invalidator signing/broadcast failed"
22067
+ };
22068
+ }
22069
+ if (invalidation.alreadySpent) {
22070
+ return {
22071
+ phase: "awaiting-confirmations",
22072
+ invalidatorTxid: invalidation.alreadySpent.spendingTxid,
22073
+ confirmations: 0,
22074
+ required: REQUIRED_CONFS
22075
+ };
22076
+ }
22077
+ return {
22078
+ phase: "invalidator-broadcast",
22079
+ invalidatorTxid: invalidation.invalidatorTxid,
22080
+ valueMismatch: invalidation.valueMismatch
22081
+ };
22082
+ }
21719
22083
  /**
21720
22084
  * Withdraw BTC and execute transfer (Complete Flow)
21721
22085
  *
@@ -22126,10 +22490,10 @@ Message: ${causeMessage}${quantumContext}${mintDebtDiagnostics}`
22126
22490
  "function allowance(address owner, address spender) view returns (uint256)",
22127
22491
  "function approve(address spender, uint256 amount) returns (bool)"
22128
22492
  ];
22129
- const stablecoin = new import_ethers14.Contract(params.stablecoinAddress, erc20Abi, params.signer);
22493
+ const stablecoin = new import_ethers15.Contract(params.stablecoinAddress, erc20Abi, params.signer);
22130
22494
  const allowance = await stablecoin.allowance(signerAddress, psmAddress);
22131
22495
  if (allowance < params.amountWei) {
22132
- const approveTx = await stablecoin.approve(psmAddress, import_ethers14.MaxUint256);
22496
+ const approveTx = await stablecoin.approve(psmAddress, import_ethers15.MaxUint256);
22133
22497
  await approveTx.wait();
22134
22498
  }
22135
22499
  const psm = SimplePSMV2__factory.connect(psmAddress, params.signer);
@@ -22164,10 +22528,10 @@ Message: ${causeMessage}${quantumContext}${mintDebtDiagnostics}`
22164
22528
  "function allowance(address owner, address spender) view returns (uint256)",
22165
22529
  "function approve(address spender, uint256 amount) returns (bool)"
22166
22530
  ];
22167
- const ucdToken = new import_ethers14.Contract(ucdAddress, erc20Abi, params.signer);
22531
+ const ucdToken = new import_ethers15.Contract(ucdAddress, erc20Abi, params.signer);
22168
22532
  const allowance = await ucdToken.allowance(signerAddress, ucdControllerAddress);
22169
22533
  if (allowance < params.ucdAmountWei) {
22170
- const approveTx = await ucdToken.approve(ucdControllerAddress, import_ethers14.MaxUint256);
22534
+ const approveTx = await ucdToken.approve(ucdControllerAddress, import_ethers15.MaxUint256);
22171
22535
  await approveTx.wait();
22172
22536
  }
22173
22537
  const psm = SimplePSMV2__factory.connect(psmAddress, params.signer);
@@ -22379,7 +22743,7 @@ Message: ${causeMessage}${quantumContext}${mintDebtDiagnostics}`
22379
22743
  const maxUcdWhole = BigInt(result[3].toString());
22380
22744
  return success({
22381
22745
  liquidationThreshold: result[0].toString(),
22382
- minimumLoanValueUcd: (0, import_ethers14.formatUnits)(result[2], 18),
22746
+ minimumLoanValueUcd: (0, import_ethers15.formatUnits)(result[2], 18),
22383
22747
  minimumLoanValueWei: result[2].toString(),
22384
22748
  maxSingleLoanValueUcd: maxUcdWhole.toString(),
22385
22749
  maxSingleLoanValueWei: (maxUcdWhole * 10n ** 18n).toString()
@@ -22416,7 +22780,7 @@ Message: ${causeMessage}${quantumContext}${mintDebtDiagnostics}`
22416
22780
  const balanceWei = await provider.getBalance(address);
22417
22781
  return success({
22418
22782
  balanceWei: balanceWei.toString(),
22419
- balanceEth: (0, import_ethers14.formatEther)(balanceWei)
22783
+ balanceEth: (0, import_ethers15.formatEther)(balanceWei)
22420
22784
  });
22421
22785
  } catch (error) {
22422
22786
  return failure(new SDKError({
@@ -22806,7 +23170,7 @@ Message: ${causeMessage}${quantumContext}${mintDebtDiagnostics}`
22806
23170
  * Convert decimal position ID to bytes32 format
22807
23171
  */
22808
23172
  toBytes32(value) {
22809
- return (0, import_ethers14.zeroPadValue)((0, import_ethers14.toBeHex)(BigInt(value)), 32);
23173
+ return (0, import_ethers15.zeroPadValue)((0, import_ethers15.toBeHex)(BigInt(value)), 32);
22810
23174
  }
22811
23175
  /**
22812
23176
  * Check if an error indicates a technical failure vs business logic rejection
@@ -22847,7 +23211,7 @@ Message: ${causeMessage}${quantumContext}${mintDebtDiagnostics}`
22847
23211
  const coreModuleAbi = [
22848
23212
  "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
23213
  ];
22850
- const coreModule = new import_ethers14.Contract(
23214
+ const coreModule = new import_ethers15.Contract(
22851
23215
  coreModuleAddress,
22852
23216
  coreModuleAbi,
22853
23217
  provider
@@ -22914,7 +23278,7 @@ Message: ${causeMessage}${quantumContext}${mintDebtDiagnostics}`
22914
23278
  const corePositionAbi = [
22915
23279
  "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
23280
  ];
22917
- const corePositionContract = new import_ethers14.Contract(
23281
+ const corePositionContract = new import_ethers15.Contract(
22918
23282
  coreAddress,
22919
23283
  corePositionAbi,
22920
23284
  provider
@@ -22925,7 +23289,7 @@ Message: ${causeMessage}${quantumContext}${mintDebtDiagnostics}`
22925
23289
  positionIdBytes32
22926
23290
  );
22927
23291
  const positionIdFromCore = corePosition?.positionId || corePosition?.[0] || null;
22928
- if (positionIdFromCore && positionIdFromCore !== import_ethers14.ZeroHash && positionIdFromCore !== "0x0000000000000000000000000000000000000000000000000000000000000000") {
23292
+ if (positionIdFromCore && positionIdFromCore !== import_ethers15.ZeroHash && positionIdFromCore !== "0x0000000000000000000000000000000000000000000000000000000000000000") {
22929
23293
  if (this.config.debug) {
22930
23294
  log.info("Position exists in core contract", {
22931
23295
  positionId,
@@ -22993,7 +23357,7 @@ Message: ${causeMessage}${quantumContext}${mintDebtDiagnostics}`
22993
23357
  throw new Error("loanOperationsManager address not configured");
22994
23358
  }
22995
23359
  const runner = this.config.contractSigner || this.getProviderOrThrow();
22996
- const contract = new import_ethers14.Contract(
23360
+ const contract = new import_ethers15.Contract(
22997
23361
  addr.loanOperationsManager,
22998
23362
  [
22999
23363
  "function getProtocolConfig() external view returns (uint256 liquidationThreshold, uint256 minimumLoanValueUcd, uint256 minimumLoanValueWei, uint256 maxSingleLoanValueUcd)"
@@ -23006,7 +23370,7 @@ Message: ${causeMessage}${quantumContext}${mintDebtDiagnostics}`
23006
23370
  const maxUcdWhole = BigInt(result[3].toString());
23007
23371
  return {
23008
23372
  liquidationThreshold: result[0].toString(),
23009
- minimumLoanValueUcd: (0, import_ethers14.formatUnits)(result[2], 18),
23373
+ minimumLoanValueUcd: (0, import_ethers15.formatUnits)(result[2], 18),
23010
23374
  minimumLoanValueWei: result[2].toString(),
23011
23375
  maxSingleLoanValueUcd: maxUcdWhole.toString(),
23012
23376
  maxSingleLoanValueWei: (maxUcdWhole * 10n ** 18n).toString()
@@ -23024,8 +23388,8 @@ Message: ${causeMessage}${quantumContext}${mintDebtDiagnostics}`
23024
23388
  const MIN_REVEAL_DELAY = 60;
23025
23389
  const MAX_RANDOM_DELAY = 240;
23026
23390
  const entropyInput = positionId + quantumTimestamp.toString();
23027
- const hash = (0, import_ethers14.keccak256)(
23028
- (0, import_ethers14.toUtf8Bytes)(entropyInput)
23391
+ const hash = (0, import_ethers15.keccak256)(
23392
+ (0, import_ethers15.toUtf8Bytes)(entropyInput)
23029
23393
  );
23030
23394
  const randomValue = BigInt(hash);
23031
23395
  const randomDelay = Number(randomValue % BigInt(MAX_RANDOM_DELAY));
@@ -23050,12 +23414,12 @@ Message: ${causeMessage}${quantumContext}${mintDebtDiagnostics}`
23050
23414
  const rawPositionId = /^0x/i.test(params.positionId.trim()) ? params.positionId.trim().slice(2) : params.positionId.trim();
23051
23415
  const canonicalPositionId = "0x" + rawPositionId.padStart(64, "0").toLowerCase();
23052
23416
  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)(
23417
+ const intentActionHash = (0, import_ethers15.keccak256)((0, import_ethers15.toUtf8Bytes)("liquidate-position"));
23418
+ const intentHash = (0, import_ethers15.solidityPackedKeccak256)(
23055
23419
  ["bytes32", "uint256", "uint256", "address", "bytes32"],
23056
23420
  [canonicalPositionId, intentTimestamp, chainId, intentSigner, intentActionHash]
23057
23421
  );
23058
- const intentSignature = await signer.signMessage((0, import_ethers14.getBytes)(intentHash));
23422
+ const intentSignature = await signer.signMessage((0, import_ethers15.getBytes)(intentHash));
23059
23423
  const response = await fetch(endpoint, {
23060
23424
  method: "POST",
23061
23425
  headers: { "Content-Type": "application/json" },
@@ -23107,7 +23471,7 @@ Message: ${causeMessage}${quantumContext}${mintDebtDiagnostics}`
23107
23471
  const vrfSeedRaw = await lmResult.value["vrfSeeds"](positionId);
23108
23472
  const vrfSeed = BigInt(vrfSeedRaw.toString());
23109
23473
  if (vrfSeed !== 0n) {
23110
- const finalEntropy = (0, import_ethers14.solidityPackedKeccak256)(
23474
+ const finalEntropy = (0, import_ethers15.solidityPackedKeccak256)(
23111
23475
  ["uint256", "uint256", "bytes32"],
23112
23476
  [vrfSeed, BigInt(quantumTimestamp.toString()), positionId]
23113
23477
  );
@@ -23385,14 +23749,14 @@ var EventHelpers = {
23385
23749
  };
23386
23750
 
23387
23751
  // src/utils/position-delegate.utils.ts
23388
- var import_ethers15 = require("ethers");
23752
+ var import_ethers16 = require("ethers");
23389
23753
  var POSITION_DELEGATE_REGISTRY_ABI = [
23390
23754
  "function positionDelegate(bytes32 positionId) view returns (address)",
23391
23755
  "function setPositionDelegate(bytes32 positionId, address newDelegate) external",
23392
23756
  "event PositionDelegateUpdated(bytes32 indexed positionId, address indexed oldDelegate, address indexed newDelegate)"
23393
23757
  ];
23394
23758
  async function setPositionDelegate(positionId, delegate, signer, registryAddress) {
23395
- const registry = new import_ethers15.Contract(
23759
+ const registry = new import_ethers16.Contract(
23396
23760
  registryAddress,
23397
23761
  POSITION_DELEGATE_REGISTRY_ABI,
23398
23762
  signer
@@ -23400,7 +23764,7 @@ async function setPositionDelegate(positionId, delegate, signer, registryAddress
23400
23764
  return registry["setPositionDelegate"](positionId, delegate);
23401
23765
  }
23402
23766
  async function getPositionDelegate(positionId, provider, registryAddress) {
23403
- const registry = new import_ethers15.Contract(
23767
+ const registry = new import_ethers16.Contract(
23404
23768
  registryAddress,
23405
23769
  POSITION_DELEGATE_REGISTRY_ABI,
23406
23770
  provider
@@ -23429,6 +23793,7 @@ async function getPositionDelegate(positionId, provider, registryAddress) {
23429
23793
  PKPManager,
23430
23794
  PaymentType,
23431
23795
  PositionStatus,
23796
+ RECOVERY_INVALIDATE_ACTION,
23432
23797
  SDKError,
23433
23798
  SDK_DEFAULTS,
23434
23799
  SEPOLIA_CONTRACTS,
@@ -23441,6 +23806,8 @@ async function getPositionDelegate(positionId, provider, registryAddress) {
23441
23806
  assertProtocolNotPaused,
23442
23807
  assertSafeServiceEndpoint,
23443
23808
  buildBtcExecuteEnvelope,
23809
+ buildInvalidateMessageHash,
23810
+ buildInvalidateStaleSpendEnvelope,
23444
23811
  collectFailures,
23445
23812
  collectSuccesses,
23446
23813
  combine,