@gvnrdao/dh-sdk 0.0.342 → 0.0.344

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
@@ -88,7 +88,6 @@ var init_deployment_addresses = __esm({
88
88
  PositionDelegateRegistry: "0x482369De283622E7b05731875ec137d4E3D208F9",
89
89
  FeeRecipientRegistry: "0x95795F8403DDb629E8527B2934C4e71f5fC0C374",
90
90
  BitcoinWithdrawalAddressRegistry: "0x6376D392097F0A81e51BD83960A97EA20eaf1dbe",
91
- CarryAgentRegistry: "0x5595CB538D44E6Cf179D20364fD631D0477e69f7",
92
91
  AgentDelegationRegistry: "0x6AE7fc6bE0925126b9D25b1B7Ce5AD5d127ec025",
93
92
  DHAgentDelegate: "0xa5A14489ae883960df6E1463A41a47aBE9Ecc5AF",
94
93
  AgentModuleFactory: "0x1Fd3aCa2C030Cf77ce28Af9694D3Bb3034ACa2E5"
@@ -137,11 +136,11 @@ var init_deployment_addresses = __esm({
137
136
  reason: "Shared upgrade script: AdminModule implementation update"
138
137
  },
139
138
  PositionManagerViews: {
140
- previousImplementation: "0x1EB2B1d058006ACd9033E01e846D73eDE686b620",
141
- newImplementation: "0xA455B542cFb36AF8451fc420dB89e590E5c87cef",
142
- upgradedAt: "2026-07-03T20:11:25.817Z",
143
- upgradedBy: "0xF20986F02420EF443AE9BE5092FB8A4975cF3aA6",
144
- reason: "Shared upgrade script: PositionManagerViews implementation update"
139
+ previousImplementation: "0xA455B542cFb36AF8451fc420dB89e590E5c87cef",
140
+ newImplementation: "0x8cEB3F1c07fDB3301f55b96a5B9aDb33C8d36Da3",
141
+ upgradedAt: "2026-10-02T17:04:25.853Z",
142
+ upgradedBy: "0x0f8f23674cc90Ef7107930a4437341fD8B460362",
143
+ reason: "1.1.2: getBackingVaults (PoR backing set) + implementation lock (constructor)"
145
144
  },
146
145
  TestPositionManager: {
147
146
  previousImplementation: "0x0B46Ee1a9C6b42559758B7FF78294Cd867BB08f8",
@@ -358,8 +357,6 @@ var init_deployment_addresses = __esm({
358
357
  OPERATION_AUTHORIZATION_REGISTRY_IMPL: "0xe0D981B60351f0f8fFDA2b50C8180Fb37CeF3883",
359
358
  BITCOIN_WITHDRAWAL_ADDRESS_REGISTRY: "0x6376D392097F0A81e51BD83960A97EA20eaf1dbe",
360
359
  BITCOIN_WITHDRAWAL_ADDRESS_REGISTRY_IMPL: "0x76E0a2c9d89562fD7c50b5f554d7fa25957e39Db",
361
- CARRY_AGENT_REGISTRY: "0x5595CB538D44E6Cf179D20364fD631D0477e69f7",
362
- CARRY_AGENT_REGISTRY_IMPL: "0x1b11a3D5e46F3672E643c997f0d569DFf0b64a01",
363
360
  AGENT_DELEGATION_REGISTRY: "0x6AE7fc6bE0925126b9D25b1B7Ce5AD5d127ec025",
364
361
  AGENT_DELEGATION_REGISTRY_IMPL: "0xE931E4b9ceF2A48Ac7D57192da4B523756cFC310",
365
362
  DH_AGENT_DELEGATE: "0xa5A14489ae883960df6E1463A41a47aBE9Ecc5AF"
@@ -391,7 +388,6 @@ var init_deployment_addresses = __esm({
391
388
  PositionDelegateRegistry: "0x482369De283622E7b05731875ec137d4E3D208F9",
392
389
  FeeRecipientRegistry: "0x95795F8403DDb629E8527B2934C4e71f5fC0C374",
393
390
  BitcoinWithdrawalAddressRegistry: "0x6376D392097F0A81e51BD83960A97EA20eaf1dbe",
394
- CarryAgentRegistry: "0x5595CB538D44E6Cf179D20364fD631D0477e69f7",
395
391
  AgentDelegationRegistry: "0x6AE7fc6bE0925126b9D25b1B7Ce5AD5d127ec025",
396
392
  DHAgentDelegate: "0xa5A14489ae883960df6E1463A41a47aBE9Ecc5AF",
397
393
  AgentModuleFactory: "0x1Fd3aCa2C030Cf77ce28Af9694D3Bb3034ACa2E5"
@@ -1368,113 +1364,113 @@ var require_pkg_src = __commonJS({
1368
1364
  deployedAt: 1784569687492,
1369
1365
  size: 4140,
1370
1366
  hash: "4c0d65bf1f33cdac22a78fd8c4764319cc3fe00650e0fe7fa8a6090d9a318a7b",
1371
- validatorWalletAddress: "0x82db9f515957aa380b596c6ea2bd30cef181f236",
1367
+ validatorWalletAddress: "0xefb258d455a31d061bbeb3de3d2143bdfcb67a6c",
1372
1368
  pkp: {
1373
1369
  publicKey: "0x04ec0e3acc40884e3f366ca469d08899eb640ad5259fa196b0238075086208a9f8732a3175704f35f0bcc28e07406cfb24c254efd1e7355640577330f0d2dd755f",
1374
- ethAddress: "0xc7e1588Db94Bbe92Ab209B833235144Fc5b97607"
1370
+ ethAddress: "0xEfb258D455a31d061Bbeb3DE3D2143BdFCB67a6C"
1375
1371
  }
1376
1372
  },
1377
1373
  btcTransactionSigner: {
1378
- cid: "QmVi1BYdxvCX3QUhXwPtP6FjWMzqSPtXzrS54YsXjTgjYf",
1374
+ cid: "QmULkz7hwwqsyLwY23U14dnartdVuSNMrykt69PaNiAq7U",
1379
1375
  authorizedCidHex: cidToHex(
1380
- "QmVi1BYdxvCX3QUhXwPtP6FjWMzqSPtXzrS54YsXjTgjYf"
1376
+ "QmULkz7hwwqsyLwY23U14dnartdVuSNMrykt69PaNiAq7U"
1381
1377
  ),
1382
1378
  name: "Btc Transaction Signer",
1383
1379
  description: "Production Btc Transaction Signer",
1384
1380
  version: "1.1.1",
1385
1381
  deployed: true,
1386
- deployedAt: 1787923905597,
1387
- size: 70646,
1388
- hash: "37c3bb72a660c8275d92e1b73f9482742d86b64789480b9246304c0ca1bab47a"
1382
+ deployedAt: 1790246185256,
1383
+ size: 73313,
1384
+ hash: "d8b6bc646ba33fee7d46c8e9b281de776081ea6f182f56fd15d4c52aaf3dd030"
1389
1385
  },
1390
1386
  ucdMintValidator: {
1391
- cid: "QmUWR5fLiyimLT9TPXpYx3HgwNwkvR6MxjZ7hdeYCFodbc",
1387
+ cid: "QmcxVSn9saEPGBS6mqPhNefgW83V2qeZjjXbhwYLP373xe",
1392
1388
  authorizedCidHex: cidToHex(
1393
- "QmUWR5fLiyimLT9TPXpYx3HgwNwkvR6MxjZ7hdeYCFodbc"
1389
+ "QmcxVSn9saEPGBS6mqPhNefgW83V2qeZjjXbhwYLP373xe"
1394
1390
  ),
1395
1391
  name: "Ucd Mint Validator",
1396
1392
  description: "Production Ucd Mint Validator",
1397
- version: "1.2.1",
1393
+ version: "1.3.0",
1398
1394
  deployed: true,
1399
- deployedAt: 1787923919527,
1400
- size: 86197,
1401
- hash: "c2d80939746cc37f65ef2f63c6a3215b929214a63f10c78144e1f5c98320dabf",
1402
- validatorWalletAddress: "0x82DB9F515957aA380B596C6eA2Bd30CEF181f236",
1395
+ deployedAt: 1790246219868,
1396
+ size: 90022,
1397
+ hash: "65e8cb778c2b767ae6eb37cb5db7b4c5a3f2468d508463c847c83c1b6825fadd",
1398
+ validatorWalletAddress: "0xEfb258D455a31d061Bbeb3DE3D2143BdFCB67a6C",
1403
1399
  pkp: {
1404
1400
  publicKey: "0x041ab17cd91fc5c0b761eea6092d032807561b621b82c488826776e04a9158d61ba64d809a4729f0501289d980732cb06d8dfd06999dd9c8efd2f495dad78b31bb",
1405
- ethAddress: "0xc7e1588Db94Bbe92Ab209B833235144Fc5b97607"
1401
+ ethAddress: "0xEfb258D455a31d061Bbeb3DE3D2143BdFCB67a6C"
1406
1402
  }
1407
1403
  },
1408
1404
  processPaymentValidator: {
1409
- cid: "QmXmXuMRAjMLdgKGyTf9KQdGwYrDp8DxkiF44TvSXDf7wF",
1405
+ cid: "QmWFbxJkfxhCtES4wrePWQkYtjhtrP1tohvn9d1r9N5Hd8",
1410
1406
  authorizedCidHex: cidToHex(
1411
- "QmXmXuMRAjMLdgKGyTf9KQdGwYrDp8DxkiF44TvSXDf7wF"
1407
+ "QmWFbxJkfxhCtES4wrePWQkYtjhtrP1tohvn9d1r9N5Hd8"
1412
1408
  ),
1413
1409
  name: "Process Payment Validator",
1414
1410
  description: "Production Process Payment Validator",
1415
1411
  version: "1.2.1",
1416
1412
  deployed: true,
1417
- deployedAt: 1787923987153,
1418
- size: 82217,
1419
- hash: "13defa19614215ab3b1fe88955d69e530d13a09475396af932fe0e213637da2f",
1420
- validatorWalletAddress: "0x82DB9F515957aA380B596C6eA2Bd30CEF181f236",
1413
+ deployedAt: 1790246225795,
1414
+ size: 85107,
1415
+ hash: "25ecf952c4c44c40b0920b92d57906e7010ed9a38e2ba41ccdee6d3377c2b596",
1416
+ validatorWalletAddress: "0xEfb258D455a31d061Bbeb3DE3D2143BdFCB67a6C",
1421
1417
  pkp: {
1422
1418
  publicKey: "0x04cfccb9b6c7addc79469c0e9fafebef4c70801302c62cdb26b610723a9b8527d23f98a40158c7340d83fd0e62d02b5ec74c12f7a86d98e8c6973b4811110f19ad",
1423
- ethAddress: "0xc7e1588Db94Bbe92Ab209B833235144Fc5b97607"
1419
+ ethAddress: "0xEfb258D455a31d061Bbeb3DE3D2143BdFCB67a6C"
1424
1420
  }
1425
1421
  },
1426
1422
  extendPositionValidator: {
1427
- cid: "QmU8h99EEVEsQkxroXiYqLsKZw9gNjE6N5CcTpE9aUc12m",
1423
+ cid: "QmZ3g7g5DkgU1gEYpFjprQf3sctUHtGjNQVYezw2bnPGEX",
1428
1424
  authorizedCidHex: cidToHex(
1429
- "QmU8h99EEVEsQkxroXiYqLsKZw9gNjE6N5CcTpE9aUc12m"
1425
+ "QmZ3g7g5DkgU1gEYpFjprQf3sctUHtGjNQVYezw2bnPGEX"
1430
1426
  ),
1431
1427
  name: "Extend Position Validator",
1432
1428
  description: "Production Extend Position Validator",
1433
1429
  version: "1.2.1",
1434
1430
  deployed: true,
1435
- deployedAt: 1787923999294,
1436
- size: 79975,
1437
- hash: "31c1aaf883ef22f37681ddb0a4a949be5c05304b6aef178989475a2da935ef9a",
1438
- validatorWalletAddress: "0x82DB9F515957aA380B596C6eA2Bd30CEF181f236",
1431
+ deployedAt: 1790246231975,
1432
+ size: 82853,
1433
+ hash: "25d4887b7f646649db2bb7f2bfb77d039db83228a6c454377ca26c779b0903cc",
1434
+ validatorWalletAddress: "0xEfb258D455a31d061Bbeb3DE3D2143BdFCB67a6C",
1439
1435
  pkp: {
1440
1436
  publicKey: "0x04e52338f6a0c3362800f1a94c4c8f08be5030dde0fa217388c53d1c1a4790f4443c9f2886b2d2d8f4b75a9a156e9b028011b1a1cf7648da0e556aa980ec692836",
1441
- ethAddress: "0xc7e1588Db94Bbe92Ab209B833235144Fc5b97607"
1437
+ ethAddress: "0xEfb258D455a31d061Bbeb3DE3D2143BdFCB67a6C"
1442
1438
  }
1443
1439
  },
1444
1440
  btcWithdrawal: {
1445
- cid: "QmZQWET9pzrVD4gwQuSzYZmqa24JrUNtnnGFDd513sxMCY",
1441
+ cid: "QmbRaaMQr1jCctDGe8mPADsUz1rkb4frT1YqSKroiXjzyP",
1446
1442
  authorizedCidHex: cidToHex(
1447
- "QmZQWET9pzrVD4gwQuSzYZmqa24JrUNtnnGFDd513sxMCY"
1443
+ "QmbRaaMQr1jCctDGe8mPADsUz1rkb4frT1YqSKroiXjzyP"
1448
1444
  ),
1449
1445
  name: "Btc Withdrawal",
1450
1446
  description: "Production Btc Withdrawal",
1451
1447
  version: "1.2.7",
1452
1448
  deployed: true,
1453
- deployedAt: 1787924017769,
1454
- size: 100069,
1455
- hash: "4f8e27414e4da235e63d6ae1325c63f3d2fb956464515a21aa007a99935f0f13",
1456
- validatorWalletAddress: "0x82DB9F515957aA380B596C6eA2Bd30CEF181f236",
1449
+ deployedAt: 1790246239599,
1450
+ size: 101228,
1451
+ hash: "2ed25eca6cc80a43061b7ad119737af48158fdb61d59f10cd06cea51b607f112",
1452
+ validatorWalletAddress: "0xEfb258D455a31d061Bbeb3DE3D2143BdFCB67a6C",
1457
1453
  pkp: {
1458
1454
  publicKey: "0x043616787c5432415c24378c4ef48de2bcd6bb7b575b837e3cff09171802662da7105d79586c7659677a0ecbaddac4cce06cb2a11f69a16fa0c4d7002ac7d51a4d",
1459
- ethAddress: "0xc7e1588Db94Bbe92Ab209B833235144Fc5b97607"
1455
+ ethAddress: "0xEfb258D455a31d061Bbeb3DE3D2143BdFCB67a6C"
1460
1456
  }
1461
1457
  },
1462
1458
  liquidationValidator: {
1463
- cid: "Qme6aGADhiszkQbZL977E6nmBacd2PEB7K9Hs8puVrscNx",
1459
+ cid: "QmTs2w8gfAwWZLbzJZg2CZmiLhVXS5kbMgaj42Zuxfodpb",
1464
1460
  authorizedCidHex: cidToHex(
1465
- "Qme6aGADhiszkQbZL977E6nmBacd2PEB7K9Hs8puVrscNx"
1461
+ "QmTs2w8gfAwWZLbzJZg2CZmiLhVXS5kbMgaj42Zuxfodpb"
1466
1462
  ),
1467
1463
  name: "Liquidation Validator",
1468
1464
  description: "Production Liquidation Validator",
1469
1465
  version: "1.2.1",
1470
1466
  deployed: true,
1471
- deployedAt: 1785173262533,
1472
- size: 66846,
1473
- hash: "b35ee7706d733d625faa4dbe37f73c8e20f0c1befa897cd7875e827de52003de",
1474
- validatorWalletAddress: "0x82DB9F515957aA380B596C6eA2Bd30CEF181f236",
1467
+ deployedAt: 1790246247904,
1468
+ size: 70308,
1469
+ hash: "582ccf0ec7f715195e20fdc885996743cb42125b64173424e360ee63db62bbd8",
1470
+ validatorWalletAddress: "0xEfb258D455a31d061Bbeb3DE3D2143BdFCB67a6C",
1475
1471
  pkp: {
1476
1472
  publicKey: "0x041a241de58976c13e3d7ca5a18e494f7330151e3818706135d50176e78ffb673e58b11f0b67a87c73fade6c6b27d6e7a7377ea9f4c10bf31880f1d725f18cc6f8",
1477
- ethAddress: "0xc7e1588Db94Bbe92Ab209B833235144Fc5b97607"
1473
+ ethAddress: "0xEfb258D455a31d061Bbeb3DE3D2143BdFCB67a6C"
1478
1474
  }
1479
1475
  },
1480
1476
  priceOracle: {
@@ -1489,28 +1485,28 @@ var require_pkg_src = __commonJS({
1489
1485
  deployedAt: 1781116663270,
1490
1486
  size: 8695,
1491
1487
  hash: "ba20ade60a7fa5acd80dadfafa179c507388cfe6ce48a22a672d70b317ffcc74",
1492
- validatorWalletAddress: "0x82db9f515957aa380b596c6ea2bd30cef181f236",
1488
+ validatorWalletAddress: "0xefb258d455a31d061bbeb3de3d2143bdfcb67a6c",
1493
1489
  pkp: {
1494
1490
  publicKey: "0x043beaa1da47875601a8d6f430b1438ee2d4732eefd06e5c63a474bbdaf9e7df1797b1b951e041b627c2bf839788164825324c9cbd1e2d6f740fdd4bff69b1900b",
1495
- ethAddress: "0xc7e1588Db94Bbe92Ab209B833235144Fc5b97607"
1491
+ ethAddress: "0xEfb258D455a31d061Bbeb3DE3D2143BdFCB67a6C"
1496
1492
  }
1497
1493
  },
1498
1494
  loanVaultBtcBalance: {
1499
- cid: "QmaeQoHYvcMYobNbu9hQavGDudi8AXoW9tg3YHrvy1g2A4",
1495
+ cid: "QmZ27xCzuoaAhWxRsMPsUQkp45a8WPBb21uhxwchw3LG5W",
1500
1496
  authorizedCidHex: cidToHex(
1501
- "QmaeQoHYvcMYobNbu9hQavGDudi8AXoW9tg3YHrvy1g2A4"
1497
+ "QmZ27xCzuoaAhWxRsMPsUQkp45a8WPBb21uhxwchw3LG5W"
1502
1498
  ),
1503
1499
  name: "Loan Vault Btc Balance",
1504
1500
  description: "Production Loan Vault Btc Balance",
1505
1501
  version: "1.2.1",
1506
1502
  deployed: true,
1507
- deployedAt: 1785173271802,
1508
- size: 56800,
1509
- hash: "a059133214e6ba0a73d655a15600c4b33e361fb340c98f8eecaf8ab7b95aaf83",
1510
- validatorWalletAddress: "0x82DB9F515957aA380B596C6eA2Bd30CEF181f236",
1503
+ deployedAt: 1790179961079,
1504
+ size: 60046,
1505
+ hash: "922e86c0a667fe0c0945771f84aa6b9fe08be9c96dd2f73a9c5cb257d24e22b0",
1506
+ validatorWalletAddress: "0xEfb258D455a31d061Bbeb3DE3D2143BdFCB67a6C",
1511
1507
  pkp: {
1512
1508
  publicKey: "0x043616787c5432415c24378c4ef48de2bcd6bb7b575b837e3cff09171802662da7105d79586c7659677a0ecbaddac4cce06cb2a11f69a16fa0c4d7002ac7d51a4d",
1513
- ethAddress: "0xc7e1588Db94Bbe92Ab209B833235144Fc5b97607"
1509
+ ethAddress: "0xEfb258D455a31d061Bbeb3DE3D2143BdFCB67a6C"
1514
1510
  }
1515
1511
  },
1516
1512
  // btc-address-balance (Option B) — address-only signed total balance via
@@ -1520,21 +1516,21 @@ var require_pkg_src = __commonJS({
1520
1516
  // Requires BitcoinProviderRegistry.addAllowedCid(chainId, keccak256(utf8(cid)))
1521
1517
  // on each target chain (the action decrypts registry slots). No OAR entry.
1522
1518
  btcAddressBalance: {
1523
- cid: "QmUXUtU9r1HhQVYgkXPN5s19SKXanhn4pMsCtFEP3GK4Kj",
1519
+ cid: "QmVVjB6zCBiXFKffhQPYUAZhj7TXduuvcrPqKtHa3DMXhN",
1524
1520
  authorizedCidHex: cidToHex(
1525
- "QmUXUtU9r1HhQVYgkXPN5s19SKXanhn4pMsCtFEP3GK4Kj"
1521
+ "QmVVjB6zCBiXFKffhQPYUAZhj7TXduuvcrPqKtHa3DMXhN"
1526
1522
  ),
1527
1523
  name: "Btc Address Balance",
1528
1524
  description: "Address-only signed total BTC balance via registry consensus (no positionId, no price)",
1529
1525
  version: "0.2.1",
1530
1526
  deployed: true,
1531
- deployedAt: 1785173280221,
1532
- size: 27309,
1533
- hash: "f0d08938713d9d89a56a3a386cacbc2b57afd5ad367ea82d827d40e1bfc70989",
1534
- validatorWalletAddress: "0x82DB9F515957aA380B596C6eA2Bd30CEF181f236",
1527
+ deployedAt: 1790179971315,
1528
+ size: 30295,
1529
+ hash: "2c67d9cfa4d50e835fbb28ae50e80217ceb2be3bb862c89290aadf43fdc739c9",
1530
+ validatorWalletAddress: "0xEfb258D455a31d061Bbeb3DE3D2143BdFCB67a6C",
1535
1531
  pkp: {
1536
1532
  publicKey: "0x0498cbb31facfa26e3ec83ccdabfe4fe341ca0282e0c3cb81da7113723b9726e1e49efa92165cc3faa66ced4454cea56dbab12267852d6525a55d7c4f128b912cd",
1537
- ethAddress: "0xc7e1588Db94Bbe92Ab209B833235144Fc5b97607"
1533
+ ethAddress: "0xEfb258D455a31d061Bbeb3DE3D2143BdFCB67a6C"
1538
1534
  }
1539
1535
  },
1540
1536
  alwaysSigner: {
@@ -1564,48 +1560,74 @@ var require_pkg_src = __commonJS({
1564
1560
  hash: "03ee5be239c91c735d2c95db89a0d1b77e602cfc18af8eb64b3281fddcd90a72"
1565
1561
  },
1566
1562
  agentModuleExecutor: {
1567
- cid: "QmcD65vuremot5fsHVgp9JBAmei6gAaEtm5mdtLP7Yt9Kf",
1563
+ cid: "QmSwPPvQhT7UhcuVA2m3UxGhVj5WqMpDvYNKU1228QLFsX",
1568
1564
  authorizedCidHex: cidToHex(
1569
- "QmcD65vuremot5fsHVgp9JBAmei6gAaEtm5mdtLP7Yt9Kf"
1565
+ "QmSwPPvQhT7UhcuVA2m3UxGhVj5WqMpDvYNKU1228QLFsX"
1570
1566
  ),
1571
1567
  name: "Agent Module Executor",
1572
1568
  description: "Production Agent Module Executor",
1573
1569
  version: "1.1.1",
1574
1570
  deployed: true,
1575
- deployedAt: 1787924032013,
1576
- size: 13878,
1577
- hash: "a7f0204700912e26e5a354bee13a1242a2baa218643b3bb22d28481f67f9baf4"
1571
+ deployedAt: 1790179978959,
1572
+ size: 14688,
1573
+ hash: "8edb9b12c784c8d7d153cce97235584c24665a788767ae68713dce91109ab35e"
1578
1574
  },
1579
1575
  staleSpendRecoveryValidator: {
1580
- cid: "QmNuwo4PT4AikAmhMdZgPWCb2mJDwWa9TnUqrqvofjbrT8",
1576
+ cid: "Qmarj59zdSSgivkimryrdvnyZqH5YpTimKj1LivXNBHmNz",
1581
1577
  authorizedCidHex: cidToHex(
1582
- "QmNuwo4PT4AikAmhMdZgPWCb2mJDwWa9TnUqrqvofjbrT8"
1578
+ "Qmarj59zdSSgivkimryrdvnyZqH5YpTimKj1LivXNBHmNz"
1583
1579
  ),
1584
1580
  name: "Stale Spend Recovery Validator",
1585
1581
  description: "Production Stale Spend Recovery Validator",
1586
1582
  version: "1.1.2",
1587
1583
  deployed: true,
1588
- deployedAt: 1787924048772,
1589
- size: 41424,
1590
- hash: "3c5f028d2bef4344768462993616d45e30d9d44ef126e04d6eb579821d57d99c",
1591
- validatorWalletAddress: "0x82DB9F515957aA380B596C6eA2Bd30CEF181f236",
1584
+ deployedAt: 1790246256280,
1585
+ size: 48143,
1586
+ hash: "ec9236bcbe0af24d3e1844791fc8fe37371bbecd8ce95d02e13f7c6e1fc7d94c",
1587
+ validatorWalletAddress: "0xEfb258D455a31d061Bbeb3DE3D2143BdFCB67a6C",
1592
1588
  pkp: {
1593
1589
  publicKey: "0x046da0ad6da7dd4a0063cbeac6f2bdb6a9889c2178b23470833356a8ee5630f7f0eee0db348d9d9aaaadd23eccf0063c8f68ee5e446abe30b882bf1de4c932bc21",
1594
- ethAddress: "0xc7e1588Db94Bbe92Ab209B833235144Fc5b97607"
1590
+ ethAddress: "0xEfb258D455a31d061Bbeb3DE3D2143BdFCB67a6C"
1595
1591
  }
1596
1592
  },
1597
1593
  btcUtxoInvalidator: {
1598
- cid: "QmaNGeWut7EiGwW4zUc2sFSt7RY5NWFgxYboyG333TwrJf",
1594
+ cid: "QmbS44bGcmKYF64Cu35qzsk9sxiU4Umde8Z3q24ZnEbQvX",
1599
1595
  authorizedCidHex: cidToHex(
1600
- "QmaNGeWut7EiGwW4zUc2sFSt7RY5NWFgxYboyG333TwrJf"
1596
+ "QmbS44bGcmKYF64Cu35qzsk9sxiU4Umde8Z3q24ZnEbQvX"
1601
1597
  ),
1602
1598
  name: "Btc Utxo Invalidator",
1603
1599
  description: "Production Btc Utxo Invalidator",
1604
1600
  version: "1.0.0",
1605
1601
  deployed: true,
1606
- deployedAt: 1787924133241,
1607
- size: 66026,
1608
- hash: "603bc50920d7f1dee77086f2c518d9e2922ab3858a419d3fbea8221ea3a6d9e9"
1602
+ deployedAt: 1790246264563,
1603
+ size: 69219,
1604
+ hash: "bda048d8cd6b5a39c2774bcf1320e82d1eea935c2a521006fb8b887e13b6dd8d"
1605
+ },
1606
+ carryCollateralAttestation: {
1607
+ cid: "QmYWULmXD9S5AmTdQqWqoZ28ctsZQNcXkAgre9G2Xo9dh8",
1608
+ authorizedCidHex: cidToHex(
1609
+ "QmYWULmXD9S5AmTdQqWqoZ28ctsZQNcXkAgre9G2Xo9dh8"
1610
+ ),
1611
+ name: "Carry Collateral Attestation",
1612
+ description: "LoanCarryVault collateral attestation (borrower, BTC vault, confirmed BTC)",
1613
+ version: "1.0.0",
1614
+ deployed: true,
1615
+ deployedAt: 1790927734070,
1616
+ size: 21156,
1617
+ hash: "05b177e0bb36b0483db4a42d33c1bbbf47eb9ef34ae278459397d51a7f8957ff"
1618
+ },
1619
+ carryFundingAttestation: {
1620
+ cid: "QmWhox3xUZMNR5NpPZ9WLSPC5GoW4ms88GanVRKr8uuS3W",
1621
+ authorizedCidHex: cidToHex(
1622
+ "QmWhox3xUZMNR5NpPZ9WLSPC5GoW4ms88GanVRKr8uuS3W"
1623
+ ),
1624
+ name: "Carry Funding Attestation",
1625
+ description: "LoanCarryVault funding attestation (Hyperliquid BTC windowed hourly average)",
1626
+ version: "1.0.0",
1627
+ deployed: true,
1628
+ deployedAt: 1790925699980,
1629
+ size: 7193,
1630
+ hash: "4944ada61610cf64b32e33b5be62087088dcf5e821040c69e67942e643ce74c9"
1609
1631
  }
1610
1632
  };
1611
1633
  function getDeploymentsForNetwork(network) {
@@ -2373,7 +2395,10 @@ ${errorReport}`);
2373
2395
  BTCSpendAuthorizer: "0xfBbF108486fa07F1B06a811C5b66ed68DD9c508a",
2374
2396
  BitcoinProviderRegistry: "0x4ab3Fb96e02893Ed6FAa61bad1918390c8DbbFFC",
2375
2397
  LITActionValidator: "0xD2c5d59c2CC5c409AC65ce0A817236aeC6869512",
2376
- PositionDelegateRegistry: "0xf0aa2678aD4F60f49e8F7725089B5E86B7F8FE4C"
2398
+ PositionDelegateRegistry: "0xf0aa2678aD4F60f49e8F7725089B5E86B7F8FE4C",
2399
+ TermManagerModule: "0xDB99CdF883ffa38acD099bC39F8d1f4508c9239E",
2400
+ UCDController: "0x4b4f8063048bCD59D469219E3f07C6aaDF4f6157",
2401
+ LiquidationManagerModule: "0x74B28695352E7bf736D6c9F76ccb7B4439477De9"
2377
2402
  },
2378
2403
  11155111: {
2379
2404
  PositionManager: "0x68e0507D982AEBF1D1C1Af8FBbd842327e2deeFF",
@@ -2381,7 +2406,10 @@ ${errorReport}`);
2381
2406
  BTCSpendAuthorizer: "0xd7E9Eb5eE53f1d9ee55Dc162bBC7486bE437B6bD",
2382
2407
  BitcoinProviderRegistry: "0xbfA0c48B070D0a9A9CD27469AeacFD2d4261cEE2",
2383
2408
  LITActionValidator: "0x54eECd7C90F8A8fac27749Ba30BbE8AFBAccc856",
2384
- PositionDelegateRegistry: "0x482369De283622E7b05731875ec137d4E3D208F9"
2409
+ PositionDelegateRegistry: "0x482369De283622E7b05731875ec137d4E3D208F9",
2410
+ TermManagerModule: "0x94Adc6F9558368B1482197584f1fc7133Ecf835b",
2411
+ UCDController: "0x360Bde4e489ee94E26601B206932De09EE60FF04",
2412
+ LiquidationManagerModule: "0xC4AB00f39e7ceD812F5C67058C9fa44e15d40e76"
2385
2413
  }
2386
2414
  };
2387
2415
  function getPinnedContractAddresses(chainId) {
@@ -2567,10 +2595,10 @@ ${errorReport}`);
2567
2595
  };
2568
2596
  }
2569
2597
  const ratioBigInt = collateralValueUsd * UCD_TOKEN_DECIMALS * 10000n / ucdDebt;
2570
- const collateralRatioBps = Number(ratioBigInt);
2598
+ const collateralRatioBps2 = Number(ratioBigInt);
2571
2599
  return {
2572
2600
  collateralValueUsd,
2573
- collateralRatioBps
2601
+ collateralRatioBps: collateralRatioBps2
2574
2602
  };
2575
2603
  }
2576
2604
  function hasSufficientCollateralForDebt(collateralValueUsd, currentDebt, additionalDebt, requiredRatioBps) {
@@ -3424,6 +3452,17 @@ ${auth.clientId}`;
3424
3452
  );
3425
3453
  }
3426
3454
  }
3455
+ var TIP_READ_FAILURE_PREFIX = "Bitcoin tip-height read failed";
3456
+ var BitcoinTipUnreadableError = class extends Error {
3457
+ constructor(message) {
3458
+ super(message);
3459
+ this.isBitcoinTipUnreadable = true;
3460
+ this.name = "BitcoinTipUnreadableError";
3461
+ }
3462
+ };
3463
+ function isBitcoinTipUnreadableError(error) {
3464
+ return typeof error === "object" && error !== null && error.isBitcoinTipUnreadable === true;
3465
+ }
3427
3466
  var BitcoinDataProvider = class {
3428
3467
  constructor(config) {
3429
3468
  this.config = config;
@@ -3875,27 +3914,12 @@ ${auth.clientId}`;
3875
3914
  if (!data.status.confirmed || !data.status.block_height) {
3876
3915
  return { txid: data.txid ?? txid, confirmations: 0 };
3877
3916
  }
3878
- try {
3879
- const tipResp = await fetch(
3880
- `${this.config.providerUrl}/blocks/tip/height`,
3881
- { signal: controller.signal, headers: await this.withAuth() }
3882
- );
3883
- if (!tipResp.ok) {
3884
- return { txid: data.txid ?? txid, confirmations: 1 };
3885
- }
3886
- const tipBody = (await tipResp.text()).trim();
3887
- const tipHeight = Number.parseInt(tipBody, 10);
3888
- if (!Number.isFinite(tipHeight) || tipHeight <= 0) {
3889
- return { txid: data.txid ?? txid, confirmations: 1 };
3890
- }
3891
- const depth = tipHeight - data.status.block_height + 1;
3892
- return {
3893
- txid: data.txid ?? txid,
3894
- confirmations: depth > 0 ? depth : 0
3895
- };
3896
- } catch {
3897
- return { txid: data.txid ?? txid, confirmations: 1 };
3898
- }
3917
+ const tipHeight = await this.fetchTipHeight(controller.signal);
3918
+ const depth = tipHeight - data.status.block_height + 1;
3919
+ return {
3920
+ txid: data.txid ?? txid,
3921
+ confirmations: depth > 0 ? depth : 0
3922
+ };
3899
3923
  }
3900
3924
  return null;
3901
3925
  } catch (error) {
@@ -3903,12 +3927,55 @@ ${auth.clientId}`;
3903
3927
  if (isAbortError(error)) {
3904
3928
  throw new Error(`Request timeout after ${this.timeout}ms`);
3905
3929
  }
3930
+ if (isBitcoinTipUnreadableError(error)) {
3931
+ throw error;
3932
+ }
3906
3933
  if (getUnknownErrorMessage(error).includes("404")) {
3907
3934
  return null;
3908
3935
  }
3909
3936
  throw error;
3910
3937
  }
3911
3938
  }
3939
+ /**
3940
+ * Current chain tip height from THIS provider — or throw.
3941
+ *
3942
+ * Every exit is a throw naming the provider and the precise failure, because
3943
+ * the only alternative is inventing a confirmation depth (see the call site).
3944
+ * The single `try` exists solely to attach that name to a transport-level
3945
+ * rejection (DNS, TLS, connection reset, abort); it re-throws the cause
3946
+ * verbatim inside the message and never substitutes a value — authorized for
3947
+ * this case by the Batch 2 plan, §C2.
3948
+ *
3949
+ * @param signal - The caller's AbortSignal, so this read shares the same
3950
+ * timeout budget as the transaction fetch it serves.
3951
+ */
3952
+ async fetchTipHeight(signal) {
3953
+ const endpoint = `${this.config.providerUrl}/blocks/tip/height`;
3954
+ let tipResp;
3955
+ try {
3956
+ tipResp = await fetch(endpoint, {
3957
+ signal,
3958
+ headers: await this.withAuth()
3959
+ });
3960
+ } catch (error) {
3961
+ throw new BitcoinTipUnreadableError(
3962
+ `${TIP_READ_FAILURE_PREFIX}: GET ${endpoint} threw \u2014 ${getUnknownErrorMessage(error)}`
3963
+ );
3964
+ }
3965
+ if (!tipResp.ok) {
3966
+ throw new BitcoinTipUnreadableError(
3967
+ `${TIP_READ_FAILURE_PREFIX}: GET ${endpoint} \u2192 ${tipResp.status} ${tipResp.statusText}`
3968
+ );
3969
+ }
3970
+ const tipBody = (await tipResp.text()).trim();
3971
+ const tipHeight = Number.parseInt(tipBody, 10);
3972
+ if (!Number.isFinite(tipHeight) || tipHeight <= 0) {
3973
+ throw new BitcoinTipUnreadableError(
3974
+ `${TIP_READ_FAILURE_PREFIX}: GET ${endpoint} returned an unusable tip height "${tipBody.slice(0, 64)}"`
3975
+ );
3976
+ }
3977
+ return tipHeight;
3978
+ }
3912
3979
  /**
3913
3980
  * Get outputs (vouts) of a Bitcoin transaction
3914
3981
  *
@@ -4546,10 +4613,13 @@ ${auth.clientId}`;
4546
4613
  * only on unanimity. The confirmed-balance consensus the validators run
4547
4614
  * covers `chain_stats` only, so without this the primary provider alone
4548
4615
  * could fabricate an unconfirmed UTXO plus a self-consistent parent proof
4549
- * and inflate the signed balance. Any provider failure or verdict
4550
- * disagreement THROWS (fail-closed) — exclusion on a suppressed proof
4551
- * would deflate the balance and open a wrongful-liquidation window, so
4552
- * neither direction may proceed without agreement.
4616
+ * and inflate the signed balance. Any verdict disagreement THROWS
4617
+ * (fail-closed) — exclusion on a suppressed proof would deflate the balance
4618
+ * and open a wrongful-liquidation window, so neither direction may proceed
4619
+ * without agreement. A provider that cannot state the chain tip — and only
4620
+ * that failure — is dropped from the quorum rather than aborting the read (it
4621
+ * never counts as agreeing), and falling below `minConsensusProviders`
4622
+ * survivors throws — see `verifyParentIsSelfSpendConsensus`.
4553
4623
  *
4554
4624
  * The same per-provider `/tx` fetch also returns the parent's outputs, and
4555
4625
  * every provider must corroborate each claimed UTXO (index, vault address,
@@ -4644,10 +4714,26 @@ ${auth.clientId}`;
4644
4714
  }
4645
4715
  /**
4646
4716
  * Run the self-spend proof against every configured provider and require
4647
- * unanimity. Fail-closed: a provider request failure or a verdict
4648
- * disagreement throws and aborts the balance calculation — see
4717
+ * unanimity AMONG THE PROVIDERS THAT ANSWERED. Fail-closed on disagreement:
4718
+ * a verdict mismatch throws and aborts the balance calculation — see
4649
4719
  * classifySelfChange for why exclusion is not a safe fallback here.
4650
4720
  *
4721
+ * Quorum semantics (2026-09-23, plan C2). ONE failure class is tolerated: a
4722
+ * provider that could not state the chain tip (`BitcoinTipUnreadableError`).
4723
+ * It is ABSENT from the quorum — never counted as agreeing, never allowed to
4724
+ * decide the verdict — and the policy floor, not "at least one", decides when
4725
+ * that absence is fatal: below `minConsensusProviders` surviving readings
4726
+ * there is no cross-check left to trust, and the read fails loudly naming
4727
+ * every provider that dropped out.
4728
+ *
4729
+ * Why only that class. `getTransaction` now throws on an unreadable tip
4730
+ * instead of fabricating `confirmations: 1`; without this carve-out one flaky
4731
+ * `/blocks/tip/height` endpoint would take every balance and spend path down
4732
+ * with it. Every OTHER failure remains fatal, as before: a provider that
4733
+ * answers "I have never seen that transaction" is making a claim about the
4734
+ * chain rather than suffering an outage, and that shape is precisely the
4735
+ * fabricated-UTXO signature the fail-closed rule exists to catch.
4736
+ *
4651
4737
  * When the parent IS a unanimous self-spend, every provider's view of the
4652
4738
  * parent's OUTPUTS must additionally corroborate the primary's claimed
4653
4739
  * UTXOs (index exists, pays the vault, exact value). Without this, a
@@ -4672,32 +4758,52 @@ ${auth.clientId}`;
4672
4758
  )
4673
4759
  )
4674
4760
  );
4675
- const failures = settled.map((r, i) => ({ r, name: providerName(i) })).filter(
4676
- (x) => x.r.status === "rejected"
4677
- ).map(
4678
- ({ r, name }) => `${name} \u2192 ${r.reason?.message ?? String(r.reason)}`
4679
- );
4761
+ const answered = [];
4762
+ const absences = [];
4763
+ const failures = [];
4764
+ settled.forEach((result, i) => {
4765
+ if (result.status === "fulfilled") {
4766
+ answered.push({ index: i, evaluation: result.value });
4767
+ return;
4768
+ }
4769
+ const described = `${providerName(i)} \u2192 ${result.reason?.message ?? String(result.reason)}`;
4770
+ if (isBitcoinTipUnreadableError(result.reason)) {
4771
+ absences.push(described);
4772
+ return;
4773
+ }
4774
+ failures.push(described);
4775
+ });
4680
4776
  if (failures.length > 0) {
4681
4777
  throw new Error(
4682
4778
  `Self-change classification failed for tx ${parentTxid} on ${failures.length}/${providerConfigs.length} provider(s): ${failures.join("; ")}`
4683
4779
  );
4684
4780
  }
4685
- const evaluations = settled.map(
4686
- (r) => r.value
4687
- );
4688
- const votes = evaluations.map((e) => e.selfSpend);
4689
- const disagreements = votes.map((vote, i) => ({ vote, name: providerName(i) })).filter((x) => x.vote !== votes[0]).map(
4690
- (x) => `${providerName(0)}=${votes[0]} vs ${x.name}=${x.vote}`
4781
+ const floor = Math.max(1, this.minConsensusProviders);
4782
+ if (answered.length < floor) {
4783
+ throw new Error(
4784
+ `Self-change classification for tx ${parentTxid}: only ${answered.length}/${providerConfigs.length} provider(s) could state a confirmation depth, below this chain's floor of ${floor}. Unreadable tips: ${absences.join("; ")}`
4785
+ );
4786
+ }
4787
+ if (absences.length > 0) {
4788
+ litDebugLog(
4789
+ `[VaultBalance] self-change: tx ${parentTxid} classified on a reduced quorum \u2014 ${answered.length}/${providerConfigs.length} provider(s) answered (floor ${floor}); dropped for an unreadable chain tip: ${absences.join("; ")}`
4790
+ );
4791
+ }
4792
+ const first = answered[0];
4793
+ const disagreements = answered.slice(1).filter((a) => a.evaluation.selfSpend !== first.evaluation.selfSpend).map(
4794
+ (a) => `${providerName(first.index)}=${first.evaluation.selfSpend} vs ${providerName(a.index)}=${a.evaluation.selfSpend}`
4691
4795
  );
4692
4796
  if (disagreements.length > 0) {
4693
4797
  throw new Error(
4694
4798
  `Self-change consensus mismatch for tx ${parentTxid}: ${disagreements.join("; ")}. A provider may be compromised or out of sync; refusing to sign.`
4695
4799
  );
4696
4800
  }
4697
- if (!votes[0]) {
4801
+ if (!first.evaluation.selfSpend) {
4698
4802
  return false;
4699
4803
  }
4700
- const outputMismatches = evaluations.map((e, i) => e.outputMismatch ? `${providerName(i)} \u2192 ${e.outputMismatch}` : null).filter((m) => m !== null);
4804
+ const outputMismatches = answered.map(
4805
+ (a) => a.evaluation.outputMismatch ? `${providerName(a.index)} \u2192 ${a.evaluation.outputMismatch}` : null
4806
+ ).filter((m) => m !== null);
4701
4807
  if (outputMismatches.length > 0) {
4702
4808
  throw new Error(
4703
4809
  `Self-change output claim mismatch for tx ${parentTxid}: ${outputMismatches.join("; ")}. The reported UTXO set contradicts the parent transaction; refusing to sign.`
@@ -4940,16 +5046,6 @@ ${auth.clientId}`;
4940
5046
  minConfirmations
4941
5047
  );
4942
5048
  const authorizedSpends = await this.getAuthorizedSpendsFromContract(positionId);
4943
- for (const spend of authorizedSpends) {
4944
- const utxoStillExists = utxoSet.utxos.some(
4945
- (utxo) => utxo.txid === spend.txid && utxo.vout === spend.vout
4946
- );
4947
- if (utxoStillExists) {
4948
- throw new Error(
4949
- `Authorized UTXO ${spend.txid}:${spend.vout} not yet spent. Transaction was authorized in smart contract but not signed and broadcasted to Bitcoin network. Complete the transaction by signing and broadcasting it.`
4950
- );
4951
- }
4952
- }
4953
5049
  const authorizedBalance = authorizedSpends.reduce(
4954
5050
  (sum, spend) => sum + spend.satoshis,
4955
5051
  0n
@@ -5245,7 +5341,13 @@ ${auth.clientId}`;
5245
5341
  allowDevSinglePriceProvider: false,
5246
5342
  minBitcoinBalanceConfirmations: 1,
5247
5343
  minBitcoinSpendConfirmations: 1,
5248
- minConsensusProviders: 1
5344
+ // 2 since 2026-09-23. It was 1 because Sepolia ran a single faucet provider
5345
+ // "by design", so the consensus floor was documented as a mainnet-only
5346
+ // guarantee. The registry now holds two, and leaving the floor at 1 meant
5347
+ // Sepolia could never exercise the multi-provider agreement the stale-spend
5348
+ // and balance paths rely on — the one environment where that logic is
5349
+ // supposed to be proved before mainnet.
5350
+ minConsensusProviders: 2
5249
5351
  },
5250
5352
  [
5251
5353
  "ethereum"
@@ -5556,7 +5658,6 @@ function getSepoliaConfig() {
5556
5658
  feeRecipientRegistry: SEPOLIA_CONTRACTS.FeeRecipientRegistry || "",
5557
5659
  positionDelegateRegistry: SEPOLIA_CONTRACTS.PositionDelegateRegistry || "",
5558
5660
  bitcoinWithdrawalAddressRegistry: SEPOLIA_CONTRACTS.BitcoinWithdrawalAddressRegistry || "",
5559
- carryAgentRegistry: SEPOLIA_CONTRACTS.CarryAgentRegistry || "",
5560
5661
  agentDelegationRegistry: SEPOLIA_CONTRACTS.AgentDelegationRegistry || "",
5561
5662
  dhAgentDelegate: SEPOLIA_CONTRACTS.DHAgentDelegate || "",
5562
5663
  agentModuleFactory: SEPOLIA_CONTRACTS.AgentModuleFactory || ""
@@ -5610,7 +5711,6 @@ function getMainnetConfig() {
5610
5711
  feeRecipientRegistry: MAINNET_CONTRACTS.FeeRecipientRegistry || "",
5611
5712
  positionDelegateRegistry: MAINNET_CONTRACTS.PositionDelegateRegistry || "",
5612
5713
  bitcoinWithdrawalAddressRegistry: MAINNET_CONTRACTS.BitcoinWithdrawalAddressRegistry || "",
5613
- carryAgentRegistry: MAINNET_CONTRACTS.CarryAgentRegistry || "",
5614
5714
  agentDelegationRegistry: MAINNET_CONTRACTS.AgentDelegationRegistry || "",
5615
5715
  dhAgentDelegate: MAINNET_CONTRACTS.DHAgentDelegate || "",
5616
5716
  // Empty on mainnet until the factory is deployed there — the ceremony is Sepolia-only.
@@ -6905,7 +7005,54 @@ async function resolveAuthorizationInput(provider, signer, ctx) {
6905
7005
  return { timestamp: result.timestamp, signature: result.signature };
6906
7006
  }
6907
7007
 
7008
+ // src/utils/btc-dust.utils.ts
7009
+ var BECH32_CHARSET = "qpzry9x8gf2tvdw0s3jn54khce6mua7l";
7010
+ function segwitProgramShape(address) {
7011
+ const lower2 = address.trim().toLowerCase();
7012
+ if (!/^(bc1|tb1|bcrt1)/.test(lower2))
7013
+ return null;
7014
+ const sep = lower2.lastIndexOf("1");
7015
+ const data = lower2.slice(sep + 1);
7016
+ if (data.length < 8)
7017
+ return null;
7018
+ const version = BECH32_CHARSET.indexOf(data[0]);
7019
+ if (version < 0)
7020
+ return null;
7021
+ const programChars = data.length - 1 - 6;
7022
+ return { version, programBytes: Math.floor(programChars * 5 / 8) };
7023
+ }
7024
+ function dustLimitForAddress(address) {
7025
+ const shape = segwitProgramShape(address);
7026
+ if (shape === null)
7027
+ return 546;
7028
+ if (shape.version === 0 && shape.programBytes === 20)
7029
+ return 294;
7030
+ if (shape.version === 0 && shape.programBytes === 32)
7031
+ return 330;
7032
+ if (shape.version === 1 && shape.programBytes === 32)
7033
+ return 330;
7034
+ return 546;
7035
+ }
7036
+ function destinationDustShortfall(targetAmount, networkFee, destination) {
7037
+ const limit = dustLimitForAddress(destination);
7038
+ return targetAmount - networkFee < limit ? limit : null;
7039
+ }
7040
+
6908
7041
  // src/utils/loan-helpers.utils.ts
7042
+ function calculateMintFee(params) {
7043
+ const { mintAmount, mintTimestamp, originationFeeBps, previousExpiryAt, selectedTerm, totalTerm } = params;
7044
+ let mintFee = mintAmount * BigInt(originationFeeBps) / 10000n;
7045
+ if (previousExpiryAt > 0 && mintTimestamp < previousExpiryAt) {
7046
+ const tailSeconds = BigInt(previousExpiryAt) - BigInt(mintTimestamp);
7047
+ const originalTermMonths = totalTerm - selectedTerm;
7048
+ const originalTermSeconds = BigInt(
7049
+ originalTermMonths === 12 ? 365 * 86400 : originalTermMonths * 30 * 86400
7050
+ );
7051
+ const tailFee = tailSeconds * BigInt(originationFeeBps) * mintAmount / (10000n * originalTermSeconds);
7052
+ mintFee = mintFee + tailFee;
7053
+ }
7054
+ return mintFee;
7055
+ }
6909
7056
  function baseMintFeeWei(mintAmountWei, originationFeeBps) {
6910
7057
  if (mintAmountWei < 0n)
6911
7058
  throw new Error("baseMintFeeWei: mintAmountWei cannot be negative");
@@ -6924,20 +7071,34 @@ function debtAfterMintExceedsLoanCap(params) {
6924
7071
  }
6925
7072
  return currentDebtWei + mintAmountWei + mintFeeWei > maxLoanWei;
6926
7073
  }
6927
- function maxPrincipalWithinLoanCap(params) {
6928
- const { maxLoanWei, currentDebtWei, originationFeeBps } = params;
6929
- if (maxLoanWei < 0n || currentDebtWei < 0n) {
6930
- throw new Error("maxPrincipalWithinLoanCap: amounts cannot be negative");
7074
+ function collateralRatioBps(sats, price8, debtWei) {
7075
+ if (sats < 0n || price8 < 0n) {
7076
+ throw new Error("collateralRatioBps: sats and price cannot be negative");
6931
7077
  }
6932
- if (!Number.isInteger(originationFeeBps) || originationFeeBps < 0 || originationFeeBps > 1e4) {
6933
- throw new Error(
6934
- `maxPrincipalWithinLoanCap: originationFeeBps must be an integer in [0, 10000] (got ${String(originationFeeBps)})`
6935
- );
7078
+ if (debtWei <= 0n) {
7079
+ throw new Error("collateralRatioBps: debt must be positive");
6936
7080
  }
6937
- const room = maxLoanWei - currentDebtWei;
6938
- if (room <= 0n)
6939
- return 0n;
6940
- return room * 10000n / (10000n + BigInt(originationFeeBps));
7081
+ return sats * price8 * 100n * 10000n / debtWei;
7082
+ }
7083
+ function collateralRatioPercentString(sats, price8, debtWei) {
7084
+ const bps = collateralRatioBps(sats, price8, debtWei);
7085
+ return `${bps / 100n}.${(bps % 100n).toString().padStart(2, "0")}`;
7086
+ }
7087
+ function maxPrincipalForFee(room, fee) {
7088
+ if (room < 0n)
7089
+ throw new Error("maxPrincipalForFee: room cannot be negative");
7090
+ if (fee(0n) !== 0n)
7091
+ throw new Error("maxPrincipalForFee: fee(0) must be 0");
7092
+ let lo = 0n;
7093
+ let hi = room;
7094
+ while (lo < hi) {
7095
+ const mid = (lo + hi + 1n) / 2n;
7096
+ if (mid + fee(mid) <= room)
7097
+ lo = mid;
7098
+ else
7099
+ hi = mid - 1n;
7100
+ }
7101
+ return lo;
6941
7102
  }
6942
7103
 
6943
7104
  // src/utils/eip712-login.ts
@@ -19230,9 +19391,17 @@ async function mintAgentPkp(params) {
19230
19391
  }
19231
19392
  var AGENT_STATUS = { None: 0, Active: 1, Revoked: 2 };
19232
19393
  function planAgentBinding(params) {
19233
- const { isActive, record, nowSeconds } = params;
19394
+ const { isActive, paused, record, nowSeconds } = params;
19395
+ if (typeof paused !== "boolean") {
19396
+ throw new Error("planAgentBinding: `paused` must be read from the registry (boolean required)");
19397
+ }
19234
19398
  if (isActive)
19235
19399
  return { kind: "reuse", agent: record.agent };
19400
+ if (paused) {
19401
+ throw new Error(
19402
+ "AgentDelegationRegistry is paused \u2014 agent delegation cannot be changed until it is unpaused."
19403
+ );
19404
+ }
19236
19405
  const status = Number(record.status);
19237
19406
  if (status === AGENT_STATUS.None || status === AGENT_STATUS.Revoked) {
19238
19407
  return { kind: "register" };
@@ -19242,7 +19411,7 @@ function planAgentBinding(params) {
19242
19411
  }
19243
19412
  if (Number(record.validUntil) > nowSeconds) {
19244
19413
  throw new Error(
19245
- "AgentDelegationRegistry reports an unexpired agent as inactive \u2014 the registry is paused. Agent delegation cannot be changed until it is unpaused."
19414
+ "AgentDelegationRegistry returned an inconsistent read (an unexpired, unpaused Active agent reported inactive); retry."
19246
19415
  );
19247
19416
  }
19248
19417
  return { kind: "rotate" };
@@ -20444,7 +20613,7 @@ function normalizeBigNumberish(value) {
20444
20613
  }
20445
20614
  return value;
20446
20615
  }
20447
- if (typeof value === "object" && value !== null && "toString" in value && typeof value.toString === "function") {
20616
+ if (typeof value === "object" && value !== null && "toString" in value && typeof value.toString === "function" && value.toString !== Object.prototype.toString) {
20448
20617
  const result = value.toString();
20449
20618
  if (typeof result === "object" && result !== null && "_hex" in result) {
20450
20619
  const resultObj = result;
@@ -21857,12 +22026,21 @@ var DiamondHandsSDK = class _DiamondHandsSDK {
21857
22026
  maxLoanWei: maxLoanValueWei
21858
22027
  })) {
21859
22028
  const debtAfterWei = currentDebtWei + requestAmountWei + baseFeeWei;
22029
+ const suggestionStamp = calculateNextQuantumTimestamp();
22030
+ const room = maxLoanValueWei > currentDebtWei ? maxLoanValueWei - currentDebtWei : 0n;
21860
22031
  const maxPrincipalUcd = Number(
21861
- maxPrincipalWithinLoanCap({
21862
- maxLoanWei: maxLoanValueWei,
21863
- currentDebtWei,
21864
- originationFeeBps: positionTerm.originationFeeBps
21865
- }) / BigInt(10 ** 18)
22032
+ maxPrincipalForFee(
22033
+ room,
22034
+ (principal) => calculateMintFee({
22035
+ mintAmount: principal,
22036
+ mintTimestamp: suggestionStamp,
22037
+ originationFeeBps: positionTerm.originationFeeBps,
22038
+ expiryAt: Number(position2.expiryAt),
22039
+ previousExpiryAt: Number(position2.previousExpiryAt),
22040
+ selectedTerm: Number(position2.selectedTerm),
22041
+ totalTerm: Number(position2.totalTerm)
22042
+ })
22043
+ ) / BigInt(10 ** 18)
21866
22044
  );
21867
22045
  return {
21868
22046
  success: false,
@@ -22940,11 +23118,7 @@ Message: ${causeMessage}${quantumContext}${loanCapDiagnostics}${mintDebtDiagnost
22940
23118
  const debt = positionDetails.debt || positionDetails.ucdDebt || "0";
22941
23119
  const btcPrice2 = litActionResult.btcPrice || "0";
22942
23120
  const btcVaultBalance = litActionResult.btcAmountSats || positionDetails.btcVaultBalance || "0";
22943
- const usdPricePerBTC = Number(btcPrice2) / 1e8;
22944
- const btcAmount = Number(btcVaultBalance) / 1e8;
22945
- const btcValueUSD = btcAmount * usdPricePerBTC;
22946
- const debtUSD = Number(debt) / 1e18;
22947
- const ratio = debtUSD > 0 ? (btcValueUSD / debtUSD * 100).toFixed(2) : "0.00";
23121
+ const ratio = BigInt(debt) > 0n ? collateralRatioPercentString(BigInt(btcVaultBalance), BigInt(btcPrice2), BigInt(debt)) : "0.00";
22948
23122
  const message = formatLiquidationSkippedMessage(
22949
23123
  request.positionId,
22950
23124
  ratio,
@@ -23433,14 +23607,15 @@ Message: ${causeMessage}${quantumContext}${loanCapDiagnostics}${mintDebtDiagnost
23433
23607
  }
23434
23608
  const debt = positionDetails.debt || positionDetails.ucdDebt || "0";
23435
23609
  const btcPrice2 = litActionResult.btcPrice || "0";
23436
- const ratio = debt !== "0" ? (Number(positionDetails.btcVaultBalance || "0") * Number(btcPrice2) / Number(debt) * 100 / 1e8).toFixed(2) : "0.00";
23610
+ const btcVaultBalance = litActionResult.btcAmountSats || positionDetails.btcVaultBalance || "0";
23611
+ const ratio = BigInt(debt) > 0n ? collateralRatioPercentString(BigInt(btcVaultBalance), BigInt(btcPrice2), BigInt(debt)) : "0.00";
23437
23612
  const message = formatLiquidationSuccessMessage(
23438
23613
  request.positionId,
23439
23614
  ratio,
23440
23615
  `${liquidationThreshold / 100}`,
23441
23616
  // Convert to percentage
23442
23617
  positionDetails.btcVault || "unknown",
23443
- positionDetails.btcVaultBalance || "0",
23618
+ btcVaultBalance,
23444
23619
  debt,
23445
23620
  btcPrice2
23446
23621
  );
@@ -25913,6 +26088,17 @@ Message: ${causeMessage}${quantumContext}${loanCapDiagnostics}${mintDebtDiagnost
25913
26088
  error: `networkFee=${request.networkFee} is \u2265 50% of targetAmount=${request.targetAmount}. Refusing to broadcast \u2014 real Bitcoin fees are typically <1% of value.`
25914
26089
  };
25915
26090
  }
26091
+ const destinationDustLimit = destinationDustShortfall(
26092
+ request.targetAmount,
26093
+ request.networkFee,
26094
+ request.destination
26095
+ );
26096
+ if (destinationDustLimit !== null) {
26097
+ return {
26098
+ success: false,
26099
+ error: `Destination would receive ${request.targetAmount - request.networkFee} sats (targetAmount=${request.targetAmount} \u2212 networkFee=${request.networkFee}), below the ${destinationDustLimit}-sat dust limit for ${request.destination}; the transaction would not relay.`
26100
+ };
26101
+ }
25916
26102
  const [txid, voutStr] = request.utxoIdentifier.split(":");
25917
26103
  const vout = parseInt(voutStr || "0", 10);
25918
26104
  if (!txid || isNaN(vout)) {
@@ -27385,8 +27571,9 @@ Message: ${causeMessage}${quantumContext}${loanCapDiagnostics}${mintDebtDiagnost
27385
27571
  const user = await signer.getAddress();
27386
27572
  const registry = AgentDelegationRegistry__factory.connect(addr, signer);
27387
27573
  let agentAddress;
27388
- const [isActive, record, latestBlock] = await Promise.all([
27574
+ const [isActive, paused, record, latestBlock] = await Promise.all([
27389
27575
  registry.isAgentActive(user),
27576
+ registry.paused(),
27390
27577
  registry.agentOf(user),
27391
27578
  this.getProviderOrThrow().getBlock("latest")
27392
27579
  ]);
@@ -27397,7 +27584,7 @@ Message: ${causeMessage}${quantumContext}${loanCapDiagnostics}${mintDebtDiagnost
27397
27584
  severity: "HIGH" /* HIGH */
27398
27585
  });
27399
27586
  }
27400
- const plan = planAgentBinding({ isActive, record, nowSeconds: latestBlock.timestamp });
27587
+ const plan = planAgentBinding({ isActive, paused, record, nowSeconds: latestBlock.timestamp });
27401
27588
  if (plan.kind === "reuse") {
27402
27589
  agentAddress = plan.agent;
27403
27590
  } else {