@gvnrdao/dh-sdk 0.0.347 → 0.0.349

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.mjs CHANGED
@@ -364,7 +364,7 @@ var init_deployment_addresses = __esm({
364
364
  BITCOIN_WITHDRAWAL_ADDRESS_REGISTRY: "0x6376D392097F0A81e51BD83960A97EA20eaf1dbe",
365
365
  BITCOIN_WITHDRAWAL_ADDRESS_REGISTRY_IMPL: "0x76E0a2c9d89562fD7c50b5f554d7fa25957e39Db",
366
366
  AGENT_DELEGATION_REGISTRY: "0x6AE7fc6bE0925126b9D25b1B7Ce5AD5d127ec025",
367
- AGENT_DELEGATION_REGISTRY_IMPL: "0xE931E4b9ceF2A48Ac7D57192da4B523756cFC310",
367
+ AGENT_DELEGATION_REGISTRY_IMPL: "0x56a5af2C1549EFf70feD1F3BB8E1997717A84973",
368
368
  DH_AGENT_DELEGATE: "0xa5A14489ae883960df6E1463A41a47aBE9Ecc5AF"
369
369
  }
370
370
  };
@@ -547,14 +547,26 @@ var init_deployment_addresses = __esm({
547
547
  block: 25669024
548
548
  },
549
549
  PositionManagerViews: {
550
- previousImplementation: "0x9225647a30bbACA4Acc0491B786869036914242e",
551
- newImplementation: "0xE68DC096A65Ecddbc6A9b5c6e5f878e2CE143Bfe",
550
+ previousImplementation: "0xE68DC096A65Ecddbc6A9b5c6e5f878e2CE143Bfe",
551
+ newImplementation: "0x8fe7aF14dB9Bef814c4c8fBc0ce206Cb17F25E8e",
552
552
  proxy: "0x8B57954eA338c6A6bfF1457f71080e25baFF3937",
553
- upgradedAt: "2026-08-03T08:34:23.000Z",
554
- upgradedBy: "REPLACED, not upgraded. Fresh ERC1967Proxy (atomically initialized) + AdminModule generic-op 0x848a97186f0d PositionManager.setViews(proxy) \u2014 3-of-3, 24h timelock, executed in onchain-auth/.safe-batches/mainnet-release-execute-B.json",
555
- reason: "2026-08 agent-stack release. The mainnet PositionManagerViews at 0x9225647a was deployed as a BARE implementation (EIP-1967 slot 0x00), so upgradeToAndCall reverts UUPSUnauthorizedCallContext \u2014 it could never be upgraded. PositionManager.setViews (added in the same Execute B batch) removed the repoint blocker, so Views was replaced behind a new proxy rather than upgraded. This makes the Pashov F3 renewal debt-ceiling check REACHABLE for the first time: ExceedsMaxLoan (0x499e7985) is present in 0xE68DC096 and absent from 0x9225647a. Views holds no protocol state (8 wiring slots + roles + pause), which is what made replacement safe. The old contract is ABANDONED, not decommissioned \u2014 it stays live and callable as the rollback target for setViews. NOTE: VERSION reads 1.1.1 on both sides; verify by address.",
556
- executeTx: "0xf1f8d5fc13f45d7a3f932bf1a2d6e29381fdd41cd31298ad785bf7688df07fe6",
557
- block: 25673200
553
+ upgradedAt: "2026-10-17T12:16:35.000Z",
554
+ upgradedBy: "AdminModule generic-op 0x60494d283c30afb95748d8c1bb95b800ab8f17d2a2a45fb04784ebde7b05393c upgradeToAndCall(0x8fe7aF14, initializeV2(AdminModule)) \u2014 3-of-3 signatures (0x3030C041, 0x52b67f31, 0xfb3B8cbe), 24h timelock; proposed by Safe 0x3030C0414B6d95aA9d5A57269E51a347fCBaB472 in tx 0xffe3dd376736d542a89f944290b876d8eb8e5c3df8fc8349bc34a963106dd0f2, executed from Safe 0x52b67f31Ca7A58Ef20322512EB359b7D4758C868 via onchain-auth/.safe-batches/mainnet-pmv-backing-view-execute.json",
555
+ reason: "PoR vault-address gaps (tasks/vault-address-por-gaps-plan-2026-10-02.md, runbook tasks/RUNBOOK-pmv-backing-view-mainnet-2026-10-02.md). VERSION 1.1.1 -> 1.1.2: adds getBackingVaults (paged backing set: positions with ucdDebt > 0 and their stored vault addresses), locks the implementation (_disableInitializers constructor), and the call data initializeV2(AdminModule) consumes the previously OPEN reinitializer(2) (Cloudflare audit finding) without changing adminModule. No storage layout change. Post-upgrade: scripts/audit/backing-vaults-verify.ts PASS @ block 26226360 (72 positions, 15 backing vaults, view == independent scan; Initializable version 2; impl locked). Pre-proposed rollback op 0x43f50eb30d360a779f24c8229dd2d3b56a5d9eb40f056d3cd13047e5f0f51e84 (1/3 sigs) is to be cancelled by the proposer Safe via mainnet-pmv-backing-view-cancel-REVERT.json.",
556
+ executeTx: "0xbb36e557141827a0de990b7124ef8615352a2eb8c197efb3ce3a63998994fef5",
557
+ block: 26212216,
558
+ history: [
559
+ {
560
+ previousImplementation: "0x9225647a30bbACA4Acc0491B786869036914242e",
561
+ newImplementation: "0xE68DC096A65Ecddbc6A9b5c6e5f878e2CE143Bfe",
562
+ proxy: "0x8B57954eA338c6A6bfF1457f71080e25baFF3937",
563
+ upgradedAt: "2026-08-03T08:34:23.000Z",
564
+ upgradedBy: "REPLACED, not upgraded. Fresh ERC1967Proxy (atomically initialized) + AdminModule generic-op 0x848a97186f0d PositionManager.setViews(proxy) \u2014 3-of-3, 24h timelock, executed in onchain-auth/.safe-batches/mainnet-release-execute-B.json",
565
+ reason: "2026-08 agent-stack release. The mainnet PositionManagerViews at 0x9225647a was deployed as a BARE implementation (EIP-1967 slot 0x00), so upgradeToAndCall reverts UUPSUnauthorizedCallContext \u2014 it could never be upgraded. PositionManager.setViews (added in the same Execute B batch) removed the repoint blocker, so Views was replaced behind a new proxy rather than upgraded. This makes the Pashov F3 renewal debt-ceiling check REACHABLE for the first time: ExceedsMaxLoan (0x499e7985) is present in 0xE68DC096 and absent from 0x9225647a. Views holds no protocol state (8 wiring slots + roles + pause), which is what made replacement safe. The old contract is ABANDONED, not decommissioned \u2014 it stays live and callable as the rollback target for setViews. NOTE: VERSION reads 1.1.1 on both sides; verify by address.",
566
+ executeTx: "0xf1f8d5fc13f45d7a3f932bf1a2d6e29381fdd41cd31298ad785bf7688df07fe6",
567
+ block: 25673200
568
+ }
569
+ ]
558
570
  },
559
571
  AgentDelegationRegistry: {
560
572
  newImplementation: "0xa9fF405Edd4329fc3159a64F56B37EBD253e4928",
@@ -1117,6 +1129,9 @@ var require_pkg_src = __commonJS({
1117
1129
  BORROWER_AUTHORIZATION_ENCODE_TYPES: () => BORROWER_AUTHORIZATION_ENCODE_TYPES,
1118
1130
  BORROWER_AUTHORIZATION_FIELDS: () => BORROWER_AUTHORIZATION_FIELDS,
1119
1131
  BORROWER_AUTHORIZATION_PRIMARY_TYPES: () => BORROWER_AUTHORIZATION_PRIMARY_TYPES,
1132
+ BTC_SPEND_REQUEST_ENCODE_TYPES: () => BTC_SPEND_REQUEST_ENCODE_TYPES,
1133
+ BTC_SPEND_REQUEST_FIELDS: () => BTC_SPEND_REQUEST_FIELDS,
1134
+ BTC_SPEND_REQUEST_PRIMARY_TYPES: () => BTC_SPEND_REQUEST_PRIMARY_TYPES,
1120
1135
  CHIPOTLE_DEPLOYMENTS: () => CHIPOTLE_DEPLOYMENTS,
1121
1136
  DEFAULT_CACHE_CONFIG: () => DEFAULT_CACHE_CONFIG,
1122
1137
  DEFAULT_DEBUG_CONFIG: () => DEFAULT_DEBUG_CONFIG,
@@ -1130,8 +1145,11 @@ var require_pkg_src = __commonJS({
1130
1145
  RetryStrategy: () => RetryStrategy,
1131
1146
  analyzeError: () => analyzeError,
1132
1147
  borrowerAuthorizationTypes: () => borrowerAuthorizationTypes,
1148
+ btcSpendRequestTypes: () => btcSpendRequestTypes,
1133
1149
  buildBorrowerAuthorizationDomain: () => buildBorrowerAuthorizationDomain,
1150
+ buildBtcSpendRequestDomain: () => buildBtcSpendRequestDomain,
1134
1151
  calculateDelay: () => calculateDelay,
1152
+ canonicalBtcTxid: () => canonicalBtcTxid2,
1135
1153
  cidToHex: () => cidToHex,
1136
1154
  classifyError: () => classifyError,
1137
1155
  clearSessionSignatureCache: () => clearSessionSignatureCache,
@@ -1377,30 +1395,30 @@ var require_pkg_src = __commonJS({
1377
1395
  }
1378
1396
  },
1379
1397
  btcTransactionSigner: {
1380
- cid: "QmULkz7hwwqsyLwY23U14dnartdVuSNMrykt69PaNiAq7U",
1398
+ cid: "Qmb6TKy8Qv9PYXzjhgfKRnVaNW7SPXsrRUrUhcaaDQ39wd",
1381
1399
  authorizedCidHex: cidToHex(
1382
- "QmULkz7hwwqsyLwY23U14dnartdVuSNMrykt69PaNiAq7U"
1400
+ "Qmb6TKy8Qv9PYXzjhgfKRnVaNW7SPXsrRUrUhcaaDQ39wd"
1383
1401
  ),
1384
1402
  name: "Btc Transaction Signer",
1385
1403
  description: "Production Btc Transaction Signer",
1386
- version: "1.1.1",
1404
+ version: "1.3.1",
1387
1405
  deployed: true,
1388
- deployedAt: 1790246185256,
1389
- size: 73313,
1390
- hash: "d8b6bc646ba33fee7d46c8e9b281de776081ea6f182f56fd15d4c52aaf3dd030"
1406
+ deployedAt: 1792436882589,
1407
+ size: 78254,
1408
+ hash: "194e1c3e9d2f07873bab8e431ba0cda4f66143b15deb196651a375682408c8c4"
1391
1409
  },
1392
1410
  ucdMintValidator: {
1393
- cid: "QmcxVSn9saEPGBS6mqPhNefgW83V2qeZjjXbhwYLP373xe",
1411
+ cid: "QmRUdAWMRmTno7SBNLj26ptjKYm8wY9CZN7QiNtuZ8oDkZ",
1394
1412
  authorizedCidHex: cidToHex(
1395
- "QmcxVSn9saEPGBS6mqPhNefgW83V2qeZjjXbhwYLP373xe"
1413
+ "QmRUdAWMRmTno7SBNLj26ptjKYm8wY9CZN7QiNtuZ8oDkZ"
1396
1414
  ),
1397
1415
  name: "Ucd Mint Validator",
1398
1416
  description: "Production Ucd Mint Validator",
1399
- version: "1.3.0",
1417
+ version: "1.4.3",
1400
1418
  deployed: true,
1401
- deployedAt: 1790246219868,
1402
- size: 90022,
1403
- hash: "65e8cb778c2b767ae6eb37cb5db7b4c5a3f2468d508463c847c83c1b6825fadd",
1419
+ deployedAt: 1792487391394,
1420
+ size: 91079,
1421
+ hash: "6cb1dfee7f71c2748b036893b9ed4721faf400f65b5fd1dd6e0a692676ad527c",
1404
1422
  validatorWalletAddress: "0xEfb258D455a31d061Bbeb3DE3D2143BdFCB67a6C",
1405
1423
  pkp: {
1406
1424
  publicKey: "0x041ab17cd91fc5c0b761eea6092d032807561b621b82c488826776e04a9158d61ba64d809a4729f0501289d980732cb06d8dfd06999dd9c8efd2f495dad78b31bb",
@@ -1408,17 +1426,17 @@ var require_pkg_src = __commonJS({
1408
1426
  }
1409
1427
  },
1410
1428
  processPaymentValidator: {
1411
- cid: "QmWFbxJkfxhCtES4wrePWQkYtjhtrP1tohvn9d1r9N5Hd8",
1429
+ cid: "Qme4X6mFBWr8ERR33CxQX7V6Y9x5ohJPx6idcYV5wDCpNW",
1412
1430
  authorizedCidHex: cidToHex(
1413
- "QmWFbxJkfxhCtES4wrePWQkYtjhtrP1tohvn9d1r9N5Hd8"
1431
+ "Qme4X6mFBWr8ERR33CxQX7V6Y9x5ohJPx6idcYV5wDCpNW"
1414
1432
  ),
1415
1433
  name: "Process Payment Validator",
1416
1434
  description: "Production Process Payment Validator",
1417
- version: "1.2.1",
1435
+ version: "1.3.3",
1418
1436
  deployed: true,
1419
- deployedAt: 1790246225795,
1420
- size: 85107,
1421
- hash: "25ecf952c4c44c40b0920b92d57906e7010ed9a38e2ba41ccdee6d3377c2b596",
1437
+ deployedAt: 1792487398483,
1438
+ size: 86733,
1439
+ hash: "6cef474b774d1b82988fcb0353c5549c2a2bec343b6b3bef15958b8a42050e51",
1422
1440
  validatorWalletAddress: "0xEfb258D455a31d061Bbeb3DE3D2143BdFCB67a6C",
1423
1441
  pkp: {
1424
1442
  publicKey: "0x04cfccb9b6c7addc79469c0e9fafebef4c70801302c62cdb26b610723a9b8527d23f98a40158c7340d83fd0e62d02b5ec74c12f7a86d98e8c6973b4811110f19ad",
@@ -1426,17 +1444,17 @@ var require_pkg_src = __commonJS({
1426
1444
  }
1427
1445
  },
1428
1446
  extendPositionValidator: {
1429
- cid: "QmZ3g7g5DkgU1gEYpFjprQf3sctUHtGjNQVYezw2bnPGEX",
1447
+ cid: "QmZRw8DcV3MY7qt9JSYRvEtXtq675y6JHsqyx7WyvhFrFv",
1430
1448
  authorizedCidHex: cidToHex(
1431
- "QmZ3g7g5DkgU1gEYpFjprQf3sctUHtGjNQVYezw2bnPGEX"
1449
+ "QmZRw8DcV3MY7qt9JSYRvEtXtq675y6JHsqyx7WyvhFrFv"
1432
1450
  ),
1433
1451
  name: "Extend Position Validator",
1434
1452
  description: "Production Extend Position Validator",
1435
- version: "1.2.1",
1453
+ version: "1.3.3",
1436
1454
  deployed: true,
1437
- deployedAt: 1790246231975,
1438
- size: 82853,
1439
- hash: "25d4887b7f646649db2bb7f2bfb77d039db83228a6c454377ca26c779b0903cc",
1455
+ deployedAt: 1792487408209,
1456
+ size: 84013,
1457
+ hash: "e5073a6a7e6f4731a786936b602147c9176a3fa4b19e6b8c71a79faec6837e30",
1440
1458
  validatorWalletAddress: "0xEfb258D455a31d061Bbeb3DE3D2143BdFCB67a6C",
1441
1459
  pkp: {
1442
1460
  publicKey: "0x04e52338f6a0c3362800f1a94c4c8f08be5030dde0fa217388c53d1c1a4790f4443c9f2886b2d2d8f4b75a9a156e9b028011b1a1cf7648da0e556aa980ec692836",
@@ -1444,17 +1462,17 @@ var require_pkg_src = __commonJS({
1444
1462
  }
1445
1463
  },
1446
1464
  btcWithdrawal: {
1447
- cid: "QmbRaaMQr1jCctDGe8mPADsUz1rkb4frT1YqSKroiXjzyP",
1465
+ cid: "QmPUCksZufT1aNX8rxaPDxqfbv36oT8A73us6sdauCiBSC",
1448
1466
  authorizedCidHex: cidToHex(
1449
- "QmbRaaMQr1jCctDGe8mPADsUz1rkb4frT1YqSKroiXjzyP"
1467
+ "QmPUCksZufT1aNX8rxaPDxqfbv36oT8A73us6sdauCiBSC"
1450
1468
  ),
1451
1469
  name: "Btc Withdrawal",
1452
1470
  description: "Production Btc Withdrawal",
1453
- version: "1.2.7",
1471
+ version: "1.3.3",
1454
1472
  deployed: true,
1455
- deployedAt: 1790246239599,
1456
- size: 101228,
1457
- hash: "2ed25eca6cc80a43061b7ad119737af48158fdb61d59f10cd06cea51b607f112",
1473
+ deployedAt: 1792487416965,
1474
+ size: 102401,
1475
+ hash: "aebb2a8721cd919bfc4754b12ca5e08ff2c776e3588994005dc5fad172bcfa42",
1458
1476
  validatorWalletAddress: "0xEfb258D455a31d061Bbeb3DE3D2143BdFCB67a6C",
1459
1477
  pkp: {
1460
1478
  publicKey: "0x043616787c5432415c24378c4ef48de2bcd6bb7b575b837e3cff09171802662da7105d79586c7659677a0ecbaddac4cce06cb2a11f69a16fa0c4d7002ac7d51a4d",
@@ -1462,17 +1480,17 @@ var require_pkg_src = __commonJS({
1462
1480
  }
1463
1481
  },
1464
1482
  liquidationValidator: {
1465
- cid: "QmTs2w8gfAwWZLbzJZg2CZmiLhVXS5kbMgaj42Zuxfodpb",
1483
+ cid: "QmRQFACoNtDVSKs95MhXPhkLL2tnv62ym31n8DXxHHghpw",
1466
1484
  authorizedCidHex: cidToHex(
1467
- "QmTs2w8gfAwWZLbzJZg2CZmiLhVXS5kbMgaj42Zuxfodpb"
1485
+ "QmRQFACoNtDVSKs95MhXPhkLL2tnv62ym31n8DXxHHghpw"
1468
1486
  ),
1469
1487
  name: "Liquidation Validator",
1470
1488
  description: "Production Liquidation Validator",
1471
- version: "1.2.1",
1489
+ version: "1.3.3",
1472
1490
  deployed: true,
1473
- deployedAt: 1790246247904,
1474
- size: 70308,
1475
- hash: "582ccf0ec7f715195e20fdc885996743cb42125b64173424e360ee63db62bbd8",
1491
+ deployedAt: 1792487425791,
1492
+ size: 71477,
1493
+ hash: "f4d466f290ffb5c07ae1204f239accffb8c26ee74db947255c8031a3cb34fdcd",
1476
1494
  validatorWalletAddress: "0xEfb258D455a31d061Bbeb3DE3D2143BdFCB67a6C",
1477
1495
  pkp: {
1478
1496
  publicKey: "0x041a241de58976c13e3d7ca5a18e494f7330151e3818706135d50176e78ffb673e58b11f0b67a87c73fade6c6b27d6e7a7377ea9f4c10bf31880f1d725f18cc6f8",
@@ -1498,17 +1516,17 @@ var require_pkg_src = __commonJS({
1498
1516
  }
1499
1517
  },
1500
1518
  loanVaultBtcBalance: {
1501
- cid: "QmZ27xCzuoaAhWxRsMPsUQkp45a8WPBb21uhxwchw3LG5W",
1519
+ cid: "QmRzXY7nHYyJPi5yWKbCJNwTnxW7HcrxnAsKyiiGNmztZ5",
1502
1520
  authorizedCidHex: cidToHex(
1503
- "QmZ27xCzuoaAhWxRsMPsUQkp45a8WPBb21uhxwchw3LG5W"
1521
+ "QmRzXY7nHYyJPi5yWKbCJNwTnxW7HcrxnAsKyiiGNmztZ5"
1504
1522
  ),
1505
1523
  name: "Loan Vault Btc Balance",
1506
1524
  description: "Production Loan Vault Btc Balance",
1507
- version: "1.2.1",
1525
+ version: "1.3.3",
1508
1526
  deployed: true,
1509
- deployedAt: 1790179961079,
1510
- size: 60046,
1511
- hash: "922e86c0a667fe0c0945771f84aa6b9fe08be9c96dd2f73a9c5cb257d24e22b0",
1527
+ deployedAt: 1792487434368,
1528
+ size: 61212,
1529
+ hash: "0b6b07ceb204a790a9ab83a36597012c733572c7423dd4acf49bde1363d5e96c",
1512
1530
  validatorWalletAddress: "0xEfb258D455a31d061Bbeb3DE3D2143BdFCB67a6C",
1513
1531
  pkp: {
1514
1532
  publicKey: "0x043616787c5432415c24378c4ef48de2bcd6bb7b575b837e3cff09171802662da7105d79586c7659677a0ecbaddac4cce06cb2a11f69a16fa0c4d7002ac7d51a4d",
@@ -1522,17 +1540,17 @@ var require_pkg_src = __commonJS({
1522
1540
  // Requires BitcoinProviderRegistry.addAllowedCid(chainId, keccak256(utf8(cid)))
1523
1541
  // on each target chain (the action decrypts registry slots). No OAR entry.
1524
1542
  btcAddressBalance: {
1525
- cid: "QmVVjB6zCBiXFKffhQPYUAZhj7TXduuvcrPqKtHa3DMXhN",
1543
+ cid: "QmYqAW1sDqPEos5KhhLkRXsgKUEScxM9cpeNnLkHusEMpF",
1526
1544
  authorizedCidHex: cidToHex(
1527
- "QmVVjB6zCBiXFKffhQPYUAZhj7TXduuvcrPqKtHa3DMXhN"
1545
+ "QmYqAW1sDqPEos5KhhLkRXsgKUEScxM9cpeNnLkHusEMpF"
1528
1546
  ),
1529
1547
  name: "Btc Address Balance",
1530
1548
  description: "Address-only signed total BTC balance via registry consensus (no positionId, no price)",
1531
- version: "0.2.1",
1549
+ version: "0.3.2",
1532
1550
  deployed: true,
1533
- deployedAt: 1790179971315,
1534
- size: 30295,
1535
- hash: "2c67d9cfa4d50e835fbb28ae50e80217ceb2be3bb862c89290aadf43fdc739c9",
1551
+ deployedAt: 1792360075629,
1552
+ size: 31909,
1553
+ hash: "2297c7b625340f048b5926325a14c958016594b77f4c4270ef413b164a8ac975",
1536
1554
  validatorWalletAddress: "0xEfb258D455a31d061Bbeb3DE3D2143BdFCB67a6C",
1537
1555
  pkp: {
1538
1556
  publicKey: "0x0498cbb31facfa26e3ec83ccdabfe4fe341ca0282e0c3cb81da7113723b9726e1e49efa92165cc3faa66ced4454cea56dbab12267852d6525a55d7c4f128b912cd",
@@ -1566,30 +1584,30 @@ var require_pkg_src = __commonJS({
1566
1584
  hash: "03ee5be239c91c735d2c95db89a0d1b77e602cfc18af8eb64b3281fddcd90a72"
1567
1585
  },
1568
1586
  agentModuleExecutor: {
1569
- cid: "QmSwPPvQhT7UhcuVA2m3UxGhVj5WqMpDvYNKU1228QLFsX",
1587
+ cid: "QmPTQm5CtKnN3PLAitDRNQCuAeegATMWVWQbRrKiMCTz6V",
1570
1588
  authorizedCidHex: cidToHex(
1571
- "QmSwPPvQhT7UhcuVA2m3UxGhVj5WqMpDvYNKU1228QLFsX"
1589
+ "QmPTQm5CtKnN3PLAitDRNQCuAeegATMWVWQbRrKiMCTz6V"
1572
1590
  ),
1573
1591
  name: "Agent Module Executor",
1574
1592
  description: "Production Agent Module Executor",
1575
- version: "1.1.1",
1593
+ version: "1.3.0",
1576
1594
  deployed: true,
1577
- deployedAt: 1790179978959,
1578
- size: 14688,
1579
- hash: "8edb9b12c784c8d7d153cce97235584c24665a788767ae68713dce91109ab35e"
1595
+ deployedAt: 1792419196606,
1596
+ size: 17562,
1597
+ hash: "a10d463ffd48f2392401efe3dde566faa1869e5e089db830632873a5b9528ee0"
1580
1598
  },
1581
1599
  staleSpendRecoveryValidator: {
1582
- cid: "Qmarj59zdSSgivkimryrdvnyZqH5YpTimKj1LivXNBHmNz",
1600
+ cid: "QmYnD65RjagWkv2eLz117GBfNfPwB7Dy1e8WXFe7yGWrt3",
1583
1601
  authorizedCidHex: cidToHex(
1584
- "Qmarj59zdSSgivkimryrdvnyZqH5YpTimKj1LivXNBHmNz"
1602
+ "QmYnD65RjagWkv2eLz117GBfNfPwB7Dy1e8WXFe7yGWrt3"
1585
1603
  ),
1586
1604
  name: "Stale Spend Recovery Validator",
1587
1605
  description: "Production Stale Spend Recovery Validator",
1588
- version: "1.1.2",
1606
+ version: "1.2.3",
1589
1607
  deployed: true,
1590
- deployedAt: 1790246256280,
1591
- size: 48143,
1592
- hash: "ec9236bcbe0af24d3e1844791fc8fe37371bbecd8ce95d02e13f7c6e1fc7d94c",
1608
+ deployedAt: 1792436943524,
1609
+ size: 49866,
1610
+ hash: "8f66007ed73c0a969051bbb8fec1cc51d119ecd01748eed4cdc59b3b1e4597fa",
1593
1611
  validatorWalletAddress: "0xEfb258D455a31d061Bbeb3DE3D2143BdFCB67a6C",
1594
1612
  pkp: {
1595
1613
  publicKey: "0x046da0ad6da7dd4a0063cbeac6f2bdb6a9889c2178b23470833356a8ee5630f7f0eee0db348d9d9aaaadd23eccf0063c8f68ee5e446abe30b882bf1de4c932bc21",
@@ -1597,30 +1615,30 @@ var require_pkg_src = __commonJS({
1597
1615
  }
1598
1616
  },
1599
1617
  btcUtxoInvalidator: {
1600
- cid: "QmbS44bGcmKYF64Cu35qzsk9sxiU4Umde8Z3q24ZnEbQvX",
1618
+ cid: "QmSnXqdDt92epKi9zD7P1KqGMSzBLzCp2x4a34gHkyXvmi",
1601
1619
  authorizedCidHex: cidToHex(
1602
- "QmbS44bGcmKYF64Cu35qzsk9sxiU4Umde8Z3q24ZnEbQvX"
1620
+ "QmSnXqdDt92epKi9zD7P1KqGMSzBLzCp2x4a34gHkyXvmi"
1603
1621
  ),
1604
1622
  name: "Btc Utxo Invalidator",
1605
1623
  description: "Production Btc Utxo Invalidator",
1606
- version: "1.0.0",
1624
+ version: "1.2.1",
1607
1625
  deployed: true,
1608
- deployedAt: 1790246264563,
1609
- size: 69219,
1610
- hash: "bda048d8cd6b5a39c2774bcf1320e82d1eea935c2a521006fb8b887e13b6dd8d"
1626
+ deployedAt: 1792436952354,
1627
+ size: 73451,
1628
+ hash: "a04848a16b411362aa7a5ff05ad7c93adc6a1368ef2c5f25dcfbe7c225ff5d1f"
1611
1629
  },
1612
1630
  carryCollateralAttestation: {
1613
- cid: "QmYWULmXD9S5AmTdQqWqoZ28ctsZQNcXkAgre9G2Xo9dh8",
1631
+ cid: "QmXq8oBGZEP39pAGYe5vMvzMYUHmSVDcBb4o8XYotEE79m",
1614
1632
  authorizedCidHex: cidToHex(
1615
- "QmYWULmXD9S5AmTdQqWqoZ28ctsZQNcXkAgre9G2Xo9dh8"
1633
+ "QmXq8oBGZEP39pAGYe5vMvzMYUHmSVDcBb4o8XYotEE79m"
1616
1634
  ),
1617
1635
  name: "Carry Collateral Attestation",
1618
1636
  description: "LoanCarryVault collateral attestation (borrower, BTC vault, confirmed BTC)",
1619
- version: "1.0.0",
1637
+ version: "1.1.3",
1620
1638
  deployed: true,
1621
- deployedAt: 1790927734070,
1622
- size: 21156,
1623
- hash: "05b177e0bb36b0483db4a42d33c1bbbf47eb9ef34ae278459397d51a7f8957ff"
1639
+ deployedAt: 1792487442698,
1640
+ size: 22275,
1641
+ hash: "0a4203a829b9af30f694190137f80b278b438fe2f885596dba469a6811ca1008"
1624
1642
  },
1625
1643
  carryFundingAttestation: {
1626
1644
  cid: "QmWhox3xUZMNR5NpPZ9WLSPC5GoW4ms88GanVRKr8uuS3W",
@@ -2379,7 +2397,7 @@ ${errorReport}`);
2379
2397
  }
2380
2398
  init_debug_logger();
2381
2399
  init_session_signature_cache();
2382
- var import_ethers24 = __require("ethers");
2400
+ var import_ethers25 = __require("ethers");
2383
2401
  var EXPIRED_LOAN_MIN_LIQUIDATION_THRESHOLD_BPS = 11e3;
2384
2402
  var GRACE_PERIOD_DAYS = 30;
2385
2403
  var SATOSHIS_PER_BITCOIN = 100000000n;
@@ -2617,6 +2635,87 @@ ${errorReport}`);
2617
2635
  );
2618
2636
  return newCollateralRatioBps >= requiredRatioBps;
2619
2637
  }
2638
+ var DRPC_DOMAINS = ["drpc.org", "drpc.live"];
2639
+ var DRPC_KEY_HEADER = "Drpc-Key";
2640
+ var DRPC_KEY_PATTERN = /^[A-Za-z0-9_-]{16,128}$/;
2641
+ function isDrpcHost(hostname) {
2642
+ return DRPC_DOMAINS.some(
2643
+ (domain) => hostname === domain || hostname.endsWith(`.${domain}`)
2644
+ );
2645
+ }
2646
+ function assertKeyFormat(key, label) {
2647
+ if (typeof key !== "string" || !DRPC_KEY_PATTERN.test(key)) {
2648
+ throw new Error(
2649
+ `Invalid ${label}: expected 16-128 characters of [A-Za-z0-9_-]`
2650
+ );
2651
+ }
2652
+ }
2653
+ function assertHttps(url) {
2654
+ if (url.protocol !== "https:") {
2655
+ throw new Error(
2656
+ `A dRPC key is only sent over https, but the RPC URL scheme is "${url.protocol}"`
2657
+ );
2658
+ }
2659
+ }
2660
+ function resolveDrpcKey(rpcUrl, drpcKey) {
2661
+ if (drpcKey === void 0) {
2662
+ return void 0;
2663
+ }
2664
+ assertKeyFormat(drpcKey, '"drpcKey"');
2665
+ const url = new URL(rpcUrl);
2666
+ if (!isDrpcHost(url.hostname)) {
2667
+ throw new Error(
2668
+ `"drpcKey" is only sent to dRPC, but the RPC host is "${url.hostname}" (expected ${DRPC_DOMAINS.join(" or ")})`
2669
+ );
2670
+ }
2671
+ assertHttps(url);
2672
+ if (url.searchParams.has("dkey")) {
2673
+ throw new Error(
2674
+ '"drpcKey" and a keyed rpcUrl (?dkey=) are mutually exclusive \u2014 send one'
2675
+ );
2676
+ }
2677
+ return drpcKey;
2678
+ }
2679
+ async function litNodeRpcUrl(chain, drpcKey) {
2680
+ if (drpcKey !== void 0) {
2681
+ throw new Error(
2682
+ `"drpcKey" was supplied without an "rpcUrl" \u2014 the key only authenticates a caller-supplied dRPC rpcUrl, never the Lit node's own endpoint`
2683
+ );
2684
+ }
2685
+ return Lit.Actions.getRpcUrl({ chain });
2686
+ }
2687
+ function evmRpcConnection(rpcUrl, drpcKey, timeout) {
2688
+ const connection = { url: rpcUrl };
2689
+ const key = resolveDrpcKey(rpcUrl, drpcKey);
2690
+ if (key !== void 0) {
2691
+ connection.headers = { [DRPC_KEY_HEADER]: key };
2692
+ } else {
2693
+ const url = new URL(rpcUrl);
2694
+ const legacyKeys = url.searchParams.getAll("dkey");
2695
+ if (legacyKeys.length > 1) {
2696
+ throw new Error(
2697
+ `rpcUrl carries ${legacyKeys.length} "dkey" parameters \u2014 send exactly one dRPC key`
2698
+ );
2699
+ }
2700
+ if (legacyKeys.length === 1 && !isDrpcHost(url.hostname)) {
2701
+ throw new Error(
2702
+ `rpcUrl carries a dRPC key (?dkey=) but the RPC host is "${url.hostname}" \u2014 a dRPC key is only sent to ${DRPC_DOMAINS.join(" or ")}`
2703
+ );
2704
+ }
2705
+ if (legacyKeys.length === 1) {
2706
+ const legacyKey = legacyKeys[0];
2707
+ assertKeyFormat(legacyKey, "dRPC key in rpcUrl (?dkey=)");
2708
+ assertHttps(url);
2709
+ url.searchParams.delete("dkey");
2710
+ connection.url = url.toString();
2711
+ connection.headers = { [DRPC_KEY_HEADER]: legacyKey };
2712
+ }
2713
+ }
2714
+ if (timeout !== void 0) {
2715
+ connection.timeout = timeout;
2716
+ }
2717
+ return connection;
2718
+ }
2620
2719
  var ProtocolParametersModule = class {
2621
2720
  constructor(config) {
2622
2721
  this.termManagerAddress = config.termManagerAddress;
@@ -2625,6 +2724,7 @@ ${errorReport}`);
2625
2724
  this.chain = config.chain;
2626
2725
  this.chainId = config.chainId;
2627
2726
  this.rpcUrl = config.rpcUrl;
2727
+ this.drpcKey = config.drpcKey;
2628
2728
  }
2629
2729
  /**
2630
2730
  * Get liquidation threshold from LoanOperationsManager
@@ -2637,10 +2737,10 @@ ${errorReport}`);
2637
2737
  if (this.rpcUrl) {
2638
2738
  rpcUrl = this.rpcUrl;
2639
2739
  } else {
2640
- rpcUrl = await Lit.Actions.getRpcUrl({ chain: this.chain });
2740
+ rpcUrl = await litNodeRpcUrl(this.chain, this.drpcKey);
2641
2741
  }
2642
2742
  const provider = new ethers.providers.StaticJsonRpcProvider(
2643
- { url: rpcUrl, timeout: LIT_ACTION_ETH_RPC_TIMEOUT_MS },
2743
+ evmRpcConnection(rpcUrl, this.drpcKey, LIT_ACTION_ETH_RPC_TIMEOUT_MS),
2644
2744
  {
2645
2745
  name: "any",
2646
2746
  chainId: this.chainId
@@ -2684,10 +2784,10 @@ ${errorReport}`);
2684
2784
  if (this.rpcUrl) {
2685
2785
  rpcUrl = this.rpcUrl;
2686
2786
  } else {
2687
- rpcUrl = await Lit.Actions.getRpcUrl({ chain: this.chain });
2787
+ rpcUrl = await litNodeRpcUrl(this.chain, this.drpcKey);
2688
2788
  }
2689
2789
  const provider = new ethers.providers.StaticJsonRpcProvider(
2690
- { url: rpcUrl, timeout: LIT_ACTION_ETH_RPC_TIMEOUT_MS },
2790
+ evmRpcConnection(rpcUrl, this.drpcKey, LIT_ACTION_ETH_RPC_TIMEOUT_MS),
2691
2791
  {
2692
2792
  name: "any",
2693
2793
  chainId: this.chainId
@@ -2740,9 +2840,9 @@ ${errorReport}`);
2740
2840
  */
2741
2841
  async getAuthorizedSpendsHash(positionId) {
2742
2842
  try {
2743
- const rpcUrl = this.rpcUrl || await Lit.Actions.getRpcUrl({ chain: this.chain });
2843
+ const rpcUrl = this.rpcUrl || await litNodeRpcUrl(this.chain, this.drpcKey);
2744
2844
  const provider = new ethers.providers.StaticJsonRpcProvider(
2745
- { url: rpcUrl, timeout: LIT_ACTION_ETH_RPC_TIMEOUT_MS },
2845
+ evmRpcConnection(rpcUrl, this.drpcKey, LIT_ACTION_ETH_RPC_TIMEOUT_MS),
2746
2846
  {
2747
2847
  name: "any",
2748
2848
  chainId: this.chainId
@@ -2788,10 +2888,10 @@ ${errorReport}`);
2788
2888
  if (this.rpcUrl) {
2789
2889
  rpcUrl = this.rpcUrl;
2790
2890
  } else {
2791
- rpcUrl = await Lit.Actions.getRpcUrl({ chain: this.chain });
2891
+ rpcUrl = await litNodeRpcUrl(this.chain, this.drpcKey);
2792
2892
  }
2793
2893
  const provider = new ethers.providers.StaticJsonRpcProvider(
2794
- { url: rpcUrl, timeout: LIT_ACTION_ETH_RPC_TIMEOUT_MS },
2894
+ evmRpcConnection(rpcUrl, this.drpcKey, LIT_ACTION_ETH_RPC_TIMEOUT_MS),
2795
2895
  {
2796
2896
  name: "any",
2797
2897
  chainId: this.chainId
@@ -2833,14 +2933,14 @@ ${errorReport}`);
2833
2933
  if (typeof parsed === "object" && parsed !== null) {
2834
2934
  const chainLower = chain.toLowerCase();
2835
2935
  if (chainLower === "sepolia") {
2836
- return parsed.regtest || parsed.testnet || parsed.mainnet;
2936
+ return parsed.regtest || parsed.testnet || void 0;
2837
2937
  }
2838
2938
  const bitcoinNetwork = getBitcoinNetworkForChain(chain);
2839
2939
  if (bitcoinNetwork === "regtest") {
2840
- return parsed.regtest || parsed.testnet || parsed.mainnet;
2940
+ return parsed.regtest || parsed.testnet || void 0;
2841
2941
  }
2842
2942
  if (bitcoinNetwork === "testnet") {
2843
- return parsed.testnet || parsed.regtest || parsed.mainnet;
2943
+ return parsed.testnet || parsed.regtest || void 0;
2844
2944
  }
2845
2945
  return parsed.mainnet;
2846
2946
  }
@@ -2850,6 +2950,9 @@ ${errorReport}`);
2850
2950
  }
2851
2951
  var VaultSnapshotModule = class {
2852
2952
  constructor(config) {
2953
+ if (!Number.isInteger(config.chainId) || config.chainId <= 0) {
2954
+ throw new Error(`VaultSnapshotModule requires a positive integer chainId, got ${String(config.chainId)}`);
2955
+ }
2853
2956
  this.config = config;
2854
2957
  }
2855
2958
  /**
@@ -2866,8 +2969,7 @@ ${errorReport}`);
2866
2969
  console.log(
2867
2970
  `[Vault Snapshot] Raw vault address from contract: "${positionState.vaultAddress}"`
2868
2971
  );
2869
- const useStubbedBtcData = this.config.debugOverrides?.useStubbedBtcData === true;
2870
- const [balanceResult, btcPriceUsd] = useStubbedBtcData ? this.buildStubbedBtcSnapshotInputs(positionState) : await Promise.all([
2972
+ const [balanceResult, btcPriceUsd] = await Promise.all([
2871
2973
  this.config.vaultBalance.calculateTrustedBalance(
2872
2974
  positionId,
2873
2975
  positionState.vaultAddress
@@ -2879,9 +2981,9 @@ ${errorReport}`);
2879
2981
  loanOpsManagerAddress: this.config.loanOpsManagerAddress,
2880
2982
  liquidationManagerAddress: this.config.liquidationManagerAddress,
2881
2983
  chain: this.config.chain,
2882
- chainId: this.config.chainId || 1,
2883
- // Default to mainnet if not provided
2884
- rpcUrl: this.config.rpcUrl
2984
+ chainId: this.config.chainId,
2985
+ rpcUrl: this.config.rpcUrl,
2986
+ drpcKey: this.config.drpcKey
2885
2987
  });
2886
2988
  const termForFees = this.config.termOverride ?? positionState.selectedTerm;
2887
2989
  const [liquidationThresholdBps, maxEscalatedThresholdBps, termFees] = await Promise.all([
@@ -2960,34 +3062,6 @@ ${errorReport}`);
2960
3062
  // a snapshot whose balance skipped UTXO validation + consensus must never
2961
3063
  // exist within reach of a signing flow. Every snapshot now runs the full
2962
3064
  // validation path above.
2963
- buildStubbedBtcSnapshotInputs(positionState) {
2964
- const stubbedAvailableBtcSats = BigInt(
2965
- this.config.debugOverrides?.stubbedAvailableBtcSats ?? "10000000"
2966
- );
2967
- const stubbedBtcPriceUsd = BigInt(
2968
- this.config.debugOverrides?.stubbedBtcPriceUsd ?? "5000000000000"
2969
- );
2970
- const stubbedAuthorizedSpendsHash = this.config.debugOverrides?.stubbedAuthorizedSpendsHash ?? // keccak256(abi.encode(positionId, []))
2971
- ethers.utils.keccak256(
2972
- ethers.utils.defaultAbiCoder.encode(
2973
- ["bytes32", "bytes32[]"],
2974
- [positionState.positionId, []]
2975
- )
2976
- );
2977
- const balanceResult = {
2978
- totalUTXOs: [],
2979
- totalBalance: stubbedAvailableBtcSats,
2980
- authorizedUTXOs: [],
2981
- authorizedBalance: 0n,
2982
- authorizedSpendsHash: stubbedAuthorizedSpendsHash,
2983
- availableUTXOs: [],
2984
- availableBalance: stubbedAvailableBtcSats,
2985
- vaultAddress: positionState.vaultAddress,
2986
- positionId: positionState.positionId,
2987
- timestamp: Date.now()
2988
- };
2989
- return [balanceResult, stubbedBtcPriceUsd];
2990
- }
2991
3065
  /**
2992
3066
  * Query position state from smart contract
2993
3067
  *
@@ -3004,10 +3078,10 @@ ${errorReport}`);
3004
3078
  if (this.config.rpcUrl) {
3005
3079
  rpcUrl = this.config.rpcUrl;
3006
3080
  } else {
3007
- rpcUrl = await Lit.Actions.getRpcUrl({ chain: this.config.chain });
3081
+ rpcUrl = await litNodeRpcUrl(this.config.chain, this.config.drpcKey);
3008
3082
  }
3009
3083
  const provider = new ethers.providers.StaticJsonRpcProvider(
3010
- { url: rpcUrl, timeout: LIT_ACTION_ETH_RPC_TIMEOUT_MS },
3084
+ evmRpcConnection(rpcUrl, this.config.drpcKey, LIT_ACTION_ETH_RPC_TIMEOUT_MS),
3011
3085
  this.config.chainId
3012
3086
  );
3013
3087
  const diamondContract = new ethers.Contract(
@@ -5216,10 +5290,10 @@ ${auth.clientId}`;
5216
5290
  if (this.config.rpcUrl) {
5217
5291
  rpcUrl = this.config.rpcUrl;
5218
5292
  } else {
5219
- rpcUrl = await Lit.Actions.getRpcUrl({ chain: this.config.chain });
5293
+ rpcUrl = await litNodeRpcUrl(this.config.chain, this.config.drpcKey);
5220
5294
  }
5221
5295
  const provider = new ethers.providers.StaticJsonRpcProvider(
5222
- { url: rpcUrl, timeout: LIT_ACTION_ETH_RPC_TIMEOUT_MS },
5296
+ evmRpcConnection(rpcUrl, this.config.drpcKey, LIT_ACTION_ETH_RPC_TIMEOUT_MS),
5223
5297
  this.config.chainId
5224
5298
  );
5225
5299
  const contract = new ethers.Contract(
@@ -5386,13 +5460,17 @@ ${auth.clientId}`;
5386
5460
  return policy;
5387
5461
  }
5388
5462
  async function executeVaultSnapshot(params) {
5463
+ const chainId = params.chainId;
5464
+ if (chainId === void 0 || !Number.isInteger(chainId) || chainId <= 0) {
5465
+ throw new Error(`executeVaultSnapshot requires a positive integer chainId, got ${String(chainId)}`);
5466
+ }
5389
5467
  global.ethers = {
5390
- ...import_ethers24.ethers,
5468
+ ...import_ethers25.ethers,
5391
5469
  providers: {
5392
- StaticJsonRpcProvider: import_ethers24.ethers.JsonRpcProvider
5470
+ StaticJsonRpcProvider: import_ethers25.ethers.JsonRpcProvider
5393
5471
  },
5394
- Contract: import_ethers24.ethers.Contract,
5395
- utils: import_ethers24.ethers
5472
+ Contract: import_ethers25.ethers.Contract,
5473
+ utils: import_ethers25.ethers
5396
5474
  // v6 moved utils to top level
5397
5475
  };
5398
5476
  global.Lit = {
@@ -5425,8 +5503,7 @@ ${auth.clientId}`;
5425
5503
  const vaultBalance = createVaultBalanceModule({
5426
5504
  contractAddress: params.loanOpsManagerAddress,
5427
5505
  chain: params.chain,
5428
- chainId: params.chainId || 1,
5429
- // Default to mainnet if not provided
5506
+ chainId,
5430
5507
  rpcUrl: params.rpcUrl,
5431
5508
  bitcoinProvider,
5432
5509
  minConfirmations: params.minConfirmations ?? getChainPolicy(params.chain).minBitcoinBalanceConfirmations
@@ -5437,7 +5514,7 @@ ${auth.clientId}`;
5437
5514
  loanOpsManagerAddress: params.loanOpsManagerAddress,
5438
5515
  liquidationManagerAddress: params.liquidationManagerAddress,
5439
5516
  chain: params.chain,
5440
- chainId: params.chainId,
5517
+ chainId,
5441
5518
  rpcUrl: params.rpcUrl,
5442
5519
  vaultBalance,
5443
5520
  priceOracle
@@ -5503,6 +5580,79 @@ ${auth.clientId}`;
5503
5580
  version: "2.0.0"
5504
5581
  }
5505
5582
  };
5583
+ var BTC_SPEND_REQUEST_PRIMARY_TYPES = {
5584
+ EXECUTE: "ExecuteBtcWithdrawalRequest",
5585
+ INVALIDATE: "InvalidateStaleSpendRequest"
5586
+ };
5587
+ var BTC_SPEND_REQUEST_FIELDS = {
5588
+ ExecuteBtcWithdrawalRequest: [
5589
+ { name: "positionId", type: "bytes32" },
5590
+ { name: "withdrawalAddress", type: "string" },
5591
+ { name: "recipientAmount", type: "uint256" },
5592
+ { name: "networkFee", type: "uint256" },
5593
+ { name: "totalDeduction", type: "uint256" },
5594
+ { name: "spendTxid", type: "string" },
5595
+ { name: "spendVout", type: "uint32" },
5596
+ { name: "inputSetHash", type: "bytes32" },
5597
+ { name: "quantumTimestamp", type: "uint256" }
5598
+ ],
5599
+ InvalidateStaleSpendRequest: [
5600
+ { name: "positionId", type: "bytes32" },
5601
+ { name: "spendTxid", type: "string" },
5602
+ { name: "spendVout", type: "uint32" },
5603
+ { name: "quantumTimestamp", type: "uint256" }
5604
+ ]
5605
+ };
5606
+ var BTC_SPEND_REQUEST_ENCODE_TYPES = {
5607
+ ExecuteBtcWithdrawalRequest: "ExecuteBtcWithdrawalRequest(bytes32 positionId,string withdrawalAddress,uint256 recipientAmount,uint256 networkFee,uint256 totalDeduction,string spendTxid,uint32 spendVout,bytes32 inputSetHash,uint256 quantumTimestamp)",
5608
+ InvalidateStaleSpendRequest: "InvalidateStaleSpendRequest(bytes32 positionId,string spendTxid,uint32 spendVout,uint256 quantumTimestamp)"
5609
+ };
5610
+ function btcSpendRequestTypes(primaryType) {
5611
+ const fields = BTC_SPEND_REQUEST_FIELDS[primaryType];
5612
+ if (!fields) {
5613
+ throw new Error(
5614
+ `Unknown BTC spend request primary type "${primaryType}"; expected one of ${Object.keys(BTC_SPEND_REQUEST_FIELDS).join(", ")}`
5615
+ );
5616
+ }
5617
+ return { [primaryType]: fields.map((field) => ({ ...field })) };
5618
+ }
5619
+ function buildBtcSpendRequestDomain(chainId, verifyingContractOverride) {
5620
+ if (!Number.isInteger(chainId) || chainId <= 0) {
5621
+ throw new Error(
5622
+ `BTC spend request domain requires a positive integer chainId, got ${String(chainId)}`
5623
+ );
5624
+ }
5625
+ const pinned = getPinnedContractAddresses(chainId);
5626
+ const pinnedAuthorizer = pinned?.BTCSpendAuthorizer;
5627
+ if (pinnedAuthorizer && verifyingContractOverride) {
5628
+ if (pinnedAuthorizer.toLowerCase() !== verifyingContractOverride.toLowerCase()) {
5629
+ throw new Error(
5630
+ `Refusing a caller-supplied verifyingContract that contradicts the pin for chainId ${chainId}: caller ${verifyingContractOverride}, pinned ${pinnedAuthorizer}`
5631
+ );
5632
+ }
5633
+ }
5634
+ const verifyingContract = pinnedAuthorizer ?? verifyingContractOverride;
5635
+ if (!verifyingContract) {
5636
+ throw new Error(
5637
+ `No pinned BTCSpendAuthorizer for chainId ${chainId} and no verifyingContract supplied; refusing to build a BTC spend request domain without one`
5638
+ );
5639
+ }
5640
+ return {
5641
+ name: PROTOCOL_EIP712_DOMAIN_NAME,
5642
+ version: PROTOCOL_EIP712_DOMAIN_VERSION,
5643
+ chainId,
5644
+ verifyingContract
5645
+ };
5646
+ }
5647
+ function canonicalBtcTxid2(txid) {
5648
+ const canonical = String(txid).toLowerCase().replace(/^0x/, "");
5649
+ if (!/^[0-9a-f]{64}$/.test(canonical)) {
5650
+ throw new Error(
5651
+ `Invalid Bitcoin txid "${String(txid)}": expected 64 hex characters (optionally 0x-prefixed)`
5652
+ );
5653
+ }
5654
+ return canonical;
5655
+ }
5506
5656
  }
5507
5657
  });
5508
5658
 
@@ -5742,7 +5892,7 @@ function getMainnetConfig() {
5742
5892
  function getLocalhostConfig() {
5743
5893
  const deployment = loadDeploymentData("localhost");
5744
5894
  const contracts = deployment?.contracts || {};
5745
- const getAddress = (envKey, contractKey) => {
5895
+ const getAddress2 = (envKey, contractKey) => {
5746
5896
  return process.env[envKey] || contracts[contractKey] || "";
5747
5897
  };
5748
5898
  logNetworkConfig(
@@ -5751,17 +5901,17 @@ function getLocalhostConfig() {
5751
5901
  deployment ? "YES" : "NO"
5752
5902
  );
5753
5903
  logNetworkConfig("log", "[NetworkConfig] Localhost contracts:", {
5754
- PositionManager: getAddress("POSITION_MANAGER_ADDRESS", "PositionManager"),
5755
- PositionManagerCore: getAddress(
5904
+ PositionManager: getAddress2("POSITION_MANAGER_ADDRESS", "PositionManager"),
5905
+ PositionManagerCore: getAddress2(
5756
5906
  "POSITION_MANAGER_CORE_ADDRESS",
5757
5907
  "PositionManagerCoreModule"
5758
5908
  ),
5759
- LoanOperationsManagerModule: getAddress(
5909
+ LoanOperationsManagerModule: getAddress2(
5760
5910
  "LOAN_OPERATIONS_MANAGER_ADDRESS",
5761
5911
  "LoanOperationsManagerModule"
5762
5912
  ),
5763
- TermManagerModule: getAddress("TERM_MANAGER_ADDRESS", "TermManagerModule"),
5764
- UCDToken: getAddress("UCD_TOKEN_ADDRESS", "UCDToken")
5913
+ TermManagerModule: getAddress2("TERM_MANAGER_ADDRESS", "TermManagerModule"),
5914
+ UCDToken: getAddress2("UCD_TOKEN_ADDRESS", "UCDToken")
5765
5915
  });
5766
5916
  return {
5767
5917
  mode: "service",
@@ -5770,43 +5920,43 @@ function getLocalhostConfig() {
5770
5920
  name: "localhost",
5771
5921
  rpcUrls: ["http://localhost:8545"],
5772
5922
  contractAddresses: {
5773
- positionManager: getAddress(
5923
+ positionManager: getAddress2(
5774
5924
  "POSITION_MANAGER_ADDRESS",
5775
5925
  "PositionManager"
5776
5926
  ),
5777
- positionManagerCore: getAddress(
5927
+ positionManagerCore: getAddress2(
5778
5928
  "POSITION_MANAGER_CORE_ADDRESS",
5779
5929
  "PositionManagerCoreModule"
5780
5930
  ),
5781
- positionManagerViews: getAddress(
5931
+ positionManagerViews: getAddress2(
5782
5932
  "POSITION_MANAGER_VIEWS_ADDRESS",
5783
5933
  "PositionManagerViews"
5784
5934
  ),
5785
- simplePsmV2: getAddress("SIMPLE_PSM_V2_ADDRESS", "SimplePSMV2"),
5786
- loanOperationsManager: getAddress(
5935
+ simplePsmV2: getAddress2("SIMPLE_PSM_V2_ADDRESS", "SimplePSMV2"),
5936
+ loanOperationsManager: getAddress2(
5787
5937
  "LOAN_OPERATIONS_MANAGER_ADDRESS",
5788
5938
  "LoanOperationsManagerModule"
5789
5939
  ),
5790
- termManager: getAddress("TERM_MANAGER_ADDRESS", "TermManagerModule"),
5791
- circuitBreaker: getAddress(
5940
+ termManager: getAddress2("TERM_MANAGER_ADDRESS", "TermManagerModule"),
5941
+ circuitBreaker: getAddress2(
5792
5942
  "CIRCUIT_BREAKER_ADDRESS",
5793
5943
  "CircuitBreakerModule"
5794
5944
  ),
5795
- liquidationManager: getAddress(
5945
+ liquidationManager: getAddress2(
5796
5946
  "LIQUIDATION_MANAGER_ADDRESS",
5797
5947
  "LiquidationManagerModule"
5798
5948
  ),
5799
- ucdToken: getAddress("UCD_TOKEN_ADDRESS", "UCDToken"),
5800
- ucdController: getAddress("UCD_CONTROLLER_ADDRESS", "UCDController"),
5801
- priceFeedConsumer: getAddress(
5949
+ ucdToken: getAddress2("UCD_TOKEN_ADDRESS", "UCDToken"),
5950
+ ucdController: getAddress2("UCD_CONTROLLER_ADDRESS", "UCDController"),
5951
+ priceFeedConsumer: getAddress2(
5802
5952
  "PRICE_FEED_CONSUMER_ADDRESS",
5803
5953
  "PriceFeedConsumer"
5804
5954
  ),
5805
- operationAuthorizationRegistry: getAddress(
5955
+ operationAuthorizationRegistry: getAddress2(
5806
5956
  "OPERATION_AUTHORIZATION_REGISTRY_ADDRESS",
5807
5957
  "OperationAuthorizationRegistry"
5808
5958
  ),
5809
- btcSpendAuthorizer: getAddress(
5959
+ btcSpendAuthorizer: getAddress2(
5810
5960
  "BTC_SPEND_AUTHORIZER_ADDRESS",
5811
5961
  "BTCSpendAuthorizer"
5812
5962
  )
@@ -5874,7 +6024,7 @@ var init_network_configs = __esm({
5874
6024
  });
5875
6025
 
5876
6026
  // src/modules/diamond-hands-sdk.ts
5877
- import { Contract as Contract9, Interface as Interface6, JsonRpcProvider, AbiCoder as AbiCoder2, keccak256 as keccak2565, solidityPackedKeccak256 as solidityPackedKeccak2564, toUtf8Bytes as toUtf8Bytes5, getBytes as getBytes4, zeroPadValue as zeroPadValue5, toBeHex as toBeHex2, parseEther, formatEther, formatUnits, computeAddress, Signature, ZeroHash, ZeroAddress as ZeroAddress3 } from "ethers";
6027
+ import { Contract as Contract10, Interface as Interface6, JsonRpcProvider, AbiCoder as AbiCoder2, keccak256 as keccak2565, solidityPackedKeccak256 as solidityPackedKeccak2563, toUtf8Bytes as toUtf8Bytes5, getBytes as getBytes2, zeroPadValue as zeroPadValue4, toBeHex as toBeHex2, parseEther, formatEther, formatUnits, computeAddress, Signature, ZeroHash, ZeroAddress as ZeroAddress3, getAddress, verifyTypedData } from "ethers";
5878
6028
 
5879
6029
  // src/types/result.ts
5880
6030
  function success(value) {
@@ -7951,12 +8101,206 @@ import {
7951
8101
  keccak256 as keccak2562,
7952
8102
  toUtf8Bytes as toUtf8Bytes2,
7953
8103
  solidityPackedKeccak256 as solidityPackedKeccak2562,
7954
- getBytes as getBytes2,
7955
8104
  zeroPadValue
7956
8105
  } from "ethers";
8106
+
8107
+ // src/utils/btc-spend-request-712.ts
8108
+ init_deployment_addresses();
8109
+ import {
8110
+ Contract as Contract2,
8111
+ TypedDataEncoder as TypedDataEncoder2
8112
+ } from "ethers";
8113
+ var BTC_SPEND_REQUEST_712_DOMAIN_NAME = "DiamondHands.Protocol";
8114
+ var BTC_SPEND_REQUEST_712_DOMAIN_VERSION = "1";
8115
+ var BTC_SPEND_REQUEST_712_FIELDS = {
8116
+ ExecuteBtcWithdrawalRequest: [
8117
+ { name: "positionId", type: "bytes32" },
8118
+ { name: "withdrawalAddress", type: "string" },
8119
+ { name: "recipientAmount", type: "uint256" },
8120
+ { name: "networkFee", type: "uint256" },
8121
+ { name: "totalDeduction", type: "uint256" },
8122
+ { name: "spendTxid", type: "string" },
8123
+ { name: "spendVout", type: "uint32" },
8124
+ { name: "inputSetHash", type: "bytes32" },
8125
+ { name: "quantumTimestamp", type: "uint256" }
8126
+ ],
8127
+ InvalidateStaleSpendRequest: [
8128
+ { name: "positionId", type: "bytes32" },
8129
+ { name: "spendTxid", type: "string" },
8130
+ { name: "spendVout", type: "uint32" },
8131
+ { name: "quantumTimestamp", type: "uint256" }
8132
+ ]
8133
+ };
8134
+ function btcSpendRequest712Types(primaryType) {
8135
+ const fields = BTC_SPEND_REQUEST_712_FIELDS[primaryType];
8136
+ if (!fields) {
8137
+ throw new Error(
8138
+ `Unknown BTC spend request primary type "${primaryType}"; expected one of ` + Object.keys(BTC_SPEND_REQUEST_712_FIELDS).join(", ")
8139
+ );
8140
+ }
8141
+ return { [primaryType]: fields.map((field) => ({ ...field })) };
8142
+ }
8143
+ function btcSpendAuthorizerAddress(chainId) {
8144
+ if (!Number.isInteger(chainId) || chainId <= 0) {
8145
+ throw new Error(
8146
+ `BTC spend request domain requires a positive integer chainId, got ${String(chainId)}`
8147
+ );
8148
+ }
8149
+ const deployment = chainId === 31337 ? ALL_DEPLOYMENTS["localhost"] : Object.values(ALL_DEPLOYMENTS).find((d) => d.chainId === chainId);
8150
+ const address = deployment?.contracts?.BTCSpendAuthorizer;
8151
+ if (!address) {
8152
+ throw new Error(
8153
+ `No BTCSpendAuthorizer deployment known for chainId ${chainId}; refusing to build a BTC spend request domain without one`
8154
+ );
8155
+ }
8156
+ return address;
8157
+ }
8158
+ function buildBtcSpendRequest712Domain(chainId) {
8159
+ return {
8160
+ name: BTC_SPEND_REQUEST_712_DOMAIN_NAME,
8161
+ version: BTC_SPEND_REQUEST_712_DOMAIN_VERSION,
8162
+ chainId,
8163
+ verifyingContract: btcSpendAuthorizerAddress(chainId)
8164
+ };
8165
+ }
8166
+ function canonicalBtcTxid(txid) {
8167
+ const canonical = String(txid).toLowerCase().replace(/^0x/, "");
8168
+ if (!/^[0-9a-f]{64}$/.test(canonical)) {
8169
+ throw new Error(
8170
+ `Invalid Bitcoin txid "${String(txid)}": expected 64 hex characters (optionally 0x-prefixed)`
8171
+ );
8172
+ }
8173
+ return canonical;
8174
+ }
8175
+ function toBytes32PositionId(positionId) {
8176
+ const hex = positionId.startsWith("0x") ? positionId : `0x${positionId}`;
8177
+ if (!/^0x[0-9a-fA-F]{64}$/.test(hex)) {
8178
+ throw new Error(`positionId must be a bytes32 hex string, got "${positionId}"`);
8179
+ }
8180
+ return hex;
8181
+ }
8182
+ var GET_AUTHORIZED_SPENDS_ABI = [
8183
+ "function getAuthorizedSpends(bytes32 positionId) view returns (tuple(string txid, uint32 vout, uint256 satoshis, string targetAddress, uint256 targetAmount, uint256 authorizedAt)[])"
8184
+ ];
8185
+ async function readAuthorizedSpend(params) {
8186
+ const authorizer = new Contract2(
8187
+ btcSpendAuthorizerAddress(params.chainId),
8188
+ GET_AUTHORIZED_SPENDS_ABI,
8189
+ params.runner
8190
+ );
8191
+ const positionId = toBytes32PositionId(params.positionId);
8192
+ const wanted = canonicalBtcTxid(params.txid);
8193
+ const spends = await authorizer.getFunction("getAuthorizedSpends").staticCall(positionId);
8194
+ const match2 = spends.find(
8195
+ (s) => String(s.txid).toLowerCase().replace(/^0x/, "") === wanted && Number(s.vout) === Number(params.vout)
8196
+ );
8197
+ if (!match2) {
8198
+ throw new Error(
8199
+ `No on-chain authorized spend for ${params.txid}:${params.vout} under position ${positionId}`
8200
+ );
8201
+ }
8202
+ return {
8203
+ txid: String(match2.txid),
8204
+ vout: Number(match2.vout),
8205
+ satoshis: BigInt(match2.satoshis),
8206
+ targetAddress: String(match2.targetAddress),
8207
+ targetAmount: BigInt(match2.targetAmount),
8208
+ authorizedAt: BigInt(match2.authorizedAt)
8209
+ };
8210
+ }
8211
+ function assertRecordIsOutpoint(record, txid, vout) {
8212
+ if (canonicalBtcTxid(record.txid) !== canonicalBtcTxid(txid) || Number(record.vout) !== Number(vout)) {
8213
+ throw new Error(
8214
+ `The authorized spend record is for ${record.txid}:${record.vout}, not ${txid}:${vout}; refusing to sign`
8215
+ );
8216
+ }
8217
+ }
8218
+ function buildExecuteBtcWithdrawalTypedData(params) {
8219
+ const { networkFee } = params;
8220
+ if (!Number.isSafeInteger(networkFee) || networkFee < 0) {
8221
+ throw new Error(
8222
+ `networkFee must be a non-negative integer number of satoshis, got ${String(networkFee)}`
8223
+ );
8224
+ }
8225
+ const totalDeduction = BigInt(params.record.targetAmount);
8226
+ if (BigInt(networkFee) >= totalDeduction) {
8227
+ throw new Error(
8228
+ `Network fee ${networkFee} sats must be below the authorized total ${totalDeduction.toString()} sats`
8229
+ );
8230
+ }
8231
+ const primaryType = "ExecuteBtcWithdrawalRequest";
8232
+ return {
8233
+ domain: buildBtcSpendRequest712Domain(params.chainId),
8234
+ types: btcSpendRequest712Types(primaryType),
8235
+ primaryType,
8236
+ message: {
8237
+ positionId: toBytes32PositionId(params.positionId),
8238
+ withdrawalAddress: params.record.targetAddress,
8239
+ recipientAmount: (totalDeduction - BigInt(networkFee)).toString(),
8240
+ networkFee: String(networkFee),
8241
+ totalDeduction: totalDeduction.toString(),
8242
+ spendTxid: canonicalBtcTxid(params.record.txid),
8243
+ spendVout: Number(params.record.vout),
8244
+ inputSetHash: params.inputSetHash,
8245
+ quantumTimestamp: String(params.quantumTimestamp)
8246
+ }
8247
+ };
8248
+ }
8249
+ function buildInvalidateStaleSpendTypedData(params) {
8250
+ const primaryType = "InvalidateStaleSpendRequest";
8251
+ return {
8252
+ domain: buildBtcSpendRequest712Domain(params.chainId),
8253
+ types: btcSpendRequest712Types(primaryType),
8254
+ primaryType,
8255
+ message: {
8256
+ positionId: toBytes32PositionId(params.positionId),
8257
+ spendTxid: canonicalBtcTxid(params.record.txid),
8258
+ spendVout: Number(params.record.vout),
8259
+ quantumTimestamp: String(params.quantumTimestamp)
8260
+ }
8261
+ };
8262
+ }
8263
+ function btcSpendRequest712Digest(payload) {
8264
+ return TypedDataEncoder2.hash(payload.domain, payload.types, payload.message);
8265
+ }
8266
+ var BTC_SPEND_QUANTUM_SECONDS = 60;
8267
+ var BTC_SPEND_RELAY_DEADLINE_SECONDS = 90;
8268
+ function quantumStart(nowMs) {
8269
+ return Math.floor(nowMs / 1e3 / BTC_SPEND_QUANTUM_SECONDS) * BTC_SPEND_QUANTUM_SECONDS;
8270
+ }
8271
+ async function signBtcSpendRequest712(signer, build) {
8272
+ let signature;
8273
+ let quantumTimestamp;
8274
+ const restamp = signer.dhRestampTypedData;
8275
+ if (typeof restamp === "function") {
8276
+ ({ signature, quantumTimestamp } = await restamp.call(signer, build));
8277
+ } else {
8278
+ const signTypedData = signer.signTypedData;
8279
+ if (typeof signTypedData !== "function") {
8280
+ throw new Error(
8281
+ `Signer has no signTypedData \u2014 cannot produce an EIP-712 BTC spend request. Wallets without typed-data support must supply the signature via an authorizationProvider instead of a connected signer.`
8282
+ );
8283
+ }
8284
+ quantumTimestamp = quantumStart(Date.now());
8285
+ const payload = build(quantumTimestamp);
8286
+ signature = await signTypedData.call(signer, payload.domain, payload.types, payload.message);
8287
+ }
8288
+ const nowMs = Date.now();
8289
+ if (quantumTimestamp > quantumStart(nowMs)) {
8290
+ throw new Error(
8291
+ `The signature is stamped ${quantumTimestamp}, in a quantum that has not started; the Bitcoin signer refuses future stamps. Nothing was submitted.`
8292
+ );
8293
+ }
8294
+ if (nowMs / 1e3 - quantumTimestamp > BTC_SPEND_RELAY_DEADLINE_SECONDS) {
8295
+ throw new Error(
8296
+ `Signed too late: the signature is stamped ${quantumTimestamp}, more than ${BTC_SPEND_RELAY_DEADLINE_SECONDS} s ago, so the Bitcoin signer would refuse it. Nothing was submitted; retry and approve promptly.`
8297
+ );
8298
+ }
8299
+ return { signature, quantumTimestamp, payload: build(quantumTimestamp) };
8300
+ }
8301
+
8302
+ // src/utils/stale-spend-invalidate-message.ts
7957
8303
  var RECOVERY_INVALIDATE_ACTION = "btc-utxo-invalidator";
7958
- var QUANTUM_SECONDS = 60;
7959
- var QUANTUM_SAFE_THRESHOLD = 40;
7960
8304
  function buildInvalidateMessageHash(params) {
7961
8305
  const positionIdBytes32 = zeroPadValue(
7962
8306
  params.positionId.startsWith("0x") ? params.positionId : `0x${params.positionId}`,
@@ -7990,32 +8334,29 @@ function buildInvalidateMessageHash(params) {
7990
8334
  }
7991
8335
  async function buildInvalidateStaleSpendEnvelope(params) {
7992
8336
  const { positionId, utxoTxid, utxoVout, chainId, signer } = params;
7993
- const nowSec = Date.now() / 1e3;
7994
- const currentQuantumStart = Math.floor(nowSec / QUANTUM_SECONDS) * QUANTUM_SECONDS;
7995
- const secsIntoQuantum = nowSec - currentQuantumStart;
7996
- let timestamp;
7997
- if (secsIntoQuantum > QUANTUM_SAFE_THRESHOLD) {
7998
- const nextQuantumStart = currentQuantumStart + QUANTUM_SECONDS;
7999
- const waitMs = Math.max(0, (nextQuantumStart - nowSec) * 1e3 + 500);
8000
- await new Promise((r) => setTimeout(r, waitMs));
8001
- timestamp = nextQuantumStart;
8002
- } else {
8003
- timestamp = currentQuantumStart;
8337
+ if (params.provider === void 0 === (params.authorizedSpend === void 0)) {
8338
+ throw new Error(
8339
+ "buildInvalidateStaleSpendEnvelope: supply exactly one of `provider` or `authorizedSpend` so the outpoint comes from the on-chain record"
8340
+ );
8004
8341
  }
8005
- const messageHash = buildInvalidateMessageHash({
8006
- positionId,
8007
- timestamp,
8342
+ const record = params.authorizedSpend ?? await readAuthorizedSpend({
8343
+ runner: params.provider,
8008
8344
  chainId,
8009
- utxoTxid,
8010
- utxoVout
8345
+ positionId,
8346
+ txid: utxoTxid,
8347
+ vout: utxoVout
8011
8348
  });
8012
- const signature = await signer.signMessage(getBytes2(messageHash));
8349
+ assertRecordIsOutpoint(record, utxoTxid, utxoVout);
8350
+ const { signature, quantumTimestamp } = await signBtcSpendRequest712(
8351
+ signer,
8352
+ (stamp) => buildInvalidateStaleSpendTypedData({ chainId, positionId, record, quantumTimestamp: stamp })
8353
+ );
8013
8354
  const borrowerAddress = await signer.getAddress();
8014
8355
  return {
8015
8356
  positionId,
8016
8357
  utxoTxid,
8017
8358
  utxoVout,
8018
- timestamp,
8359
+ timestamp: quantumTimestamp,
8019
8360
  chainId,
8020
8361
  action: RECOVERY_INVALIDATE_ACTION,
8021
8362
  signature,
@@ -8024,9 +8365,7 @@ async function buildInvalidateStaleSpendEnvelope(params) {
8024
8365
  }
8025
8366
 
8026
8367
  // src/utils/btc-withdrawal-message.ts
8027
- import { keccak256 as keccak2563, toUtf8Bytes as toUtf8Bytes3, solidityPackedKeccak256 as solidityPackedKeccak2563, getBytes as getBytes3, zeroPadValue as zeroPadValue2 } from "ethers";
8028
- var QUANTUM_SECONDS2 = 60;
8029
- var QUANTUM_SAFE_THRESHOLD2 = 40;
8368
+ import { keccak256 as keccak2563, toUtf8Bytes as toUtf8Bytes3 } from "ethers";
8030
8369
  function hashBtcInputSet(utxos) {
8031
8370
  if (!Array.isArray(utxos) || utxos.length === 0) {
8032
8371
  throw new Error("hashBtcInputSet: at least one input is required");
@@ -8058,23 +8397,28 @@ function hashBtcInputSet(utxos) {
8058
8397
  return keccak2563(toUtf8Bytes3(canonical));
8059
8398
  }
8060
8399
  async function buildBtcExecuteEnvelope(params) {
8061
- const {
8062
- positionId,
8063
- txid,
8064
- vout,
8065
- satoshis,
8066
- targetAddress,
8067
- targetAmount,
8068
- networkFee,
8069
- chainId,
8070
- signer
8071
- } = params;
8072
- if (!targetAddress || typeof targetAddress !== "string") {
8073
- throw new Error("buildBtcExecuteEnvelope: targetAddress is required");
8400
+ const { positionId, txid, vout, satoshis, networkFee, chainId, signer } = params;
8401
+ if (params.provider === void 0 === (params.authorizedSpend === void 0)) {
8402
+ throw new Error(
8403
+ "buildBtcExecuteEnvelope: supply exactly one of `provider` or `authorizedSpend` so the destination and amount come from the on-chain record"
8404
+ );
8405
+ }
8406
+ const record = params.authorizedSpend ?? await readAuthorizedSpend({ runner: params.provider, chainId, positionId, txid, vout });
8407
+ assertRecordIsOutpoint(record, txid, vout);
8408
+ if (params.targetAddress !== void 0 && params.targetAddress !== record.targetAddress) {
8409
+ throw new Error(
8410
+ `buildBtcExecuteEnvelope: destination "${params.targetAddress}" disagrees with the on-chain authorized spend "${record.targetAddress}"; refusing to sign`
8411
+ );
8412
+ }
8413
+ if (params.targetAmount !== void 0 && BigInt(params.targetAmount) !== record.targetAmount) {
8414
+ throw new Error(
8415
+ `buildBtcExecuteEnvelope: amount ${params.targetAmount} sats disagrees with the on-chain authorized spend ${record.targetAmount.toString()} sats; refusing to sign`
8416
+ );
8074
8417
  }
8075
- if (!Number.isFinite(targetAmount) || targetAmount <= 0) {
8418
+ const targetAmount = Number(record.targetAmount);
8419
+ if (!Number.isSafeInteger(targetAmount) || targetAmount <= 0) {
8076
8420
  throw new Error(
8077
- "buildBtcExecuteEnvelope: targetAmount must be a positive number of satoshis"
8421
+ `buildBtcExecuteEnvelope: on-chain targetAmount ${record.targetAmount.toString()} is not a positive safe integer`
8078
8422
  );
8079
8423
  }
8080
8424
  const utxos = params.utxos && params.utxos.length > 0 ? params.utxos : [{ txid, vout, value: satoshis }];
@@ -8087,73 +8431,30 @@ async function buildBtcExecuteEnvelope(params) {
8087
8431
  `buildBtcExecuteEnvelope: the authorized UTXO ${txid}:${vout} must be part of utxos[]`
8088
8432
  );
8089
8433
  }
8090
- const utxosHash = hashBtcInputSet(utxos);
8091
- const nowSec = Date.now() / 1e3;
8092
- const currentQuantumStart = Math.floor(nowSec / QUANTUM_SECONDS2) * QUANTUM_SECONDS2;
8093
- const secsIntoQuantum = nowSec - currentQuantumStart;
8094
- let timestamp;
8095
- if (secsIntoQuantum > QUANTUM_SAFE_THRESHOLD2) {
8096
- const nextQuantumStart = currentQuantumStart + QUANTUM_SECONDS2;
8097
- const waitMs = Math.max(0, (nextQuantumStart - nowSec) * 1e3 + 500);
8098
- await new Promise((r) => setTimeout(r, waitMs));
8099
- timestamp = nextQuantumStart;
8100
- } else {
8101
- timestamp = currentQuantumStart;
8102
- }
8103
- const actionHash = keccak2563(
8104
- toUtf8Bytes3("execute-btc-withdrawal")
8105
- );
8106
- const utxoIdentifier = `${txid}:${vout}`;
8107
- const positionIdBytes32 = zeroPadValue2(
8108
- positionId.startsWith("0x") ? positionId : `0x${positionId}`,
8109
- 32
8110
- );
8111
- const messageHash = solidityPackedKeccak2563(
8112
- [
8113
- "bytes32",
8114
- // positionId
8115
- "uint256",
8116
- // timestamp
8117
- "uint256",
8118
- // chainId
8119
- "string",
8120
- // utxoIdentifier ("txid:vout")
8121
- "uint256",
8122
- // networkFee
8123
- "string",
8124
- // targetAddress (BTC destination)
8125
- "uint256",
8126
- // targetAmount (sats authorized to recipient)
8127
- "bytes32",
8128
- // utxosHash (canonical hash of the FULL input set — P6/#8)
8129
- "bytes32"
8130
- // actionHash
8131
- ],
8132
- [
8133
- positionIdBytes32,
8134
- timestamp,
8434
+ const inputSetHash = hashBtcInputSet(utxos);
8435
+ const { signature, quantumTimestamp } = await signBtcSpendRequest712(
8436
+ signer,
8437
+ (stamp) => buildExecuteBtcWithdrawalTypedData({
8135
8438
  chainId,
8136
- utxoIdentifier,
8439
+ positionId,
8440
+ record,
8137
8441
  networkFee,
8138
- targetAddress,
8139
- targetAmount,
8140
- utxosHash,
8141
- actionHash
8142
- ]
8442
+ inputSetHash,
8443
+ quantumTimestamp: stamp
8444
+ })
8143
8445
  );
8144
- const userSignature = await signer.signMessage(getBytes3(messageHash));
8145
8446
  const borrowerAddress = await signer.getAddress();
8146
8447
  return {
8147
8448
  positionId,
8148
8449
  txid,
8149
8450
  vout,
8150
8451
  satoshis,
8151
- targetAddress,
8452
+ targetAddress: record.targetAddress,
8152
8453
  targetAmount,
8153
8454
  networkFee,
8154
8455
  chainId,
8155
- timestamp,
8156
- userSignature,
8456
+ timestamp: quantumTimestamp,
8457
+ userSignature: signature,
8157
8458
  borrowerAddress,
8158
8459
  utxos
8159
8460
  };
@@ -8205,7 +8506,7 @@ function maybeTemperSignature(signature, shouldTemper, operationName) {
8205
8506
  }
8206
8507
 
8207
8508
  // src/utils/address-conversion.utils.ts
8208
- import { zeroPadValue as zeroPadValue3 } from "ethers";
8509
+ import { zeroPadValue as zeroPadValue2 } from "ethers";
8209
8510
 
8210
8511
  // src/utils/chunks/bitcoin-utils.ts
8211
8512
  import { sha256 as nobleSha256 } from "@noble/hashes/sha256";
@@ -8396,6 +8697,8 @@ function isValidBech32Address(address) {
8396
8697
  const witnessVersion = decoded.words[0];
8397
8698
  if (witnessVersion < 0 || witnessVersion > 16)
8398
8699
  return false;
8700
+ if (witnessVersion === 0 !== (codec === bech32))
8701
+ return false;
8399
8702
  const program = bech32.fromWords(decoded.words.slice(1));
8400
8703
  if (program.length < 2 || program.length > 40)
8401
8704
  return false;
@@ -8492,14 +8795,23 @@ function safeValidateBitcoinAddress(address, network) {
8492
8795
  }
8493
8796
  return address;
8494
8797
  }
8798
+ var BECH32_PREFIX = /^(bc1|tb1|bcrt1)/i;
8799
+ function bitcoinAddressCaseError(address) {
8800
+ const trimmed = address.trim();
8801
+ if (!BECH32_PREFIX.test(trimmed))
8802
+ return null;
8803
+ if (trimmed === trimmed.toLowerCase() || trimmed === trimmed.toUpperCase())
8804
+ return null;
8805
+ return `Bitcoin address ${trimmed} mixes upper and lower case \u2014 a bech32 address must be entirely one case (BIP-173). Re-copy it from the source.`;
8806
+ }
8495
8807
  function normalizeBitcoinAddress(address) {
8496
8808
  if (!address || typeof address !== "string")
8497
8809
  return address;
8498
8810
  const trimmed = address.trim();
8499
- if (/^(bc1|tb1|bcrt1)/i.test(trimmed)) {
8500
- return trimmed.toLowerCase();
8501
- }
8502
- return trimmed;
8811
+ const caseError = bitcoinAddressCaseError(trimmed);
8812
+ if (caseError)
8813
+ throw new Error(caseError);
8814
+ return BECH32_PREFIX.test(trimmed) ? trimmed.toLowerCase() : trimmed;
8503
8815
  }
8504
8816
 
8505
8817
  // src/protocol/protocol-pause.ts
@@ -8659,7 +8971,7 @@ function extractOptionalLitSignature(raw) {
8659
8971
 
8660
8972
  // src/modules/contract/contract-manager.module.ts
8661
8973
  init_deployment_addresses();
8662
- import { Contract as Contract2, isAddress, ZeroAddress } from "ethers";
8974
+ import { Contract as Contract3, isAddress, ZeroAddress } from "ethers";
8663
8975
  var POSITION_MANAGER_ABI = [
8664
8976
  "function createPosition(bytes32 pkpId, bytes calldata validatorSignature, string mainnetVaultAddress, string regtestVaultAddress, uint256 selectedTermMonths, uint256 validatorVersion, bytes calldata pkpPublicKey) external returns (bytes32 positionId)",
8665
8977
  "function mintUCD(bytes32 positionId, uint256 mintAmount, uint256 mintFee, uint256 newDebt, uint256 newCollateral, uint256 btcPrice, bytes32 authorizedSpendsHash, bytes32 ucdDebtHash, bytes32 contractHash, uint256 quantumTimestamp, bytes calldata mintValidatorSignature) external returns (bool)",
@@ -8732,37 +9044,37 @@ var ContractManager = class {
8732
9044
  }
8733
9045
  const contractRunner = runner;
8734
9046
  const contracts = {
8735
- positionManager: new Contract2(
9047
+ positionManager: new Contract3(
8736
9048
  contractAddresses.positionManager,
8737
9049
  POSITION_MANAGER_ABI,
8738
9050
  contractRunner
8739
9051
  ),
8740
- loanOperationsManager: new Contract2(
9052
+ loanOperationsManager: new Contract3(
8741
9053
  contractAddresses.loanOperationsManager || ZeroAddress,
8742
9054
  LOAN_OPS_ABI,
8743
9055
  contractRunner
8744
9056
  ),
8745
- ucdController: new Contract2(
9057
+ ucdController: new Contract3(
8746
9058
  contractAddresses.ucdToken,
8747
9059
  UCD_CONTROLLER_ABI,
8748
9060
  contractRunner
8749
9061
  ),
8750
- termManager: new Contract2(
9062
+ termManager: new Contract3(
8751
9063
  contractAddresses.termManager || ZeroAddress,
8752
9064
  TERM_MANAGER_ABI,
8753
9065
  contractRunner
8754
9066
  ),
8755
- circuitBreaker: new Contract2(
9067
+ circuitBreaker: new Contract3(
8756
9068
  contractAddresses.circuitBreaker || ZeroAddress,
8757
9069
  CIRCUIT_BREAKER_ABI,
8758
9070
  contractRunner
8759
9071
  ),
8760
- liquidationManager: new Contract2(
9072
+ liquidationManager: new Contract3(
8761
9073
  contractAddresses.liquidationManager || ZeroAddress,
8762
9074
  LIQUIDATION_MANAGER_ABI,
8763
9075
  contractRunner
8764
9076
  ),
8765
- bitcoinWithdrawalAddressRegistry: new Contract2(
9077
+ bitcoinWithdrawalAddressRegistry: new Contract3(
8766
9078
  contractAddresses.bitcoinWithdrawalAddressRegistry || ZeroAddress,
8767
9079
  BITCOIN_WITHDRAWAL_ADDRESS_REGISTRY_ABI,
8768
9080
  contractRunner
@@ -9784,7 +10096,7 @@ function createPKPManager(config) {
9784
10096
  }
9785
10097
 
9786
10098
  // src/modules/loan/loan-creator.module.ts
9787
- import { Contract as Contract3, Interface as Interface2, zeroPadValue as zeroPadValue4, toBeHex, SigningKey } from "ethers";
10099
+ import { Contract as Contract4, Interface as Interface2, zeroPadValue as zeroPadValue3, toBeHex, SigningKey } from "ethers";
9788
10100
  var import_dh_lit_actions = __toESM(require_pkg_src());
9789
10101
 
9790
10102
  // src/utils/contract-wallet.utils.ts
@@ -10143,7 +10455,7 @@ var LoanCreator = class {
10143
10455
  try {
10144
10456
  const mainnetVaultAddress = bitcoinAddresses.mainnet;
10145
10457
  const regtestVaultAddress = bitcoinAddresses.regtest;
10146
- const pkpIdBytes32 = zeroPadValue4(
10458
+ const pkpIdBytes32 = zeroPadValue3(
10147
10459
  toBeHex(BigInt(pkpData.tokenId)),
10148
10460
  32
10149
10461
  );
@@ -10332,7 +10644,7 @@ var LoanCreator = class {
10332
10644
  }
10333
10645
  }
10334
10646
  if (this.config.debug) {
10335
- const pkpIdBytes32Check = zeroPadValue4(
10647
+ const pkpIdBytes32Check = zeroPadValue3(
10336
10648
  toBeHex(BigInt(pkpData.tokenId)),
10337
10649
  32
10338
10650
  );
@@ -10494,7 +10806,7 @@ var LoanCreator = class {
10494
10806
  const coreAddress = this.config.contractManager.getContractAddresses().positionManagerCore;
10495
10807
  if (coreAddress) {
10496
10808
  try {
10497
- const core = new Contract3(
10809
+ const core = new Contract4(
10498
10810
  coreAddress,
10499
10811
  [
10500
10812
  "function getPositionDetails(bytes32) view returns (tuple(bytes32 positionId, bytes32 pkpId, uint256 ucdDebt, string vaultAddress, address borrower, uint40 createdAt, uint40 lastUpdated, uint16 selectedTerm, uint40 expiryAt, uint8 status))"
@@ -10631,7 +10943,7 @@ var LoanStatus = /* @__PURE__ */ ((LoanStatus2) => {
10631
10943
  })(LoanStatus || {});
10632
10944
 
10633
10945
  // src/modules/loan/loan-query.module.ts
10634
- import { Contract as Contract4, isAddress as isAddress2 } from "ethers";
10946
+ import { Contract as Contract5, isAddress as isAddress2 } from "ethers";
10635
10947
 
10636
10948
  // src/constants/chunks/sdk-limits.ts
10637
10949
  var THE_GRAPH_MAX_BATCH_SIZE = 1e3;
@@ -11028,7 +11340,7 @@ var LoanQuery = class {
11028
11340
  const isChipotlePkpId2 = typeof rawId === "string" && isNormalizedChipotlePkpId(rawId);
11029
11341
  if (isChipotlePkpId2) {
11030
11342
  if (this.config.positionManagerCoreAddress && this.config.provider) {
11031
- const pmContract = new Contract4(
11343
+ const pmContract = new Contract5(
11032
11344
  this.config.positionManagerCoreAddress,
11033
11345
  POSITION_CORE_ABI,
11034
11346
  this.config.provider
@@ -11422,10 +11734,32 @@ var WithdrawalAddressModule = class {
11422
11734
  isConfigured() {
11423
11735
  return this.getRegistry().success;
11424
11736
  }
11425
- /** keccak256 of the canonicalized address — matches the on-chain key. */
11737
+ /**
11738
+ * keccak256 of the canonicalized address — matches the on-chain key.
11739
+ * @throws on mixed-case bech32, which has no canonical spelling (BIP-173).
11740
+ */
11426
11741
  static addressHash(btcAddress) {
11427
11742
  return keccak2564(toUtf8Bytes4(normalizeBitcoinAddress(btcAddress)));
11428
11743
  }
11744
+ /**
11745
+ * The canonical spelling the registry keys on, or a VALIDATION failure for mixed-case
11746
+ * bech32 — reported as a value, like every other failure of this module, never thrown.
11747
+ */
11748
+ canonicalAddress(btcAddress) {
11749
+ const caseError = bitcoinAddressCaseError(btcAddress);
11750
+ if (caseError) {
11751
+ return failure(
11752
+ new SDKError({
11753
+ code: "SDK_INVALID_BITCOIN_ADDRESS",
11754
+ message: caseError,
11755
+ category: "VALIDATION" /* VALIDATION */,
11756
+ severity: "MEDIUM" /* MEDIUM */,
11757
+ context: { btcAddress }
11758
+ })
11759
+ );
11760
+ }
11761
+ return success(normalizeBitcoinAddress(btcAddress));
11762
+ }
11429
11763
  /**
11430
11764
  * Add a Bitcoin address to the caller's allowlist. It becomes usable only
11431
11765
  * after the registry's delay elapses. Returns the submitted tx.
@@ -11434,7 +11768,10 @@ var WithdrawalAddressModule = class {
11434
11768
  const reg = this.getRegistry();
11435
11769
  if (!reg.success)
11436
11770
  return reg;
11437
- const normalized = normalizeBitcoinAddress(btcAddress);
11771
+ const canonical = this.canonicalAddress(btcAddress);
11772
+ if (!canonical.success)
11773
+ return canonical;
11774
+ const normalized = canonical.value;
11438
11775
  try {
11439
11776
  const tx = await reg.value.addAddress(normalized);
11440
11777
  return success(tx);
@@ -11452,7 +11789,10 @@ var WithdrawalAddressModule = class {
11452
11789
  const reg = this.getRegistry();
11453
11790
  if (!reg.success)
11454
11791
  return reg;
11455
- const normalized = normalizeBitcoinAddress(btcAddress);
11792
+ const canonical = this.canonicalAddress(btcAddress);
11793
+ if (!canonical.success)
11794
+ return canonical;
11795
+ const normalized = canonical.value;
11456
11796
  try {
11457
11797
  const tx = await reg.value.removeAddress(normalized);
11458
11798
  return success(tx);
@@ -11473,11 +11813,11 @@ var WithdrawalAddressModule = class {
11473
11813
  const reg = this.getRegistry();
11474
11814
  if (!reg.success)
11475
11815
  return reg;
11816
+ const canonical = this.canonicalAddress(btcAddress);
11817
+ if (!canonical.success)
11818
+ return canonical;
11476
11819
  try {
11477
- const ok = await reg.value.isApproved(
11478
- user,
11479
- normalizeBitcoinAddress(btcAddress)
11480
- );
11820
+ const ok = await reg.value.isApproved(user, canonical.value);
11481
11821
  return success(ok);
11482
11822
  } catch (error) {
11483
11823
  return this.txFailure("isApproved", error, btcAddress);
@@ -14891,7 +15231,7 @@ var DiamondHandsGraph = class {
14891
15231
 
14892
15232
  // src/contracts/typechain-contracts/factories/src/psm/SimplePSMV2__factory.ts
14893
15233
  import {
14894
- Contract as Contract6,
15234
+ Contract as Contract7,
14895
15235
  ContractFactory,
14896
15236
  Interface as Interface3
14897
15237
  } from "ethers";
@@ -17485,13 +17825,13 @@ var SimplePSMV2__factory = class extends ContractFactory {
17485
17825
  return new Interface3(_abi);
17486
17826
  }
17487
17827
  static connect(address, runner) {
17488
- return new Contract6(address, _abi, runner);
17828
+ return new Contract7(address, _abi, runner);
17489
17829
  }
17490
17830
  };
17491
17831
 
17492
17832
  // src/contracts/typechain-contracts/factories/src/agent/AgentDelegationRegistry__factory.ts
17493
17833
  import {
17494
- Contract as Contract7,
17834
+ Contract as Contract8,
17495
17835
  ContractFactory as ContractFactory2,
17496
17836
  Interface as Interface4
17497
17837
  } from "ethers";
@@ -17604,6 +17944,11 @@ var _abi2 = [
17604
17944
  name: "InvalidAddress",
17605
17945
  type: "error"
17606
17946
  },
17947
+ {
17948
+ inputs: [],
17949
+ name: "InvalidAgentConsent",
17950
+ type: "error"
17951
+ },
17607
17952
  {
17608
17953
  inputs: [],
17609
17954
  name: "InvalidFloor",
@@ -18057,6 +18402,12 @@ var _abi2 = [
18057
18402
  name: "ContractUpgraded",
18058
18403
  type: "event"
18059
18404
  },
18405
+ {
18406
+ anonymous: false,
18407
+ inputs: [],
18408
+ name: "EIP712DomainChanged",
18409
+ type: "event"
18410
+ },
18060
18411
  {
18061
18412
  anonymous: false,
18062
18413
  inputs: [
@@ -18228,6 +18579,19 @@ var _abi2 = [
18228
18579
  name: "Upgraded",
18229
18580
  type: "event"
18230
18581
  },
18582
+ {
18583
+ inputs: [],
18584
+ name: "AGENT_BINDING_CONSENT_TYPEHASH",
18585
+ outputs: [
18586
+ {
18587
+ internalType: "bytes32",
18588
+ name: "",
18589
+ type: "bytes32"
18590
+ }
18591
+ ],
18592
+ stateMutability: "view",
18593
+ type: "function"
18594
+ },
18231
18595
  {
18232
18596
  inputs: [],
18233
18597
  name: "DEFAULT_ADMIN_ROLE",
@@ -18358,6 +18722,30 @@ var _abi2 = [
18358
18722
  stateMutability: "view",
18359
18723
  type: "function"
18360
18724
  },
18725
+ {
18726
+ inputs: [
18727
+ {
18728
+ internalType: "address",
18729
+ name: "user",
18730
+ type: "address"
18731
+ },
18732
+ {
18733
+ internalType: "address",
18734
+ name: "agent",
18735
+ type: "address"
18736
+ }
18737
+ ],
18738
+ name: "agentBindingConsentDigest",
18739
+ outputs: [
18740
+ {
18741
+ internalType: "bytes32",
18742
+ name: "",
18743
+ type: "bytes32"
18744
+ }
18745
+ ],
18746
+ stateMutability: "view",
18747
+ type: "function"
18748
+ },
18361
18749
  {
18362
18750
  inputs: [],
18363
18751
  name: "agentMintFloorMinBps",
@@ -18608,6 +18996,49 @@ var _abi2 = [
18608
18996
  stateMutability: "nonpayable",
18609
18997
  type: "function"
18610
18998
  },
18999
+ {
19000
+ inputs: [],
19001
+ name: "eip712Domain",
19002
+ outputs: [
19003
+ {
19004
+ internalType: "bytes1",
19005
+ name: "fields",
19006
+ type: "bytes1"
19007
+ },
19008
+ {
19009
+ internalType: "string",
19010
+ name: "name",
19011
+ type: "string"
19012
+ },
19013
+ {
19014
+ internalType: "string",
19015
+ name: "version",
19016
+ type: "string"
19017
+ },
19018
+ {
19019
+ internalType: "uint256",
19020
+ name: "chainId",
19021
+ type: "uint256"
19022
+ },
19023
+ {
19024
+ internalType: "address",
19025
+ name: "verifyingContract",
19026
+ type: "address"
19027
+ },
19028
+ {
19029
+ internalType: "bytes32",
19030
+ name: "salt",
19031
+ type: "bytes32"
19032
+ },
19033
+ {
19034
+ internalType: "uint256[]",
19035
+ name: "extensions",
19036
+ type: "uint256[]"
19037
+ }
19038
+ ],
19039
+ stateMutability: "view",
19040
+ type: "function"
19041
+ },
18611
19042
  {
18612
19043
  inputs: [
18613
19044
  {
@@ -18980,6 +19411,11 @@ var _abi2 = [
18980
19411
  internalType: "uint64",
18981
19412
  name: "validUntil",
18982
19413
  type: "uint64"
19414
+ },
19415
+ {
19416
+ internalType: "bytes",
19417
+ name: "agentConsent",
19418
+ type: "bytes"
18983
19419
  }
18984
19420
  ],
18985
19421
  name: "registerAgent",
@@ -19057,6 +19493,11 @@ var _abi2 = [
19057
19493
  internalType: "uint64",
19058
19494
  name: "validUntil",
19059
19495
  type: "uint64"
19496
+ },
19497
+ {
19498
+ internalType: "bytes",
19499
+ name: "agentConsent",
19500
+ type: "bytes"
19060
19501
  }
19061
19502
  ],
19062
19503
  name: "rotateAgent",
@@ -19185,7 +19626,7 @@ var _abi2 = [
19185
19626
  type: "function"
19186
19627
  }
19187
19628
  ];
19188
- var _bytecode2 = "0x60a080604052346100ea57306080527ff0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a005460ff8160401c166100d9576002600160401b03196001600160401b03821601610073575b60405161304c90816100f0823960805181818161114401526113290152f35b6001600160401b0319166001600160401b039081177ff0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a005581527fc7f505b2f371ae2175ee4913f4499e1f2633a7b5936321eed1cdaeb6115181d290602090a13880610054565b63f92ee8a960e01b60005260046000fd5b600080fdfe608080604052600436101561001357600080fd5b60003560e01c90816301ffc9a714611ff7575080630d33f3c214611fd35780630f3f4a9414611f885780631459457a14611be257806318c38b8914611ad15780631d44454114611a005780632106764c146119d9578063248a9ca3146119b35780632ec22d4c146118f25780632f0647ce146118775780632f2ff15d14611846578063324207441461177257806336568abe1461172c578063392f1087146116f65780633f4ba83a146115fe5780633f5aadc91461158f5780634f1ef286146112ad57806352340363146111c45780635273b6f61461119b57806352d1902d14611131578063554c4f4b146110a1578063561b7f8a14610f755780635bc26aea14610ee85780635c975abb14610eb85780636289d18c14610e375780636711cc0b14610e1b5780636e852a7814610d1a5780637e35bf6e14610ce65780638343f67414610cb95780638456cb5914610bc35780638f33527f14610b895780639010d07c14610b3557806391d1485414610adb5780639b9d30c114610ab2578063a19af3f614610a01578063a217fddf146109e5578063a3246ad314610923578063a878086414610907578063ac3c0e30146107fa578063ad3cb1cc146107b3578063b3fad6381461070e578063c34e9c26146106f2578063c86deb31146106d6578063ca15c8731461069d578063d547741f14610665578063dd71d99a14610623578063e0922fa114610576578063efa9b4ae14610507578063f2f4eb26146104de578063f68e9553146104b5578063f94f67ab146103de578063fd437d391461029f5763ffa1ad741461026657600080fd5b3461029a57600036600319011261029a576102966102826121ed565b6040519182916020835260208301906121c8565b0390f35b600080fd5b3461029a57606036600319011261029a576102b861207a565b6102c0612064565b906102c961218f565b906102d2612795565b6001600160a01b0316338190036103ce5780600052600160205260406000209283549360ff8560e01c1660038110156103b8576001036103a75781600160209261033e877fc5d5c5bbf10444998e0ea6d4725e79027b574e1c14ec929279e8a9a95c6c6e919688612c43565b818060a01b038316828060a01b031982541617815561035d878261239f565b0180546001600160401b031916426001600160401b03908116919091179091556001600160a01b0391821660008181526002855260409081902087905551969091168652951693a4005b632437e77160e11b60005260046000fd5b634e487b7160e01b600052602160045260246000fd5b62fca64560e31b60005260046000fd5b3461029a57604036600319011261029a576004356103fa6120c9565b90610403612795565b63ffffffff600554169163ffffffff8116928084109081156104ac575b5061049b5760207f6b7727cc9c3df4a29acf0afe01594c1b7e845d20f40f4a14e4c292164a9ed8e191610452846127e0565b9161046a600863ffffffff845460a01c1617836122e3565b81546001600160e01b031660e09190911b6001600160e01b0319161790556040519485526001600160a01b031693a3005b634346c13160e01b60005260046000fd5b90501584610420565b3461029a57600036600319011261029a576020604051600080516020612fe08339815191528152f35b3461029a57600036600319011261029a576003546040516001600160a01b039091168152602090f35b3461029a57602036600319011261029a57600435610523612795565b61054561052f826127e0565b9190600163ffffffff825460a01c1617906122e3565b6001600160a01b0316907f812690e0a9dff5bf3add998111b8af5c8299608d859025bfe35662060ab4267d600080a3005b3461029a57602036600319011261029a576004356001600160401b0381169081810361029a576000546001600160a01b038116330361061257600160a01b600160e01b0319811660a092831b600160a01b600160e01b031617600055604080519190921c6001600160401b0316815260208101929092527f9c195448332abd01f716db873b329752ea02f19d33f7e311fb0daf082c4edd0391a1005b6349db3bd360e01b60005260046000fd5b3461029a57602036600319011261029a576001600160a01b0361064461207a565b166000526002602052602060018060a01b0360406000205416604051908152f35b3461029a57604036600319011261029a5761069b600435610684612064565b90610696610691826122c2565b6126bf565b612751565b005b3461029a57602036600319011261029a57600435600052600080516020612ee08339815191526020526020604060002054604051908152f35b3461029a57600036600319011261029a57602060405160088152f35b3461029a57600036600319011261029a57602060405160028152f35b3461029a57602036600319011261029a576000606060405161072f81612136565b828152826020820152826040820152015260043560005260046020526080604060002063ffffffff6040519161076483612136565b548160018060a01b038216938481528160208201818560a01c16815260606040840193838760c01c168552019460e01c8552604051968752511660208601525116604084015251166060820152f35b3461029a57600036600319011261029a5761029660408051906107d68183612151565b60058252640352e302e360dc1b6020830152519182916020835260208301906121c8565b3461029a57602036600319011261029a5761081361207a565b6000608060405161082381612105565b828152826020820152826040820152826060820152015260018060a01b03166000526001602052604060002060405161085b81612105565b81546001600160a01b038116825260a081901c6001600160401b03166020830190815292604083019160e01c60ff169060038210156103b857908252600101546001600160401b0380821660608501908152604092831c821660808601908152925194516001600160a01b03168552945116602084015290519260038410156103b857604083019390935291516001600160401b0390811660608301529151909116608082015260a090f35b3461029a57600036600319011261029a57602060405160018152f35b3461029a57602036600319011261029a57600435600052600080516020612ee083398151915260205260406000206040518060208354918281520190819360005260206000209060005b8181106109cf5750505081610983910382612151565b6040519182916020830190602084525180915260408301919060005b8181106109ad575050500390f35b82516001600160a01b031684528594506020938401939092019160010161099f565b825484526020909301926001928301920161096d565b3461029a57600036600319011261029a57602060405160008152f35b3461029a57604036600319011261029a57600435610a1d6120c9565b90610a26612795565b63ffffffff600554169163ffffffff811692808410908115610aa9575b5061049b5760207f1da95b87b4c773f68c1447ffc5644e41a8a8887d55065beb64852014cf7140be91610a96610a78856127e0565b9290610a91600463ffffffff835460a01c1617826122e3565b612210565b6040519485526001600160a01b031693a3005b90501584610a43565b3461029a57600036600319011261029a576020604051600080516020612f208339815191528152f35b3461029a57604036600319011261029a57610af4612064565b600435600052600080516020612fc083398151915260205260406000209060018060a01b0316600052602052602060ff604060002054166040519015158152f35b3461029a57604036600319011261029a57600435600052600080516020612ee08339815191526020526020610b706024356040600020612d0c565b905460405160039290921b1c6001600160a01b03168152f35b3461029a57602036600319011261029a576001600160a01b03610baa61207a565b1660005260026020526020604060002054604051908152f35b3461029a57600036600319011261029a573360009081527f0ac8cc3d209806126662940717264973110c39045b305f6ba49613325a615e09602052604090205460ff1615610c9257610c13612795565b600160ff19600080516020613000833981519152541617600080516020613000833981519152557f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a2586020604051338152a16040514281527f80170b5fcdd2bf1e0660ef4b8851f86685f64d41b1a19de1471947ece8725aac60203392a2005b63e2517d3f60e01b60005233600452600080516020612f2083398151915260245260446000fd5b3461029a57600036600319011261029a5760005460405160a09190911c6001600160401b03168152602090f35b3461029a57604036600319011261029a57610d0a610d02612064565b60043561236c565b906102966040519283928361209a565b3461029a57604036600319011261029a57610d3361207a565b336000908152600080516020612f60833981519152602052604090205460ff161580610e08575b6103ce576001600160a01b03166000818152600160205260409020805460e01c60ff1660038110156103b8576001036103a757805460ff60e01b198116600160e11b1782556001919091018054600160401b600160801b03191642604090811b600160401b600160801b0316919091179091555160243581526001600160a01b0390911691907fc0499cc07ed9d734deec6857802d3f0fa8d5afaf79a7008beb8ba7bef62a271b90602090a3005b50336001600160a01b0382161415610d5a565b3461029a57600036600319011261029a57602060405160048152f35b3461029a57602036600319011261029a57610e506120b6565b6000546001600160a01b031633036106125763ffffffff8116908115610ea757600080516020612fa083398151915291610ea263ffffffff926005549284198416176005556040519384931683612233565b0390a1005b6338f3377360e21b60005260046000fd5b3461029a57600036600319011261029a57602060ff60008051602061300083398151915254166040519015158152f35b3461029a57602036600319011261029a57610f0161207a565b6000546001600160a01b0381169033829003610612576001600160a01b038316928315610f64573b15610f53576001600160a01b03191682176000908155600080516020612f808339815191529080a3005b636f7c43f160e01b60005260046000fd5b63e6c4247b60e01b60005260046000fd5b3461029a57606036600319011261029a57610f8e61207a565b610f96612064565b610f9e61218f565b91610fa7612795565b6001600160a01b031690338290036103ce57816000526001602052604060002060ff815460e01c1660038110156103b857600114611090578160209161100f867ff223dc085722c94c84dcf67427e225799be616382a2a484d378f8921c69a20339587612c43565b80546001600160a01b0319166001600160a01b038316178155611032868261239f565b6001810180546001600160801b031916426001600160401b0390811691909117909155815460ff60e01b1916600160e01b179091556001600160a01b03919091166000818152600284526040908190208690555195909116855293a3005b639d2c8fdf60e01b60005260046000fd5b3461029a57602036600319011261029a576001600160a01b036110c261207a565b166000526001602052604060002060ff60008051602061300083398151915254161580611115575b602091816110fe575b506040519015158152f35b5460a01c6001600160401b031642109050826110f3565b5060ff815460e01c169060038210156103b857906001146110ea565b3461029a57600036600319011261029a577f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316300361118a576020604051600080516020612f408339815191528152f35b63703e46dd60e11b60005260046000fd5b3461029a57600036600319011261029a576000546040516001600160a01b039091168152602090f35b3461029a57602036600319011261029a57600435604060008281526004602052209081549160018060a01b03831692831590811561129e575b5061128d57336000908152600080516020612f60833981519152602052604090205460ff161580611283575b611272578061124563fffffffe61124b935460a01c16826122e3565b8261269b565b7fa5ffbdba01b15df97334e34ad816b9986b6057a5ddc97aba93b7e8ccd21759ed600080a3005b630a606ec360e11b60005260046000fd5b5082331415611229565b6360eb6c2360e01b60005260046000fd5b6001915060a01c1615846111fd565b604036600319011261029a576112c161207a565b602435906001600160401b03821161029a573660238301121561029a578160040135906112ed82612174565b916112fb6040519384612151565b8083526020830193366024838301011161029a57816000926024602093018737840101526001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001630811490811561156c575b5061118a576000546001600160a01b03163303610612576001600160a01b038116928315610f6457813b1561155b5730841461154c57600080516020612f4083398151915254846113a36121ed565b7f6ea8b34d59b2818d3f37a08dddaa06f5886b9c20c907b36f03ca6528e106e86f6113d9604051926040845260408401906121c8565b4260208401526001600160a01b038516929081900390a36040516352d1902d60e01b8152602081600481895afa60009181611518575b506114295785634c9c8ce360e01b60005260045260246000fd5b9081600080516020612f408339815191528793036115045750833b156114ef576001600160a01b0319168117600080516020612f40833981519152557fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b600080a28251156114d4576000809161069b945190845af43d156114cc573d916114af83612174565b926114bd6040519485612151565b83523d6000602085013e612e7e565b606091612e7e565b505050346114de57005b63b398979f60e01b60005260046000fd5b50634c9c8ce360e01b60005260045260246000fd5b632a87526960e21b60005260045260246000fd5b9091506020813d602011611544575b8161153460209383612151565b8101031261029a5751908761140f565b3d9150611527565b614e8d60eb1b60005260046000fd5b632e07c4bd60e11b60005260046000fd5b600080516020612f40833981519152546001600160a01b03161415905084611354565b3461029a57602036600319011261029a576004356115ab612795565b6115cd6115b7826127e0565b9190600263ffffffff825460a01c1617906122e3565b6001600160a01b0316907fc2713e691344add4705edc62a0ee5aede95ba66ad68f97316efef9cb50644edd600080a3005b3461029a57600036600319011261029a57336000908152600080516020612f60833981519152602052604090205460ff1615806116e1575b6116d0576000805160206130008339815191525460ff8116156116bf5760ff1916600080516020613000833981519152557f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa6020604051338152a16040514281527f107553d8191d85b405879cf752997865edd48d94e20bda4dd27223c94b31a7cc60203392a2005b638dfc202b60e01b60005260046000fd5b63659a07b360e11b60005260046000fd5b506000546001600160a01b0316331415611636565b3461029a57604036600319011261029a5761029661171d611715612064565b600435612306565b604093919351938493846120dc565b3461029a57604036600319011261029a57611745612064565b336001600160a01b038216036117615761069b90600435612751565b63334bd91960e11b60005260046000fd5b3461029a57602036600319011261029a57600435604060008281526004602052209081549160018060a01b038316928315908115611837575b5061128d57336000908152600080516020612f60833981519152602052604090205460ff16158061182d575b61127257806117f363fffffff7611806935460a01c16826122e3565b80546001600160e01b031681558261269b565b7f054490ec6650e07db9b97a06ea31d44cebd44b390c9975a380055e1b4d3cac21600080a3005b50823314156117d7565b6008915060a01c1615846117ab565b3461029a57604036600319011261029a5761069b600435611865612064565b90611872610691826122c2565b612709565b3461029a57602036600319011261029a576004356118c161189782612629565b91906118ad63fffffffb825460a01c16826122e3565b805463ffffffff60c01b191681558361269b565b6001600160a01b0316907f09cb4ec44cdef8489412844b9682f87f7900758fa2bd7e039113e9125e538e0f600080a3005b3461029a57602036600319011261029a57600435604060008281526004602052209081549160018060a01b0383169283159081156119a4575b5061128d57336000908152600080516020612f60833981519152602052604090205460ff16158061199a575b611272578061124563fffffffd611973935460a01c16826122e3565b7fb390ab029eab314bd18190ebe73d7e5c1c336beaa5c83ac22578378dc9ccc405600080a3005b5082331415611957565b6002915060a01c16158461192b565b3461029a57602036600319011261029a5760206119d16004356122c2565b604051908152f35b3461029a57604036600319011261029a5761029661171d6119f8612064565b60043561224a565b3461029a57604036600319011261029a57600435611a1c6120c9565b63ffffffff600554169063ffffffff811691808310908115611ac8575b5061049b57611a4783612629565b909263ffffffff845460c01c16809260018060a01b03163314159182611abd575b5050611aac57611a98827e8a218591d4362499c38c38eb1c12e7a7cc97a9068818d1fe6046a42ba4a5ba94612210565b611aa760405192839283612233565b0390a2005b634e80a40760e11b60005260046000fd5b111590508186611a68565b90501584611a39565b3461029a57602036600319011261029a57611aea6120b6565b6000805160206130208339815191525460ff8160401c16908115611bca575b50611bb957600080516020613020833981519152805460026001600160401b0319821681179092556000546001600160481b031990911690911791906001600160a01b031633036106125763ffffffff168015610ea757604081600080516020612fa08339815191529263ffffffff196005541617600555815190600082526020820152a160008051602061302083398151915255600080516020612f00833981519152602060405160028152a1005b63f92ee8a960e01b60005260046000fd5b60026001600160401b03919091161015905082611b09565b3461029a5760a036600319011261029a57611bfb61207a565b611c03612064565b906044356001600160a01b03811680820361029a576064356001600160a01b0381169182820361029a576084356001600160a01b038116949085900361029a5760008051602061302083398151915254604081901c60ff161596906001600160401b031680159081611f80575b6001149081611f76575b159081611f6d575b50611bb95760008051602061302083398151915280546001600160401b031916600117905586611f48575b611cb5612acc565b611cbd612acc565b611cc5612acc565b611ccd612acc565b6001600160a01b038116908115610f64578315610f64578515610f64576001600160a01b038916988915610f64573b15610f5357858414611f375762aa36a746148015611f2c575b8015611f21575b1580611f0f575b610f5357611d32906000612afa565b9081611ec8575b5015611e0d57611d5790600080516020612fe0833981519152612afa565b9081611e73575b5015611e0d57611d7c90600080516020612f20833981519152612afa565b9081611e1e575b5015611e0d57600080546001600160a01b031916841781556040519390600080516020612f808339815191528180a38015610f6457803b15610f5357600380546001600160a01b031916919091179055611dd957005b600080516020613020833981519152805460ff60401b1916905560018152600080516020612f0083398151915290602090a1005b63cf5a8e3360e01b60005260046000fd5b600080516020612f20833981519152600052600080516020612ee0833981519152602052611e6c907ffff5b43478fa6840382eb63777e0da6941d320b940e3f70f0ea4780feff95827612d3a565b5084611d83565b600080516020612fe0833981519152600052600080516020612ee0833981519152602052611ec1907f32d31393d541a265984ec379cddd8b1fcbe5f2b0eb8ad81dddfead454f135eaa612d3a565b5086611d5e565b60008052600080516020612ee0833981519152602052611f08907f615f0f9e84155bea8cc509fe18befeb1baf65611e38a6ba60964480fb29dfd44612d3a565b5088611d39565b50823b1580611d235750843b15611d23565b50617a694614611d1c565b506105394614611d15565b638135316560e01b60005260046000fd5b600080516020613020833981519152805460ff60401b1916600160401b179055611cad565b90501589611c82565b303b159150611c7a565b889150611c70565b3461029a57604036600319011261029a57610296611fbc611fa7612064565b600435600052600460205260406000206123c8565b611fc581612090565b60405191818392158361209a565b3461029a57600036600319011261029a57602063ffffffff60055416604051908152f35b3461029a57602036600319011261029a576004359063ffffffff60e01b821680920361029a57602091635a05180f60e01b8114908115612039575b5015158152f35b637965db0b60e01b811491508115612053575b5083612032565b6301ffc9a760e01b1490508361204c565b602435906001600160a01b038216820361029a57565b600435906001600160a01b038216820361029a57565b600811156103b857565b9015158152604081019291906020906120b283612090565b0152565b6004359063ffffffff8216820361029a57565b6024359063ffffffff8216820361029a57565b91604091949363ffffffff916060850196151585526120fa81612090565b602085015216910152565b60a081019081106001600160401b0382111761212057604052565b634e487b7160e01b600052604160045260246000fd5b608081019081106001600160401b0382111761212057604052565b601f909101601f19168101906001600160401b0382119082101761212057604052565b6001600160401b03811161212057601f01601f191660200190565b604435906001600160401b038216820361029a57565b60005b8381106121b85750506000910152565b81810151838201526020016121a8565b906020916121e1815180928185528580860191016121a5565b601f01601f1916010190565b604051906121fc604083612151565b60058252640322e312e360dc1b6020830152565b805463ffffffff60c01b191660c09290921b63ffffffff60c01b16919091179055565b63ffffffff91821681529116602082015260400190565b600052600460205261226160406000209182612485565b61226a81612090565b806122b857505460e01c63ffffffff60055416811580156122b0575b6122a35780821061229c57505b60019160009190565b9050612293565b5050600090600390600090565b508015612286565b6000929091508290565b600052600080516020612fc083398151915260205260016040600020015490565b805463ffffffff60a01b191660a09290921b63ffffffff60a01b16919091179055565b919091600052600460205261232060406000209283612511565b9161232a83612090565b826123625763ffffffff9192505460c01c1663ffffffff60055416811580156122b0576122a35780821061229c575060019160009190565b5060009190600090565b90612383916000526004602052604060002061259d565b61238c81612090565b8061239a5750600190600090565b600091565b8054600160a01b600160e01b03191660a09290921b600160a01b600160e01b0316919091179055565b60ff600080516020613000833981519152541661247e57546001600160a01b0381169081156124765760a01c6002161561246f5760005260016020526040600020549060ff8260e01c1660038110156103b857801561246757600214612460574260a083901c6001600160401b03161115612459576001600160a01b0390811691160361245457600090565b600790565b5050600690565b5050600590565b505050600490565b5050600390565b505050600290565b5050600190565b60ff600080516020613000833981519152541661247e57546001600160a01b0381169081156124765760a01c6008161561246f5760005260016020526040600020549060ff8260e01c1660038110156103b857801561246757600214612460574260a083901c6001600160401b03161115612459576001600160a01b0390811691160361245457600090565b60ff600080516020613000833981519152541661247e57546001600160a01b0381169081156124765760a01c6004161561246f5760005260016020526040600020549060ff8260e01c1660038110156103b857801561246757600214612460574260a083901c6001600160401b03161115612459576001600160a01b0390811691160361245457600090565b60ff600080516020613000833981519152541661247e57546001600160a01b0381169081156124765760a01c6001161561246f5760005260016020526040600020549060ff8260e01c1660038110156103b857801561246757600214612460574260a083901c6001600160401b03161115612459576001600160a01b0390811691160361245457600090565b6000908152600460205260409020805490916001600160a01b03821691821590811561268c575b5061128d57336000908152600080516020612f60833981519152602052604090205460ff161580612682575b61127257565b508133141561267c565b6004915060a01c161538612650565b905460a01c63ffffffff16156126ae5750565b600052600460205260006040812055565b6000818152600080516020612fc08339815191526020908152604080832033845290915290205460ff16156126f15750565b63e2517d3f60e01b6000523360045260245260446000fd5b6127138282612afa565b918261271e57505090565b6000918252600080516020612ee0833981519152602052604090912061274d916001600160a01b031690612d3a565b5090565b61275b8282612ba3565b918261276657505090565b6000918252600080516020612ee0833981519152602052604090912061274d916001600160a01b031690612dab565b60ff60008051602061300083398151915254166127ae57565b63d93c066560e01b60005260046000fd5b519064ffffffffff8216820361029a57565b519061ffff8216820361029a57565b8015612abb57600354604051638d34875560e01b8152600481018390529190600090839060249082906001600160a01b03165afa918215612aaf57600092612904575b5060808201516001600160a01b0316913383900361127257610120015161284981612090565b61285281612090565b600381149081156128ef575b81156128db575b506128ca5781600052600160205260ff60406000205460e01c1660038110156103b8576001036128b957600090815260046020526040902080546001600160a01b0319166001600160a01b03831617815591565b632e68d1d360e21b60005260046000fd5b63e9f6db8560e01b60005260046000fd5b600791506128e881612090565b1438612865565b90506128fa81612090565b600581149061285e565b90913d8082843e6129158184612151565b820191602081840312612a8f578051906001600160401b038211612a975701906101a082840312612a8c57604051926101a084016001600160401b03811185821017612a9b5760409081528351855260208085015190860152838101519085015260608301516001600160401b038111612a9757830181601f82011215612a97578051906129a282612174565b926129b06040519485612151565b82845260208383010111612a9357906129cf91602080850191016121a5565b606084015260808201516001600160a01b0381168103612a8f5760808401526129fa60a083016127bf565b60a0840152612a0b60c083016127bf565b60c0840152612a1c60e083016127d1565b60e0840152612a2e61010083016127bf565b610100840152610120820151906008821015612a8c5750612a7f9161018091610120850152612a6061014082016127bf565b610140850152612a7361016082016127d1565b610160850152016127bf565b6101808201529038612823565b80fd5b5080fd5b8380fd5b8280fd5b634e487b7160e01b83526041600452602483fd5b6040513d6000823e3d90fd5b637bb0b62160e01b60005260046000fd5b60ff6000805160206130208339815191525460401c1615612ae957565b631afcd79f60e31b60005260046000fd5b6000818152600080516020612fc0833981519152602090815260408083206001600160a01b038616845290915290205460ff16612b9c576000818152600080516020612fc0833981519152602090815260408083206001600160a01b0395909516808452949091528120805460ff19166001179055339291907f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d9080a4600190565b5050600090565b6000818152600080516020612fc0833981519152602090815260408083206001600160a01b038616845290915290205460ff1615612b9c576000818152600080516020612fc0833981519152602090815260408083206001600160a01b0395909516808452949091528120805460ff19169055339291907ff6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b9080a4600190565b158015612cfb575b610f64576001600160a01b0316600090815260026020526040902054612cea576001600160401b031642811115612cd95760005460a01c6001600160401b03168015159182612cae575b5050612c9d57565b63e774e7b560e01b60005260046000fd5b909150428103908111612cc357113880612c95565b634e487b7160e01b600052601160045260246000fd5b63efa7aefd60e01b60005260046000fd5b633b53f64f60e21b60005260046000fd5b506001600160a01b03811615612c4b565b8054821015612d245760005260206000200190600090565b634e487b7160e01b600052603260045260246000fd5b6001810190826000528160205260406000205415600014612da3578054600160401b81101561212057612d8e612d77826001879401855584612d0c565b819391549060031b91821b91600019901b19161790565b90555491600052602052604060002055600190565b505050600090565b9060018201918160005282602052604060002054801515600014612e75576000198101818111612cc3578254600019810191908211612cc357818103612e3e575b50505080548015612e28576000190190612e068282612d0c565b8154906000199060031b1b191690555560005260205260006040812055600190565b634e487b7160e01b600052603160045260246000fd5b612e5e612e4e612d779386612d0c565b90549060031b1c92839286612d0c565b905560005283602052604060002055388080612dec565b50505050600090565b90612ea45750805115612e9357602081519101fd5b63d6bda27560e01b60005260046000fd5b81511580612ed6575b612eb5575090565b639996b31560e01b60009081526001600160a01b0391909116600452602490fd5b50803b15612ead56fec1f6fe24621ce81ec5827caf0253cadb74709b061630e6b55e82371705932000c7f505b2f371ae2175ee4913f4499e1f2633a7b5936321eed1cdaeb6115181d275027301df982f5215b4963a854cf9c73219df80cb6acd8f098189c9480c7bbc360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc07966f2ab141347034724e9b2a472c2f77f5cd745aeba27cacba797b8fcb708617dc5b1290f7495d7f8cc68476e6941aaf510598fa925d0d2720edc8805a846cd37bc77615afefc793aa17d75d4249a9b517ba91b0e54a49c9c4a44b3d7e228302dd7bc7dec4dceedda775e58dd541e08a116c6c53815c0bd028192f7b626800edcc084d3dcd65a1f7f23c65c46722faca6953d28e43150a467cf43e5c309238cd5ed15c6e187e77e9aee88184c21f4f2182ab5827cb3b7e07fbedcd63f03300f0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a00a164736f6c6343000822000a";
19629
+ var _bytecode2 = "0x60a080604052346100ea57306080527ff0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a005460ff8160401c166100d9576002600160401b03196001600160401b03821601610073575b60405161394690816100f082396080518181816112d4015261148b0152f35b6001600160401b0319166001600160401b039081177ff0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a005581527fc7f505b2f371ae2175ee4913f4499e1f2633a7b5936321eed1cdaeb6115181d290602090a13880610054565b63f92ee8a960e01b60005260046000fd5b600080fdfe608080604052600436101561001357600080fd5b60003560e01c90816301ffc9a7146124f5575080630d33f3c2146124d15780630f3f4a94146124865780631459457a14611d3e57806318c38b8914611c2d5780631d44454114611b5c5780632106764c14611b35578063248a9ca314611b175780632ec22d4c14611a565780632f0647ce146119db5780632f2ff15d146119aa57806332420744146118d657806336568abe14611890578063392f10871461185a5780633f4ba83a146117625780633f5aadc9146116f35780634f1ef2861461143d57806352340363146113545780635273b6f61461132b57806352d1902d146112c1578063554c4f4b146112315780635bc26aea146111a45780635c975abb146111745780636289d18c146110f35780636711cc0b146110d75780636e852a7814610fd65780637e35bf6e14610fa25780638343f67414610f755780638456cb5914610e7f57806384b0196e14610d545780638c02cabd14610d2b5780638f33527f14610cf15780639010d07c14610c9d57806391d1485414610c435780639b9d30c114610c1a578063a19af3f614610b69578063a217fddf14610b4d578063a3246ad314610a8b578063a878086414610a6f578063ac3c0e3014610962578063ad3cb1cc1461091b578063b3fad63814610876578063b48d36de14610842578063c040b8ae14610726578063c34e9c261461070a578063c86deb31146106ee578063ca15c873146106b5578063d547741f1461067d578063dd71d99a1461063b578063e0922fa11461058e578063efa9b4ae1461051f578063f2f4eb26146104f6578063f68e9553146104cd578063f94f67ab146103f6578063fcc1f21a146102c05763ffa1ad741461028757600080fd5b346102bb5760003660031901126102bb576102b76102a3612780565b6040519182916020835260208301906126d1565b0390f35b600080fd5b346102bb576102ce366126f6565b91926102d8612e42565b6001600160a01b03851692338490036103e657836000526001602052604060002080549160ff8360e01c1660038110156103d0576001036103bf577fc5d5c5bbf10444998e0ea6d4725e79027b574e1c14ec929279e8a9a95c6c6e91948460016103a2946103498b6020998c613385565b818060a01b038316828060a01b03198254161781556103688b82612a4c565b0180546001600160401b031916426001600160401b03161790556001600160a01b0381166000818152600288526040902089905599613179565b6040516001600160401b0390951685526001600160a01b031693a4005b632437e77160e11b60005260046000fd5b634e487b7160e01b600052602160045260246000fd5b62fca64560e31b60005260046000fd5b346102bb5760403660031901126102bb576004356104126125c7565b9061041b612e42565b63ffffffff600554169163ffffffff8116928084109081156104c4575b506104b35760207f6b7727cc9c3df4a29acf0afe01594c1b7e845d20f40f4a14e4c292164a9ed8e19161046a84612e8d565b91610482600863ffffffff845460a01c1617836128c8565b81546001600160e01b031660e09190911b6001600160e01b0319161790556040519485526001600160a01b031693a3005b634346c13160e01b60005260046000fd5b90501584610438565b346102bb5760003660031901126102bb5760206040516000805160206138ba8339815191528152f35b346102bb5760003660031901126102bb576003546040516001600160a01b039091168152602090f35b346102bb5760203660031901126102bb5760043561053b612e42565b61055d61054782612e8d565b9190600163ffffffff825460a01c1617906128c8565b6001600160a01b0316907f812690e0a9dff5bf3add998111b8af5c8299608d859025bfe35662060ab4267d600080a3005b346102bb5760203660031901126102bb576004356001600160401b038116908181036102bb576000546001600160a01b038116330361062a57600160a01b600160e01b0319811660a092831b600160a01b600160e01b031617600055604080519190921c6001600160401b0316815260208101929092527f9c195448332abd01f716db873b329752ea02f19d33f7e311fb0daf082c4edd0391a1005b6349db3bd360e01b60005260046000fd5b346102bb5760203660031901126102bb576001600160a01b0361065c612578565b166000526002602052602060018060a01b0360406000205416604051908152f35b346102bb5760403660031901126102bb576106b360043561069c612562565b906106ae6106a9826128a7565b612d6c565b612dfe565b005b346102bb5760203660031901126102bb5760043560005260008051602061373a8339815191526020526020604060002054604051908152f35b346102bb5760003660031901126102bb57602060405160088152f35b346102bb5760003660031901126102bb57602060405160028152f35b346102bb57610734366126f6565b92909161073f612e42565b6001600160a01b03851693338590036103e65784600052600160205260406000209060ff825460e01c1660038110156103d057600114610831577ff223dc085722c94c84dcf67427e225799be616382a2a484d378f8921c69a2033948461081e936107ad866020988b613385565b80546001600160a01b0319166001600160a01b0383161781556107d08682612a4c565b6001810180546001600160801b031916426001600160401b0316179055805460ff60e01b1916600160e01b1790556001600160a01b0381166000818152600288526040902089905598613179565b6040516001600160401b039091168152a3005b639d2c8fdf60e01b60005260046000fd5b346102bb5760403660031901126102bb57602061086e610860612578565b610868612562565b90612984565b604051908152f35b346102bb5760203660031901126102bb57600060606040516108978161261e565b828152826020820152826040820152015260043560005260046020526080604060002063ffffffff604051916108cc8361261e565b548160018060a01b038216938481528160208201818560a01c16815260606040840193838760c01c168552019460e01c8552604051968752511660208601525116604084015251166060820152f35b346102bb5760003660031901126102bb576102b7604080519061093e8183612639565b60058252640352e302e360dc1b6020830152519182916020835260208301906126d1565b346102bb5760203660031901126102bb5761097b612578565b6000608060405161098b81612603565b828152826020820152826040820152826060820152015260018060a01b0316600052600160205260406000206040516109c381612603565b81546001600160a01b038116825260a081901c6001600160401b03166020830190815292604083019160e01c60ff169060038210156103d057908252600101546001600160401b0380821660608501908152604092831c821660808601908152925194516001600160a01b03168552945116602084015290519260038410156103d057604083019390935291516001600160401b0390811660608301529151909116608082015260a090f35b346102bb5760003660031901126102bb57602060405160018152f35b346102bb5760203660031901126102bb5760043560005260008051602061373a83398151915260205260406000206040518060208354918281520190819360005260206000209060005b818110610b375750505081610aeb910382612639565b6040519182916020830190602084525180915260408301919060005b818110610b15575050500390f35b82516001600160a01b0316845285945060209384019390920191600101610b07565b8254845260209093019260019283019201610ad5565b346102bb5760003660031901126102bb57602060405160008152f35b346102bb5760403660031901126102bb57600435610b856125c7565b90610b8e612e42565b63ffffffff600554169163ffffffff811692808410908115610c11575b506104b35760207f1da95b87b4c773f68c1447ffc5644e41a8a8887d55065beb64852014cf7140be91610bfe610be085612e8d565b9290610bf9600463ffffffff835460a01c1617826128c8565b6127f5565b6040519485526001600160a01b031693a3005b90501584610bab565b346102bb5760003660031901126102bb5760206040516000805160206137fa8339815191528152f35b346102bb5760403660031901126102bb57610c5c612562565b60043560005260008051602061389a83398151915260205260406000209060018060a01b0316600052602052602060ff604060002054166040519015158152f35b346102bb5760403660031901126102bb5760043560005260008051602061373a8339815191526020526020610cd86024356040600020613357565b905460405160039290921b1c6001600160a01b03168152f35b346102bb5760203660031901126102bb576001600160a01b03610d12612578565b1660005260026020526020604060002054604051908152f35b346102bb5760003660031901126102bb5760206040516000805160206137da8339815191528152f35b346102bb5760003660031901126102bb576000805160206137ba833981519152541580610e68575b15610e2b57610dcd610d8c6127a3565b610d946127d6565b6020610ddb60405192610da78385612639565b600084526000368137604051958695600f60f81b875260e08588015260e08701906126d1565b9085820360408701526126d1565b466060850152306080850152600060a085015283810360c085015281808451928381520193019160005b828110610e1457505050500390f35b835185528695509381019392810192600101610e05565b60405162461bcd60e51b81526020600482015260156024820152741152540dcc4c8e88155b9a5b9a5d1a585b1a5e9959605a1b6044820152606490fd5b5060008051602061391a8339815191525415610d7c565b346102bb5760003660031901126102bb573360009081527f0ac8cc3d209806126662940717264973110c39045b305f6ba49613325a615e09602052604090205460ff1615610f4e57610ecf612e42565b600160ff196000805160206138da8339815191525416176000805160206138da833981519152557f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a2586020604051338152a16040514281527f80170b5fcdd2bf1e0660ef4b8851f86685f64d41b1a19de1471947ece8725aac60203392a2005b63e2517d3f60e01b600052336004526000805160206137fa83398151915260245260446000fd5b346102bb5760003660031901126102bb5760005460405160a09190911c6001600160401b03168152602090f35b346102bb5760403660031901126102bb57610fc6610fbe612562565b600435612951565b906102b760405192839283612598565b346102bb5760403660031901126102bb57610fef612578565b33600090815260008051602061383a833981519152602052604090205460ff1615806110c4575b6103e6576001600160a01b03166000818152600160205260409020805460e01c60ff1660038110156103d0576001036103bf57805460ff60e01b198116600160e11b1782556001919091018054600160401b600160801b03191642604090811b600160401b600160801b0316919091179091555160243581526001600160a01b0390911691907fc0499cc07ed9d734deec6857802d3f0fa8d5afaf79a7008beb8ba7bef62a271b90602090a3005b50336001600160a01b0382161415611016565b346102bb5760003660031901126102bb57602060405160048152f35b346102bb5760203660031901126102bb5761110c6125b4565b6000546001600160a01b0316330361062a5763ffffffff81169081156111635760008051602061387a8339815191529161115e63ffffffff926005549284198416176005556040519384931683612818565b0390a1005b6338f3377360e21b60005260046000fd5b346102bb5760003660031901126102bb57602060ff6000805160206138da83398151915254166040519015158152f35b346102bb5760203660031901126102bb576111bd612578565b6000546001600160a01b038116903382900361062a576001600160a01b038316928315611220573b1561120f576001600160a01b0319168217600090815560008051602061385a8339815191529080a3005b636f7c43f160e01b60005260046000fd5b63e6c4247b60e01b60005260046000fd5b346102bb5760203660031901126102bb576001600160a01b03611252612578565b166000526001602052604060002060ff6000805160206138da833981519152541615806112a5575b6020918161128e575b506040519015158152f35b5460a01c6001600160401b03164210905082611283565b5060ff815460e01c169060038210156103d0579060011461127a565b346102bb5760003660031901126102bb577f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316300361131a57602060405160008051602061381a8339815191528152f35b63703e46dd60e11b60005260046000fd5b346102bb5760003660031901126102bb576000546040516001600160a01b039091168152602090f35b346102bb5760203660031901126102bb57600435604060008281526004602052209081549160018060a01b03831692831590811561142e575b5061141d5733600090815260008051602061383a833981519152602052604090205460ff161580611413575b61140257806113d563fffffffe6113db935460a01c16826128c8565b82612d48565b7fa5ffbdba01b15df97334e34ad816b9986b6057a5ddc97aba93b7e8ccd21759ed600080a3005b630a606ec360e11b60005260046000fd5b50823314156113b9565b6360eb6c2360e01b60005260046000fd5b6001915060a01c16158461138d565b60403660031901126102bb57611451612578565b6024356001600160401b0381116102bb57366023820112156102bb57611481903690602481600401359101612677565b6001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000163081149081156116d0575b5061131a576000546001600160a01b0316330361062a576001600160a01b03821691821561122057803b156116bf573083146116b05760008051602061381a8339815191525483611505612780565b7f6ea8b34d59b2818d3f37a08dddaa06f5886b9c20c907b36f03ca6528e106e86f61153b604051926040845260408401906126d1565b4260208401526001600160a01b038516929081900390a36040516352d1902d60e01b8152602081600481885afa6000918161167c575b5061158b5784634c9c8ce360e01b60005260045260246000fd5b908160008051602061381a8339815191528693036116685750823b15611653576001600160a01b031916811760008051602061381a833981519152557fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b600080a2815115611639576000808360206106b395519101845af43d15611631573d916116148361265c565b926116226040519485612639565b83523d6000602085013e61364d565b60609161364d565b50503461164257005b63b398979f60e01b60005260046000fd5b50634c9c8ce360e01b60005260045260246000fd5b632a87526960e21b60005260045260246000fd5b9091506020813d6020116116a8575b8161169860209383612639565b810103126102bb57519086611571565b3d915061168b565b614e8d60eb1b60005260046000fd5b632e07c4bd60e11b60005260046000fd5b60008051602061381a833981519152546001600160a01b031614159050836114b6565b346102bb5760203660031901126102bb5760043561170f612e42565b61173161171b82612e8d565b9190600263ffffffff825460a01c1617906128c8565b6001600160a01b0316907fc2713e691344add4705edc62a0ee5aede95ba66ad68f97316efef9cb50644edd600080a3005b346102bb5760003660031901126102bb5733600090815260008051602061383a833981519152602052604090205460ff161580611845575b611834576000805160206138da8339815191525460ff8116156118235760ff19166000805160206138da833981519152557f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa6020604051338152a16040514281527f107553d8191d85b405879cf752997865edd48d94e20bda4dd27223c94b31a7cc60203392a2005b638dfc202b60e01b60005260046000fd5b63659a07b360e11b60005260046000fd5b506000546001600160a01b031633141561179a565b346102bb5760403660031901126102bb576102b7611881611879612562565b6004356128eb565b604093919351938493846125da565b346102bb5760403660031901126102bb576118a9612562565b336001600160a01b038216036118c5576106b390600435612dfe565b63334bd91960e11b60005260046000fd5b346102bb5760203660031901126102bb57600435604060008281526004602052209081549160018060a01b03831692831590811561199b575b5061141d5733600090815260008051602061383a833981519152602052604090205460ff161580611991575b611402578061195763fffffff761196a935460a01c16826128c8565b80546001600160e01b0316815582612d48565b7f054490ec6650e07db9b97a06ea31d44cebd44b390c9975a380055e1b4d3cac21600080a3005b508233141561193b565b6008915060a01c16158461190f565b346102bb5760403660031901126102bb576106b36004356119c9612562565b906119d66106a9826128a7565b612db6565b346102bb5760203660031901126102bb57600435611a256119fb82612cd6565b9190611a1163fffffffb825460a01c16826128c8565b805463ffffffff60c01b1916815583612d48565b6001600160a01b0316907f09cb4ec44cdef8489412844b9682f87f7900758fa2bd7e039113e9125e538e0f600080a3005b346102bb5760203660031901126102bb57600435604060008281526004602052209081549160018060a01b038316928315908115611b08575b5061141d5733600090815260008051602061383a833981519152602052604090205460ff161580611afe575b61140257806113d563fffffffd611ad7935460a01c16826128c8565b7fb390ab029eab314bd18190ebe73d7e5c1c336beaa5c83ac22578378dc9ccc405600080a3005b5082331415611abb565b6002915060a01c161584611a8f565b346102bb5760203660031901126102bb57602061086e6004356128a7565b346102bb5760403660031901126102bb576102b7611881611b54612562565b60043561282f565b346102bb5760403660031901126102bb57600435611b786125c7565b63ffffffff600554169063ffffffff811691808310908115611c24575b506104b357611ba383612cd6565b909263ffffffff845460c01c16809260018060a01b03163314159182611c19575b5050611c0857611bf4827e8a218591d4362499c38c38eb1c12e7a7cc97a9068818d1fe6046a42ba4a5ba946127f5565b611c0360405192839283612818565b0390a2005b634e80a40760e11b60005260046000fd5b111590508186611bc4565b90501584611b95565b346102bb5760203660031901126102bb57611c466125b4565b6000805160206138fa8339815191525460ff8160401c16908115611d26575b50611d15576000805160206138fa833981519152805460026001600160401b0319821681179092556000546001600160481b031990911690911791906001600160a01b0316330361062a5763ffffffff1680156111635760408160008051602061387a8339815191529263ffffffff196005541617600555815190600082526020820152a16000805160206138fa8339815191525560008051602061377a833981519152602060405160028152a1005b63f92ee8a960e01b60005260046000fd5b60026001600160401b03919091161015905082611c65565b346102bb5760a03660031901126102bb57611d57612578565b611d5f612562565b604435906001600160a01b0382168083036102bb576064356001600160a01b038116918282036102bb576084356001600160a01b03811695908690036102bb576000805160206138fa83398151915254604081901c60ff161597906001600160401b03168015908161247e575b6001149081612474575b15908161246b575b50611d15576000805160206138fa83398151915280546001600160401b031916600117905587612446575b611e116131e0565b611e196131e0565b611e216131e0565b611e296131e0565b6001600160a01b038116908115611220578315611220578515611220576001600160a01b038716968715611220573b1561120f578584146124355762aa36a74614801561242a575b801561241f575b158061240d575b61120f57611e8e90600061320e565b90816123c6575b501561230b57611eb3906000805160206138ba83398151915261320e565b9081612371575b501561230b57611ed8906000805160206137fa83398151915261320e565b908161231c575b501561230b57600080546001600160a01b0319168217815560008051602061385a8339815191528180a3611f116127a3565b91611f1a6127d6565b91611f236131e0565b611f2b6131e0565b83516001600160401b0381116121e05760008051602061375a83398151915254600181811c91168015612301575b60208210146121c057601f8111612282575b50602094601f8211600114612201579481929394956000926121f6575b50508160011b916000199060031b1c19161760008051602061375a833981519152555b82516001600160401b0381116121e05760008051602061379a83398151915254600181811c911680156121d6575b60208210146121c057601f8111612141575b506020601f82116001146120c057819293946000926120b5575b50508160011b916000199060031b1c19161760008051602061379a833981519152555b60006000805160206137ba83398151915255600060008051602061391a83398151915255801561122057803b1561120f57600380546001600160a01b03191691909117905561207357005b60ff60401b196000805160206138fa83398151915254166000805160206138fa8339815191525560008051602061377a833981519152602060405160018152a1005b015190508480612005565b601f1982169060008051602061379a833981519152600052806000209160005b81811061212957509583600195969710612110575b505050811b0160008051602061379a83398151915255612028565b015160001960f88460031b161c191690558480806120f5565b9192602060018192868b0151815501940192016120e0565b81811115611feb5760008051602061379a833981519152600052601f820160051c7f5f9ce34815f8e11431c7bb75a8e6886a91478f7ffc1dbb0a98dc240fddd76b75602084106121b7575b81601f9101920160051c039060005b8281106121a9575050611feb565b60008282015560010161219b565b6000915061218c565b634e487b7160e01b600052602260045260246000fd5b90607f1690611fd9565b634e487b7160e01b600052604160045260246000fd5b015190508580611f88565b601f1982169560008051602061375a833981519152600052806000209160005b88811061226a57508360019596979810612251575b505050811b0160008051602061375a83398151915255611fab565b015160001960f88460031b161c19169055858080612236565b91926020600181928685015181550194019201612221565b81811115611f6b5760008051602061375a833981519152600052601f820160051c7f42ad5d3e1f2e6e70edcf6d991b8a3023d3fca8047a131592f9edb9fd9b89d57d602084106122f8575b81601f9101920160051c039060005b8281106122ea575050611f6b565b6000828201556001016122dc565b600091506122cd565b90607f1690611f59565b63cf5a8e3360e01b60005260046000fd5b6000805160206137fa83398151915260005260008051602061373a83398151915260205261236a907ffff5b43478fa6840382eb63777e0da6941d320b940e3f70f0ea4780feff9582761348a565b5084611edf565b6000805160206138ba83398151915260005260008051602061373a8339815191526020526123bf907f32d31393d541a265984ec379cddd8b1fcbe5f2b0eb8ad81dddfead454f135eaa61348a565b5086611eba565b6000805260008051602061373a833981519152602052612406907f615f0f9e84155bea8cc509fe18befeb1baf65611e38a6ba60964480fb29dfd4461348a565b5088611e95565b50823b1580611e7f5750843b15611e7f565b50617a694614611e78565b506105394614611e71565b638135316560e01b60005260046000fd5b6000805160206138fa833981519152805460ff60401b1916600160401b179055611e09565b90501589611dde565b303b159150611dd6565b899150611dcc565b346102bb5760403660031901126102bb576102b76124ba6124a5612562565b60043560005260046020526040600020612a75565b6124c38161258e565b604051918183921583612598565b346102bb5760003660031901126102bb57602063ffffffff60055416604051908152f35b346102bb5760203660031901126102bb576004359063ffffffff60e01b82168092036102bb57602091635a05180f60e01b8114908115612537575b5015158152f35b637965db0b60e01b811491508115612551575b5083612530565b6301ffc9a760e01b1490508361254a565b602435906001600160a01b03821682036102bb57565b600435906001600160a01b03821682036102bb57565b600811156103d057565b9015158152604081019291906020906125b08361258e565b0152565b6004359063ffffffff821682036102bb57565b6024359063ffffffff821682036102bb57565b91604091949363ffffffff916060850196151585526125f88161258e565b602085015216910152565b60a081019081106001600160401b038211176121e057604052565b608081019081106001600160401b038211176121e057604052565b601f909101601f19168101906001600160401b038211908210176121e057604052565b6001600160401b0381116121e057601f01601f191660200190565b9291926126838261265c565b916126916040519384612639565b8294818452818301116102bb578281602093846000960137010152565b60005b8381106126c15750506000910152565b81810151838201526020016126b1565b906020916126ea815180928185528580860191016126ae565b601f01601f1916010190565b60806003198201126102bb576004356001600160a01b03811681036102bb57916024356001600160a01b03811681036102bb57916044356001600160401b03811681036102bb57916064356001600160401b0381116102bb57826023820112156102bb576004810135926001600160401b0384116102bb57602484830101116102bb576024019190565b6040519061278f604083612639565b60058252640332e302e360dc1b6020830152565b604051906127b2604083612639565b6015825274111a585b5bdb9912185b991ccb941c9bdd1bd8dbdb605a1b6020830152565b604051906127e5604083612639565b60018252603160f81b6020830152565b805463ffffffff60c01b191660c09290921b63ffffffff60c01b16919091179055565b63ffffffff91821681529116602082015260400190565b600052600460205261284660406000209182612b32565b61284f8161258e565b8061289d57505460e01c63ffffffff6005541681158015612895575b6128885780821061288157505b60019160009190565b9050612878565b5050600090600390600090565b50801561286b565b6000929091508290565b60005260008051602061389a83398151915260205260016040600020015490565b805463ffffffff60a01b191660a09290921b63ffffffff60a01b16919091179055565b919091600052600460205261290560406000209283612bbe565b9161290f8361258e565b826129475763ffffffff9192505460c01c1663ffffffff60055416811580156128955761288857808210612881575060019160009190565b5060009190600090565b906129689160005260046020526040600020612c4a565b6129718161258e565b8061297f5750600190600090565b600091565b6042916040519060208201926000805160206137da833981519152845260018060a01b0316604083015260018060a01b03166060820152606081526129ca608082612639565b5190206129d56136ae565b6129dd613706565b6040519060208201927f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f8452604083015260608201524660808201523060a082015260a08152612a2e60c082612639565b519020906040519161190160f01b8352600283015260228201522090565b8054600160a01b600160e01b03191660a09290921b600160a01b600160e01b0316919091179055565b60ff6000805160206138da8339815191525416612b2b57546001600160a01b038116908115612b235760a01c60021615612b1c5760005260016020526040600020549060ff8260e01c1660038110156103d0578015612b1457600214612b0d574260a083901c6001600160401b03161115612b06576001600160a01b03908116911603612b0157600090565b600790565b5050600690565b5050600590565b505050600490565b5050600390565b505050600290565b5050600190565b60ff6000805160206138da8339815191525416612b2b57546001600160a01b038116908115612b235760a01c60081615612b1c5760005260016020526040600020549060ff8260e01c1660038110156103d0578015612b1457600214612b0d574260a083901c6001600160401b03161115612b06576001600160a01b03908116911603612b0157600090565b60ff6000805160206138da8339815191525416612b2b57546001600160a01b038116908115612b235760a01c60041615612b1c5760005260016020526040600020549060ff8260e01c1660038110156103d0578015612b1457600214612b0d574260a083901c6001600160401b03161115612b06576001600160a01b03908116911603612b0157600090565b60ff6000805160206138da8339815191525416612b2b57546001600160a01b038116908115612b235760a01c60011615612b1c5760005260016020526040600020549060ff8260e01c1660038110156103d0578015612b1457600214612b0d574260a083901c6001600160401b03161115612b06576001600160a01b03908116911603612b0157600090565b6000908152600460205260409020805490916001600160a01b038216918215908115612d39575b5061141d5733600090815260008051602061383a833981519152602052604090205460ff161580612d2f575b61140257565b5081331415612d29565b6004915060a01c161538612cfd565b905460a01c63ffffffff1615612d5b5750565b600052600460205260006040812055565b600081815260008051602061389a8339815191526020908152604080832033845290915290205460ff1615612d9e5750565b63e2517d3f60e01b6000523360045260245260446000fd5b612dc0828261320e565b9182612dcb57505090565b600091825260008051602061373a8339815191526020526040909120612dfa916001600160a01b03169061348a565b5090565b612e0882826132b7565b9182612e1357505090565b600091825260008051602061373a8339815191526020526040909120612dfa916001600160a01b0316906134fb565b60ff6000805160206138da8339815191525416612e5b57565b63d93c066560e01b60005260046000fd5b519064ffffffffff821682036102bb57565b519061ffff821682036102bb57565b801561316857600354604051638d34875560e01b8152600481018390529190600090839060249082906001600160a01b03165afa91821561315c57600092612fb1575b5060808201516001600160a01b03169133839003611402576101200151612ef68161258e565b612eff8161258e565b60038114908115612f9c575b8115612f88575b50612f775781600052600160205260ff60406000205460e01c1660038110156103d057600103612f6657600090815260046020526040902080546001600160a01b0319166001600160a01b03831617815591565b632e68d1d360e21b60005260046000fd5b63e9f6db8560e01b60005260046000fd5b60079150612f958161258e565b1438612f12565b9050612fa78161258e565b6005811490612f0b565b90913d8082843e612fc28184612639565b82019160208184031261313c578051906001600160401b0382116131445701906101a08284031261313957604051926101a084016001600160401b038111858210176131485760409081528351855260208085015190860152838101519085015260608301516001600160401b03811161314457830181601f820112156131445780519061304f8261265c565b9261305d6040519485612639565b82845260208383010111613140579061307c91602080850191016126ae565b606084015260808201516001600160a01b038116810361313c5760808401526130a760a08301612e6c565b60a08401526130b860c08301612e6c565b60c08401526130c960e08301612e7e565b60e08401526130db6101008301612e6c565b610100840152610120820151906008821015613139575061312c916101809161012085015261310d6101408201612e6c565b6101408501526131206101608201612e7e565b61016085015201612e6c565b6101808201529038612ed0565b80fd5b5080fd5b8380fd5b8280fd5b634e487b7160e01b83526041600452602483fd5b6040513d6000823e3d90fd5b637bb0b62160e01b60005260046000fd5b61319b9261318d8361319593969496612984565b923691612677565b9061344e565b5060048110156103d05715918215926131c8575b50506131b757565b63cacba36560e01b60005260046000fd5b6001600160a01b0391821691161415905038806131af565b60ff6000805160206138fa8339815191525460401c16156131fd57565b631afcd79f60e31b60005260046000fd5b600081815260008051602061389a833981519152602090815260408083206001600160a01b038616845290915290205460ff166132b057600081815260008051602061389a833981519152602090815260408083206001600160a01b0395909516808452949091528120805460ff19166001179055339291907f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d9080a4600190565b5050600090565b600081815260008051602061389a833981519152602090815260408083206001600160a01b038616845290915290205460ff16156132b057600081815260008051602061389a833981519152602090815260408083206001600160a01b0395909516808452949091528120805460ff19169055339291907ff6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b9080a4600190565b805482101561336f5760005260206000200190600090565b634e487b7160e01b600052603260045260246000fd5b15801561343d575b611220576001600160a01b031660009081526002602052604090205461342c576001600160401b03164281111561341b5760005460a01c6001600160401b031680151591826133f0575b50506133df57565b63e774e7b560e01b60005260046000fd5b909150428103908111613405571138806133d7565b634e487b7160e01b600052601160045260246000fd5b63efa7aefd60e01b60005260046000fd5b633b53f64f60e21b60005260046000fd5b506001600160a01b0381161561338d565b815191906041830361347f5761347892506020820151906060604084015193015160001a906135ce565b9192909190565b505060009160029190565b60018101908260005281602052604060002054156000146134f3578054600160401b8110156121e0576134de6134c7826001879401855584613357565b819391549060031b91821b91600019901b19161790565b90555491600052602052604060002055600190565b505050600090565b90600182019181600052826020526040600020548015156000146135c55760001981018181116134055782546000198101919082116134055781810361358e575b505050805480156135785760001901906135568282613357565b8154906000199060031b1b191690555560005260205260006040812055600190565b634e487b7160e01b600052603160045260246000fd5b6135ae61359e6134c79386613357565b90549060031b1c92839286613357565b90556000528360205260406000205538808061353c565b50505050600090565b91906fa2a8918ca85bafe22016d0b997e4df60600160ff1b038411613641579160209360809260ff60009560405194855216868401526040830152606082015282805260015afa1561315c576000516001600160a01b038116156136355790600090600090565b50600090600190600090565b50505060009160039190565b90613673575080511561366257602081519101fd5b63d6bda27560e01b60005260046000fd5b815115806136a5575b613684575090565b639996b31560e01b60009081526001600160a01b0391909116600452602490fd5b50803b1561367c565b6136b66127a3565b80519081156136c6576020012090565b50506000805160206137ba8339815191525480156136e15790565b507fc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a47090565b61370e6127d6565b805190811561371e576020012090565b505060008051602061391a8339815191525480156136e1579056fec1f6fe24621ce81ec5827caf0253cadb74709b061630e6b55e82371705932000a16a46d94261c7517cc8ff89f61c0ce93598e3c849801011dee649a6a557d102c7f505b2f371ae2175ee4913f4499e1f2633a7b5936321eed1cdaeb6115181d2a16a46d94261c7517cc8ff89f61c0ce93598e3c849801011dee649a6a557d103a16a46d94261c7517cc8ff89f61c0ce93598e3c849801011dee649a6a557d1002b26bde9d050a2447879fc2826d068ca8d51a693da5ddde56556964c09fea96875027301df982f5215b4963a854cf9c73219df80cb6acd8f098189c9480c7bbc360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc07966f2ab141347034724e9b2a472c2f77f5cd745aeba27cacba797b8fcb708617dc5b1290f7495d7f8cc68476e6941aaf510598fa925d0d2720edc8805a846cd37bc77615afefc793aa17d75d4249a9b517ba91b0e54a49c9c4a44b3d7e228302dd7bc7dec4dceedda775e58dd541e08a116c6c53815c0bd028192f7b626800edcc084d3dcd65a1f7f23c65c46722faca6953d28e43150a467cf43e5c309238cd5ed15c6e187e77e9aee88184c21f4f2182ab5827cb3b7e07fbedcd63f03300f0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a00a16a46d94261c7517cc8ff89f61c0ce93598e3c849801011dee649a6a557d101a164736f6c6343000822000a";
19189
19630
  var isSuperArgs2 = (xs) => xs.length > 1;
19190
19631
  var AgentDelegationRegistry__factory = class extends ContractFactory2 {
19191
19632
  constructor(...args) {
@@ -19210,7 +19651,7 @@ var AgentDelegationRegistry__factory = class extends ContractFactory2 {
19210
19651
  return new Interface4(_abi2);
19211
19652
  }
19212
19653
  static connect(address, runner) {
19213
- return new Contract7(
19654
+ return new Contract8(
19214
19655
  address,
19215
19656
  _abi2,
19216
19657
  runner
@@ -19219,7 +19660,7 @@ var AgentDelegationRegistry__factory = class extends ContractFactory2 {
19219
19660
  };
19220
19661
 
19221
19662
  // src/utils/position-delegate.utils.ts
19222
- import { Contract as Contract8 } from "ethers";
19663
+ import { Contract as Contract9 } from "ethers";
19223
19664
  var POSITION_DELEGATE_REGISTRY_ABI = [
19224
19665
  "function positionDelegate(bytes32 positionId) view returns (address)",
19225
19666
  "function isDelegate(bytes32 positionId, address delegate) view returns (bool)",
@@ -19238,7 +19679,7 @@ var DELEGATE_STATUS_ABI = [
19238
19679
  "function delegateStatus(bytes32 positionId, address delegate) view returns (bool ok, uint8 reason)"
19239
19680
  ];
19240
19681
  async function setPositionDelegate(positionId, delegate, signer, registryAddress) {
19241
- const registry = new Contract8(
19682
+ const registry = new Contract9(
19242
19683
  registryAddress,
19243
19684
  POSITION_DELEGATE_REGISTRY_ABI,
19244
19685
  signer
@@ -19246,7 +19687,7 @@ async function setPositionDelegate(positionId, delegate, signer, registryAddress
19246
19687
  return registry["setPositionDelegate"](positionId, delegate);
19247
19688
  }
19248
19689
  async function getPositionDelegate(positionId, provider, registryAddress) {
19249
- const registry = new Contract8(
19690
+ const registry = new Contract9(
19250
19691
  registryAddress,
19251
19692
  POSITION_DELEGATE_REGISTRY_ABI,
19252
19693
  provider
@@ -19254,7 +19695,7 @@ async function getPositionDelegate(positionId, provider, registryAddress) {
19254
19695
  return registry["positionDelegate"](positionId);
19255
19696
  }
19256
19697
  async function isPositionDelegate(positionId, delegate, provider, registryAddress) {
19257
- const registry = new Contract8(
19698
+ const registry = new Contract9(
19258
19699
  registryAddress,
19259
19700
  POSITION_DELEGATE_REGISTRY_ABI,
19260
19701
  provider
@@ -19262,7 +19703,7 @@ async function isPositionDelegate(positionId, delegate, provider, registryAddres
19262
19703
  return registry["isDelegate"](positionId, delegate);
19263
19704
  }
19264
19705
  async function getDelegateStatus(positionId, delegate, provider, registryAddress) {
19265
- const registry = new Contract8(
19706
+ const registry = new Contract9(
19266
19707
  registryAddress,
19267
19708
  DELEGATE_STATUS_ABI,
19268
19709
  provider
@@ -19277,6 +19718,12 @@ async function getDelegateStatus(positionId, delegate, provider, registryAddress
19277
19718
  }
19278
19719
 
19279
19720
  // src/utils/agent-delegation.utils.ts
19721
+ var AGENT_BINDING_CONSENT_TYPES = {
19722
+ AgentBindingConsent: [
19723
+ { name: "user", type: "address" },
19724
+ { name: "agent", type: "address" }
19725
+ ]
19726
+ };
19280
19727
  async function mintAgentPkp(params) {
19281
19728
  const { serviceEndpoint, authHeader, timeoutMs = 3e4 } = params;
19282
19729
  if (!serviceEndpoint) {
@@ -19309,7 +19756,12 @@ async function mintAgentPkp(params) {
19309
19756
  `Agent PKP mint returned no address: ${data.error ?? JSON.stringify(data)}`
19310
19757
  );
19311
19758
  }
19312
- return data.walletAddress;
19759
+ if (typeof data.agentConsent !== "string" || !/^0x[0-9a-fA-F]{130}$/.test(data.agentConsent)) {
19760
+ throw new Error(
19761
+ `Agent PKP mint returned no binding consent for ${data.walletAddress} \u2014 the server predates AgentDelegationRegistry 3.0.0, which cannot bind an agent without one`
19762
+ );
19763
+ }
19764
+ return { walletAddress: data.walletAddress, agentConsent: data.agentConsent };
19313
19765
  } finally {
19314
19766
  clearTimeout(timeout);
19315
19767
  }
@@ -20800,10 +21252,11 @@ var DiamondHandsSDK = class _DiamondHandsSDK {
20800
21252
  * from live chain state so a half-done ceremony resumes.
20801
21253
  *
20802
21254
  * Service-mode only — the server holds the Chipotle account that mints the
20803
- * PKP and it gates the route to current Safe owners. `knownAgentAddress` is
20804
- * the caller-persisted agent from an earlier prepare whose ceremony has not
20805
- * landed yet; echoing it back prevents a duplicate mint after a server
20806
- * restart.
21255
+ * PKP and it gates the route to current Safe owners. `knownAgentAddress` +
21256
+ * `knownAgentConsent` are the caller-persisted agent and its binding consent
21257
+ * from an earlier prepare whose ceremony has not landed yet; echoing them back
21258
+ * prevents a duplicate mint after a server restart. The server reuses an
21259
+ * address only with a consent that verifies for this Safe (issue #1197).
20807
21260
  */
20808
21261
  async prepareSafeAgentModule(request) {
20809
21262
  if (this.config.mode !== "service") {
@@ -20827,7 +21280,8 @@ var DiamondHandsSDK = class _DiamondHandsSDK {
20827
21280
  signal: abort.signal,
20828
21281
  body: JSON.stringify({
20829
21282
  safeAddress: request.safeAddress,
20830
- ...request.knownAgentAddress ? { knownAgentAddress: request.knownAgentAddress } : {}
21283
+ ...request.knownAgentAddress ? { knownAgentAddress: request.knownAgentAddress } : {},
21284
+ ...request.knownAgentConsent ? { knownAgentConsent: request.knownAgentConsent } : {}
20831
21285
  })
20832
21286
  }
20833
21287
  );
@@ -20844,9 +21298,21 @@ var DiamondHandsSDK = class _DiamondHandsSDK {
20844
21298
  `prepareSafeAgentModule failed (${resp.status}): ${data?.error ?? "no error detail from server"}`
20845
21299
  );
20846
21300
  }
21301
+ const selectors = data.calls.map((c) => c.data.slice(0, 10).toLowerCase());
21302
+ if (selectors.some((s) => s === "0x561b7f8a" || s === "0xfd437d39")) {
21303
+ throw new Error(
21304
+ "prepareSafeAgentModule returned a 3-argument registerAgent/rotateAgent \u2014 the delegation server predates AgentDelegationRegistry 3.0.0, which would revert it"
21305
+ );
21306
+ }
21307
+ if (selectors.some((s) => s === "0xc040b8ae" || s === "0xfcc1f21a") && typeof data.agentConsent !== "string") {
21308
+ throw new Error(
21309
+ "prepareSafeAgentModule returned a registration without the agent's binding consent"
21310
+ );
21311
+ }
20847
21312
  return {
20848
21313
  status: data.status,
20849
21314
  agentAddress: data.agentAddress,
21315
+ agentConsent: data.agentConsent ?? null,
20850
21316
  moduleAddress: data.moduleAddress,
20851
21317
  validUntil: data.validUntil,
20852
21318
  calls: data.calls
@@ -21859,6 +22325,14 @@ var DiamondHandsSDK = class _DiamondHandsSDK {
21859
22325
  }
21860
22326
  }
21861
22327
  async _requestMintUCDAttempt(request) {
22328
+ if (request.debugOverrides !== void 0) {
22329
+ throw new SDKError({
22330
+ code: "SDK_DEBUG_OVERRIDES_REMOVED",
22331
+ message: "debugOverrides is not supported: BTC stub mode was removed from the mint validator",
22332
+ category: "VALIDATION" /* VALIDATION */,
22333
+ severity: "MEDIUM" /* MEDIUM */
22334
+ });
22335
+ }
21862
22336
  try {
21863
22337
  if (this.config.debug) {
21864
22338
  log.info("\u{1FA99} Requesting UCD minting...", {});
@@ -22136,9 +22610,6 @@ var DiamondHandsSDK = class _DiamondHandsSDK {
22136
22610
  } : {},
22137
22611
  rpcUrl: request.rpcUrl || this.config.ethRpcUrl,
22138
22612
  // Pass RPC URL to LIT Action (ngrok for Hardhat)
22139
- ...request.debugOverrides && {
22140
- debugOverrides: request.debugOverrides
22141
- },
22142
22613
  ...this.config.priceProviders && {
22143
22614
  priceProviders: this.config.priceProviders
22144
22615
  }
@@ -22418,7 +22889,7 @@ var DiamondHandsSDK = class _DiamondHandsSDK {
22418
22889
  const coreAbi = [
22419
22890
  "function getPositionDetails(bytes32) view returns (tuple(bytes32 positionId, bytes32 pkpId, uint256 ucdDebt, string vaultAddress, address borrower, uint40 createdAt, uint40 lastUpdated, uint16 selectedTerm, uint40 expiryAt, uint8 status, uint40 previousExpiryAt, uint16 totalTerm))"
22420
22891
  ];
22421
- const positionCore = new Contract9(
22892
+ const positionCore = new Contract10(
22422
22893
  coreAddress,
22423
22894
  coreAbi,
22424
22895
  this.getSignerOrThrow().provider
@@ -22474,7 +22945,7 @@ var DiamondHandsSDK = class _DiamondHandsSDK {
22474
22945
  "function getCurrentQuantum() view returns (uint256)",
22475
22946
  "function isQuantumValid(bytes32,uint256) view returns (bool)"
22476
22947
  ];
22477
- const registry = new Contract9(
22948
+ const registry = new Contract10(
22478
22949
  registryAddress,
22479
22950
  registryAbi,
22480
22951
  this.getSignerOrThrow().provider
@@ -22626,7 +23097,7 @@ var DiamondHandsSDK = class _DiamondHandsSDK {
22626
23097
  if (viewsAddress) {
22627
23098
  let diagnosis = null;
22628
23099
  try {
22629
- const views = new Contract9(
23100
+ const views = new Contract10(
22630
23101
  viewsAddress,
22631
23102
  [
22632
23103
  "function diagnoseMintUCD(bytes32,uint256,uint256,uint256,uint256,uint256,bytes32,bytes32,bytes32,uint256,bytes) view returns (string)"
@@ -23338,7 +23809,7 @@ Message: ${causeMessage}${quantumContext}${loanCapDiagnostics}${mintDebtDiagnost
23338
23809
  }
23339
23810
  const loanOpsForUcd = loanOpsForUcdResult.value;
23340
23811
  const ucdTokenAddress = await loanOpsForUcd.ucdToken();
23341
- const ucdToken = new Contract9(
23812
+ const ucdToken = new Contract10(
23342
23813
  ucdTokenAddress,
23343
23814
  [
23344
23815
  "function balanceOf(address) view returns (uint256)",
@@ -24517,7 +24988,7 @@ Message: ${causeMessage}${quantumContext}${loanCapDiagnostics}${mintDebtDiagnost
24517
24988
  };
24518
24989
  }
24519
24990
  const ucdTokenAddress = await loanOps.ucdToken();
24520
- const ucdToken = new Contract9(
24991
+ const ucdToken = new Contract10(
24521
24992
  ucdTokenAddress,
24522
24993
  [
24523
24994
  "function balanceOf(address) view returns (uint256)",
@@ -25126,6 +25597,11 @@ Message: ${causeMessage}${quantumContext}${loanCapDiagnostics}${mintDebtDiagnost
25126
25597
  error: "Invalid withdrawal address"
25127
25598
  };
25128
25599
  }
25600
+ const caseError = bitcoinAddressCaseError(withdrawalAddress);
25601
+ if (caseError) {
25602
+ return { success: false, error: caseError };
25603
+ }
25604
+ withdrawalAddress = normalizeBitcoinAddress(withdrawalAddress);
25129
25605
  try {
25130
25606
  const btcNetwork = this.bitcoinOperations.getNetwork();
25131
25607
  safeValidateBitcoinAddress(withdrawalAddress.trim(), btcNetwork);
@@ -25175,7 +25651,7 @@ Message: ${causeMessage}${quantumContext}${loanCapDiagnostics}${mintDebtDiagnost
25175
25651
  const pkpId = position.pkpId;
25176
25652
  if (litValidatorAddr && pkpId) {
25177
25653
  try {
25178
- const litValidator = new Contract9(
25654
+ const litValidator = new Contract10(
25179
25655
  litValidatorAddr,
25180
25656
  ["function pkpOwners(bytes32) view returns (address)"],
25181
25657
  this.getProviderOrThrow()
@@ -26079,6 +26555,7 @@ Message: ${causeMessage}${quantumContext}${loanCapDiagnostics}${mintDebtDiagnost
26079
26555
  networkFee: request.networkFee,
26080
26556
  chainId,
26081
26557
  signer,
26558
+ provider: this.getProviderOrThrow(),
26082
26559
  ...executionUtxos ? { utxos: executionUtxos } : {}
26083
26560
  });
26084
26561
  if (this.config.mode !== "service") {
@@ -26231,8 +26708,8 @@ Message: ${causeMessage}${quantumContext}${loanCapDiagnostics}${mintDebtDiagnost
26231
26708
  });
26232
26709
  }
26233
26710
  const contractAddresses = this.getContractAddressesOrThrow();
26234
- const btcSpendAuthorizerAddress = contractAddresses.btcSpendAuthorizer;
26235
- if (!btcSpendAuthorizerAddress) {
26711
+ const btcSpendAuthorizerAddress2 = contractAddresses.btcSpendAuthorizer;
26712
+ if (!btcSpendAuthorizerAddress2) {
26236
26713
  return [
26237
26714
  {
26238
26715
  success: false,
@@ -26243,8 +26720,8 @@ Message: ${causeMessage}${quantumContext}${loanCapDiagnostics}${mintDebtDiagnost
26243
26720
  const btcSpendAuthorizerAbi = [
26244
26721
  "function getAuthorizedSpends(bytes32) view returns (tuple(string txid, uint32 vout, uint256 satoshis, string targetAddress, uint256 targetAmount, uint256 authorizedAt)[])"
26245
26722
  ];
26246
- const btcSpendAuthorizer = new Contract9(
26247
- btcSpendAuthorizerAddress,
26723
+ const btcSpendAuthorizer = new Contract10(
26724
+ btcSpendAuthorizerAddress2,
26248
26725
  btcSpendAuthorizerAbi,
26249
26726
  this.getProviderOrThrow()
26250
26727
  );
@@ -26270,7 +26747,9 @@ Message: ${causeMessage}${quantumContext}${loanCapDiagnostics}${mintDebtDiagnost
26270
26747
  const result = await this.executeBTCWithdrawal({
26271
26748
  positionId,
26272
26749
  utxoIdentifier,
26273
- utxoSatoshis: spend.satoshis,
26750
+ // uint256 decodes to bigint; the Phase-2 request is JSON-serialized, so a bigint
26751
+ // here failed every retry with "Do not know how to serialize a BigInt".
26752
+ utxoSatoshis: Number(spend.satoshis),
26274
26753
  networkFee,
26275
26754
  destination: spend.targetAddress,
26276
26755
  // CRIT-1: bind the on-chain-authorized targetAmount into the
@@ -26316,8 +26795,8 @@ Message: ${causeMessage}${quantumContext}${loanCapDiagnostics}${mintDebtDiagnost
26316
26795
  async getPendingWithdrawals(positionId) {
26317
26796
  this.ensureInitialized();
26318
26797
  const contractAddresses = this.getContractAddressesOrThrow();
26319
- const btcSpendAuthorizerAddress = contractAddresses.btcSpendAuthorizer;
26320
- if (!btcSpendAuthorizerAddress) {
26798
+ const btcSpendAuthorizerAddress2 = contractAddresses.btcSpendAuthorizer;
26799
+ if (!btcSpendAuthorizerAddress2) {
26321
26800
  throw new SDKError({
26322
26801
  code: "SDK_CONTRACT_ADDRESSES_NOT_CONFIGURED",
26323
26802
  message: "BTCSpendAuthorizer address not configured",
@@ -26329,8 +26808,8 @@ Message: ${causeMessage}${quantumContext}${loanCapDiagnostics}${mintDebtDiagnost
26329
26808
  const abi = [
26330
26809
  "function getAuthorizedSpends(bytes32) view returns (tuple(string txid, uint32 vout, uint256 satoshis, string targetAddress, uint256 targetAmount, uint256 authorizedAt)[])"
26331
26810
  ];
26332
- const contract = new Contract9(
26333
- btcSpendAuthorizerAddress,
26811
+ const contract = new Contract10(
26812
+ btcSpendAuthorizerAddress2,
26334
26813
  abi,
26335
26814
  this.getProviderOrThrow()
26336
26815
  );
@@ -26343,7 +26822,7 @@ Message: ${causeMessage}${quantumContext}${loanCapDiagnostics}${mintDebtDiagnost
26343
26822
  targetAddress: spend.targetAddress,
26344
26823
  targetAmount: Number(spend.targetAmount),
26345
26824
  authorizedAt: Number(spend.authorizedAt),
26346
- utxoKey: solidityPackedKeccak2564(
26825
+ utxoKey: solidityPackedKeccak2563(
26347
26826
  ["string", "uint32"],
26348
26827
  [spend.txid, Number(spend.vout)]
26349
26828
  )
@@ -26432,8 +26911,8 @@ Message: ${causeMessage}${quantumContext}${loanCapDiagnostics}${mintDebtDiagnost
26432
26911
  this.ensureInitialized();
26433
26912
  try {
26434
26913
  const contractAddresses = this.getContractAddressesOrThrow();
26435
- const btcSpendAuthorizerAddress = contractAddresses.btcSpendAuthorizer;
26436
- if (!btcSpendAuthorizerAddress) {
26914
+ const btcSpendAuthorizerAddress2 = contractAddresses.btcSpendAuthorizer;
26915
+ if (!btcSpendAuthorizerAddress2) {
26437
26916
  return {
26438
26917
  success: false,
26439
26918
  failedStep: "config",
@@ -26523,7 +27002,7 @@ Message: ${causeMessage}${quantumContext}${loanCapDiagnostics}${mintDebtDiagnost
26523
27002
  invalidatorTxid: params.invalidatorTxid,
26524
27003
  contractAddresses: {
26525
27004
  PositionManager: contractAddresses.positionManager,
26526
- BTCSpendAuthorizer: btcSpendAuthorizerAddress,
27005
+ BTCSpendAuthorizer: btcSpendAuthorizerAddress2,
26527
27006
  ...contractAddresses.bitcoinProviderRegistry && {
26528
27007
  BitcoinProviderRegistry: contractAddresses.bitcoinProviderRegistry
26529
27008
  }
@@ -26549,8 +27028,8 @@ Message: ${causeMessage}${quantumContext}${loanCapDiagnostics}${mintDebtDiagnost
26549
27028
  error: attRes.error ?? attRes.reason ?? `LIT recovery attestation rejected${attRes.failedStep ? ` at step ${attRes.failedStep}` : ""}`
26550
27029
  };
26551
27030
  }
26552
- const btcSpendAuthorizer = new Contract9(
26553
- btcSpendAuthorizerAddress,
27031
+ const btcSpendAuthorizer = new Contract10(
27032
+ btcSpendAuthorizerAddress2,
26554
27033
  [
26555
27034
  "function cancelStaleSpendWithProof(bytes32 positionId, bytes32 utxoKey, uint256 authorizedAt, string calldata invalidatorTxid, uint256 attestationTimestamp, bytes calldata litSignature) external"
26556
27035
  ],
@@ -26604,7 +27083,8 @@ Message: ${causeMessage}${quantumContext}${loanCapDiagnostics}${mintDebtDiagnost
26604
27083
  utxoTxid: params.utxoTxid,
26605
27084
  utxoVout: params.utxoVout,
26606
27085
  chainId,
26607
- signer
27086
+ signer,
27087
+ provider: this.getProviderOrThrow()
26608
27088
  });
26609
27089
  if (this.config.mode === "service" && this.config.serviceEndpoint) {
26610
27090
  const headers = {
@@ -26849,6 +27329,14 @@ Message: ${causeMessage}${quantumContext}${loanCapDiagnostics}${mintDebtDiagnost
26849
27329
  if (typeof positionId !== "string" || !positionId) {
26850
27330
  return { success: false, error: "positionId is required" };
26851
27331
  }
27332
+ if (typeof withdrawalAddress !== "string" || withdrawalAddress.trim().length === 0) {
27333
+ return { success: false, error: "withdrawalAddress is required" };
27334
+ }
27335
+ const destinationCaseError = bitcoinAddressCaseError(withdrawalAddress);
27336
+ if (destinationCaseError) {
27337
+ return { success: false, error: destinationCaseError };
27338
+ }
27339
+ withdrawalAddress = normalizeBitcoinAddress(withdrawalAddress);
26852
27340
  const lockFailure = this.tryAcquireWriteLock(positionId);
26853
27341
  if (lockFailure)
26854
27342
  return lockFailure;
@@ -27383,9 +27871,9 @@ Message: ${causeMessage}${quantumContext}${loanCapDiagnostics}${mintDebtDiagnost
27383
27871
  to: registryAddress,
27384
27872
  data: iface.encodeFunctionData("getLoanGrant", [pid])
27385
27873
  });
27386
- if (getBytes4(data).length < 96) {
27874
+ if (getBytes2(data).length < 96) {
27387
27875
  throw new SDKError({
27388
- message: `AgentDelegationRegistry at ${registryAddress} returned ${getBytes4(data).length} bytes for getLoanGrant(bytes32) \u2014 expected at least 96. Wrong address, or a registry version this SDK does not support.`,
27876
+ message: `AgentDelegationRegistry at ${registryAddress} returned ${getBytes2(data).length} bytes for getLoanGrant(bytes32) \u2014 expected at least 96. Wrong address, or a registry version this SDK does not support.`,
27389
27877
  category: "CONTRACT" /* CONTRACT */,
27390
27878
  severity: "HIGH" /* HIGH */
27391
27879
  });
@@ -27394,7 +27882,7 @@ Message: ${causeMessage}${quantumContext}${loanCapDiagnostics}${mintDebtDiagnost
27394
27882
  "getLoanGrant",
27395
27883
  data
27396
27884
  );
27397
- const raw = getBytes4(data);
27885
+ const raw = getBytes2(data);
27398
27886
  const withdrawScopeSupported = raw.length >= 128;
27399
27887
  const minWithdrawRatioBps = withdrawScopeSupported ? Number(
27400
27888
  AbiCoder2.defaultAbiCoder().decode(["uint32"], raw.slice(96, 128))[0]
@@ -27513,13 +28001,32 @@ Message: ${causeMessage}${quantumContext}${loanCapDiagnostics}${mintDebtDiagnost
27513
28001
  if (plan.kind === "reuse") {
27514
28002
  agentAddress = plan.agent;
27515
28003
  } else {
27516
- agentAddress = await mintAgentPkp({
28004
+ const minted = await mintAgentPkp({
27517
28005
  serviceEndpoint: this.config.serviceEndpoint,
27518
28006
  authHeader: this.serverSession ? () => this.serverSession.getAuthHeader() : void 0
27519
28007
  });
28008
+ agentAddress = minted.walletAddress;
28009
+ const consentSigner = verifyTypedData(
28010
+ {
28011
+ name: "DiamondHands.Protocol",
28012
+ version: "1",
28013
+ chainId: (await this.getProviderOrThrow().getNetwork()).chainId,
28014
+ verifyingContract: addr
28015
+ },
28016
+ AGENT_BINDING_CONSENT_TYPES,
28017
+ { user, agent: agentAddress },
28018
+ minted.agentConsent
28019
+ );
28020
+ if (getAddress(consentSigner) !== getAddress(agentAddress)) {
28021
+ throw new SDKError({
28022
+ message: `Agent ${agentAddress}'s binding consent is not for ${user} on registry ${addr} \u2014 the lit-ops session must be signed in as the same wallet that binds the agent`,
28023
+ category: "AUTHORIZATION" /* AUTHORIZATION */,
28024
+ severity: "HIGH" /* HIGH */
28025
+ });
28026
+ }
27520
28027
  const validitySeconds = options?.agentValiditySeconds ?? 90 * 24 * 60 * 60;
27521
28028
  const validUntil = latestBlock.timestamp + validitySeconds;
27522
- const bindTx = plan.kind === "rotate" ? await registry.rotateAgent(user, agentAddress, validUntil) : await registry.registerAgent(user, agentAddress, validUntil);
28029
+ const bindTx = plan.kind === "rotate" ? await registry.rotateAgent(user, agentAddress, validUntil, minted.agentConsent) : await registry.registerAgent(user, agentAddress, validUntil, minted.agentConsent);
27523
28030
  await bindTx.wait();
27524
28031
  }
27525
28032
  const currentDelegate = await getPositionDelegate(pid, signer, pdrAddr).catch(
@@ -28397,7 +28904,7 @@ Message: ${causeMessage}${quantumContext}${loanCapDiagnostics}${mintDebtDiagnost
28397
28904
  * Convert decimal position ID to bytes32 format
28398
28905
  */
28399
28906
  toBytes32(value) {
28400
- return zeroPadValue5(toBeHex2(BigInt(value)), 32);
28907
+ return zeroPadValue4(toBeHex2(BigInt(value)), 32);
28401
28908
  }
28402
28909
  /**
28403
28910
  * Check if an error indicates a technical failure vs business logic rejection
@@ -28438,7 +28945,7 @@ Message: ${causeMessage}${quantumContext}${loanCapDiagnostics}${mintDebtDiagnost
28438
28945
  const coreModuleAbi = [
28439
28946
  "function getPositionDetails(bytes32) view returns (tuple(bytes32 positionId, bytes32 pkpId, uint256 ucdDebt, string vaultAddress, address borrower, uint40 createdAt, uint40 lastUpdated, uint16 selectedTerm, uint40 expiryAt, uint8 status, uint40 previousExpiryAt, uint16 totalTerm))"
28440
28947
  ];
28441
- const coreModule = new Contract9(
28948
+ const coreModule = new Contract10(
28442
28949
  coreModuleAddress,
28443
28950
  coreModuleAbi,
28444
28951
  provider
@@ -28505,7 +29012,7 @@ Message: ${causeMessage}${quantumContext}${loanCapDiagnostics}${mintDebtDiagnost
28505
29012
  const corePositionAbi = [
28506
29013
  "function getPositionDetails(bytes32) view returns (tuple(bytes32 positionId, bytes32 pkpId, uint256 ucdDebt, string vaultAddress, address borrower, uint40 createdAt, uint40 lastUpdated, uint16 selectedTerm, uint40 expiryAt, uint8 status, uint40 previousExpiryAt, uint16 totalTerm))"
28507
29014
  ];
28508
- const corePositionContract = new Contract9(
29015
+ const corePositionContract = new Contract10(
28509
29016
  coreAddress,
28510
29017
  corePositionAbi,
28511
29018
  provider
@@ -28584,7 +29091,7 @@ Message: ${causeMessage}${quantumContext}${loanCapDiagnostics}${mintDebtDiagnost
28584
29091
  throw new Error("loanOperationsManager address not configured");
28585
29092
  }
28586
29093
  const runner = this.config.contractSigner || this.getProviderOrThrow();
28587
- const contract = new Contract9(
29094
+ const contract = new Contract10(
28588
29095
  addr.loanOperationsManager,
28589
29096
  [
28590
29097
  "function getProtocolConfig() external view returns (uint256 liquidationThreshold, uint256 minimumLoanValueUcd, uint256 minimumLoanValueWei, uint256 maxSingleLoanValueUcd)"
@@ -28642,11 +29149,11 @@ Message: ${causeMessage}${quantumContext}${loanCapDiagnostics}${mintDebtDiagnost
28642
29149
  const canonicalPositionId = "0x" + rawPositionId.padStart(64, "0").toLowerCase();
28643
29150
  const intentTimestamp = Math.floor(Date.now() / 1e3);
28644
29151
  const intentActionHash = keccak2565(toUtf8Bytes5("liquidate-position"));
28645
- const intentHash = solidityPackedKeccak2564(
29152
+ const intentHash = solidityPackedKeccak2563(
28646
29153
  ["bytes32", "uint256", "uint256", "address", "bytes32"],
28647
29154
  [canonicalPositionId, intentTimestamp, chainId, intentSigner, intentActionHash]
28648
29155
  );
28649
- const intentSignature = await signer.signMessage(getBytes4(intentHash));
29156
+ const intentSignature = await signer.signMessage(getBytes2(intentHash));
28650
29157
  const response = await fetch(endpoint, {
28651
29158
  method: "POST",
28652
29159
  headers: { "Content-Type": "application/json" },
@@ -28698,7 +29205,7 @@ Message: ${causeMessage}${quantumContext}${loanCapDiagnostics}${mintDebtDiagnost
28698
29205
  const vrfSeedRaw = await lmResult.value["vrfSeeds"](positionId);
28699
29206
  const vrfSeed = BigInt(vrfSeedRaw.toString());
28700
29207
  if (vrfSeed !== 0n) {
28701
- const finalEntropy = solidityPackedKeccak2564(
29208
+ const finalEntropy = solidityPackedKeccak2563(
28702
29209
  ["uint256", "uint256", "bytes32"],
28703
29210
  [vrfSeed, BigInt(quantumTimestamp.toString()), positionId]
28704
29211
  );
@@ -28977,7 +29484,7 @@ var EventHelpers = {
28977
29484
 
28978
29485
  // src/utils/safe-agent-delegation.utils.ts
28979
29486
  init_deployment_addresses();
28980
- import { Contract as Contract10, Interface as Interface7 } from "ethers";
29487
+ import { Contract as Contract11, Interface as Interface7 } from "ethers";
28981
29488
  var SAFE_ABI = [
28982
29489
  "function getModulesPaginated(address start, uint256 pageSize) view returns (address[] modules, address next)"
28983
29490
  ];
@@ -28994,7 +29501,7 @@ var MODULE_LIST_SENTINEL = "0x0000000000000000000000000000000000000001";
28994
29501
  var MODULE_PAGE_SIZE = 50;
28995
29502
  var lower = (v) => v.trim().toLowerCase();
28996
29503
  async function classifyModule(provider, moduleAddress, safeAddress, positionManager, factoryAddress) {
28997
- const module = new Contract10(moduleAddress, MODULE_ABI, provider);
29504
+ const module = new Contract11(moduleAddress, MODULE_ABI, provider);
28998
29505
  let boundSafe;
28999
29506
  try {
29000
29507
  boundSafe = await module.safe();
@@ -29014,7 +29521,7 @@ async function classifyModule(provider, moduleAddress, safeAddress, positionMana
29014
29521
  if (!factoryAddress)
29015
29522
  return null;
29016
29523
  try {
29017
- const factory = new Contract10(factoryAddress, FACTORY_ABI, provider);
29524
+ const factory = new Contract11(factoryAddress, FACTORY_ABI, provider);
29018
29525
  return await factory.isFromFactory(moduleAddress) === true;
29019
29526
  } catch {
29020
29527
  return null;
@@ -29043,7 +29550,7 @@ async function getSafeAgentDelegation(params) {
29043
29550
  let modules;
29044
29551
  let next;
29045
29552
  try {
29046
- const safe = new Contract10(safeAddress, SAFE_ABI, provider);
29553
+ const safe = new Contract11(safeAddress, SAFE_ABI, provider);
29047
29554
  const page = await safe.getModulesPaginated(
29048
29555
  MODULE_LIST_SENTINEL,
29049
29556
  MODULE_PAGE_SIZE
@@ -29071,7 +29578,7 @@ async function getSafeAgentDelegation(params) {
29071
29578
  continue;
29072
29579
  let agentAddress = null;
29073
29580
  try {
29074
- agentAddress = await new Contract10(
29581
+ agentAddress = await new Contract11(
29075
29582
  moduleAddress,
29076
29583
  MODULE_ABI,
29077
29584
  provider
@@ -29085,7 +29592,7 @@ async function getSafeAgentDelegation(params) {
29085
29592
  let validUntil;
29086
29593
  let status;
29087
29594
  try {
29088
- const record = await new Contract10(
29595
+ const record = await new Contract11(
29089
29596
  registryAddress,
29090
29597
  REGISTRY_ABI,
29091
29598
  provider
@@ -29119,6 +29626,11 @@ export {
29119
29626
  ALL_DEPLOYMENTS,
29120
29627
  AuthParamsValidation,
29121
29628
  BPSConversions,
29629
+ BTC_SPEND_QUANTUM_SECONDS,
29630
+ BTC_SPEND_RELAY_DEADLINE_SECONDS,
29631
+ BTC_SPEND_REQUEST_712_DOMAIN_NAME,
29632
+ BTC_SPEND_REQUEST_712_DOMAIN_VERSION,
29633
+ BTC_SPEND_REQUEST_712_FIELDS,
29122
29634
  BitcoinOperations,
29123
29635
  CacheManager,
29124
29636
  ContractManager,
@@ -29152,9 +29664,15 @@ export {
29152
29664
  andThen,
29153
29665
  assertProtocolNotPaused,
29154
29666
  assertSafeServiceEndpoint,
29667
+ btcSpendAuthorizerAddress,
29668
+ btcSpendRequest712Digest,
29669
+ btcSpendRequest712Types,
29155
29670
  buildBtcExecuteEnvelope,
29671
+ buildBtcSpendRequest712Domain,
29672
+ buildExecuteBtcWithdrawalTypedData,
29156
29673
  buildInvalidateMessageHash,
29157
29674
  buildInvalidateStaleSpendEnvelope,
29675
+ buildInvalidateStaleSpendTypedData,
29158
29676
  buildLoginDomain,
29159
29677
  buildSignedLoginPayload,
29160
29678
  collectFailures,
@@ -29196,8 +29714,10 @@ export {
29196
29714
  mapError,
29197
29715
  match,
29198
29716
  numericToPositionStatus,
29717
+ readAuthorizedSpend,
29199
29718
  reconcileAuthorizedSpend,
29200
29719
  setPositionDelegate,
29720
+ signBtcSpendRequest712,
29201
29721
  success,
29202
29722
  toPromise,
29203
29723
  tryCatch,