@gvnrdao/dh-sdk 0.0.332 → 0.0.334

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
@@ -1105,6 +1105,9 @@ var require_pkg_src = __commonJS({
1105
1105
  });
1106
1106
  var index_exports = {};
1107
1107
  __export2(index_exports, {
1108
+ BORROWER_AUTHORIZATION_ENCODE_TYPES: () => BORROWER_AUTHORIZATION_ENCODE_TYPES,
1109
+ BORROWER_AUTHORIZATION_FIELDS: () => BORROWER_AUTHORIZATION_FIELDS,
1110
+ BORROWER_AUTHORIZATION_PRIMARY_TYPES: () => BORROWER_AUTHORIZATION_PRIMARY_TYPES,
1108
1111
  CHIPOTLE_DEPLOYMENTS: () => CHIPOTLE_DEPLOYMENTS,
1109
1112
  DEFAULT_CACHE_CONFIG: () => DEFAULT_CACHE_CONFIG,
1110
1113
  DEFAULT_DEBUG_CONFIG: () => DEFAULT_DEBUG_CONFIG,
@@ -1117,6 +1120,8 @@ var require_pkg_src = __commonJS({
1117
1120
  PerformanceTracker: () => PerformanceTracker,
1118
1121
  RetryStrategy: () => RetryStrategy,
1119
1122
  analyzeError: () => analyzeError,
1123
+ borrowerAuthorizationTypes: () => borrowerAuthorizationTypes,
1124
+ buildBorrowerAuthorizationDomain: () => buildBorrowerAuthorizationDomain,
1120
1125
  calculateDelay: () => calculateDelay,
1121
1126
  cidToHex: () => cidToHex,
1122
1127
  classifyError: () => classifyError,
@@ -1363,30 +1368,30 @@ var require_pkg_src = __commonJS({
1363
1368
  }
1364
1369
  },
1365
1370
  btcTransactionSigner: {
1366
- cid: "QmakWzTce8NH1Jkgv1xwg83Bg9WmF2UG1Mq76pDYDSwwUp",
1371
+ cid: "QmVi1BYdxvCX3QUhXwPtP6FjWMzqSPtXzrS54YsXjTgjYf",
1367
1372
  authorizedCidHex: cidToHex(
1368
- "QmakWzTce8NH1Jkgv1xwg83Bg9WmF2UG1Mq76pDYDSwwUp"
1373
+ "QmVi1BYdxvCX3QUhXwPtP6FjWMzqSPtXzrS54YsXjTgjYf"
1369
1374
  ),
1370
1375
  name: "Btc Transaction Signer",
1371
1376
  description: "Production Btc Transaction Signer",
1372
1377
  version: "1.1.1",
1373
1378
  deployed: true,
1374
- deployedAt: 1786465606156,
1375
- size: 67999,
1376
- hash: "83f3644c68819215e05ba8db3225571354a009458fc1437f606df6cb9142d3f9"
1379
+ deployedAt: 1787923905597,
1380
+ size: 70646,
1381
+ hash: "37c3bb72a660c8275d92e1b73f9482742d86b64789480b9246304c0ca1bab47a"
1377
1382
  },
1378
1383
  ucdMintValidator: {
1379
- cid: "Qmd8jgKRceLvf5aoTtwdXG2JqMoBK5cRJwrvEtQkgvbFbx",
1384
+ cid: "QmUWR5fLiyimLT9TPXpYx3HgwNwkvR6MxjZ7hdeYCFodbc",
1380
1385
  authorizedCidHex: cidToHex(
1381
- "Qmd8jgKRceLvf5aoTtwdXG2JqMoBK5cRJwrvEtQkgvbFbx"
1386
+ "QmUWR5fLiyimLT9TPXpYx3HgwNwkvR6MxjZ7hdeYCFodbc"
1382
1387
  ),
1383
1388
  name: "Ucd Mint Validator",
1384
1389
  description: "Production Ucd Mint Validator",
1385
1390
  version: "1.2.1",
1386
1391
  deployed: true,
1387
- deployedAt: 1786465627201,
1388
- size: 82739,
1389
- hash: "2bdd9aebdaad58a43a4731d5b7284f2531b7a9caaf8caf5719d891c4ed33cb2e",
1392
+ deployedAt: 1787923919527,
1393
+ size: 86197,
1394
+ hash: "c2d80939746cc37f65ef2f63c6a3215b929214a63f10c78144e1f5c98320dabf",
1390
1395
  validatorWalletAddress: "0x82DB9F515957aA380B596C6eA2Bd30CEF181f236",
1391
1396
  pkp: {
1392
1397
  publicKey: "0x041ab17cd91fc5c0b761eea6092d032807561b621b82c488826776e04a9158d61ba64d809a4729f0501289d980732cb06d8dfd06999dd9c8efd2f495dad78b31bb",
@@ -1394,17 +1399,17 @@ var require_pkg_src = __commonJS({
1394
1399
  }
1395
1400
  },
1396
1401
  processPaymentValidator: {
1397
- cid: "QmNXVdysXDhCaQ1uNE2Vgjbuzy6yUEnnVgHzmDfNKXMU6z",
1402
+ cid: "QmXmXuMRAjMLdgKGyTf9KQdGwYrDp8DxkiF44TvSXDf7wF",
1398
1403
  authorizedCidHex: cidToHex(
1399
- "QmNXVdysXDhCaQ1uNE2Vgjbuzy6yUEnnVgHzmDfNKXMU6z"
1404
+ "QmXmXuMRAjMLdgKGyTf9KQdGwYrDp8DxkiF44TvSXDf7wF"
1400
1405
  ),
1401
1406
  name: "Process Payment Validator",
1402
1407
  description: "Production Process Payment Validator",
1403
1408
  version: "1.2.1",
1404
1409
  deployed: true,
1405
- deployedAt: 1786465654796,
1406
- size: 78736,
1407
- hash: "17191ecc9c009e0fa5ab52c876330beb2a9a75d30cccb92e7c0c04f169df088b",
1410
+ deployedAt: 1787923987153,
1411
+ size: 82217,
1412
+ hash: "13defa19614215ab3b1fe88955d69e530d13a09475396af932fe0e213637da2f",
1408
1413
  validatorWalletAddress: "0x82DB9F515957aA380B596C6eA2Bd30CEF181f236",
1409
1414
  pkp: {
1410
1415
  publicKey: "0x04cfccb9b6c7addc79469c0e9fafebef4c70801302c62cdb26b610723a9b8527d23f98a40158c7340d83fd0e62d02b5ec74c12f7a86d98e8c6973b4811110f19ad",
@@ -1412,17 +1417,17 @@ var require_pkg_src = __commonJS({
1412
1417
  }
1413
1418
  },
1414
1419
  extendPositionValidator: {
1415
- cid: "QmYwBsyrhGfHWyRKx549G4tKHxsBLAuRUHcecigeUCkFav",
1420
+ cid: "QmU8h99EEVEsQkxroXiYqLsKZw9gNjE6N5CcTpE9aUc12m",
1416
1421
  authorizedCidHex: cidToHex(
1417
- "QmYwBsyrhGfHWyRKx549G4tKHxsBLAuRUHcecigeUCkFav"
1422
+ "QmU8h99EEVEsQkxroXiYqLsKZw9gNjE6N5CcTpE9aUc12m"
1418
1423
  ),
1419
1424
  name: "Extend Position Validator",
1420
1425
  description: "Production Extend Position Validator",
1421
1426
  version: "1.2.1",
1422
1427
  deployed: true,
1423
- deployedAt: 1786465681874,
1424
- size: 76515,
1425
- hash: "1d4e085335af80f194a663a577876902c83015177e95906a0b461fa93bd5da08",
1428
+ deployedAt: 1787923999294,
1429
+ size: 79975,
1430
+ hash: "31c1aaf883ef22f37681ddb0a4a949be5c05304b6aef178989475a2da935ef9a",
1426
1431
  validatorWalletAddress: "0x82DB9F515957aA380B596C6eA2Bd30CEF181f236",
1427
1432
  pkp: {
1428
1433
  publicKey: "0x04e52338f6a0c3362800f1a94c4c8f08be5030dde0fa217388c53d1c1a4790f4443c9f2886b2d2d8f4b75a9a156e9b028011b1a1cf7648da0e556aa980ec692836",
@@ -1430,17 +1435,17 @@ var require_pkg_src = __commonJS({
1430
1435
  }
1431
1436
  },
1432
1437
  btcWithdrawal: {
1433
- cid: "QmRYVoTTDxk2McvBqxSm9M7YcaBGdTqjnZGPX4Y191DaZh",
1438
+ cid: "QmZQWET9pzrVD4gwQuSzYZmqa24JrUNtnnGFDd513sxMCY",
1434
1439
  authorizedCidHex: cidToHex(
1435
- "QmRYVoTTDxk2McvBqxSm9M7YcaBGdTqjnZGPX4Y191DaZh"
1440
+ "QmZQWET9pzrVD4gwQuSzYZmqa24JrUNtnnGFDd513sxMCY"
1436
1441
  ),
1437
1442
  name: "Btc Withdrawal",
1438
1443
  description: "Production Btc Withdrawal",
1439
1444
  version: "1.2.7",
1440
1445
  deployed: true,
1441
- deployedAt: 1786446046614,
1442
- size: 97456,
1443
- hash: "3cae8250861832f91ee3c573abeb50ff27b9acd34148176071cbfbabb359fc91",
1446
+ deployedAt: 1787924017769,
1447
+ size: 100069,
1448
+ hash: "4f8e27414e4da235e63d6ae1325c63f3d2fb956464515a21aa007a99935f0f13",
1444
1449
  validatorWalletAddress: "0x82DB9F515957aA380B596C6eA2Bd30CEF181f236",
1445
1450
  pkp: {
1446
1451
  publicKey: "0x043616787c5432415c24378c4ef48de2bcd6bb7b575b837e3cff09171802662da7105d79586c7659677a0ecbaddac4cce06cb2a11f69a16fa0c4d7002ac7d51a4d",
@@ -1552,30 +1557,30 @@ var require_pkg_src = __commonJS({
1552
1557
  hash: "03ee5be239c91c735d2c95db89a0d1b77e602cfc18af8eb64b3281fddcd90a72"
1553
1558
  },
1554
1559
  agentModuleExecutor: {
1555
- cid: "QmdhC18wF7PFGMQ8aThdPsEVSpuDewA27dFvbA3bG6kVDQ",
1560
+ cid: "QmcD65vuremot5fsHVgp9JBAmei6gAaEtm5mdtLP7Yt9Kf",
1556
1561
  authorizedCidHex: cidToHex(
1557
- "QmdhC18wF7PFGMQ8aThdPsEVSpuDewA27dFvbA3bG6kVDQ"
1562
+ "QmcD65vuremot5fsHVgp9JBAmei6gAaEtm5mdtLP7Yt9Kf"
1558
1563
  ),
1559
1564
  name: "Agent Module Executor",
1560
1565
  description: "Production Agent Module Executor",
1561
1566
  version: "1.1.1",
1562
1567
  deployed: true,
1563
- deployedAt: 1786446108348,
1564
- size: 11655,
1565
- hash: "d4e2149f843d6c2699fc61114d54b268ba4ed2c46ebdaee1145e0f101ec2a1ec"
1568
+ deployedAt: 1787924032013,
1569
+ size: 13878,
1570
+ hash: "a7f0204700912e26e5a354bee13a1242a2baa218643b3bb22d28481f67f9baf4"
1566
1571
  },
1567
1572
  staleSpendRecoveryValidator: {
1568
- cid: "QmXQWT8V4wjuvH8BbC7xrkYxsVu5AKfvfWcS7jnYfrexYm",
1573
+ cid: "QmNuwo4PT4AikAmhMdZgPWCb2mJDwWa9TnUqrqvofjbrT8",
1569
1574
  authorizedCidHex: cidToHex(
1570
- "QmXQWT8V4wjuvH8BbC7xrkYxsVu5AKfvfWcS7jnYfrexYm"
1575
+ "QmNuwo4PT4AikAmhMdZgPWCb2mJDwWa9TnUqrqvofjbrT8"
1571
1576
  ),
1572
1577
  name: "Stale Spend Recovery Validator",
1573
1578
  description: "Production Stale Spend Recovery Validator",
1574
1579
  version: "1.1.2",
1575
1580
  deployed: true,
1576
- deployedAt: 1785173285829,
1577
- size: 37108,
1578
- hash: "04de5fc5b6f5131dc1544e3d3d187a1f9ef9616ffd12483d119f9102b3671791",
1581
+ deployedAt: 1787924048772,
1582
+ size: 41424,
1583
+ hash: "3c5f028d2bef4344768462993616d45e30d9d44ef126e04d6eb579821d57d99c",
1579
1584
  validatorWalletAddress: "0x82DB9F515957aA380B596C6eA2Bd30CEF181f236",
1580
1585
  pkp: {
1581
1586
  publicKey: "0x046da0ad6da7dd4a0063cbeac6f2bdb6a9889c2178b23470833356a8ee5630f7f0eee0db348d9d9aaaadd23eccf0063c8f68ee5e446abe30b882bf1de4c932bc21",
@@ -1583,17 +1588,17 @@ var require_pkg_src = __commonJS({
1583
1588
  }
1584
1589
  },
1585
1590
  btcUtxoInvalidator: {
1586
- cid: "Qmf4Ze8yhnQhHbnX5RPgJrC7Jw1aA3gbpfpd52kFg7fd1m",
1591
+ cid: "QmaNGeWut7EiGwW4zUc2sFSt7RY5NWFgxYboyG333TwrJf",
1587
1592
  authorizedCidHex: cidToHex(
1588
- "Qmf4Ze8yhnQhHbnX5RPgJrC7Jw1aA3gbpfpd52kFg7fd1m"
1593
+ "QmaNGeWut7EiGwW4zUc2sFSt7RY5NWFgxYboyG333TwrJf"
1589
1594
  ),
1590
1595
  name: "Btc Utxo Invalidator",
1591
1596
  description: "Production Btc Utxo Invalidator",
1592
1597
  version: "1.0.0",
1593
1598
  deployed: true,
1594
- deployedAt: 1786465704240,
1595
- size: 62553,
1596
- hash: "1dcea2b49e545c423195be22e072dc5e3039ed1c95a8490b23505956029f5b33"
1599
+ deployedAt: 1787924133241,
1600
+ size: 66026,
1601
+ hash: "603bc50920d7f1dee77086f2c518d9e2922ab3858a419d3fbea8221ea3a6d9e9"
1597
1602
  }
1598
1603
  };
1599
1604
  function getDeploymentsForNetwork(network) {
@@ -2354,6 +2359,101 @@ ${errorReport}`);
2354
2359
  var SECONDS_PER_DAY = 86400;
2355
2360
  var DAYS_PER_MONTH = 30;
2356
2361
  var LIT_ACTION_ETH_RPC_TIMEOUT_MS = 8e3;
2362
+ var PINNED_CONTRACT_ADDRESSES = {
2363
+ 1: {
2364
+ PositionManager: "0x12A1836e56139ccaD8722B89519d84233efc224B",
2365
+ LoanOperationsManagerModule: "0x2561974A40F1AEed1251d0A090A83cF8536FB9E9",
2366
+ BTCSpendAuthorizer: "0xfBbF108486fa07F1B06a811C5b66ed68DD9c508a",
2367
+ BitcoinProviderRegistry: "0x4ab3Fb96e02893Ed6FAa61bad1918390c8DbbFFC",
2368
+ LITActionValidator: "0xD2c5d59c2CC5c409AC65ce0A817236aeC6869512",
2369
+ PositionDelegateRegistry: "0xf0aa2678aD4F60f49e8F7725089B5E86B7F8FE4C"
2370
+ },
2371
+ 11155111: {
2372
+ PositionManager: "0x68e0507D982AEBF1D1C1Af8FBbd842327e2deeFF",
2373
+ LoanOperationsManagerModule: "0x3e05e760a87715207b7F4e8fD35EF7559BcA72C0",
2374
+ BTCSpendAuthorizer: "0xd7E9Eb5eE53f1d9ee55Dc162bBC7486bE437B6bD",
2375
+ BitcoinProviderRegistry: "0xbfA0c48B070D0a9A9CD27469AeacFD2d4261cEE2",
2376
+ LITActionValidator: "0x54eECd7C90F8A8fac27749Ba30BbE8AFBAccc856",
2377
+ PositionDelegateRegistry: "0x482369De283622E7b05731875ec137d4E3D208F9"
2378
+ }
2379
+ };
2380
+ function getPinnedContractAddresses(chainId) {
2381
+ return PINNED_CONTRACT_ADDRESSES[chainId] ?? null;
2382
+ }
2383
+ var PROTOCOL_EIP712_DOMAIN_NAME = "DiamondHands.Protocol";
2384
+ var PROTOCOL_EIP712_DOMAIN_VERSION = "1";
2385
+ var BORROWER_AUTHORIZATION_PRIMARY_TYPES = {
2386
+ MINT: "MintRequest",
2387
+ REPAY: "RepayRequest",
2388
+ RENEW: "RenewRequest",
2389
+ WITHDRAW: "WithdrawRequest"
2390
+ };
2391
+ var BORROWER_AUTHORIZATION_FIELDS = {
2392
+ MintRequest: [
2393
+ { name: "positionId", type: "bytes32" },
2394
+ { name: "mintAmount", type: "uint256" },
2395
+ { name: "quantumTimestamp", type: "uint256" }
2396
+ ],
2397
+ RepayRequest: [
2398
+ { name: "positionId", type: "bytes32" },
2399
+ { name: "paymentAmount", type: "uint256" },
2400
+ { name: "quantumTimestamp", type: "uint256" }
2401
+ ],
2402
+ RenewRequest: [
2403
+ { name: "positionId", type: "bytes32" },
2404
+ { name: "selectedTerm", type: "uint256" },
2405
+ { name: "quantumTimestamp", type: "uint256" }
2406
+ ],
2407
+ WithdrawRequest: [
2408
+ { name: "positionId", type: "bytes32" },
2409
+ { name: "totalDeduction", type: "uint256" },
2410
+ { name: "withdrawalAddress", type: "string" },
2411
+ { name: "quantumTimestamp", type: "uint256" }
2412
+ ]
2413
+ };
2414
+ var BORROWER_AUTHORIZATION_ENCODE_TYPES = {
2415
+ MintRequest: "MintRequest(bytes32 positionId,uint256 mintAmount,uint256 quantumTimestamp)",
2416
+ RepayRequest: "RepayRequest(bytes32 positionId,uint256 paymentAmount,uint256 quantumTimestamp)",
2417
+ RenewRequest: "RenewRequest(bytes32 positionId,uint256 selectedTerm,uint256 quantumTimestamp)",
2418
+ WithdrawRequest: "WithdrawRequest(bytes32 positionId,uint256 totalDeduction,string withdrawalAddress,uint256 quantumTimestamp)"
2419
+ };
2420
+ function borrowerAuthorizationTypes(primaryType) {
2421
+ const fields = BORROWER_AUTHORIZATION_FIELDS[primaryType];
2422
+ if (!fields) {
2423
+ throw new Error(
2424
+ `Unknown borrower authorization primary type "${primaryType}"; expected one of ${Object.keys(BORROWER_AUTHORIZATION_FIELDS).join(", ")}`
2425
+ );
2426
+ }
2427
+ return { [primaryType]: fields.map((field) => ({ ...field })) };
2428
+ }
2429
+ function buildBorrowerAuthorizationDomain(chainId, verifyingContractOverride) {
2430
+ if (!Number.isInteger(chainId) || chainId <= 0) {
2431
+ throw new Error(
2432
+ `Borrower authorization domain requires a positive integer chainId, got ${String(chainId)}`
2433
+ );
2434
+ }
2435
+ const pinned = getPinnedContractAddresses(chainId);
2436
+ const pinnedLom = pinned?.LoanOperationsManagerModule;
2437
+ if (pinnedLom && verifyingContractOverride) {
2438
+ if (pinnedLom.toLowerCase() !== verifyingContractOverride.toLowerCase()) {
2439
+ throw new Error(
2440
+ `Refusing a caller-supplied verifyingContract that contradicts the pin for chainId ${chainId}: caller ${verifyingContractOverride}, pinned ${pinnedLom}`
2441
+ );
2442
+ }
2443
+ }
2444
+ const verifyingContract = pinnedLom ?? verifyingContractOverride;
2445
+ if (!verifyingContract) {
2446
+ throw new Error(
2447
+ `No pinned LoanOperationsManagerModule for chainId ${chainId} and no verifyingContract supplied; refusing to build a borrower authorization domain without one`
2448
+ );
2449
+ }
2450
+ return {
2451
+ name: PROTOCOL_EIP712_DOMAIN_NAME,
2452
+ version: PROTOCOL_EIP712_DOMAIN_VERSION,
2453
+ chainId,
2454
+ verifyingContract
2455
+ };
2456
+ }
2357
2457
  var EVMChain = /* @__PURE__ */ ((EVMChain3) => {
2358
2458
  EVMChain3["SEPOLIA"] = "sepolia";
2359
2459
  EVMChain3["ETHEREUM"] = "ethereum";
@@ -4164,11 +4264,11 @@ ${auth.clientId}`;
4164
4264
  );
4165
4265
  const prices = await Promise.race([fetchAll, timeoutPromise]);
4166
4266
  const sorted = [...prices].sort((a, b) => a - b);
4167
- let median;
4267
+ let median2;
4168
4268
  if (this.devSingleProvider) {
4169
- median = sorted[0];
4269
+ median2 = sorted[0];
4170
4270
  } else {
4171
- median = sorted[1];
4271
+ median2 = sorted[1];
4172
4272
  const spread = (sorted[2] - sorted[0]) / sorted[0];
4173
4273
  if (spread > PRICE_ORACLE_TOLERANCE) {
4174
4274
  const names = this.sources.map((s) => s.name).join(", ");
@@ -4178,10 +4278,10 @@ ${auth.clientId}`;
4178
4278
  );
4179
4279
  }
4180
4280
  }
4181
- const priceCents = Math.round(median * 100);
4281
+ const priceCents = Math.round(median2 * 100);
4182
4282
  const priceWith8Decimals = BigInt(priceCents) * 1000000n;
4183
4283
  const totalElapsed = Date.now() - startTime;
4184
- console.log(`[Price Oracle] Median price: $${median.toLocaleString()} \u2014 total time: ${totalElapsed}ms`);
4284
+ console.log(`[Price Oracle] Median price: $${median2.toLocaleString()} \u2014 total time: ${totalElapsed}ms`);
4185
4285
  console.log(`[Price Oracle] Price with 8 decimals: ${priceWith8Decimals}`);
4186
4286
  return priceWith8Decimals;
4187
4287
  }
@@ -6133,26 +6233,83 @@ var MAKE_PAYMENT_GAS_CEILING = BigInt(1e6);
6133
6233
  var EXTEND_POSITION_GAS_CEILING = BigInt(1e6);
6134
6234
  var LIQUIDATION_COMMIT_GAS_CEILING = BigInt(1e6);
6135
6235
  var LIQUIDATION_REVEAL_GAS_CEILING = BigInt(2e6);
6136
- async function resolveEip1559FeeFields(provider) {
6137
- const feeData = await provider.getFeeData();
6138
- let maxFeePerGas = feeData.maxFeePerGas ?? void 0;
6139
- let maxPriorityFeePerGas = feeData.maxPriorityFeePerGas ?? void 0;
6140
- if (!maxFeePerGas || !maxPriorityFeePerGas) {
6141
- const gasPrice = (await provider.getFeeData()).gasPrice ?? (0, import_ethers.parseUnits)("1", "gwei");
6142
- maxFeePerGas = maxFeePerGas || gasPrice * 2n;
6143
- maxPriorityFeePerGas = maxPriorityFeePerGas || (0, import_ethers.parseUnits)("1.5", "gwei");
6144
- }
6145
- if (maxFeePerGas < maxPriorityFeePerGas) {
6146
- maxFeePerGas = maxPriorityFeePerGas;
6236
+ var PRIORITY_FEE_FLOOR_WEI = (0, import_ethers.parseUnits)("0.1", "gwei");
6237
+ var PRIORITY_FEE_CAP_WEI = (0, import_ethers.parseUnits)("3", "gwei");
6238
+ var FEE_HISTORY_BLOCK_COUNT = 20;
6239
+ var FEE_HISTORY_REWARD_PERCENTILE = 75;
6240
+ function isJsonRpcSendable(provider) {
6241
+ return typeof provider.send === "function";
6242
+ }
6243
+ function parseFeeHistory(raw) {
6244
+ if (typeof raw !== "object" || raw === null) {
6245
+ throw new Error(`eth_feeHistory returned a non-object result: ${JSON.stringify(raw)}`);
6147
6246
  }
6247
+ const { baseFeePerGas, reward } = raw;
6248
+ if (!Array.isArray(baseFeePerGas) || baseFeePerGas.length === 0) {
6249
+ throw new Error(
6250
+ `eth_feeHistory returned no baseFeePerGas \u2014 the RPC does not support EIP-1559 fee history: ${JSON.stringify(raw)}`
6251
+ );
6252
+ }
6253
+ if (!Array.isArray(reward) || reward.length === 0) {
6254
+ throw new Error(
6255
+ `eth_feeHistory returned no reward percentiles \u2014 the RPC ignored the rewardPercentiles argument: ${JSON.stringify(raw)}`
6256
+ );
6257
+ }
6258
+ const nextBaseFee = (0, import_ethers.getBigInt)(baseFeePerGas[baseFeePerGas.length - 1], "baseFeePerGas");
6259
+ const tips = reward.map((perBlock, i) => {
6260
+ if (!Array.isArray(perBlock) || perBlock.length === 0) {
6261
+ throw new Error(`eth_feeHistory reward row ${i} is empty: ${JSON.stringify(raw)}`);
6262
+ }
6263
+ return (0, import_ethers.getBigInt)(perBlock[0], `reward[${i}]`);
6264
+ });
6265
+ return { nextBaseFee, tips };
6266
+ }
6267
+ function median(values) {
6268
+ const sorted = [...values].sort((a, b) => a < b ? -1 : a > b ? 1 : 0);
6269
+ const mid = sorted.length >> 1;
6270
+ const hi = sorted[mid];
6271
+ if (hi === void 0) {
6272
+ throw new Error("median: no values");
6273
+ }
6274
+ if (sorted.length % 2 === 1)
6275
+ return hi;
6276
+ const lo = sorted[mid - 1];
6277
+ if (lo === void 0) {
6278
+ throw new Error("median: no values");
6279
+ }
6280
+ return (lo + hi) / 2n;
6281
+ }
6282
+ function clamp(value, floor, cap) {
6283
+ if (value < floor)
6284
+ return floor;
6285
+ if (value > cap)
6286
+ return cap;
6287
+ return value;
6288
+ }
6289
+ async function resolveEip1559FeeFields(feeProvider) {
6290
+ if (!isJsonRpcSendable(feeProvider)) {
6291
+ throw new Error(
6292
+ "resolveEip1559FeeFields: feeProvider must be a JSON-RPC provider exposing send() (the SDK read provider), not a wallet BrowserProvider \u2014 eth_feeHistory is required"
6293
+ );
6294
+ }
6295
+ const history = parseFeeHistory(
6296
+ await feeProvider.send("eth_feeHistory", [
6297
+ (0, import_ethers.toQuantity)(FEE_HISTORY_BLOCK_COUNT),
6298
+ "latest",
6299
+ [FEE_HISTORY_REWARD_PERCENTILE]
6300
+ ])
6301
+ );
6302
+ const marketTip = median(history.tips);
6303
+ const maxPriorityFeePerGas = clamp(marketTip, PRIORITY_FEE_FLOOR_WEI, PRIORITY_FEE_CAP_WEI);
6304
+ const maxFeePerGas = history.nextBaseFee * 2n + maxPriorityFeePerGas;
6148
6305
  return { maxFeePerGas, maxPriorityFeePerGas };
6149
6306
  }
6150
6307
  async function sendEip1559Transaction(params) {
6151
- const { signer, to, data, gasLimit } = params;
6308
+ const { signer, feeProvider, to, data, gasLimit } = params;
6152
6309
  if (!signer.provider) {
6153
6310
  throw new Error("Signer must have a provider attached");
6154
6311
  }
6155
- const fees = await resolveEip1559FeeFields(signer.provider);
6312
+ const fees = await resolveEip1559FeeFields(feeProvider);
6156
6313
  return signer.sendTransaction({
6157
6314
  to,
6158
6315
  data,
@@ -6247,7 +6404,7 @@ function validateSDKConfig(config) {
6247
6404
  }
6248
6405
 
6249
6406
  // src/utils/mint-authorization.utils.ts
6250
- var import_ethers2 = require("ethers");
6407
+ var import_ethers3 = require("ethers");
6251
6408
 
6252
6409
  // src/utils/quantum-timing.ts
6253
6410
  var QUANTUM_WINDOW_SECONDS = 60;
@@ -6354,6 +6511,80 @@ async function awaitSafeSubmissionWindowOnChain(signatureQuantum, chainNow, slee
6354
6511
  return { waited: waitedSeconds > 0, waitedSeconds };
6355
6512
  }
6356
6513
 
6514
+ // src/utils/borrower-authorization-712.ts
6515
+ var import_ethers2 = require("ethers");
6516
+ init_deployment_addresses();
6517
+ var BORROWER_AUTHORIZATION_712_DOMAIN_NAME = "DiamondHands.Protocol";
6518
+ var BORROWER_AUTHORIZATION_712_DOMAIN_VERSION = "1";
6519
+ var BORROWER_AUTHORIZATION_712_FIELDS = {
6520
+ MintRequest: [
6521
+ { name: "positionId", type: "bytes32" },
6522
+ { name: "mintAmount", type: "uint256" },
6523
+ { name: "quantumTimestamp", type: "uint256" }
6524
+ ],
6525
+ RepayRequest: [
6526
+ { name: "positionId", type: "bytes32" },
6527
+ { name: "paymentAmount", type: "uint256" },
6528
+ { name: "quantumTimestamp", type: "uint256" }
6529
+ ],
6530
+ RenewRequest: [
6531
+ { name: "positionId", type: "bytes32" },
6532
+ { name: "selectedTerm", type: "uint256" },
6533
+ { name: "quantumTimestamp", type: "uint256" }
6534
+ ],
6535
+ WithdrawRequest: [
6536
+ { name: "positionId", type: "bytes32" },
6537
+ { name: "totalDeduction", type: "uint256" },
6538
+ { name: "withdrawalAddress", type: "string" },
6539
+ { name: "quantumTimestamp", type: "uint256" }
6540
+ ]
6541
+ };
6542
+ function borrowerAuthorization712Types(primaryType) {
6543
+ const fields = BORROWER_AUTHORIZATION_712_FIELDS[primaryType];
6544
+ if (!fields) {
6545
+ throw new Error(
6546
+ `Unknown borrower authorization primary type "${primaryType}"; expected one of ` + Object.keys(BORROWER_AUTHORIZATION_712_FIELDS).join(", ")
6547
+ );
6548
+ }
6549
+ return { [primaryType]: fields.map((field) => ({ ...field })) };
6550
+ }
6551
+ function buildBorrowerAuthorization712Domain(chainId) {
6552
+ if (!Number.isInteger(chainId) || chainId <= 0) {
6553
+ throw new Error(
6554
+ `Borrower authorization domain requires a positive integer chainId, got ${String(chainId)}`
6555
+ );
6556
+ }
6557
+ const deployment = Object.values(ALL_DEPLOYMENTS).find(
6558
+ (d) => d.chainId === chainId
6559
+ );
6560
+ const verifyingContract = deployment?.contracts?.LoanOperationsManagerModule;
6561
+ if (!verifyingContract) {
6562
+ throw new Error(
6563
+ `No LoanOperationsManagerModule deployment known for chainId ${chainId}; refusing to build a borrower authorization domain without one`
6564
+ );
6565
+ }
6566
+ return {
6567
+ name: BORROWER_AUTHORIZATION_712_DOMAIN_NAME,
6568
+ version: BORROWER_AUTHORIZATION_712_DOMAIN_VERSION,
6569
+ chainId,
6570
+ verifyingContract
6571
+ };
6572
+ }
6573
+ async function signBorrowerAuthorization712(signer, primaryType, chainId, message) {
6574
+ const signTypedData = signer.signTypedData;
6575
+ if (typeof signTypedData !== "function") {
6576
+ throw new Error(
6577
+ `Signer has no signTypedData \u2014 cannot produce an EIP-712 ${primaryType}. Wallets without typed-data support must supply the signature via an authorizationProvider instead of a connected signer.`
6578
+ );
6579
+ }
6580
+ return signTypedData.call(
6581
+ signer,
6582
+ buildBorrowerAuthorization712Domain(chainId),
6583
+ borrowerAuthorization712Types(primaryType),
6584
+ message
6585
+ );
6586
+ }
6587
+
6357
6588
  // src/utils/mint-authorization.utils.ts
6358
6589
  var PKP_NFT_ABI = [
6359
6590
  "function getPubkey(uint256 tokenId) external view returns (bytes memory)"
@@ -6367,29 +6598,11 @@ async function generateMintAuthorization(positionId, amount, chainId, signerOrPr
6367
6598
  const signer = signerOrPrecomputed;
6368
6599
  const timestamp = calculateNextQuantumTimestamp();
6369
6600
  const action = "mint-ucd";
6370
- const actionHash = (0, import_ethers2.keccak256)((0, import_ethers2.toUtf8Bytes)(action));
6371
- const types = [
6372
- "bytes32",
6373
- // positionId
6374
- "uint256",
6375
- // timestamp
6376
- "uint256",
6377
- // chainId
6378
- "uint256",
6379
- // amount
6380
- "bytes32"
6381
- // actionHash
6382
- ];
6383
- const values = [
6601
+ const signature = await signBorrowerAuthorization712(signer, "MintRequest", chainId, {
6384
6602
  positionId,
6385
- timestamp,
6386
- chainId,
6387
- amount.toString(),
6388
- actionHash
6389
- ];
6390
- const messageHash = (0, import_ethers2.solidityPackedKeccak256)(types, values);
6391
- const messageHashBytes = (0, import_ethers2.getBytes)(messageHash);
6392
- const signature = await signer.signMessage(messageHashBytes);
6603
+ mintAmount: amount.toString(),
6604
+ quantumTimestamp: timestamp
6605
+ });
6393
6606
  return {
6394
6607
  positionId,
6395
6608
  timestamp,
@@ -6426,44 +6639,17 @@ async function generatePaymentAuthorization(positionId, amount, chainId, signerO
6426
6639
  throw new Error(`timestamp must be a number, got ${typeof timestamp}`);
6427
6640
  }
6428
6641
  const action = "make-payment";
6429
- const actionHash = (0, import_ethers2.keccak256)((0, import_ethers2.toUtf8Bytes)(action));
6430
- if (typeof actionHash !== "string") {
6431
- throw new Error(`actionHash must be a string, got ${typeof actionHash}`);
6432
- }
6433
- const types = [
6434
- "bytes32",
6435
- // positionId
6436
- "uint256",
6437
- // timestamp
6438
- "uint256",
6439
- // chainId
6440
- "uint256",
6441
- // amount
6442
- "bytes32"
6443
- // actionHash
6444
- ];
6445
6642
  const amountStr = amount.toString();
6446
- if (typeof amountStr !== "string") {
6447
- throw new Error(
6448
- `amount.toString() must return a string, got ${typeof amountStr}`
6449
- );
6450
- }
6451
- const values = [positionId, timestamp, chainId, amountStr, actionHash];
6452
- for (let i = 0; i < values.length; i++) {
6453
- if (typeof values[i] === "object" && values[i] !== null) {
6454
- throw new Error(
6455
- `Value at index ${i} is an object: ${JSON.stringify(values[i])}`
6456
- );
6457
- }
6458
- }
6459
- const messageHash = (0, import_ethers2.solidityPackedKeccak256)(types, values);
6460
- const messageHashBytes = (0, import_ethers2.getBytes)(messageHash);
6461
- const signature = await signer.signMessage(messageHashBytes);
6643
+ const signature = await signBorrowerAuthorization712(signer, "RepayRequest", chainId, {
6644
+ positionId,
6645
+ paymentAmount: amountStr,
6646
+ quantumTimestamp: timestamp
6647
+ });
6462
6648
  return {
6463
6649
  positionId,
6464
6650
  timestamp,
6465
6651
  chainId,
6466
- amount: amount.toString(),
6652
+ amount: amountStr,
6467
6653
  action,
6468
6654
  signature
6469
6655
  };
@@ -6532,7 +6718,7 @@ async function getPKPPublicKeyFromTokenId(pkpTokenId, provider, pkpNftContractAd
6532
6718
  `pkpNftContractAddress is required for getPKPPublicKeyFromTokenId`
6533
6719
  );
6534
6720
  }
6535
- const pkpNft = new import_ethers2.Contract(
6721
+ const pkpNft = new import_ethers3.Contract(
6536
6722
  pkpNftContractAddress,
6537
6723
  PKP_NFT_ABI,
6538
6724
  provider
@@ -6550,32 +6736,12 @@ async function generateWithdrawAuthorization(positionId, amount, chainId, signer
6550
6736
  const signer = signerOrPrecomputed;
6551
6737
  const timestamp = calculateNextQuantumTimestamp();
6552
6738
  const action = "withdraw-btc";
6553
- const actionHash = (0, import_ethers2.keccak256)((0, import_ethers2.toUtf8Bytes)(action));
6554
- const types = [
6555
- "bytes32",
6556
- // positionId
6557
- "uint256",
6558
- // timestamp
6559
- "uint256",
6560
- // chainId
6561
- "uint256",
6562
- // amount (in satoshis)
6563
- "string",
6564
- // destinationAddress (Bitcoin address)
6565
- "bytes32"
6566
- // actionHash
6567
- ];
6568
- const values = [
6739
+ const signature = await signBorrowerAuthorization712(signer, "WithdrawRequest", chainId, {
6569
6740
  positionId,
6570
- timestamp,
6571
- chainId,
6572
- amount.toString(),
6573
- destinationAddress,
6574
- actionHash
6575
- ];
6576
- const messageHash = (0, import_ethers2.solidityPackedKeccak256)(types, values);
6577
- const messageHashBytes = (0, import_ethers2.getBytes)(messageHash);
6578
- const signature = await signer.signMessage(messageHashBytes);
6741
+ totalDeduction: amount.toString(),
6742
+ withdrawalAddress: destinationAddress,
6743
+ quantumTimestamp: timestamp
6744
+ });
6579
6745
  return {
6580
6746
  positionId,
6581
6747
  timestamp,
@@ -6589,7 +6755,7 @@ async function generateBalanceConfirmationAuthorization(positionId, chainId, sig
6589
6755
  const timestamp = calculateNextQuantumTimestamp();
6590
6756
  const caller = await signer.getAddress();
6591
6757
  const action = "confirm-balance";
6592
- const actionHash = (0, import_ethers2.keccak256)((0, import_ethers2.toUtf8Bytes)(action));
6758
+ const actionHash = (0, import_ethers3.keccak256)((0, import_ethers3.toUtf8Bytes)(action));
6593
6759
  const types = [
6594
6760
  "bytes32",
6595
6761
  // positionId
@@ -6603,8 +6769,8 @@ async function generateBalanceConfirmationAuthorization(positionId, chainId, sig
6603
6769
  // actionHash
6604
6770
  ];
6605
6771
  const values = [positionId, timestamp, chainId, caller, actionHash];
6606
- const messageHash = (0, import_ethers2.solidityPackedKeccak256)(types, values);
6607
- const messageHashBytes = (0, import_ethers2.getBytes)(messageHash);
6772
+ const messageHash = (0, import_ethers3.solidityPackedKeccak256)(types, values);
6773
+ const messageHashBytes = (0, import_ethers3.getBytes)(messageHash);
6608
6774
  const signature = await signer.signMessage(messageHashBytes);
6609
6775
  return {
6610
6776
  positionId,
@@ -6617,7 +6783,6 @@ async function generateBalanceConfirmationAuthorization(positionId, chainId, sig
6617
6783
  }
6618
6784
 
6619
6785
  // src/utils/extend-authorization.utils.ts
6620
- var import_ethers3 = require("ethers");
6621
6786
  async function generateExtendAuthorization(positionId, newTerm, chainId, signerOrPrecomputed) {
6622
6787
  if (typeof signerOrPrecomputed === "object" && "signature" in signerOrPrecomputed && !("signMessage" in signerOrPrecomputed)) {
6623
6788
  const { timestamp: timestamp2, signature: signature2 } = signerOrPrecomputed;
@@ -6627,29 +6792,11 @@ async function generateExtendAuthorization(positionId, newTerm, chainId, signerO
6627
6792
  const signer = signerOrPrecomputed;
6628
6793
  const timestamp = calculateNextQuantumTimestamp();
6629
6794
  const action = "extend-position";
6630
- const actionHash = (0, import_ethers3.keccak256)((0, import_ethers3.toUtf8Bytes)(action));
6631
- const types = [
6632
- "bytes32",
6633
- // positionId
6634
- "uint256",
6635
- // timestamp
6636
- "uint256",
6637
- // chainId
6638
- "uint256",
6639
- // newTerm (extension term in months)
6640
- "bytes32"
6641
- // actionHash
6642
- ];
6643
- const values = [
6795
+ const signature = await signBorrowerAuthorization712(signer, "RenewRequest", chainId, {
6644
6796
  positionId,
6645
- timestamp,
6646
- chainId,
6647
- newTerm,
6648
- actionHash
6649
- ];
6650
- const messageHash = (0, import_ethers3.solidityPackedKeccak256)(types, values);
6651
- const messageHashBytes = (0, import_ethers3.getBytes)(messageHash);
6652
- const signature = await signer.signMessage(messageHashBytes);
6797
+ selectedTerm: newTerm,
6798
+ quantumTimestamp: timestamp
6799
+ });
6653
6800
  return {
6654
6801
  positionId,
6655
6802
  timestamp,
@@ -10879,6 +11026,7 @@ function createLoanQuery(config) {
10879
11026
 
10880
11027
  // src/modules/withdrawal-address/withdrawal-address.module.ts
10881
11028
  var import_ethers13 = require("ethers");
11029
+ var STATIC_CALL_DIAGNOSTIC_TIMEOUT_MS = 5e3;
10882
11030
  var WithdrawalAddressModule = class {
10883
11031
  config;
10884
11032
  graphClient;
@@ -10923,13 +11071,17 @@ var WithdrawalAddressModule = class {
10923
11071
  const reg = this.getRegistry();
10924
11072
  if (!reg.success)
10925
11073
  return reg;
11074
+ const normalized = normalizeBitcoinAddress(btcAddress);
10926
11075
  try {
10927
- const tx = await reg.value.addAddress(
10928
- normalizeBitcoinAddress(btcAddress)
10929
- );
11076
+ const tx = await reg.value.addAddress(normalized);
10930
11077
  return success(tx);
10931
11078
  } catch (error) {
10932
- return this.txFailure("addAddress", error, btcAddress);
11079
+ return this.txFailure(
11080
+ "addAddress",
11081
+ error,
11082
+ btcAddress,
11083
+ await this.staticCallDiagnostic(reg.value, "addAddress", normalized)
11084
+ );
10933
11085
  }
10934
11086
  }
10935
11087
  /** Remove a Bitcoin address from the caller's allowlist (effective immediately). */
@@ -10937,13 +11089,17 @@ var WithdrawalAddressModule = class {
10937
11089
  const reg = this.getRegistry();
10938
11090
  if (!reg.success)
10939
11091
  return reg;
11092
+ const normalized = normalizeBitcoinAddress(btcAddress);
10940
11093
  try {
10941
- const tx = await reg.value.removeAddress(
10942
- normalizeBitcoinAddress(btcAddress)
10943
- );
11094
+ const tx = await reg.value.removeAddress(normalized);
10944
11095
  return success(tx);
10945
11096
  } catch (error) {
10946
- return this.txFailure("removeAddress", error, btcAddress);
11097
+ return this.txFailure(
11098
+ "removeAddress",
11099
+ error,
11100
+ btcAddress,
11101
+ await this.staticCallDiagnostic(reg.value, "removeAddress", normalized)
11102
+ );
10947
11103
  }
10948
11104
  }
10949
11105
  /**
@@ -11039,16 +11195,59 @@ var WithdrawalAddressModule = class {
11039
11195
  }
11040
11196
  return success(void 0);
11041
11197
  }
11042
- txFailure(op, error, context) {
11198
+ /**
11199
+ * Ask the node for the reason a failed write did not carry.
11200
+ *
11201
+ * A failing `eth_estimateGas` frequently answers with NOTHING to decode — ethers renders that
11202
+ * as `missing revert data ... data=null, reason=null, revert=null`, which names no cause and
11203
+ * cannot distinguish "the contract rejected this" from "the RPC hiccuped". An `eth_call` of the
11204
+ * same calldata usually does carry the revert reason or custom-error selector, so this runs one
11205
+ * and folds the answer into the reported error.
11206
+ *
11207
+ * Three deliberate properties:
11208
+ *
11209
+ * 1. It runs ONLY after the write has already failed. Gating the write on a static call would
11210
+ * let a flaky endpoint — precisely the condition this exists to diagnose — block an add that
11211
+ * would otherwise have succeeded.
11212
+ * 2. It costs NO extra signature. `staticCall` is `eth_call`: a node read, never a wallet prompt.
11213
+ * 3. It can never throw. A diagnostic that escapes would replace the real cause with itself.
11214
+ * (The `try/catch` here is the authorized exception to CLAUDE.md's forbidden-patterns rule;
11215
+ * it swallows nothing — every branch returns text that is reported alongside the original.)
11216
+ *
11217
+ * A static call that SUCCEEDS is itself a finding: the contract accepts this call, so the
11218
+ * failure lay outside contract logic (RPC, gas, or nonce).
11219
+ */
11220
+ async staticCallDiagnostic(registry, op, normalizedAddress) {
11221
+ try {
11222
+ await Promise.race([
11223
+ registry[op].staticCall(normalizedAddress),
11224
+ // The failure being diagnosed is often an unresponsive endpoint, so the diagnostic must
11225
+ // not inherit that hang — the user is waiting on this error message.
11226
+ new Promise(
11227
+ (_, reject) => setTimeout(
11228
+ () => reject(new Error("static call timed out after 5s")),
11229
+ STATIC_CALL_DIAGNOSTIC_TIMEOUT_MS
11230
+ )
11231
+ )
11232
+ ]);
11233
+ return "static call SUCCEEDED \u2014 the contract accepts this call, so the failure was not contract logic (RPC, gas, or nonce)";
11234
+ } catch (diagnostic) {
11235
+ const code = typeof diagnostic === "object" && diagnostic !== null ? diagnostic.code : void 0;
11236
+ const msg = diagnostic instanceof Error ? diagnostic.message : String(diagnostic);
11237
+ return typeof code === "string" ? `static call reverted [${code}]: ${msg}` : `static call failed: ${msg}`;
11238
+ }
11239
+ }
11240
+ txFailure(op, error, context, diagnostic) {
11043
11241
  const msg = error instanceof Error ? error.message : String(error);
11242
+ const detail = diagnostic ? `${msg} \u2014 ${diagnostic}` : msg;
11044
11243
  return failure(
11045
11244
  new SDKError({
11046
11245
  code: `SDK_WITHDRAWAL_REGISTRY_${op.toUpperCase()}_FAILED`,
11047
- message: `WithdrawalAddressRegistry.${op} failed: ${msg}`,
11246
+ message: `WithdrawalAddressRegistry.${op} failed: ${detail}`,
11048
11247
  category: "CONTRACT" /* CONTRACT */,
11049
11248
  severity: "MEDIUM" /* MEDIUM */,
11050
11249
  originalError: error instanceof Error ? error : new Error(String(error)),
11051
- context: { op, context }
11250
+ context: { op, context, diagnostic }
11052
11251
  })
11053
11252
  );
11054
11253
  }
@@ -12139,6 +12338,47 @@ function normalizePkpId2(pkpId) {
12139
12338
  }
12140
12339
  return pkpId;
12141
12340
  }
12341
+ function applyLoanEventsFilter(events, opts) {
12342
+ const { wantsEvent, fromTimestamp, toTimestamp, fromBlock, toBlock, limit } = opts;
12343
+ const inBounds = (e) => {
12344
+ const ts = e?.timestamp;
12345
+ const bn = e?.blockNumber;
12346
+ try {
12347
+ if (fromTimestamp !== void 0 && ts !== void 0 && BigInt(ts) < BigInt(fromTimestamp))
12348
+ return false;
12349
+ if (toTimestamp !== void 0 && ts !== void 0 && BigInt(ts) > BigInt(toTimestamp))
12350
+ return false;
12351
+ if (fromBlock !== void 0 && bn !== void 0 && BigInt(bn) < BigInt(fromBlock))
12352
+ return false;
12353
+ if (toBlock !== void 0 && bn !== void 0 && BigInt(bn) > BigInt(toBlock))
12354
+ return false;
12355
+ } catch {
12356
+ return true;
12357
+ }
12358
+ return true;
12359
+ };
12360
+ const narrow = (list, kind) => wantsEvent(kind) ? (list ?? []).filter(inBounds).slice(0, limit) : [];
12361
+ const single = (value, kind) => value && wantsEvent(kind) && inBounds(value) ? value : void 0;
12362
+ const filtered = {
12363
+ ...events,
12364
+ positionCreated: single(events.positionCreated, "positionCreated"),
12365
+ payments: narrow(events.payments, "payment"),
12366
+ statusUpdates: narrow(events.statusUpdates, "status"),
12367
+ liquidation: single(events.liquidation, "liquidation"),
12368
+ mints: narrow(events.mints, "mint"),
12369
+ withdrawals: narrow(events.withdrawals, "withdrawal"),
12370
+ renewals: narrow(events.renewals, "renewal"),
12371
+ operationFailures: narrow(events.operationFailures, "operationFailure"),
12372
+ mintRequests: narrow(events.mintRequests, "mintRequest"),
12373
+ burnRequests: narrow(events.burnRequests, "burnRequest"),
12374
+ collateralEvents: narrow(events.collateralEvents, "collateralEvent"),
12375
+ mintingFees: narrow(events.mintingFees, "mintingFee"),
12376
+ renewalFees: narrow(events.renewalFees, "renewalFee"),
12377
+ totalEvents: 0
12378
+ };
12379
+ filtered.totalEvents = (filtered.positionCreated ? 1 : 0) + (filtered.liquidation ? 1 : 0) + filtered.payments.length + filtered.statusUpdates.length + filtered.mints.length + filtered.withdrawals.length + filtered.renewals.length + filtered.operationFailures.length + filtered.mintRequests.length + filtered.burnRequests.length + filtered.collateralEvents.length + filtered.mintingFees.length + filtered.renewalFees.length;
12380
+ return filtered;
12381
+ }
12142
12382
  function hasLoanEventsFilter(filter) {
12143
12383
  if (!filter)
12144
12384
  return false;
@@ -13295,32 +13535,24 @@ var DiamondHandsGraph = class {
13295
13535
  limit = 1e3,
13296
13536
  orderDirection = "desc"
13297
13537
  } = filter || {};
13538
+ const wantsEvent = (kind) => !eventTypes || eventTypes.includes(kind);
13539
+ const hasBounds = fromTimestamp !== void 0 || toTimestamp !== void 0 || fromBlock !== void 0 || toBlock !== void 0;
13540
+ const pageSize = hasBounds ? THE_GRAPH_MAX_BATCH_SIZE : limit;
13541
+ const buildPositionWhereClause = () => `where: { position: "${positionId.toLowerCase()}" }`;
13298
13542
  const shouldQuery = {
13299
- positionCreated: !eventTypes || eventTypes.includes("positionCreated"),
13300
- payment: !eventTypes || eventTypes.includes("payment"),
13301
- status: !eventTypes || eventTypes.includes("status"),
13302
- liquidation: !eventTypes || eventTypes.includes("liquidation"),
13303
- mint: !eventTypes || eventTypes.includes("mint"),
13304
- withdrawal: !eventTypes || eventTypes.includes("withdrawal"),
13305
- renewal: !eventTypes || eventTypes.includes("renewal"),
13306
- operationFailure: !eventTypes || eventTypes.includes("operationFailure"),
13307
- mintRequest: !eventTypes || eventTypes.includes("mintRequest"),
13308
- burnRequest: !eventTypes || eventTypes.includes("burnRequest"),
13309
- collateralEvent: !eventTypes || eventTypes.includes("collateralEvent"),
13310
- mintingFee: !eventTypes || eventTypes.includes("mintingFee"),
13311
- renewalFee: !eventTypes || eventTypes.includes("renewalFee")
13312
- };
13313
- const buildPositionWhereClause = () => {
13314
- const conditions = [`position: "${positionId.toLowerCase()}"`];
13315
- if (fromTimestamp)
13316
- conditions.push(`timestamp_gte: "${fromTimestamp}"`);
13317
- if (toTimestamp)
13318
- conditions.push(`timestamp_lte: "${toTimestamp}"`);
13319
- if (fromBlock)
13320
- conditions.push(`blockNumber_gte: "${fromBlock}"`);
13321
- if (toBlock)
13322
- conditions.push(`blockNumber_lte: "${toBlock}"`);
13323
- return `where: { ${conditions.join(", ")} }`;
13543
+ positionCreated: true,
13544
+ payment: true,
13545
+ status: true,
13546
+ liquidation: true,
13547
+ mint: true,
13548
+ withdrawal: true,
13549
+ renewal: true,
13550
+ operationFailure: true,
13551
+ mintRequest: true,
13552
+ burnRequest: true,
13553
+ collateralEvent: true,
13554
+ mintingFee: true,
13555
+ renewalFee: true
13324
13556
  };
13325
13557
  const query = `
13326
13558
  query GetLoanEvents($positionId: Bytes!, $limit: Int!, $orderDirection: OrderDirection!) {
@@ -13556,11 +13788,41 @@ var DiamondHandsGraph = class {
13556
13788
  `;
13557
13789
  const variables = {
13558
13790
  positionId: positionId.toLowerCase(),
13559
- limit,
13791
+ limit: pageSize,
13560
13792
  orderDirection
13561
13793
  };
13562
13794
  const result = await this.client.execute(query, variables);
13563
- return this.assembleLoanEvents(positionId, result);
13795
+ if (hasBounds) {
13796
+ const collections = [
13797
+ ["payments", result.position?.payments],
13798
+ ["statusUpdates", result.position?.statusUpdates],
13799
+ ["withdrawals", result.position?.withdrawals],
13800
+ ["renewals", result.position?.renewals],
13801
+ ["operationFailures", result.position?.operationFailures],
13802
+ ["mintRequests", result.position?.mintRequests],
13803
+ ["burnRequests", result.position?.burnRequests],
13804
+ ["mintingFees", result.position?.mintingFees],
13805
+ ["renewalFees", result.position?.renewalFees],
13806
+ ["mints", result.ucdmintEvents],
13807
+ ["collateralEvents", result.collateralEvents]
13808
+ ];
13809
+ const saturated = collections.filter(([, list]) => (list?.length ?? 0) >= pageSize).map(([name]) => name);
13810
+ if (saturated.length > 0) {
13811
+ log.warn(
13812
+ "[DiamondHandsGraph] bounded getLoanEvents page saturated \u2014 the filtered history may be incomplete",
13813
+ { positionId, pageSize, saturated }
13814
+ );
13815
+ }
13816
+ }
13817
+ const assembled = this.assembleLoanEvents(positionId, result);
13818
+ return applyLoanEventsFilter(assembled, {
13819
+ wantsEvent,
13820
+ fromTimestamp,
13821
+ toTimestamp,
13822
+ fromBlock,
13823
+ toBlock,
13824
+ limit
13825
+ });
13564
13826
  }
13565
13827
  /**
13566
13828
  * Map one position's raw event payload into `LoanEvents`.
@@ -21004,6 +21266,7 @@ Message: ${causeMessage}${quantumContext}${mintDebtDiagnostics}`
21004
21266
  }
21005
21267
  const tx = await sendEip1559Transaction({
21006
21268
  signer,
21269
+ feeProvider: this.getProviderOrThrow(),
21007
21270
  to: positionManagerAddress,
21008
21271
  data: mintCalldata,
21009
21272
  gasLimit: MINT_UCD_GAS_CEILING
@@ -22225,6 +22488,7 @@ Message: ${causeMessage}${quantumContext}${mintDebtDiagnostics}`
22225
22488
  }
22226
22489
  const tx = await sendEip1559Transaction({
22227
22490
  signer: extendSigner,
22491
+ feeProvider: this.getProviderOrThrow(),
22228
22492
  to: extendTo,
22229
22493
  data: extendCalldata,
22230
22494
  gasLimit: EXTEND_POSITION_GAS_CEILING
@@ -23153,6 +23417,7 @@ Message: ${causeMessage}${quantumContext}${mintDebtDiagnostics}`
23153
23417
  }
23154
23418
  const tx = await sendEip1559Transaction({
23155
23419
  signer: paymentSigner,
23420
+ feeProvider: this.getProviderOrThrow(),
23156
23421
  to: paymentContractAddress,
23157
23422
  data: paymentCalldata,
23158
23423
  gasLimit: MAKE_PAYMENT_GAS_CEILING
@@ -23918,6 +24183,7 @@ Message: ${causeMessage}${quantumContext}${mintDebtDiagnostics}`
23918
24183
  });
23919
24184
  tx = await sendEip1559Transaction({
23920
24185
  signer: withdrawSigner,
24186
+ feeProvider: this.getProviderOrThrow(),
23921
24187
  to: positionManagerAddress,
23922
24188
  data: withdrawCalldata,
23923
24189
  gasLimit: WITHDRAW_BTC_GAS_CEILING