@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/browser/dist/browser.js +1 -1
- package/dist/constants/chunks/deployment-addresses.d.ts +0 -2
- package/dist/constants/chunks/network-configs.d.ts +0 -2
- package/dist/deployments.js +5 -9
- package/dist/deployments.mjs +5 -9
- package/dist/index.js +358 -171
- package/dist/index.mjs +358 -171
- package/dist/safe-delegation.js +5 -8
- package/dist/safe-delegation.mjs +5 -8
- package/dist/sign-guard.js +7 -3
- package/dist/sign-guard.mjs +7 -3
- package/dist/utils/agent-delegation.utils.d.ts +10 -3
- package/dist/utils/btc-dust.utils.d.ts +25 -0
- package/dist/utils/loan-helpers.utils.d.ts +26 -3
- package/dist/utils/sign-guard/extend-fee-bound.d.ts +5 -0
- package/dist/utils/sign-guard/op-envelope.d.ts +7 -1
- package/package.json +3 -3
package/dist/index.mjs
CHANGED
|
@@ -94,7 +94,6 @@ var init_deployment_addresses = __esm({
|
|
|
94
94
|
PositionDelegateRegistry: "0x482369De283622E7b05731875ec137d4E3D208F9",
|
|
95
95
|
FeeRecipientRegistry: "0x95795F8403DDb629E8527B2934C4e71f5fC0C374",
|
|
96
96
|
BitcoinWithdrawalAddressRegistry: "0x6376D392097F0A81e51BD83960A97EA20eaf1dbe",
|
|
97
|
-
CarryAgentRegistry: "0x5595CB538D44E6Cf179D20364fD631D0477e69f7",
|
|
98
97
|
AgentDelegationRegistry: "0x6AE7fc6bE0925126b9D25b1B7Ce5AD5d127ec025",
|
|
99
98
|
DHAgentDelegate: "0xa5A14489ae883960df6E1463A41a47aBE9Ecc5AF",
|
|
100
99
|
AgentModuleFactory: "0x1Fd3aCa2C030Cf77ce28Af9694D3Bb3034ACa2E5"
|
|
@@ -143,11 +142,11 @@ var init_deployment_addresses = __esm({
|
|
|
143
142
|
reason: "Shared upgrade script: AdminModule implementation update"
|
|
144
143
|
},
|
|
145
144
|
PositionManagerViews: {
|
|
146
|
-
previousImplementation: "
|
|
147
|
-
newImplementation: "
|
|
148
|
-
upgradedAt: "2026-
|
|
149
|
-
upgradedBy: "
|
|
150
|
-
reason: "
|
|
145
|
+
previousImplementation: "0xA455B542cFb36AF8451fc420dB89e590E5c87cef",
|
|
146
|
+
newImplementation: "0x8cEB3F1c07fDB3301f55b96a5B9aDb33C8d36Da3",
|
|
147
|
+
upgradedAt: "2026-10-02T17:04:25.853Z",
|
|
148
|
+
upgradedBy: "0x0f8f23674cc90Ef7107930a4437341fD8B460362",
|
|
149
|
+
reason: "1.1.2: getBackingVaults (PoR backing set) + implementation lock (constructor)"
|
|
151
150
|
},
|
|
152
151
|
TestPositionManager: {
|
|
153
152
|
previousImplementation: "0x0B46Ee1a9C6b42559758B7FF78294Cd867BB08f8",
|
|
@@ -364,8 +363,6 @@ var init_deployment_addresses = __esm({
|
|
|
364
363
|
OPERATION_AUTHORIZATION_REGISTRY_IMPL: "0xe0D981B60351f0f8fFDA2b50C8180Fb37CeF3883",
|
|
365
364
|
BITCOIN_WITHDRAWAL_ADDRESS_REGISTRY: "0x6376D392097F0A81e51BD83960A97EA20eaf1dbe",
|
|
366
365
|
BITCOIN_WITHDRAWAL_ADDRESS_REGISTRY_IMPL: "0x76E0a2c9d89562fD7c50b5f554d7fa25957e39Db",
|
|
367
|
-
CARRY_AGENT_REGISTRY: "0x5595CB538D44E6Cf179D20364fD631D0477e69f7",
|
|
368
|
-
CARRY_AGENT_REGISTRY_IMPL: "0x1b11a3D5e46F3672E643c997f0d569DFf0b64a01",
|
|
369
366
|
AGENT_DELEGATION_REGISTRY: "0x6AE7fc6bE0925126b9D25b1B7Ce5AD5d127ec025",
|
|
370
367
|
AGENT_DELEGATION_REGISTRY_IMPL: "0xE931E4b9ceF2A48Ac7D57192da4B523756cFC310",
|
|
371
368
|
DH_AGENT_DELEGATE: "0xa5A14489ae883960df6E1463A41a47aBE9Ecc5AF"
|
|
@@ -397,7 +394,6 @@ var init_deployment_addresses = __esm({
|
|
|
397
394
|
PositionDelegateRegistry: "0x482369De283622E7b05731875ec137d4E3D208F9",
|
|
398
395
|
FeeRecipientRegistry: "0x95795F8403DDb629E8527B2934C4e71f5fC0C374",
|
|
399
396
|
BitcoinWithdrawalAddressRegistry: "0x6376D392097F0A81e51BD83960A97EA20eaf1dbe",
|
|
400
|
-
CarryAgentRegistry: "0x5595CB538D44E6Cf179D20364fD631D0477e69f7",
|
|
401
397
|
AgentDelegationRegistry: "0x6AE7fc6bE0925126b9D25b1B7Ce5AD5d127ec025",
|
|
402
398
|
DHAgentDelegate: "0xa5A14489ae883960df6E1463A41a47aBE9Ecc5AF",
|
|
403
399
|
AgentModuleFactory: "0x1Fd3aCa2C030Cf77ce28Af9694D3Bb3034ACa2E5"
|
|
@@ -1374,113 +1370,113 @@ var require_pkg_src = __commonJS({
|
|
|
1374
1370
|
deployedAt: 1784569687492,
|
|
1375
1371
|
size: 4140,
|
|
1376
1372
|
hash: "4c0d65bf1f33cdac22a78fd8c4764319cc3fe00650e0fe7fa8a6090d9a318a7b",
|
|
1377
|
-
validatorWalletAddress: "
|
|
1373
|
+
validatorWalletAddress: "0xefb258d455a31d061bbeb3de3d2143bdfcb67a6c",
|
|
1378
1374
|
pkp: {
|
|
1379
1375
|
publicKey: "0x04ec0e3acc40884e3f366ca469d08899eb640ad5259fa196b0238075086208a9f8732a3175704f35f0bcc28e07406cfb24c254efd1e7355640577330f0d2dd755f",
|
|
1380
|
-
ethAddress: "
|
|
1376
|
+
ethAddress: "0xEfb258D455a31d061Bbeb3DE3D2143BdFCB67a6C"
|
|
1381
1377
|
}
|
|
1382
1378
|
},
|
|
1383
1379
|
btcTransactionSigner: {
|
|
1384
|
-
cid: "
|
|
1380
|
+
cid: "QmULkz7hwwqsyLwY23U14dnartdVuSNMrykt69PaNiAq7U",
|
|
1385
1381
|
authorizedCidHex: cidToHex(
|
|
1386
|
-
"
|
|
1382
|
+
"QmULkz7hwwqsyLwY23U14dnartdVuSNMrykt69PaNiAq7U"
|
|
1387
1383
|
),
|
|
1388
1384
|
name: "Btc Transaction Signer",
|
|
1389
1385
|
description: "Production Btc Transaction Signer",
|
|
1390
1386
|
version: "1.1.1",
|
|
1391
1387
|
deployed: true,
|
|
1392
|
-
deployedAt:
|
|
1393
|
-
size:
|
|
1394
|
-
hash: "
|
|
1388
|
+
deployedAt: 1790246185256,
|
|
1389
|
+
size: 73313,
|
|
1390
|
+
hash: "d8b6bc646ba33fee7d46c8e9b281de776081ea6f182f56fd15d4c52aaf3dd030"
|
|
1395
1391
|
},
|
|
1396
1392
|
ucdMintValidator: {
|
|
1397
|
-
cid: "
|
|
1393
|
+
cid: "QmcxVSn9saEPGBS6mqPhNefgW83V2qeZjjXbhwYLP373xe",
|
|
1398
1394
|
authorizedCidHex: cidToHex(
|
|
1399
|
-
"
|
|
1395
|
+
"QmcxVSn9saEPGBS6mqPhNefgW83V2qeZjjXbhwYLP373xe"
|
|
1400
1396
|
),
|
|
1401
1397
|
name: "Ucd Mint Validator",
|
|
1402
1398
|
description: "Production Ucd Mint Validator",
|
|
1403
|
-
version: "1.
|
|
1399
|
+
version: "1.3.0",
|
|
1404
1400
|
deployed: true,
|
|
1405
|
-
deployedAt:
|
|
1406
|
-
size:
|
|
1407
|
-
hash: "
|
|
1408
|
-
validatorWalletAddress: "
|
|
1401
|
+
deployedAt: 1790246219868,
|
|
1402
|
+
size: 90022,
|
|
1403
|
+
hash: "65e8cb778c2b767ae6eb37cb5db7b4c5a3f2468d508463c847c83c1b6825fadd",
|
|
1404
|
+
validatorWalletAddress: "0xEfb258D455a31d061Bbeb3DE3D2143BdFCB67a6C",
|
|
1409
1405
|
pkp: {
|
|
1410
1406
|
publicKey: "0x041ab17cd91fc5c0b761eea6092d032807561b621b82c488826776e04a9158d61ba64d809a4729f0501289d980732cb06d8dfd06999dd9c8efd2f495dad78b31bb",
|
|
1411
|
-
ethAddress: "
|
|
1407
|
+
ethAddress: "0xEfb258D455a31d061Bbeb3DE3D2143BdFCB67a6C"
|
|
1412
1408
|
}
|
|
1413
1409
|
},
|
|
1414
1410
|
processPaymentValidator: {
|
|
1415
|
-
cid: "
|
|
1411
|
+
cid: "QmWFbxJkfxhCtES4wrePWQkYtjhtrP1tohvn9d1r9N5Hd8",
|
|
1416
1412
|
authorizedCidHex: cidToHex(
|
|
1417
|
-
"
|
|
1413
|
+
"QmWFbxJkfxhCtES4wrePWQkYtjhtrP1tohvn9d1r9N5Hd8"
|
|
1418
1414
|
),
|
|
1419
1415
|
name: "Process Payment Validator",
|
|
1420
1416
|
description: "Production Process Payment Validator",
|
|
1421
1417
|
version: "1.2.1",
|
|
1422
1418
|
deployed: true,
|
|
1423
|
-
deployedAt:
|
|
1424
|
-
size:
|
|
1425
|
-
hash: "
|
|
1426
|
-
validatorWalletAddress: "
|
|
1419
|
+
deployedAt: 1790246225795,
|
|
1420
|
+
size: 85107,
|
|
1421
|
+
hash: "25ecf952c4c44c40b0920b92d57906e7010ed9a38e2ba41ccdee6d3377c2b596",
|
|
1422
|
+
validatorWalletAddress: "0xEfb258D455a31d061Bbeb3DE3D2143BdFCB67a6C",
|
|
1427
1423
|
pkp: {
|
|
1428
1424
|
publicKey: "0x04cfccb9b6c7addc79469c0e9fafebef4c70801302c62cdb26b610723a9b8527d23f98a40158c7340d83fd0e62d02b5ec74c12f7a86d98e8c6973b4811110f19ad",
|
|
1429
|
-
ethAddress: "
|
|
1425
|
+
ethAddress: "0xEfb258D455a31d061Bbeb3DE3D2143BdFCB67a6C"
|
|
1430
1426
|
}
|
|
1431
1427
|
},
|
|
1432
1428
|
extendPositionValidator: {
|
|
1433
|
-
cid: "
|
|
1429
|
+
cid: "QmZ3g7g5DkgU1gEYpFjprQf3sctUHtGjNQVYezw2bnPGEX",
|
|
1434
1430
|
authorizedCidHex: cidToHex(
|
|
1435
|
-
"
|
|
1431
|
+
"QmZ3g7g5DkgU1gEYpFjprQf3sctUHtGjNQVYezw2bnPGEX"
|
|
1436
1432
|
),
|
|
1437
1433
|
name: "Extend Position Validator",
|
|
1438
1434
|
description: "Production Extend Position Validator",
|
|
1439
1435
|
version: "1.2.1",
|
|
1440
1436
|
deployed: true,
|
|
1441
|
-
deployedAt:
|
|
1442
|
-
size:
|
|
1443
|
-
hash: "
|
|
1444
|
-
validatorWalletAddress: "
|
|
1437
|
+
deployedAt: 1790246231975,
|
|
1438
|
+
size: 82853,
|
|
1439
|
+
hash: "25d4887b7f646649db2bb7f2bfb77d039db83228a6c454377ca26c779b0903cc",
|
|
1440
|
+
validatorWalletAddress: "0xEfb258D455a31d061Bbeb3DE3D2143BdFCB67a6C",
|
|
1445
1441
|
pkp: {
|
|
1446
1442
|
publicKey: "0x04e52338f6a0c3362800f1a94c4c8f08be5030dde0fa217388c53d1c1a4790f4443c9f2886b2d2d8f4b75a9a156e9b028011b1a1cf7648da0e556aa980ec692836",
|
|
1447
|
-
ethAddress: "
|
|
1443
|
+
ethAddress: "0xEfb258D455a31d061Bbeb3DE3D2143BdFCB67a6C"
|
|
1448
1444
|
}
|
|
1449
1445
|
},
|
|
1450
1446
|
btcWithdrawal: {
|
|
1451
|
-
cid: "
|
|
1447
|
+
cid: "QmbRaaMQr1jCctDGe8mPADsUz1rkb4frT1YqSKroiXjzyP",
|
|
1452
1448
|
authorizedCidHex: cidToHex(
|
|
1453
|
-
"
|
|
1449
|
+
"QmbRaaMQr1jCctDGe8mPADsUz1rkb4frT1YqSKroiXjzyP"
|
|
1454
1450
|
),
|
|
1455
1451
|
name: "Btc Withdrawal",
|
|
1456
1452
|
description: "Production Btc Withdrawal",
|
|
1457
1453
|
version: "1.2.7",
|
|
1458
1454
|
deployed: true,
|
|
1459
|
-
deployedAt:
|
|
1460
|
-
size:
|
|
1461
|
-
hash: "
|
|
1462
|
-
validatorWalletAddress: "
|
|
1455
|
+
deployedAt: 1790246239599,
|
|
1456
|
+
size: 101228,
|
|
1457
|
+
hash: "2ed25eca6cc80a43061b7ad119737af48158fdb61d59f10cd06cea51b607f112",
|
|
1458
|
+
validatorWalletAddress: "0xEfb258D455a31d061Bbeb3DE3D2143BdFCB67a6C",
|
|
1463
1459
|
pkp: {
|
|
1464
1460
|
publicKey: "0x043616787c5432415c24378c4ef48de2bcd6bb7b575b837e3cff09171802662da7105d79586c7659677a0ecbaddac4cce06cb2a11f69a16fa0c4d7002ac7d51a4d",
|
|
1465
|
-
ethAddress: "
|
|
1461
|
+
ethAddress: "0xEfb258D455a31d061Bbeb3DE3D2143BdFCB67a6C"
|
|
1466
1462
|
}
|
|
1467
1463
|
},
|
|
1468
1464
|
liquidationValidator: {
|
|
1469
|
-
cid: "
|
|
1465
|
+
cid: "QmTs2w8gfAwWZLbzJZg2CZmiLhVXS5kbMgaj42Zuxfodpb",
|
|
1470
1466
|
authorizedCidHex: cidToHex(
|
|
1471
|
-
"
|
|
1467
|
+
"QmTs2w8gfAwWZLbzJZg2CZmiLhVXS5kbMgaj42Zuxfodpb"
|
|
1472
1468
|
),
|
|
1473
1469
|
name: "Liquidation Validator",
|
|
1474
1470
|
description: "Production Liquidation Validator",
|
|
1475
1471
|
version: "1.2.1",
|
|
1476
1472
|
deployed: true,
|
|
1477
|
-
deployedAt:
|
|
1478
|
-
size:
|
|
1479
|
-
hash: "
|
|
1480
|
-
validatorWalletAddress: "
|
|
1473
|
+
deployedAt: 1790246247904,
|
|
1474
|
+
size: 70308,
|
|
1475
|
+
hash: "582ccf0ec7f715195e20fdc885996743cb42125b64173424e360ee63db62bbd8",
|
|
1476
|
+
validatorWalletAddress: "0xEfb258D455a31d061Bbeb3DE3D2143BdFCB67a6C",
|
|
1481
1477
|
pkp: {
|
|
1482
1478
|
publicKey: "0x041a241de58976c13e3d7ca5a18e494f7330151e3818706135d50176e78ffb673e58b11f0b67a87c73fade6c6b27d6e7a7377ea9f4c10bf31880f1d725f18cc6f8",
|
|
1483
|
-
ethAddress: "
|
|
1479
|
+
ethAddress: "0xEfb258D455a31d061Bbeb3DE3D2143BdFCB67a6C"
|
|
1484
1480
|
}
|
|
1485
1481
|
},
|
|
1486
1482
|
priceOracle: {
|
|
@@ -1495,28 +1491,28 @@ var require_pkg_src = __commonJS({
|
|
|
1495
1491
|
deployedAt: 1781116663270,
|
|
1496
1492
|
size: 8695,
|
|
1497
1493
|
hash: "ba20ade60a7fa5acd80dadfafa179c507388cfe6ce48a22a672d70b317ffcc74",
|
|
1498
|
-
validatorWalletAddress: "
|
|
1494
|
+
validatorWalletAddress: "0xefb258d455a31d061bbeb3de3d2143bdfcb67a6c",
|
|
1499
1495
|
pkp: {
|
|
1500
1496
|
publicKey: "0x043beaa1da47875601a8d6f430b1438ee2d4732eefd06e5c63a474bbdaf9e7df1797b1b951e041b627c2bf839788164825324c9cbd1e2d6f740fdd4bff69b1900b",
|
|
1501
|
-
ethAddress: "
|
|
1497
|
+
ethAddress: "0xEfb258D455a31d061Bbeb3DE3D2143BdFCB67a6C"
|
|
1502
1498
|
}
|
|
1503
1499
|
},
|
|
1504
1500
|
loanVaultBtcBalance: {
|
|
1505
|
-
cid: "
|
|
1501
|
+
cid: "QmZ27xCzuoaAhWxRsMPsUQkp45a8WPBb21uhxwchw3LG5W",
|
|
1506
1502
|
authorizedCidHex: cidToHex(
|
|
1507
|
-
"
|
|
1503
|
+
"QmZ27xCzuoaAhWxRsMPsUQkp45a8WPBb21uhxwchw3LG5W"
|
|
1508
1504
|
),
|
|
1509
1505
|
name: "Loan Vault Btc Balance",
|
|
1510
1506
|
description: "Production Loan Vault Btc Balance",
|
|
1511
1507
|
version: "1.2.1",
|
|
1512
1508
|
deployed: true,
|
|
1513
|
-
deployedAt:
|
|
1514
|
-
size:
|
|
1515
|
-
hash: "
|
|
1516
|
-
validatorWalletAddress: "
|
|
1509
|
+
deployedAt: 1790179961079,
|
|
1510
|
+
size: 60046,
|
|
1511
|
+
hash: "922e86c0a667fe0c0945771f84aa6b9fe08be9c96dd2f73a9c5cb257d24e22b0",
|
|
1512
|
+
validatorWalletAddress: "0xEfb258D455a31d061Bbeb3DE3D2143BdFCB67a6C",
|
|
1517
1513
|
pkp: {
|
|
1518
1514
|
publicKey: "0x043616787c5432415c24378c4ef48de2bcd6bb7b575b837e3cff09171802662da7105d79586c7659677a0ecbaddac4cce06cb2a11f69a16fa0c4d7002ac7d51a4d",
|
|
1519
|
-
ethAddress: "
|
|
1515
|
+
ethAddress: "0xEfb258D455a31d061Bbeb3DE3D2143BdFCB67a6C"
|
|
1520
1516
|
}
|
|
1521
1517
|
},
|
|
1522
1518
|
// btc-address-balance (Option B) — address-only signed total balance via
|
|
@@ -1526,21 +1522,21 @@ var require_pkg_src = __commonJS({
|
|
|
1526
1522
|
// Requires BitcoinProviderRegistry.addAllowedCid(chainId, keccak256(utf8(cid)))
|
|
1527
1523
|
// on each target chain (the action decrypts registry slots). No OAR entry.
|
|
1528
1524
|
btcAddressBalance: {
|
|
1529
|
-
cid: "
|
|
1525
|
+
cid: "QmVVjB6zCBiXFKffhQPYUAZhj7TXduuvcrPqKtHa3DMXhN",
|
|
1530
1526
|
authorizedCidHex: cidToHex(
|
|
1531
|
-
"
|
|
1527
|
+
"QmVVjB6zCBiXFKffhQPYUAZhj7TXduuvcrPqKtHa3DMXhN"
|
|
1532
1528
|
),
|
|
1533
1529
|
name: "Btc Address Balance",
|
|
1534
1530
|
description: "Address-only signed total BTC balance via registry consensus (no positionId, no price)",
|
|
1535
1531
|
version: "0.2.1",
|
|
1536
1532
|
deployed: true,
|
|
1537
|
-
deployedAt:
|
|
1538
|
-
size:
|
|
1539
|
-
hash: "
|
|
1540
|
-
validatorWalletAddress: "
|
|
1533
|
+
deployedAt: 1790179971315,
|
|
1534
|
+
size: 30295,
|
|
1535
|
+
hash: "2c67d9cfa4d50e835fbb28ae50e80217ceb2be3bb862c89290aadf43fdc739c9",
|
|
1536
|
+
validatorWalletAddress: "0xEfb258D455a31d061Bbeb3DE3D2143BdFCB67a6C",
|
|
1541
1537
|
pkp: {
|
|
1542
1538
|
publicKey: "0x0498cbb31facfa26e3ec83ccdabfe4fe341ca0282e0c3cb81da7113723b9726e1e49efa92165cc3faa66ced4454cea56dbab12267852d6525a55d7c4f128b912cd",
|
|
1543
|
-
ethAddress: "
|
|
1539
|
+
ethAddress: "0xEfb258D455a31d061Bbeb3DE3D2143BdFCB67a6C"
|
|
1544
1540
|
}
|
|
1545
1541
|
},
|
|
1546
1542
|
alwaysSigner: {
|
|
@@ -1570,48 +1566,74 @@ var require_pkg_src = __commonJS({
|
|
|
1570
1566
|
hash: "03ee5be239c91c735d2c95db89a0d1b77e602cfc18af8eb64b3281fddcd90a72"
|
|
1571
1567
|
},
|
|
1572
1568
|
agentModuleExecutor: {
|
|
1573
|
-
cid: "
|
|
1569
|
+
cid: "QmSwPPvQhT7UhcuVA2m3UxGhVj5WqMpDvYNKU1228QLFsX",
|
|
1574
1570
|
authorizedCidHex: cidToHex(
|
|
1575
|
-
"
|
|
1571
|
+
"QmSwPPvQhT7UhcuVA2m3UxGhVj5WqMpDvYNKU1228QLFsX"
|
|
1576
1572
|
),
|
|
1577
1573
|
name: "Agent Module Executor",
|
|
1578
1574
|
description: "Production Agent Module Executor",
|
|
1579
1575
|
version: "1.1.1",
|
|
1580
1576
|
deployed: true,
|
|
1581
|
-
deployedAt:
|
|
1582
|
-
size:
|
|
1583
|
-
hash: "
|
|
1577
|
+
deployedAt: 1790179978959,
|
|
1578
|
+
size: 14688,
|
|
1579
|
+
hash: "8edb9b12c784c8d7d153cce97235584c24665a788767ae68713dce91109ab35e"
|
|
1584
1580
|
},
|
|
1585
1581
|
staleSpendRecoveryValidator: {
|
|
1586
|
-
cid: "
|
|
1582
|
+
cid: "Qmarj59zdSSgivkimryrdvnyZqH5YpTimKj1LivXNBHmNz",
|
|
1587
1583
|
authorizedCidHex: cidToHex(
|
|
1588
|
-
"
|
|
1584
|
+
"Qmarj59zdSSgivkimryrdvnyZqH5YpTimKj1LivXNBHmNz"
|
|
1589
1585
|
),
|
|
1590
1586
|
name: "Stale Spend Recovery Validator",
|
|
1591
1587
|
description: "Production Stale Spend Recovery Validator",
|
|
1592
1588
|
version: "1.1.2",
|
|
1593
1589
|
deployed: true,
|
|
1594
|
-
deployedAt:
|
|
1595
|
-
size:
|
|
1596
|
-
hash: "
|
|
1597
|
-
validatorWalletAddress: "
|
|
1590
|
+
deployedAt: 1790246256280,
|
|
1591
|
+
size: 48143,
|
|
1592
|
+
hash: "ec9236bcbe0af24d3e1844791fc8fe37371bbecd8ce95d02e13f7c6e1fc7d94c",
|
|
1593
|
+
validatorWalletAddress: "0xEfb258D455a31d061Bbeb3DE3D2143BdFCB67a6C",
|
|
1598
1594
|
pkp: {
|
|
1599
1595
|
publicKey: "0x046da0ad6da7dd4a0063cbeac6f2bdb6a9889c2178b23470833356a8ee5630f7f0eee0db348d9d9aaaadd23eccf0063c8f68ee5e446abe30b882bf1de4c932bc21",
|
|
1600
|
-
ethAddress: "
|
|
1596
|
+
ethAddress: "0xEfb258D455a31d061Bbeb3DE3D2143BdFCB67a6C"
|
|
1601
1597
|
}
|
|
1602
1598
|
},
|
|
1603
1599
|
btcUtxoInvalidator: {
|
|
1604
|
-
cid: "
|
|
1600
|
+
cid: "QmbS44bGcmKYF64Cu35qzsk9sxiU4Umde8Z3q24ZnEbQvX",
|
|
1605
1601
|
authorizedCidHex: cidToHex(
|
|
1606
|
-
"
|
|
1602
|
+
"QmbS44bGcmKYF64Cu35qzsk9sxiU4Umde8Z3q24ZnEbQvX"
|
|
1607
1603
|
),
|
|
1608
1604
|
name: "Btc Utxo Invalidator",
|
|
1609
1605
|
description: "Production Btc Utxo Invalidator",
|
|
1610
1606
|
version: "1.0.0",
|
|
1611
1607
|
deployed: true,
|
|
1612
|
-
deployedAt:
|
|
1613
|
-
size:
|
|
1614
|
-
hash: "
|
|
1608
|
+
deployedAt: 1790246264563,
|
|
1609
|
+
size: 69219,
|
|
1610
|
+
hash: "bda048d8cd6b5a39c2774bcf1320e82d1eea935c2a521006fb8b887e13b6dd8d"
|
|
1611
|
+
},
|
|
1612
|
+
carryCollateralAttestation: {
|
|
1613
|
+
cid: "QmYWULmXD9S5AmTdQqWqoZ28ctsZQNcXkAgre9G2Xo9dh8",
|
|
1614
|
+
authorizedCidHex: cidToHex(
|
|
1615
|
+
"QmYWULmXD9S5AmTdQqWqoZ28ctsZQNcXkAgre9G2Xo9dh8"
|
|
1616
|
+
),
|
|
1617
|
+
name: "Carry Collateral Attestation",
|
|
1618
|
+
description: "LoanCarryVault collateral attestation (borrower, BTC vault, confirmed BTC)",
|
|
1619
|
+
version: "1.0.0",
|
|
1620
|
+
deployed: true,
|
|
1621
|
+
deployedAt: 1790927734070,
|
|
1622
|
+
size: 21156,
|
|
1623
|
+
hash: "05b177e0bb36b0483db4a42d33c1bbbf47eb9ef34ae278459397d51a7f8957ff"
|
|
1624
|
+
},
|
|
1625
|
+
carryFundingAttestation: {
|
|
1626
|
+
cid: "QmWhox3xUZMNR5NpPZ9WLSPC5GoW4ms88GanVRKr8uuS3W",
|
|
1627
|
+
authorizedCidHex: cidToHex(
|
|
1628
|
+
"QmWhox3xUZMNR5NpPZ9WLSPC5GoW4ms88GanVRKr8uuS3W"
|
|
1629
|
+
),
|
|
1630
|
+
name: "Carry Funding Attestation",
|
|
1631
|
+
description: "LoanCarryVault funding attestation (Hyperliquid BTC windowed hourly average)",
|
|
1632
|
+
version: "1.0.0",
|
|
1633
|
+
deployed: true,
|
|
1634
|
+
deployedAt: 1790925699980,
|
|
1635
|
+
size: 7193,
|
|
1636
|
+
hash: "4944ada61610cf64b32e33b5be62087088dcf5e821040c69e67942e643ce74c9"
|
|
1615
1637
|
}
|
|
1616
1638
|
};
|
|
1617
1639
|
function getDeploymentsForNetwork(network) {
|
|
@@ -2379,7 +2401,10 @@ ${errorReport}`);
|
|
|
2379
2401
|
BTCSpendAuthorizer: "0xfBbF108486fa07F1B06a811C5b66ed68DD9c508a",
|
|
2380
2402
|
BitcoinProviderRegistry: "0x4ab3Fb96e02893Ed6FAa61bad1918390c8DbbFFC",
|
|
2381
2403
|
LITActionValidator: "0xD2c5d59c2CC5c409AC65ce0A817236aeC6869512",
|
|
2382
|
-
PositionDelegateRegistry: "0xf0aa2678aD4F60f49e8F7725089B5E86B7F8FE4C"
|
|
2404
|
+
PositionDelegateRegistry: "0xf0aa2678aD4F60f49e8F7725089B5E86B7F8FE4C",
|
|
2405
|
+
TermManagerModule: "0xDB99CdF883ffa38acD099bC39F8d1f4508c9239E",
|
|
2406
|
+
UCDController: "0x4b4f8063048bCD59D469219E3f07C6aaDF4f6157",
|
|
2407
|
+
LiquidationManagerModule: "0x74B28695352E7bf736D6c9F76ccb7B4439477De9"
|
|
2383
2408
|
},
|
|
2384
2409
|
11155111: {
|
|
2385
2410
|
PositionManager: "0x68e0507D982AEBF1D1C1Af8FBbd842327e2deeFF",
|
|
@@ -2387,7 +2412,10 @@ ${errorReport}`);
|
|
|
2387
2412
|
BTCSpendAuthorizer: "0xd7E9Eb5eE53f1d9ee55Dc162bBC7486bE437B6bD",
|
|
2388
2413
|
BitcoinProviderRegistry: "0xbfA0c48B070D0a9A9CD27469AeacFD2d4261cEE2",
|
|
2389
2414
|
LITActionValidator: "0x54eECd7C90F8A8fac27749Ba30BbE8AFBAccc856",
|
|
2390
|
-
PositionDelegateRegistry: "0x482369De283622E7b05731875ec137d4E3D208F9"
|
|
2415
|
+
PositionDelegateRegistry: "0x482369De283622E7b05731875ec137d4E3D208F9",
|
|
2416
|
+
TermManagerModule: "0x94Adc6F9558368B1482197584f1fc7133Ecf835b",
|
|
2417
|
+
UCDController: "0x360Bde4e489ee94E26601B206932De09EE60FF04",
|
|
2418
|
+
LiquidationManagerModule: "0xC4AB00f39e7ceD812F5C67058C9fa44e15d40e76"
|
|
2391
2419
|
}
|
|
2392
2420
|
};
|
|
2393
2421
|
function getPinnedContractAddresses(chainId) {
|
|
@@ -2573,10 +2601,10 @@ ${errorReport}`);
|
|
|
2573
2601
|
};
|
|
2574
2602
|
}
|
|
2575
2603
|
const ratioBigInt = collateralValueUsd * UCD_TOKEN_DECIMALS * 10000n / ucdDebt;
|
|
2576
|
-
const
|
|
2604
|
+
const collateralRatioBps2 = Number(ratioBigInt);
|
|
2577
2605
|
return {
|
|
2578
2606
|
collateralValueUsd,
|
|
2579
|
-
collateralRatioBps
|
|
2607
|
+
collateralRatioBps: collateralRatioBps2
|
|
2580
2608
|
};
|
|
2581
2609
|
}
|
|
2582
2610
|
function hasSufficientCollateralForDebt(collateralValueUsd, currentDebt, additionalDebt, requiredRatioBps) {
|
|
@@ -3430,6 +3458,17 @@ ${auth.clientId}`;
|
|
|
3430
3458
|
);
|
|
3431
3459
|
}
|
|
3432
3460
|
}
|
|
3461
|
+
var TIP_READ_FAILURE_PREFIX = "Bitcoin tip-height read failed";
|
|
3462
|
+
var BitcoinTipUnreadableError = class extends Error {
|
|
3463
|
+
constructor(message) {
|
|
3464
|
+
super(message);
|
|
3465
|
+
this.isBitcoinTipUnreadable = true;
|
|
3466
|
+
this.name = "BitcoinTipUnreadableError";
|
|
3467
|
+
}
|
|
3468
|
+
};
|
|
3469
|
+
function isBitcoinTipUnreadableError(error) {
|
|
3470
|
+
return typeof error === "object" && error !== null && error.isBitcoinTipUnreadable === true;
|
|
3471
|
+
}
|
|
3433
3472
|
var BitcoinDataProvider = class {
|
|
3434
3473
|
constructor(config) {
|
|
3435
3474
|
this.config = config;
|
|
@@ -3881,27 +3920,12 @@ ${auth.clientId}`;
|
|
|
3881
3920
|
if (!data.status.confirmed || !data.status.block_height) {
|
|
3882
3921
|
return { txid: data.txid ?? txid, confirmations: 0 };
|
|
3883
3922
|
}
|
|
3884
|
-
|
|
3885
|
-
|
|
3886
|
-
|
|
3887
|
-
|
|
3888
|
-
|
|
3889
|
-
|
|
3890
|
-
return { txid: data.txid ?? txid, confirmations: 1 };
|
|
3891
|
-
}
|
|
3892
|
-
const tipBody = (await tipResp.text()).trim();
|
|
3893
|
-
const tipHeight = Number.parseInt(tipBody, 10);
|
|
3894
|
-
if (!Number.isFinite(tipHeight) || tipHeight <= 0) {
|
|
3895
|
-
return { txid: data.txid ?? txid, confirmations: 1 };
|
|
3896
|
-
}
|
|
3897
|
-
const depth = tipHeight - data.status.block_height + 1;
|
|
3898
|
-
return {
|
|
3899
|
-
txid: data.txid ?? txid,
|
|
3900
|
-
confirmations: depth > 0 ? depth : 0
|
|
3901
|
-
};
|
|
3902
|
-
} catch {
|
|
3903
|
-
return { txid: data.txid ?? txid, confirmations: 1 };
|
|
3904
|
-
}
|
|
3923
|
+
const tipHeight = await this.fetchTipHeight(controller.signal);
|
|
3924
|
+
const depth = tipHeight - data.status.block_height + 1;
|
|
3925
|
+
return {
|
|
3926
|
+
txid: data.txid ?? txid,
|
|
3927
|
+
confirmations: depth > 0 ? depth : 0
|
|
3928
|
+
};
|
|
3905
3929
|
}
|
|
3906
3930
|
return null;
|
|
3907
3931
|
} catch (error) {
|
|
@@ -3909,12 +3933,55 @@ ${auth.clientId}`;
|
|
|
3909
3933
|
if (isAbortError(error)) {
|
|
3910
3934
|
throw new Error(`Request timeout after ${this.timeout}ms`);
|
|
3911
3935
|
}
|
|
3936
|
+
if (isBitcoinTipUnreadableError(error)) {
|
|
3937
|
+
throw error;
|
|
3938
|
+
}
|
|
3912
3939
|
if (getUnknownErrorMessage(error).includes("404")) {
|
|
3913
3940
|
return null;
|
|
3914
3941
|
}
|
|
3915
3942
|
throw error;
|
|
3916
3943
|
}
|
|
3917
3944
|
}
|
|
3945
|
+
/**
|
|
3946
|
+
* Current chain tip height from THIS provider — or throw.
|
|
3947
|
+
*
|
|
3948
|
+
* Every exit is a throw naming the provider and the precise failure, because
|
|
3949
|
+
* the only alternative is inventing a confirmation depth (see the call site).
|
|
3950
|
+
* The single `try` exists solely to attach that name to a transport-level
|
|
3951
|
+
* rejection (DNS, TLS, connection reset, abort); it re-throws the cause
|
|
3952
|
+
* verbatim inside the message and never substitutes a value — authorized for
|
|
3953
|
+
* this case by the Batch 2 plan, §C2.
|
|
3954
|
+
*
|
|
3955
|
+
* @param signal - The caller's AbortSignal, so this read shares the same
|
|
3956
|
+
* timeout budget as the transaction fetch it serves.
|
|
3957
|
+
*/
|
|
3958
|
+
async fetchTipHeight(signal) {
|
|
3959
|
+
const endpoint = `${this.config.providerUrl}/blocks/tip/height`;
|
|
3960
|
+
let tipResp;
|
|
3961
|
+
try {
|
|
3962
|
+
tipResp = await fetch(endpoint, {
|
|
3963
|
+
signal,
|
|
3964
|
+
headers: await this.withAuth()
|
|
3965
|
+
});
|
|
3966
|
+
} catch (error) {
|
|
3967
|
+
throw new BitcoinTipUnreadableError(
|
|
3968
|
+
`${TIP_READ_FAILURE_PREFIX}: GET ${endpoint} threw \u2014 ${getUnknownErrorMessage(error)}`
|
|
3969
|
+
);
|
|
3970
|
+
}
|
|
3971
|
+
if (!tipResp.ok) {
|
|
3972
|
+
throw new BitcoinTipUnreadableError(
|
|
3973
|
+
`${TIP_READ_FAILURE_PREFIX}: GET ${endpoint} \u2192 ${tipResp.status} ${tipResp.statusText}`
|
|
3974
|
+
);
|
|
3975
|
+
}
|
|
3976
|
+
const tipBody = (await tipResp.text()).trim();
|
|
3977
|
+
const tipHeight = Number.parseInt(tipBody, 10);
|
|
3978
|
+
if (!Number.isFinite(tipHeight) || tipHeight <= 0) {
|
|
3979
|
+
throw new BitcoinTipUnreadableError(
|
|
3980
|
+
`${TIP_READ_FAILURE_PREFIX}: GET ${endpoint} returned an unusable tip height "${tipBody.slice(0, 64)}"`
|
|
3981
|
+
);
|
|
3982
|
+
}
|
|
3983
|
+
return tipHeight;
|
|
3984
|
+
}
|
|
3918
3985
|
/**
|
|
3919
3986
|
* Get outputs (vouts) of a Bitcoin transaction
|
|
3920
3987
|
*
|
|
@@ -4552,10 +4619,13 @@ ${auth.clientId}`;
|
|
|
4552
4619
|
* only on unanimity. The confirmed-balance consensus the validators run
|
|
4553
4620
|
* covers `chain_stats` only, so without this the primary provider alone
|
|
4554
4621
|
* could fabricate an unconfirmed UTXO plus a self-consistent parent proof
|
|
4555
|
-
* and inflate the signed balance. Any
|
|
4556
|
-
*
|
|
4557
|
-
*
|
|
4558
|
-
*
|
|
4622
|
+
* and inflate the signed balance. Any verdict disagreement THROWS
|
|
4623
|
+
* (fail-closed) — exclusion on a suppressed proof would deflate the balance
|
|
4624
|
+
* and open a wrongful-liquidation window, so neither direction may proceed
|
|
4625
|
+
* without agreement. A provider that cannot state the chain tip — and only
|
|
4626
|
+
* that failure — is dropped from the quorum rather than aborting the read (it
|
|
4627
|
+
* never counts as agreeing), and falling below `minConsensusProviders`
|
|
4628
|
+
* survivors throws — see `verifyParentIsSelfSpendConsensus`.
|
|
4559
4629
|
*
|
|
4560
4630
|
* The same per-provider `/tx` fetch also returns the parent's outputs, and
|
|
4561
4631
|
* every provider must corroborate each claimed UTXO (index, vault address,
|
|
@@ -4650,10 +4720,26 @@ ${auth.clientId}`;
|
|
|
4650
4720
|
}
|
|
4651
4721
|
/**
|
|
4652
4722
|
* Run the self-spend proof against every configured provider and require
|
|
4653
|
-
* unanimity
|
|
4654
|
-
*
|
|
4723
|
+
* unanimity AMONG THE PROVIDERS THAT ANSWERED. Fail-closed on disagreement:
|
|
4724
|
+
* a verdict mismatch throws and aborts the balance calculation — see
|
|
4655
4725
|
* classifySelfChange for why exclusion is not a safe fallback here.
|
|
4656
4726
|
*
|
|
4727
|
+
* Quorum semantics (2026-09-23, plan C2). ONE failure class is tolerated: a
|
|
4728
|
+
* provider that could not state the chain tip (`BitcoinTipUnreadableError`).
|
|
4729
|
+
* It is ABSENT from the quorum — never counted as agreeing, never allowed to
|
|
4730
|
+
* decide the verdict — and the policy floor, not "at least one", decides when
|
|
4731
|
+
* that absence is fatal: below `minConsensusProviders` surviving readings
|
|
4732
|
+
* there is no cross-check left to trust, and the read fails loudly naming
|
|
4733
|
+
* every provider that dropped out.
|
|
4734
|
+
*
|
|
4735
|
+
* Why only that class. `getTransaction` now throws on an unreadable tip
|
|
4736
|
+
* instead of fabricating `confirmations: 1`; without this carve-out one flaky
|
|
4737
|
+
* `/blocks/tip/height` endpoint would take every balance and spend path down
|
|
4738
|
+
* with it. Every OTHER failure remains fatal, as before: a provider that
|
|
4739
|
+
* answers "I have never seen that transaction" is making a claim about the
|
|
4740
|
+
* chain rather than suffering an outage, and that shape is precisely the
|
|
4741
|
+
* fabricated-UTXO signature the fail-closed rule exists to catch.
|
|
4742
|
+
*
|
|
4657
4743
|
* When the parent IS a unanimous self-spend, every provider's view of the
|
|
4658
4744
|
* parent's OUTPUTS must additionally corroborate the primary's claimed
|
|
4659
4745
|
* UTXOs (index exists, pays the vault, exact value). Without this, a
|
|
@@ -4678,32 +4764,52 @@ ${auth.clientId}`;
|
|
|
4678
4764
|
)
|
|
4679
4765
|
)
|
|
4680
4766
|
);
|
|
4681
|
-
const
|
|
4682
|
-
|
|
4683
|
-
|
|
4684
|
-
|
|
4685
|
-
|
|
4767
|
+
const answered = [];
|
|
4768
|
+
const absences = [];
|
|
4769
|
+
const failures = [];
|
|
4770
|
+
settled.forEach((result, i) => {
|
|
4771
|
+
if (result.status === "fulfilled") {
|
|
4772
|
+
answered.push({ index: i, evaluation: result.value });
|
|
4773
|
+
return;
|
|
4774
|
+
}
|
|
4775
|
+
const described = `${providerName(i)} \u2192 ${result.reason?.message ?? String(result.reason)}`;
|
|
4776
|
+
if (isBitcoinTipUnreadableError(result.reason)) {
|
|
4777
|
+
absences.push(described);
|
|
4778
|
+
return;
|
|
4779
|
+
}
|
|
4780
|
+
failures.push(described);
|
|
4781
|
+
});
|
|
4686
4782
|
if (failures.length > 0) {
|
|
4687
4783
|
throw new Error(
|
|
4688
4784
|
`Self-change classification failed for tx ${parentTxid} on ${failures.length}/${providerConfigs.length} provider(s): ${failures.join("; ")}`
|
|
4689
4785
|
);
|
|
4690
4786
|
}
|
|
4691
|
-
const
|
|
4692
|
-
|
|
4693
|
-
|
|
4694
|
-
|
|
4695
|
-
|
|
4696
|
-
|
|
4787
|
+
const floor = Math.max(1, this.minConsensusProviders);
|
|
4788
|
+
if (answered.length < floor) {
|
|
4789
|
+
throw new Error(
|
|
4790
|
+
`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("; ")}`
|
|
4791
|
+
);
|
|
4792
|
+
}
|
|
4793
|
+
if (absences.length > 0) {
|
|
4794
|
+
litDebugLog(
|
|
4795
|
+
`[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("; ")}`
|
|
4796
|
+
);
|
|
4797
|
+
}
|
|
4798
|
+
const first = answered[0];
|
|
4799
|
+
const disagreements = answered.slice(1).filter((a) => a.evaluation.selfSpend !== first.evaluation.selfSpend).map(
|
|
4800
|
+
(a) => `${providerName(first.index)}=${first.evaluation.selfSpend} vs ${providerName(a.index)}=${a.evaluation.selfSpend}`
|
|
4697
4801
|
);
|
|
4698
4802
|
if (disagreements.length > 0) {
|
|
4699
4803
|
throw new Error(
|
|
4700
4804
|
`Self-change consensus mismatch for tx ${parentTxid}: ${disagreements.join("; ")}. A provider may be compromised or out of sync; refusing to sign.`
|
|
4701
4805
|
);
|
|
4702
4806
|
}
|
|
4703
|
-
if (!
|
|
4807
|
+
if (!first.evaluation.selfSpend) {
|
|
4704
4808
|
return false;
|
|
4705
4809
|
}
|
|
4706
|
-
const outputMismatches =
|
|
4810
|
+
const outputMismatches = answered.map(
|
|
4811
|
+
(a) => a.evaluation.outputMismatch ? `${providerName(a.index)} \u2192 ${a.evaluation.outputMismatch}` : null
|
|
4812
|
+
).filter((m) => m !== null);
|
|
4707
4813
|
if (outputMismatches.length > 0) {
|
|
4708
4814
|
throw new Error(
|
|
4709
4815
|
`Self-change output claim mismatch for tx ${parentTxid}: ${outputMismatches.join("; ")}. The reported UTXO set contradicts the parent transaction; refusing to sign.`
|
|
@@ -4946,16 +5052,6 @@ ${auth.clientId}`;
|
|
|
4946
5052
|
minConfirmations
|
|
4947
5053
|
);
|
|
4948
5054
|
const authorizedSpends = await this.getAuthorizedSpendsFromContract(positionId);
|
|
4949
|
-
for (const spend of authorizedSpends) {
|
|
4950
|
-
const utxoStillExists = utxoSet.utxos.some(
|
|
4951
|
-
(utxo) => utxo.txid === spend.txid && utxo.vout === spend.vout
|
|
4952
|
-
);
|
|
4953
|
-
if (utxoStillExists) {
|
|
4954
|
-
throw new Error(
|
|
4955
|
-
`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.`
|
|
4956
|
-
);
|
|
4957
|
-
}
|
|
4958
|
-
}
|
|
4959
5055
|
const authorizedBalance = authorizedSpends.reduce(
|
|
4960
5056
|
(sum, spend) => sum + spend.satoshis,
|
|
4961
5057
|
0n
|
|
@@ -5251,7 +5347,13 @@ ${auth.clientId}`;
|
|
|
5251
5347
|
allowDevSinglePriceProvider: false,
|
|
5252
5348
|
minBitcoinBalanceConfirmations: 1,
|
|
5253
5349
|
minBitcoinSpendConfirmations: 1,
|
|
5254
|
-
|
|
5350
|
+
// 2 since 2026-09-23. It was 1 because Sepolia ran a single faucet provider
|
|
5351
|
+
// "by design", so the consensus floor was documented as a mainnet-only
|
|
5352
|
+
// guarantee. The registry now holds two, and leaving the floor at 1 meant
|
|
5353
|
+
// Sepolia could never exercise the multi-provider agreement the stale-spend
|
|
5354
|
+
// and balance paths rely on — the one environment where that logic is
|
|
5355
|
+
// supposed to be proved before mainnet.
|
|
5356
|
+
minConsensusProviders: 2
|
|
5255
5357
|
},
|
|
5256
5358
|
[
|
|
5257
5359
|
"ethereum"
|
|
@@ -5562,7 +5664,6 @@ function getSepoliaConfig() {
|
|
|
5562
5664
|
feeRecipientRegistry: SEPOLIA_CONTRACTS.FeeRecipientRegistry || "",
|
|
5563
5665
|
positionDelegateRegistry: SEPOLIA_CONTRACTS.PositionDelegateRegistry || "",
|
|
5564
5666
|
bitcoinWithdrawalAddressRegistry: SEPOLIA_CONTRACTS.BitcoinWithdrawalAddressRegistry || "",
|
|
5565
|
-
carryAgentRegistry: SEPOLIA_CONTRACTS.CarryAgentRegistry || "",
|
|
5566
5667
|
agentDelegationRegistry: SEPOLIA_CONTRACTS.AgentDelegationRegistry || "",
|
|
5567
5668
|
dhAgentDelegate: SEPOLIA_CONTRACTS.DHAgentDelegate || "",
|
|
5568
5669
|
agentModuleFactory: SEPOLIA_CONTRACTS.AgentModuleFactory || ""
|
|
@@ -5616,7 +5717,6 @@ function getMainnetConfig() {
|
|
|
5616
5717
|
feeRecipientRegistry: MAINNET_CONTRACTS.FeeRecipientRegistry || "",
|
|
5617
5718
|
positionDelegateRegistry: MAINNET_CONTRACTS.PositionDelegateRegistry || "",
|
|
5618
5719
|
bitcoinWithdrawalAddressRegistry: MAINNET_CONTRACTS.BitcoinWithdrawalAddressRegistry || "",
|
|
5619
|
-
carryAgentRegistry: MAINNET_CONTRACTS.CarryAgentRegistry || "",
|
|
5620
5720
|
agentDelegationRegistry: MAINNET_CONTRACTS.AgentDelegationRegistry || "",
|
|
5621
5721
|
dhAgentDelegate: MAINNET_CONTRACTS.DHAgentDelegate || "",
|
|
5622
5722
|
// Empty on mainnet until the factory is deployed there — the ceremony is Sepolia-only.
|
|
@@ -6816,7 +6916,54 @@ async function resolveAuthorizationInput(provider, signer, ctx) {
|
|
|
6816
6916
|
return { timestamp: result.timestamp, signature: result.signature };
|
|
6817
6917
|
}
|
|
6818
6918
|
|
|
6919
|
+
// src/utils/btc-dust.utils.ts
|
|
6920
|
+
var BECH32_CHARSET = "qpzry9x8gf2tvdw0s3jn54khce6mua7l";
|
|
6921
|
+
function segwitProgramShape(address) {
|
|
6922
|
+
const lower2 = address.trim().toLowerCase();
|
|
6923
|
+
if (!/^(bc1|tb1|bcrt1)/.test(lower2))
|
|
6924
|
+
return null;
|
|
6925
|
+
const sep = lower2.lastIndexOf("1");
|
|
6926
|
+
const data = lower2.slice(sep + 1);
|
|
6927
|
+
if (data.length < 8)
|
|
6928
|
+
return null;
|
|
6929
|
+
const version = BECH32_CHARSET.indexOf(data[0]);
|
|
6930
|
+
if (version < 0)
|
|
6931
|
+
return null;
|
|
6932
|
+
const programChars = data.length - 1 - 6;
|
|
6933
|
+
return { version, programBytes: Math.floor(programChars * 5 / 8) };
|
|
6934
|
+
}
|
|
6935
|
+
function dustLimitForAddress(address) {
|
|
6936
|
+
const shape = segwitProgramShape(address);
|
|
6937
|
+
if (shape === null)
|
|
6938
|
+
return 546;
|
|
6939
|
+
if (shape.version === 0 && shape.programBytes === 20)
|
|
6940
|
+
return 294;
|
|
6941
|
+
if (shape.version === 0 && shape.programBytes === 32)
|
|
6942
|
+
return 330;
|
|
6943
|
+
if (shape.version === 1 && shape.programBytes === 32)
|
|
6944
|
+
return 330;
|
|
6945
|
+
return 546;
|
|
6946
|
+
}
|
|
6947
|
+
function destinationDustShortfall(targetAmount, networkFee, destination) {
|
|
6948
|
+
const limit = dustLimitForAddress(destination);
|
|
6949
|
+
return targetAmount - networkFee < limit ? limit : null;
|
|
6950
|
+
}
|
|
6951
|
+
|
|
6819
6952
|
// src/utils/loan-helpers.utils.ts
|
|
6953
|
+
function calculateMintFee(params) {
|
|
6954
|
+
const { mintAmount, mintTimestamp, originationFeeBps, previousExpiryAt, selectedTerm, totalTerm } = params;
|
|
6955
|
+
let mintFee = mintAmount * BigInt(originationFeeBps) / 10000n;
|
|
6956
|
+
if (previousExpiryAt > 0 && mintTimestamp < previousExpiryAt) {
|
|
6957
|
+
const tailSeconds = BigInt(previousExpiryAt) - BigInt(mintTimestamp);
|
|
6958
|
+
const originalTermMonths = totalTerm - selectedTerm;
|
|
6959
|
+
const originalTermSeconds = BigInt(
|
|
6960
|
+
originalTermMonths === 12 ? 365 * 86400 : originalTermMonths * 30 * 86400
|
|
6961
|
+
);
|
|
6962
|
+
const tailFee = tailSeconds * BigInt(originationFeeBps) * mintAmount / (10000n * originalTermSeconds);
|
|
6963
|
+
mintFee = mintFee + tailFee;
|
|
6964
|
+
}
|
|
6965
|
+
return mintFee;
|
|
6966
|
+
}
|
|
6820
6967
|
function baseMintFeeWei(mintAmountWei, originationFeeBps) {
|
|
6821
6968
|
if (mintAmountWei < 0n)
|
|
6822
6969
|
throw new Error("baseMintFeeWei: mintAmountWei cannot be negative");
|
|
@@ -6835,20 +6982,34 @@ function debtAfterMintExceedsLoanCap(params) {
|
|
|
6835
6982
|
}
|
|
6836
6983
|
return currentDebtWei + mintAmountWei + mintFeeWei > maxLoanWei;
|
|
6837
6984
|
}
|
|
6838
|
-
function
|
|
6839
|
-
|
|
6840
|
-
|
|
6841
|
-
throw new Error("maxPrincipalWithinLoanCap: amounts cannot be negative");
|
|
6985
|
+
function collateralRatioBps(sats, price8, debtWei) {
|
|
6986
|
+
if (sats < 0n || price8 < 0n) {
|
|
6987
|
+
throw new Error("collateralRatioBps: sats and price cannot be negative");
|
|
6842
6988
|
}
|
|
6843
|
-
if (
|
|
6844
|
-
throw new Error(
|
|
6845
|
-
`maxPrincipalWithinLoanCap: originationFeeBps must be an integer in [0, 10000] (got ${String(originationFeeBps)})`
|
|
6846
|
-
);
|
|
6989
|
+
if (debtWei <= 0n) {
|
|
6990
|
+
throw new Error("collateralRatioBps: debt must be positive");
|
|
6847
6991
|
}
|
|
6848
|
-
|
|
6849
|
-
|
|
6850
|
-
|
|
6851
|
-
|
|
6992
|
+
return sats * price8 * 100n * 10000n / debtWei;
|
|
6993
|
+
}
|
|
6994
|
+
function collateralRatioPercentString(sats, price8, debtWei) {
|
|
6995
|
+
const bps = collateralRatioBps(sats, price8, debtWei);
|
|
6996
|
+
return `${bps / 100n}.${(bps % 100n).toString().padStart(2, "0")}`;
|
|
6997
|
+
}
|
|
6998
|
+
function maxPrincipalForFee(room, fee) {
|
|
6999
|
+
if (room < 0n)
|
|
7000
|
+
throw new Error("maxPrincipalForFee: room cannot be negative");
|
|
7001
|
+
if (fee(0n) !== 0n)
|
|
7002
|
+
throw new Error("maxPrincipalForFee: fee(0) must be 0");
|
|
7003
|
+
let lo = 0n;
|
|
7004
|
+
let hi = room;
|
|
7005
|
+
while (lo < hi) {
|
|
7006
|
+
const mid = (lo + hi + 1n) / 2n;
|
|
7007
|
+
if (mid + fee(mid) <= room)
|
|
7008
|
+
lo = mid;
|
|
7009
|
+
else
|
|
7010
|
+
hi = mid - 1n;
|
|
7011
|
+
}
|
|
7012
|
+
return lo;
|
|
6852
7013
|
}
|
|
6853
7014
|
|
|
6854
7015
|
// src/utils/eip712-login.ts
|
|
@@ -19155,9 +19316,17 @@ async function mintAgentPkp(params) {
|
|
|
19155
19316
|
}
|
|
19156
19317
|
var AGENT_STATUS = { None: 0, Active: 1, Revoked: 2 };
|
|
19157
19318
|
function planAgentBinding(params) {
|
|
19158
|
-
const { isActive, record, nowSeconds } = params;
|
|
19319
|
+
const { isActive, paused, record, nowSeconds } = params;
|
|
19320
|
+
if (typeof paused !== "boolean") {
|
|
19321
|
+
throw new Error("planAgentBinding: `paused` must be read from the registry (boolean required)");
|
|
19322
|
+
}
|
|
19159
19323
|
if (isActive)
|
|
19160
19324
|
return { kind: "reuse", agent: record.agent };
|
|
19325
|
+
if (paused) {
|
|
19326
|
+
throw new Error(
|
|
19327
|
+
"AgentDelegationRegistry is paused \u2014 agent delegation cannot be changed until it is unpaused."
|
|
19328
|
+
);
|
|
19329
|
+
}
|
|
19161
19330
|
const status = Number(record.status);
|
|
19162
19331
|
if (status === AGENT_STATUS.None || status === AGENT_STATUS.Revoked) {
|
|
19163
19332
|
return { kind: "register" };
|
|
@@ -19167,7 +19336,7 @@ function planAgentBinding(params) {
|
|
|
19167
19336
|
}
|
|
19168
19337
|
if (Number(record.validUntil) > nowSeconds) {
|
|
19169
19338
|
throw new Error(
|
|
19170
|
-
"AgentDelegationRegistry
|
|
19339
|
+
"AgentDelegationRegistry returned an inconsistent read (an unexpired, unpaused Active agent reported inactive); retry."
|
|
19171
19340
|
);
|
|
19172
19341
|
}
|
|
19173
19342
|
return { kind: "rotate" };
|
|
@@ -20369,7 +20538,7 @@ function normalizeBigNumberish(value) {
|
|
|
20369
20538
|
}
|
|
20370
20539
|
return value;
|
|
20371
20540
|
}
|
|
20372
|
-
if (typeof value === "object" && value !== null && "toString" in value && typeof value.toString === "function") {
|
|
20541
|
+
if (typeof value === "object" && value !== null && "toString" in value && typeof value.toString === "function" && value.toString !== Object.prototype.toString) {
|
|
20373
20542
|
const result = value.toString();
|
|
20374
20543
|
if (typeof result === "object" && result !== null && "_hex" in result) {
|
|
20375
20544
|
const resultObj = result;
|
|
@@ -21782,12 +21951,21 @@ var DiamondHandsSDK = class _DiamondHandsSDK {
|
|
|
21782
21951
|
maxLoanWei: maxLoanValueWei
|
|
21783
21952
|
})) {
|
|
21784
21953
|
const debtAfterWei = currentDebtWei + requestAmountWei + baseFeeWei;
|
|
21954
|
+
const suggestionStamp = calculateNextQuantumTimestamp();
|
|
21955
|
+
const room = maxLoanValueWei > currentDebtWei ? maxLoanValueWei - currentDebtWei : 0n;
|
|
21785
21956
|
const maxPrincipalUcd = Number(
|
|
21786
|
-
|
|
21787
|
-
|
|
21788
|
-
|
|
21789
|
-
|
|
21790
|
-
|
|
21957
|
+
maxPrincipalForFee(
|
|
21958
|
+
room,
|
|
21959
|
+
(principal) => calculateMintFee({
|
|
21960
|
+
mintAmount: principal,
|
|
21961
|
+
mintTimestamp: suggestionStamp,
|
|
21962
|
+
originationFeeBps: positionTerm.originationFeeBps,
|
|
21963
|
+
expiryAt: Number(position2.expiryAt),
|
|
21964
|
+
previousExpiryAt: Number(position2.previousExpiryAt),
|
|
21965
|
+
selectedTerm: Number(position2.selectedTerm),
|
|
21966
|
+
totalTerm: Number(position2.totalTerm)
|
|
21967
|
+
})
|
|
21968
|
+
) / BigInt(10 ** 18)
|
|
21791
21969
|
);
|
|
21792
21970
|
return {
|
|
21793
21971
|
success: false,
|
|
@@ -22865,11 +23043,7 @@ Message: ${causeMessage}${quantumContext}${loanCapDiagnostics}${mintDebtDiagnost
|
|
|
22865
23043
|
const debt = positionDetails.debt || positionDetails.ucdDebt || "0";
|
|
22866
23044
|
const btcPrice2 = litActionResult.btcPrice || "0";
|
|
22867
23045
|
const btcVaultBalance = litActionResult.btcAmountSats || positionDetails.btcVaultBalance || "0";
|
|
22868
|
-
const
|
|
22869
|
-
const btcAmount = Number(btcVaultBalance) / 1e8;
|
|
22870
|
-
const btcValueUSD = btcAmount * usdPricePerBTC;
|
|
22871
|
-
const debtUSD = Number(debt) / 1e18;
|
|
22872
|
-
const ratio = debtUSD > 0 ? (btcValueUSD / debtUSD * 100).toFixed(2) : "0.00";
|
|
23046
|
+
const ratio = BigInt(debt) > 0n ? collateralRatioPercentString(BigInt(btcVaultBalance), BigInt(btcPrice2), BigInt(debt)) : "0.00";
|
|
22873
23047
|
const message = formatLiquidationSkippedMessage(
|
|
22874
23048
|
request.positionId,
|
|
22875
23049
|
ratio,
|
|
@@ -23358,14 +23532,15 @@ Message: ${causeMessage}${quantumContext}${loanCapDiagnostics}${mintDebtDiagnost
|
|
|
23358
23532
|
}
|
|
23359
23533
|
const debt = positionDetails.debt || positionDetails.ucdDebt || "0";
|
|
23360
23534
|
const btcPrice2 = litActionResult.btcPrice || "0";
|
|
23361
|
-
const
|
|
23535
|
+
const btcVaultBalance = litActionResult.btcAmountSats || positionDetails.btcVaultBalance || "0";
|
|
23536
|
+
const ratio = BigInt(debt) > 0n ? collateralRatioPercentString(BigInt(btcVaultBalance), BigInt(btcPrice2), BigInt(debt)) : "0.00";
|
|
23362
23537
|
const message = formatLiquidationSuccessMessage(
|
|
23363
23538
|
request.positionId,
|
|
23364
23539
|
ratio,
|
|
23365
23540
|
`${liquidationThreshold / 100}`,
|
|
23366
23541
|
// Convert to percentage
|
|
23367
23542
|
positionDetails.btcVault || "unknown",
|
|
23368
|
-
|
|
23543
|
+
btcVaultBalance,
|
|
23369
23544
|
debt,
|
|
23370
23545
|
btcPrice2
|
|
23371
23546
|
);
|
|
@@ -25838,6 +26013,17 @@ Message: ${causeMessage}${quantumContext}${loanCapDiagnostics}${mintDebtDiagnost
|
|
|
25838
26013
|
error: `networkFee=${request.networkFee} is \u2265 50% of targetAmount=${request.targetAmount}. Refusing to broadcast \u2014 real Bitcoin fees are typically <1% of value.`
|
|
25839
26014
|
};
|
|
25840
26015
|
}
|
|
26016
|
+
const destinationDustLimit = destinationDustShortfall(
|
|
26017
|
+
request.targetAmount,
|
|
26018
|
+
request.networkFee,
|
|
26019
|
+
request.destination
|
|
26020
|
+
);
|
|
26021
|
+
if (destinationDustLimit !== null) {
|
|
26022
|
+
return {
|
|
26023
|
+
success: false,
|
|
26024
|
+
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.`
|
|
26025
|
+
};
|
|
26026
|
+
}
|
|
25841
26027
|
const [txid, voutStr] = request.utxoIdentifier.split(":");
|
|
25842
26028
|
const vout = parseInt(voutStr || "0", 10);
|
|
25843
26029
|
if (!txid || isNaN(vout)) {
|
|
@@ -27310,8 +27496,9 @@ Message: ${causeMessage}${quantumContext}${loanCapDiagnostics}${mintDebtDiagnost
|
|
|
27310
27496
|
const user = await signer.getAddress();
|
|
27311
27497
|
const registry = AgentDelegationRegistry__factory.connect(addr, signer);
|
|
27312
27498
|
let agentAddress;
|
|
27313
|
-
const [isActive, record, latestBlock] = await Promise.all([
|
|
27499
|
+
const [isActive, paused, record, latestBlock] = await Promise.all([
|
|
27314
27500
|
registry.isAgentActive(user),
|
|
27501
|
+
registry.paused(),
|
|
27315
27502
|
registry.agentOf(user),
|
|
27316
27503
|
this.getProviderOrThrow().getBlock("latest")
|
|
27317
27504
|
]);
|
|
@@ -27322,7 +27509,7 @@ Message: ${causeMessage}${quantumContext}${loanCapDiagnostics}${mintDebtDiagnost
|
|
|
27322
27509
|
severity: "HIGH" /* HIGH */
|
|
27323
27510
|
});
|
|
27324
27511
|
}
|
|
27325
|
-
const plan = planAgentBinding({ isActive, record, nowSeconds: latestBlock.timestamp });
|
|
27512
|
+
const plan = planAgentBinding({ isActive, paused, record, nowSeconds: latestBlock.timestamp });
|
|
27326
27513
|
if (plan.kind === "reuse") {
|
|
27327
27514
|
agentAddress = plan.agent;
|
|
27328
27515
|
} else {
|