@gvnrdao/dh-sdk 0.0.129 → 0.0.131

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -12748,48 +12748,48 @@ var init_deployment_addresses = __esm({
12748
12748
  LOCALHOST_DEPLOYMENT = {
12749
12749
  "network": "localhost",
12750
12750
  "chainId": 31337,
12751
- "timestamp": "2025-12-05T21:33:05.298Z",
12751
+ "timestamp": "2025-12-11T16:44:37.280Z",
12752
12752
  "deployer": "",
12753
12753
  "contracts": {
12754
- "UpgradeValidator": "0x0DCd1Bf9A1b36cE34237eEaFef220932846BCD82",
12754
+ "UpgradeValidator": "0x2279B7A0a67DB372996a5FaB50D91eAA73d2eBe6",
12755
12755
  "UCDToken": "0xe7f1725E7734CE288F8367e1Bb143E90bb3F0512",
12756
12756
  "UCDController": "0xCf7Ed3AccA5a467e9e704C703E8D87F634fB0Fc9",
12757
- "PriceFeedConsumer": "0x0B306BF915C4d645ff596e518fAf3F9669b97016",
12758
- "BTCProofValidator": "0x9A9f2CCfdE556A7E9Ff0848998Aa4a0CFD8863AE",
12759
- "UCDMintingRewards": "0x3Aa5ebB10DC797CAC828524e59A333d0A371443c",
12760
- "PositionManagerCoreModule": "0x59b670e9fA9D0A427751Af201D676719a970857b",
12761
- "TermManagerModule": "0x322813Fd9A801c5507c9de605d63CEA4f2CE6c44",
12762
- "LoanOperationsManagerModule": "0x09635F643e140090A9A8Dcd712eD6285858ceBef",
12763
- "CollateralManagerModule": "0x67d269191c92Caf3cD7723F116c85e6E9bf55933",
12764
- "LiquidationManagerModule": "0xc3e53F4d16Ae77Db1c982e75a937B9f60FE63690",
12765
- "CircuitBreakerModule": "0x4A679253410272dd5232B3Ff7cF5dbB88f295319",
12766
- "CommunityManagerModule": "0x9E545E3C0baAB3E08CdfD552C960A1050f373042",
12767
- "AdminModule": "0x1613beB3B2C4f22Ee086B2b38C1476A3cE7f78E8",
12768
- "PositionManagerViews": "0x851356ae760d987E095750cCeb3bC6014560891C",
12769
- "PositionManager": "0x95401dc811bb5740090279Ba06cfA8fcF6113778",
12770
- "OperationAuthorizationRegistry": "0x5f3f1dBD7B74C6B46e8c44f98792A1dAf8d69154",
12771
- "PKPValidation": "0x82e01223d51Eb87e16A03E24687EDF0F294da6f1"
12757
+ "PriceFeedConsumer": "0x610178dA211FEF7D417bC0e6FeD39F05609AD788",
12758
+ "BTCProofValidator": "0xA51c1fc2f0D1a1b8494Ed1FE312d7C3a78Ed91C0",
12759
+ "UCDMintingRewards": "0x9A676e781A523b5d0C0e43731313A708CB607508",
12760
+ "PositionManagerCoreModule": "0x959922bE3CAee4b8Cd9a407cc3ac1C251C2007B1",
12761
+ "TermManagerModule": "0x68B1D87F95878fE05B998F19b66F4baba5De1aed",
12762
+ "LoanOperationsManagerModule": "0x4ed7c70F96B99c776995fB64377f0d4aB3B0e1C1",
12763
+ "CollateralManagerModule": "0xa85233C63b9Ee964Add6F2cffe00Fd84eb32338f",
12764
+ "LiquidationManagerModule": "0x7a2088a1bFc9d81c55368AE168C2C02570cB814F",
12765
+ "CircuitBreakerModule": "0xc6e7DF5E7b4f2A278906862b61205850344D4e7d",
12766
+ "CommunityManagerModule": "0xc5a5C42992dECbae36851359345FE25997F5C42d",
12767
+ "AdminModule": "0xE6E340D132b5f46d1e472DebcD681B2aBc16e57E",
12768
+ "PositionManagerViews": "0xc3e53F4d16Ae77Db1c982e75a937B9f60FE63690",
12769
+ "PositionManager": "0x9E545E3C0baAB3E08CdfD552C960A1050f373042",
12770
+ "OperationAuthorizationRegistry": "0x5eb3Bc0a489C5A8288765d2336659EbCA68FCd00",
12771
+ "PKPValidation": "0x4c5859f0F772848b2D91F1D83E2Fe57935348029"
12772
12772
  }
12773
12773
  };
12774
12774
  LOCALHOST_CONTRACTS = {
12775
- "UpgradeValidator": "0x0DCd1Bf9A1b36cE34237eEaFef220932846BCD82",
12775
+ "UpgradeValidator": "0x2279B7A0a67DB372996a5FaB50D91eAA73d2eBe6",
12776
12776
  "UCDToken": "0xe7f1725E7734CE288F8367e1Bb143E90bb3F0512",
12777
12777
  "UCDController": "0xCf7Ed3AccA5a467e9e704C703E8D87F634fB0Fc9",
12778
- "PriceFeedConsumer": "0x0B306BF915C4d645ff596e518fAf3F9669b97016",
12779
- "BTCProofValidator": "0x9A9f2CCfdE556A7E9Ff0848998Aa4a0CFD8863AE",
12780
- "UCDMintingRewards": "0x3Aa5ebB10DC797CAC828524e59A333d0A371443c",
12781
- "PositionManagerCoreModule": "0x59b670e9fA9D0A427751Af201D676719a970857b",
12782
- "TermManagerModule": "0x322813Fd9A801c5507c9de605d63CEA4f2CE6c44",
12783
- "LoanOperationsManagerModule": "0x09635F643e140090A9A8Dcd712eD6285858ceBef",
12784
- "CollateralManagerModule": "0x67d269191c92Caf3cD7723F116c85e6E9bf55933",
12785
- "LiquidationManagerModule": "0xc3e53F4d16Ae77Db1c982e75a937B9f60FE63690",
12786
- "CircuitBreakerModule": "0x4A679253410272dd5232B3Ff7cF5dbB88f295319",
12787
- "CommunityManagerModule": "0x9E545E3C0baAB3E08CdfD552C960A1050f373042",
12788
- "AdminModule": "0x1613beB3B2C4f22Ee086B2b38C1476A3cE7f78E8",
12789
- "PositionManagerViews": "0x851356ae760d987E095750cCeb3bC6014560891C",
12790
- "PositionManager": "0x95401dc811bb5740090279Ba06cfA8fcF6113778",
12791
- "OperationAuthorizationRegistry": "0x5f3f1dBD7B74C6B46e8c44f98792A1dAf8d69154",
12792
- "PKPValidation": "0x82e01223d51Eb87e16A03E24687EDF0F294da6f1"
12778
+ "PriceFeedConsumer": "0x610178dA211FEF7D417bC0e6FeD39F05609AD788",
12779
+ "BTCProofValidator": "0xA51c1fc2f0D1a1b8494Ed1FE312d7C3a78Ed91C0",
12780
+ "UCDMintingRewards": "0x9A676e781A523b5d0C0e43731313A708CB607508",
12781
+ "PositionManagerCoreModule": "0x959922bE3CAee4b8Cd9a407cc3ac1C251C2007B1",
12782
+ "TermManagerModule": "0x68B1D87F95878fE05B998F19b66F4baba5De1aed",
12783
+ "LoanOperationsManagerModule": "0x4ed7c70F96B99c776995fB64377f0d4aB3B0e1C1",
12784
+ "CollateralManagerModule": "0xa85233C63b9Ee964Add6F2cffe00Fd84eb32338f",
12785
+ "LiquidationManagerModule": "0x7a2088a1bFc9d81c55368AE168C2C02570cB814F",
12786
+ "CircuitBreakerModule": "0xc6e7DF5E7b4f2A278906862b61205850344D4e7d",
12787
+ "CommunityManagerModule": "0xc5a5C42992dECbae36851359345FE25997F5C42d",
12788
+ "AdminModule": "0xE6E340D132b5f46d1e472DebcD681B2aBc16e57E",
12789
+ "PositionManagerViews": "0xc3e53F4d16Ae77Db1c982e75a937B9f60FE63690",
12790
+ "PositionManager": "0x9E545E3C0baAB3E08CdfD552C960A1050f373042",
12791
+ "OperationAuthorizationRegistry": "0x5eb3Bc0a489C5A8288765d2336659EbCA68FCd00",
12792
+ "PKPValidation": "0x4c5859f0F772848b2D91F1D83E2Fe57935348029"
12793
12793
  };
12794
12794
  ALL_DEPLOYMENTS = {
12795
12795
  sepolia: SEPOLIA_DEPLOYMENT,
@@ -12937,7 +12937,7 @@ function getSepoliaConfig() {
12937
12937
  operationAuthorizationRegistry: SEPOLIA_CONTRACTS.OperationAuthorizationRegistry || ""
12938
12938
  },
12939
12939
  subgraphs: {
12940
- diamondHandsUrl: "https://api.studio.thegraph.com/query/65258/diamond-hands/version/latest"
12940
+ diamondHandsUrl: "https://api.studio.thegraph.com/query/65258/diamond-hands/v0.3.0-1765544881"
12941
12941
  },
12942
12942
  // litNetwork: "datil-test",
12943
12943
  debug: true
@@ -12991,8 +12991,14 @@ function getLocalhostConfig() {
12991
12991
  );
12992
12992
  logNetworkConfig("log", "[NetworkConfig] Localhost contracts:", {
12993
12993
  PositionManager: getAddress3("POSITION_MANAGER_ADDRESS", "PositionManager"),
12994
- PositionManagerCore: getAddress3("POSITION_MANAGER_CORE_ADDRESS", "PositionManagerCoreModule"),
12995
- LoanOperationsManagerModule: getAddress3("LOAN_OPERATIONS_MANAGER_ADDRESS", "LoanOperationsManagerModule"),
12994
+ PositionManagerCore: getAddress3(
12995
+ "POSITION_MANAGER_CORE_ADDRESS",
12996
+ "PositionManagerCoreModule"
12997
+ ),
12998
+ LoanOperationsManagerModule: getAddress3(
12999
+ "LOAN_OPERATIONS_MANAGER_ADDRESS",
13000
+ "LoanOperationsManagerModule"
13001
+ ),
12996
13002
  TermManagerModule: getAddress3("TERM_MANAGER_ADDRESS", "TermManagerModule"),
12997
13003
  UCDToken: getAddress3("UCD_TOKEN_ADDRESS", "UCDToken")
12998
13004
  });
@@ -13003,23 +13009,53 @@ function getLocalhostConfig() {
13003
13009
  name: "localhost",
13004
13010
  rpcUrls: ["http://localhost:8545"],
13005
13011
  contractAddresses: {
13006
- positionManager: getAddress3("POSITION_MANAGER_ADDRESS", "PositionManager"),
13007
- positionManagerCore: getAddress3("POSITION_MANAGER_CORE_ADDRESS", "PositionManagerCoreModule"),
13008
- positionManagerViews: getAddress3("POSITION_MANAGER_VIEWS_ADDRESS", "PositionManagerViews"),
13012
+ positionManager: getAddress3(
13013
+ "POSITION_MANAGER_ADDRESS",
13014
+ "PositionManager"
13015
+ ),
13016
+ positionManagerCore: getAddress3(
13017
+ "POSITION_MANAGER_CORE_ADDRESS",
13018
+ "PositionManagerCoreModule"
13019
+ ),
13020
+ positionManagerViews: getAddress3(
13021
+ "POSITION_MANAGER_VIEWS_ADDRESS",
13022
+ "PositionManagerViews"
13023
+ ),
13009
13024
  simplePsmV2: getAddress3("SIMPLE_PSM_V2_ADDRESS", "SimplePSMV2"),
13010
- loanOperationsManager: getAddress3("LOAN_OPERATIONS_MANAGER_ADDRESS", "LoanOperationsManagerModule"),
13025
+ loanOperationsManager: getAddress3(
13026
+ "LOAN_OPERATIONS_MANAGER_ADDRESS",
13027
+ "LoanOperationsManagerModule"
13028
+ ),
13011
13029
  termManager: getAddress3("TERM_MANAGER_ADDRESS", "TermManagerModule"),
13012
- circuitBreaker: getAddress3("CIRCUIT_BREAKER_ADDRESS", "CircuitBreakerModule"),
13013
- communityManager: getAddress3("COMMUNITY_MANAGER_ADDRESS", "CommunityManagerModule"),
13014
- liquidationManager: getAddress3("LIQUIDATION_MANAGER_ADDRESS", "LiquidationManagerModule"),
13030
+ circuitBreaker: getAddress3(
13031
+ "CIRCUIT_BREAKER_ADDRESS",
13032
+ "CircuitBreakerModule"
13033
+ ),
13034
+ communityManager: getAddress3(
13035
+ "COMMUNITY_MANAGER_ADDRESS",
13036
+ "CommunityManagerModule"
13037
+ ),
13038
+ liquidationManager: getAddress3(
13039
+ "LIQUIDATION_MANAGER_ADDRESS",
13040
+ "LiquidationManagerModule"
13041
+ ),
13015
13042
  ucdToken: getAddress3("UCD_TOKEN_ADDRESS", "UCDToken"),
13016
13043
  ucdController: getAddress3("UCD_CONTROLLER_ADDRESS", "UCDController"),
13017
- btcProofValidator: getAddress3("BTC_PROOF_VALIDATOR_ADDRESS", "BTCProofValidator"),
13018
- priceFeedConsumer: getAddress3("PRICE_FEED_CONSUMER_ADDRESS", "PriceFeedConsumer"),
13019
- operationAuthorizationRegistry: getAddress3("OPERATION_AUTHORIZATION_REGISTRY_ADDRESS", "OperationAuthorizationRegistry")
13044
+ btcProofValidator: getAddress3(
13045
+ "BTC_PROOF_VALIDATOR_ADDRESS",
13046
+ "BTCProofValidator"
13047
+ ),
13048
+ priceFeedConsumer: getAddress3(
13049
+ "PRICE_FEED_CONSUMER_ADDRESS",
13050
+ "PriceFeedConsumer"
13051
+ ),
13052
+ operationAuthorizationRegistry: getAddress3(
13053
+ "OPERATION_AUTHORIZATION_REGISTRY_ADDRESS",
13054
+ "OperationAuthorizationRegistry"
13055
+ )
13020
13056
  },
13021
13057
  subgraphs: {
13022
- diamondHandsUrl: "https://api.studio.thegraph.com/query/65258/diamond-hands/version/latest"
13058
+ diamondHandsUrl: "https://api.studio.thegraph.com/query/65258/diamond-hands/v0.3.0-1765544881"
13023
13059
  },
13024
13060
  litNetwork: "datil",
13025
13061
  debug: true
@@ -29163,42 +29199,70 @@ function validateSDKConfig(config) {
29163
29199
  }
29164
29200
 
29165
29201
  // src/utils/quantum-timing.ts
29166
- async function calculateValidQuantumTimestamp() {
29167
- console.log(" \u{1F3AF} Finding OPTIMAL quantum moment for signature...");
29168
- let now2 = Math.floor(Date.now() / 1e3);
29169
- let timeInQuantum = now2 % 100;
29170
- if (timeInQuantum !== 16) {
29171
- let waitSeconds;
29172
- if (timeInQuantum < 16) {
29173
- waitSeconds = 16 - timeInQuantum;
29174
- console.log(
29175
- ` \u23F3 Current: second ${timeInQuantum} - waiting ${waitSeconds}s for optimal moment (second 16)...`
29176
- );
29177
- } else {
29178
- waitSeconds = 100 - timeInQuantum + 16;
29179
- console.log(
29180
- ` \u23F3 Current: second ${timeInQuantum} - waiting ${waitSeconds}s for next optimal moment (second 16)...`
29181
- );
29182
- }
29183
- await new Promise((resolve) => setTimeout(resolve, waitSeconds * 1e3));
29184
- now2 = Math.floor(Date.now() / 1e3);
29185
- timeInQuantum = now2 % 100;
29186
- console.log(` \u2705 Optimal moment reached: second ${timeInQuantum}`);
29202
+ function calculateNextQuantumTimestamp() {
29203
+ const now2 = Math.floor(Date.now() / 1e3);
29204
+ const timeInQuantum = now2 % 100;
29205
+ const currentQuantum = Math.floor(now2 / 100) * 100;
29206
+ let targetTimestamp;
29207
+ if (timeInQuantum >= 16 && timeInQuantum <= 30) {
29208
+ targetTimestamp = now2;
29209
+ console.log(
29210
+ "[Quantum Timing] Already at optimal moment in current quantum"
29211
+ );
29212
+ } else if (timeInQuantum < 16 && timeInQuantum >= 8) {
29213
+ targetTimestamp = currentQuantum + 16;
29214
+ console.log("[Quantum Timing] Targeting second 16 of CURRENT quantum");
29187
29215
  } else {
29188
- console.log(` \u2705 Already at optimal moment: second ${timeInQuantum}`);
29189
- }
29190
- const timestamp = Math.floor(Date.now() / 1e3);
29191
- const quantumWindow = Math.floor(timestamp / 100) * 100;
29192
- const timeInQuantumNow = timestamp % 100;
29193
- console.log(" \u{1F4DD} Timestamp Details:");
29194
- console.log(" Timestamp:", timestamp);
29195
- console.log(" Quantum window:", quantumWindow);
29216
+ const nextQuantum = currentQuantum + 100;
29217
+ targetTimestamp = nextQuantum + 16;
29218
+ console.log("[Quantum Timing] Targeting second 16 of NEXT quantum");
29219
+ }
29220
+ console.log("[Quantum Timing] Calculated quantum timing:");
29221
+ console.log(" Current time:", now2);
29222
+ console.log(" Time in quantum:", timeInQuantum);
29223
+ console.log(" Target timestamp:", targetTimestamp);
29224
+ console.log(" Seconds until target:", targetTimestamp - now2);
29225
+ return targetTimestamp;
29226
+ }
29227
+ async function waitUntilTimestamp(targetTimestamp) {
29228
+ const now2 = Math.floor(Date.now() / 1e3);
29229
+ const waitSeconds = targetTimestamp - now2;
29230
+ if (waitSeconds <= 0) {
29231
+ console.log("[Quantum Timing] Target timestamp already reached");
29232
+ return;
29233
+ }
29196
29234
  console.log(
29197
- " Time in quantum:",
29198
- timeInQuantumNow,
29199
- "seconds (OPTIMAL: 16)"
29235
+ `[Quantum Timing] Waiting ${waitSeconds}s until timestamp ${targetTimestamp}...`
29200
29236
  );
29201
- return timestamp;
29237
+ await new Promise((resolve) => setTimeout(resolve, waitSeconds * 1e3));
29238
+ console.log("[Quantum Timing] Target timestamp reached");
29239
+ }
29240
+ function validateQuantumTiming(signedTimestamp, bufferSeconds = 30) {
29241
+ const now2 = Math.floor(Date.now() / 1e3);
29242
+ const signedQuantum = Math.floor(signedTimestamp / 100) * 100;
29243
+ const currentQuantum = Math.floor(now2 / 100) * 100;
29244
+ if (currentQuantum !== signedQuantum) {
29245
+ throw new Error(
29246
+ `Quantum window expired. User took too long to sign. Signed quantum: ${signedQuantum}, Current quantum: ${currentQuantum}`
29247
+ );
29248
+ }
29249
+ const timeInQuantum = now2 % 100;
29250
+ const isInDeadZone = timeInQuantum < 8 || timeInQuantum >= 92;
29251
+ if (isInDeadZone) {
29252
+ throw new Error(
29253
+ `Current time (${timeInQuantum}s in quantum) is in dead zone. Operation cannot proceed safely.`
29254
+ );
29255
+ }
29256
+ const secondsRemaining = 92 - timeInQuantum;
29257
+ if (secondsRemaining < bufferSeconds) {
29258
+ throw new Error(
29259
+ `Insufficient time remaining in quantum. Required: ${bufferSeconds}s, Available: ${secondsRemaining}s`
29260
+ );
29261
+ }
29262
+ console.log("[Quantum Timing] Validation passed:");
29263
+ console.log(" Time in quantum:", timeInQuantum);
29264
+ console.log(" Seconds remaining:", secondsRemaining);
29265
+ console.log(" Required buffer:", bufferSeconds);
29202
29266
  }
29203
29267
 
29204
29268
  // src/utils/mint-authorization.utils.ts
@@ -29212,7 +29276,7 @@ var PKP_NFT_ADDRESSES = {
29212
29276
  // Yellowstone/Datil (PKP native network) - same as Datil testnet
29213
29277
  };
29214
29278
  async function generateMintAuthorization(positionId, amount, chainId, mode, signer) {
29215
- const timestamp = await calculateValidQuantumTimestamp();
29279
+ const timestamp = calculateNextQuantumTimestamp();
29216
29280
  const action = "mint-ucd";
29217
29281
  const actionHash = ethers_exports.utils.keccak256(ethers_exports.utils.toUtf8Bytes(action));
29218
29282
  const types = [
@@ -29246,7 +29310,8 @@ async function generateMintAuthorization(positionId, amount, chainId, mode, sign
29246
29310
  console.log(" Action Hash:", actionHash);
29247
29311
  console.log(" Message Hash (solidityKeccak256):", messageHash);
29248
29312
  console.log(" Message Hash Bytes Length:", messageHashBytes.length);
29249
- console.log(" Signer Address:", signer.address);
29313
+ const signerAddress = await signer.getAddress();
29314
+ console.log(" Signer Address:", signerAddress);
29250
29315
  const signature2 = await signer.signMessage(messageHashBytes);
29251
29316
  return {
29252
29317
  positionId,
@@ -29290,7 +29355,7 @@ async function getPKPPublicKeyFromTokenId(pkpTokenId, provider) {
29290
29355
  return pubkeyBytes.startsWith("0x") ? pubkeyBytes : `0x${pubkeyBytes}`;
29291
29356
  }
29292
29357
  async function generateWithdrawAuthorization(positionId, amount, chainId, mode, signer, destinationAddress) {
29293
- const timestamp = await calculateValidQuantumTimestamp();
29358
+ const timestamp = calculateNextQuantumTimestamp();
29294
29359
  const action = "withdraw-btc";
29295
29360
  const actionHash = ethers_exports.utils.keccak256(ethers_exports.utils.toUtf8Bytes(action));
29296
29361
  const types = [
@@ -29326,7 +29391,8 @@ async function generateWithdrawAuthorization(positionId, amount, chainId, mode,
29326
29391
  console.log(" Action:", action);
29327
29392
  console.log(" Action Hash:", actionHash);
29328
29393
  console.log(" Message Hash (solidityKeccak256):", messageHash);
29329
- console.log(" Signer Address:", signer.address);
29394
+ const signerAddress = await signer.getAddress();
29395
+ console.log(" Signer Address:", signerAddress);
29330
29396
  const signature2 = await signer.signMessage(messageHashBytes);
29331
29397
  console.log("[SDK Withdrawal Authorization] Signature generated:");
29332
29398
  console.log(" Signature:", signature2);
@@ -29335,7 +29401,7 @@ async function generateWithdrawAuthorization(positionId, amount, chainId, mode,
29335
29401
  console.log(" Recovered Address (for verification):", recovered);
29336
29402
  console.log(
29337
29403
  " Signer Matches Recovered:",
29338
- recovered.toLowerCase() === signer.address.toLowerCase() ? "\u2705 YES" : "\u274C NO"
29404
+ recovered.toLowerCase() === signerAddress.toLowerCase() ? "\u2705 YES" : "\u274C NO"
29339
29405
  );
29340
29406
  return {
29341
29407
  positionId,
@@ -41946,38 +42012,86 @@ var ContractManager = class {
41946
42012
  }
41947
42013
  const contractRunner = runner;
41948
42014
  const contracts = {
41949
- positionManager: PositionManager__factory.connect(
41950
- contractAddresses.positionManager,
41951
- contractRunner
41952
- ),
41953
- loanOperationsManager: ILoanOperationsManager__factory.connect(
41954
- contractAddresses.loanOperationsManager || ethers_exports.constants.AddressZero,
41955
- contractRunner
41956
- ),
41957
- ucdController: IUCDController__factory.connect(
41958
- contractAddresses.ucdToken,
41959
- contractRunner
41960
- ),
41961
- priceFeed: IPriceFeedConsumer__factory.connect(
41962
- contractAddresses.priceFeedConsumer,
41963
- contractRunner
41964
- ),
41965
- termManager: ITermManager__factory.connect(
41966
- contractAddresses.termManager || ethers_exports.constants.AddressZero,
41967
- contractRunner
41968
- ),
41969
- circuitBreaker: CircuitBreakerModule__factory.connect(
41970
- contractAddresses.circuitBreaker || ethers_exports.constants.AddressZero,
41971
- contractRunner
41972
- ),
41973
- communityManager: ICommunityManager__factory.connect(
41974
- contractAddresses.communityManager || ethers_exports.constants.AddressZero,
41975
- contractRunner
41976
- ),
41977
- liquidationManager: ILiquidationManager__factory.connect(
41978
- contractAddresses.liquidationManager || ethers_exports.constants.AddressZero,
41979
- contractRunner
41980
- )
42015
+ positionManager: (() => {
42016
+ try {
42017
+ return PositionManager__factory.connect(
42018
+ contractAddresses.positionManager,
42019
+ contractRunner
42020
+ );
42021
+ } catch (error) {
42022
+ throw new Error(`Failed to connect to PositionManager at ${contractAddresses.positionManager}: ${error}`);
42023
+ }
42024
+ })(),
42025
+ loanOperationsManager: (() => {
42026
+ try {
42027
+ return ILoanOperationsManager__factory.connect(
42028
+ contractAddresses.loanOperationsManager || ethers_exports.constants.AddressZero,
42029
+ contractRunner
42030
+ );
42031
+ } catch (error) {
42032
+ throw new Error(`Failed to connect to LoanOperationsManager at ${contractAddresses.loanOperationsManager}: ${error}`);
42033
+ }
42034
+ })(),
42035
+ ucdController: (() => {
42036
+ try {
42037
+ return IUCDController__factory.connect(
42038
+ contractAddresses.ucdToken,
42039
+ contractRunner
42040
+ );
42041
+ } catch (error) {
42042
+ throw new Error(`Failed to connect to UCDController at ${contractAddresses.ucdToken}: ${error}`);
42043
+ }
42044
+ })(),
42045
+ priceFeed: (() => {
42046
+ try {
42047
+ return IPriceFeedConsumer__factory.connect(
42048
+ contractAddresses.priceFeedConsumer,
42049
+ contractRunner
42050
+ );
42051
+ } catch (error) {
42052
+ throw new Error(`Failed to connect to PriceFeed at ${contractAddresses.priceFeedConsumer}: ${error}`);
42053
+ }
42054
+ })(),
42055
+ termManager: (() => {
42056
+ try {
42057
+ return ITermManager__factory.connect(
42058
+ contractAddresses.termManager || ethers_exports.constants.AddressZero,
42059
+ contractRunner
42060
+ );
42061
+ } catch (error) {
42062
+ throw new Error(`Failed to connect to TermManager at ${contractAddresses.termManager}: ${error}`);
42063
+ }
42064
+ })(),
42065
+ circuitBreaker: (() => {
42066
+ try {
42067
+ return CircuitBreakerModule__factory.connect(
42068
+ contractAddresses.circuitBreaker || ethers_exports.constants.AddressZero,
42069
+ contractRunner
42070
+ );
42071
+ } catch (error) {
42072
+ throw new Error(`Failed to connect to CircuitBreaker at ${contractAddresses.circuitBreaker}: ${error}`);
42073
+ }
42074
+ })(),
42075
+ communityManager: (() => {
42076
+ try {
42077
+ return ICommunityManager__factory.connect(
42078
+ contractAddresses.communityManager || ethers_exports.constants.AddressZero,
42079
+ contractRunner
42080
+ );
42081
+ } catch (error) {
42082
+ throw new Error(`Failed to connect to CommunityManager at ${contractAddresses.communityManager}: ${error}`);
42083
+ }
42084
+ })(),
42085
+ liquidationManager: (() => {
42086
+ try {
42087
+ return ILiquidationManager__factory.connect(
42088
+ contractAddresses.liquidationManager || ethers_exports.constants.AddressZero,
42089
+ contractRunner
42090
+ );
42091
+ } catch (error) {
42092
+ throw new Error(`Failed to connect to LiquidationManager at ${contractAddresses.liquidationManager}: ${error}`);
42093
+ }
42094
+ })()
41981
42095
  };
41982
42096
  this.contracts = contracts;
41983
42097
  return success(contracts);
@@ -43657,6 +43771,55 @@ var LoanQuery = class {
43657
43771
  })
43658
43772
  );
43659
43773
  }
43774
+ /**
43775
+ * Get loans with BTC balance data from Bitcoin network
43776
+ *
43777
+ * Same as getLoans but includes actual Bitcoin balance for each position's vault.
43778
+ * Queries BTC balances in parallel for performance.
43779
+ *
43780
+ * @param filters - Query filters
43781
+ * @param pagination - Pagination parameters
43782
+ * @returns Paginated loans response with BTC balance data
43783
+ */
43784
+ async getLoansWithBtc(filters = {}, pagination) {
43785
+ const page = pagination?.page || 0;
43786
+ const pageSize = pagination?.pageSize || this.defaultPageSize;
43787
+ const skip = page * pageSize;
43788
+ if (!filters.borrower) {
43789
+ if (this.config.debug) {
43790
+ log.info("\u26A0\uFE0F getLoansWithBtc only supports borrower filter, falling back to getLoans");
43791
+ }
43792
+ return this.getLoans(filters, pagination);
43793
+ }
43794
+ if (this.config.debug) {
43795
+ log.info("\u{1F50D} Querying loans with BTC balance data", { filters, page, pageSize, skip });
43796
+ }
43797
+ return tryCatchAsync(
43798
+ async () => {
43799
+ const result = await this.config.graphClient.getUserPositionsWithBtc(
43800
+ filters.borrower,
43801
+ pageSize,
43802
+ skip,
43803
+ filters.orderBy || "createdAt",
43804
+ filters.orderDirection || "desc"
43805
+ );
43806
+ const enrichedLoans = await this.enrichLoansWithVaultAddresses(result.positions);
43807
+ return {
43808
+ loans: enrichedLoans,
43809
+ page,
43810
+ maxRows: pageSize,
43811
+ totalLoans: result.total
43812
+ };
43813
+ },
43814
+ (error) => new SDKError({
43815
+ message: "Failed to query loans with BTC balance",
43816
+ category: "SUBGRAPH" /* SUBGRAPH */,
43817
+ severity: "MEDIUM" /* MEDIUM */,
43818
+ originalError: error instanceof Error ? error : new Error(String(error)),
43819
+ context: { filters, page, pageSize }
43820
+ })
43821
+ );
43822
+ }
43660
43823
  /**
43661
43824
  * Enrich loans with vault addresses derived from PKP public keys
43662
43825
  *
@@ -44242,7 +44405,10 @@ async function getBitcoinAddressesFromPkp(pkpPublicKey) {
44242
44405
  var BitcoinUtils = class {
44243
44406
  static validateAddress(address) {
44244
44407
  const base58Pattern = /^[123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz]+$/;
44245
- return base58Pattern.test(address) && address.length >= 26 && address.length <= 35;
44408
+ const isBase58 = base58Pattern.test(address) && address.length >= 26 && address.length <= 35;
44409
+ const bech32Pattern = /^(bc1|tb1|bcrt1)[a-z0-9]{39,87}$/;
44410
+ const isBech32 = bech32Pattern.test(address);
44411
+ return isBase58 || isBech32;
44246
44412
  }
44247
44413
  static formatTransaction(hash3, amount, recipient) {
44248
44414
  return {
@@ -45624,7 +45790,8 @@ var MIN_BITCOIN_PROVIDERS_FOR_CONSENSUS = 2;
45624
45790
  var DiamondHandsGraph = class {
45625
45791
  client;
45626
45792
  defaultPageSize;
45627
- constructor(config) {
45793
+ bitcoinOps;
45794
+ constructor(config, bitcoinOps) {
45628
45795
  this.client = new GraphClient({
45629
45796
  endpoint: config.endpoint,
45630
45797
  requestTimeoutMs: config.requestTimeoutMs,
@@ -45632,6 +45799,7 @@ var DiamondHandsGraph = class {
45632
45799
  headers: config.headers
45633
45800
  });
45634
45801
  this.defaultPageSize = config.defaultPageSize ?? 100;
45802
+ this.bitcoinOps = bitcoinOps;
45635
45803
  }
45636
45804
  /**
45637
45805
  * Transform graph position data to LoanData interface
@@ -45701,10 +45869,7 @@ var DiamondHandsGraph = class {
45701
45869
  }
45702
45870
  }
45703
45871
  `;
45704
- const result = await this.client.execute(
45705
- query,
45706
- { ...variables, skip }
45707
- );
45872
+ const result = await this.client.execute(query, { ...variables, skip });
45708
45873
  const items = result && result["positions"] || [];
45709
45874
  totalCount += items.length;
45710
45875
  hasMore = items.length === batchSize;
@@ -45756,10 +45921,9 @@ var DiamondHandsGraph = class {
45756
45921
  query,
45757
45922
  variables
45758
45923
  );
45759
- const total = await this.getTotalCountPaginated(
45760
- "{ borrower: $borrower }",
45761
- { borrower: userAddress.toLowerCase() }
45762
- );
45924
+ const total = await this.getTotalCountPaginated("{ borrower: $borrower }", {
45925
+ borrower: userAddress.toLowerCase()
45926
+ });
45763
45927
  let positions = [];
45764
45928
  if (result && result.user && Array.isArray(result.user.positions)) {
45765
45929
  positions = result.user.positions.filter((p) => p != null).map((p) => this.transformGraphPositionToLoanData(p));
@@ -45769,6 +45933,137 @@ var DiamondHandsGraph = class {
45769
45933
  total
45770
45934
  };
45771
45935
  }
45936
+ /**
45937
+ * Get user positions with enriched Bitcoin balance data
45938
+ *
45939
+ * Same as getUserPositions but queries actual BTC balance from Bitcoin network
45940
+ * for each vault address in parallel.
45941
+ *
45942
+ * @param userAddress - User's Ethereum address
45943
+ * @param first - Optional: max number of positions to return (default: 10)
45944
+ * @param skip - Optional: number of positions to skip (default: 0)
45945
+ * @param orderBy - Optional: field to order by (default: "createdAt")
45946
+ * @param orderDirection - Optional: asc or desc (default: "desc" - most recent first)
45947
+ * @returns Positions with actual BTC balances from Bitcoin network
45948
+ */
45949
+ async getUserPositionsWithBtc(userAddress, first = 10, skip = 0, orderBy = "createdAt", orderDirection = "desc") {
45950
+ const result = await this.getUserPositions(
45951
+ userAddress,
45952
+ first,
45953
+ skip,
45954
+ orderBy,
45955
+ orderDirection
45956
+ );
45957
+ if (!this.bitcoinOps) {
45958
+ console.warn(
45959
+ "[DiamondHandsGraph] BitcoinOperations not available - returning positions without BTC balance"
45960
+ );
45961
+ return result;
45962
+ }
45963
+ const positionsWithPkp = result.positions.filter(
45964
+ (p) => p.pkpId && p.pkpId !== ""
45965
+ );
45966
+ if (positionsWithPkp.length === 0) {
45967
+ console.log("[DiamondHandsGraph] No positions with PKP IDs to check");
45968
+ return result;
45969
+ }
45970
+ console.log(
45971
+ `[DiamondHandsGraph] Deriving Bitcoin addresses and querying balances for ${positionsWithPkp.length} positions in parallel...`
45972
+ );
45973
+ const balancePromises = positionsWithPkp.map(async (position) => {
45974
+ try {
45975
+ const pkpPublicKey = await getPKPPublicKeyFromTokenId(position.pkpId);
45976
+ const addressResult = await this.bitcoinOps.deriveAddresses(
45977
+ pkpPublicKey
45978
+ );
45979
+ if (!addressResult.success) {
45980
+ console.warn(
45981
+ `[DiamondHandsGraph] Failed to derive address for PKP public key ${pkpPublicKey}:`,
45982
+ addressResult.error
45983
+ );
45984
+ return {
45985
+ pkpId: position.pkpId,
45986
+ address: null,
45987
+ balance: null,
45988
+ addresses: null
45989
+ };
45990
+ }
45991
+ const addresses = addressResult.value;
45992
+ const btcAddress = addresses.regtest || addresses.testnet || addresses.mainnet;
45993
+ if (!btcAddress) {
45994
+ console.warn(
45995
+ `[DiamondHandsGraph] No Bitcoin address available for PKP ${position.pkpId}`
45996
+ );
45997
+ return {
45998
+ pkpId: position.pkpId,
45999
+ address: null,
46000
+ balance: null,
46001
+ addresses
46002
+ };
46003
+ }
46004
+ const balanceResult = await this.bitcoinOps.getBalance(btcAddress);
46005
+ if (balanceResult.success) {
46006
+ return {
46007
+ pkpId: position.pkpId,
46008
+ address: btcAddress,
46009
+ balance: balanceResult.value,
46010
+ addresses
46011
+ };
46012
+ } else {
46013
+ console.warn(
46014
+ `[DiamondHandsGraph] Failed to get balance for ${btcAddress}:`,
46015
+ balanceResult.error
46016
+ );
46017
+ return {
46018
+ pkpId: position.pkpId,
46019
+ address: btcAddress,
46020
+ balance: null,
46021
+ addresses
46022
+ };
46023
+ }
46024
+ } catch (error) {
46025
+ console.error(
46026
+ `[DiamondHandsGraph] Error processing PKP ${position.pkpId}:`,
46027
+ error
46028
+ );
46029
+ return {
46030
+ pkpId: position.pkpId,
46031
+ address: null,
46032
+ balance: null,
46033
+ addresses: null
46034
+ };
46035
+ }
46036
+ });
46037
+ const balanceResults = await Promise.all(balancePromises);
46038
+ const balanceMap = /* @__PURE__ */ new Map();
46039
+ balanceResults.forEach(({ pkpId, address, balance, addresses }) => {
46040
+ balanceMap.set(pkpId, { address, balance, addresses });
46041
+ });
46042
+ console.log(
46043
+ `[DiamondHandsGraph] Retrieved ${balanceResults.length} BTC balances`
46044
+ );
46045
+ const enrichedPositions = result.positions.map((position) => {
46046
+ if (!position.pkpId) {
46047
+ return position;
46048
+ }
46049
+ const data = balanceMap.get(position.pkpId);
46050
+ if (!data) {
46051
+ return position;
46052
+ }
46053
+ return {
46054
+ ...position,
46055
+ collateral: {
46056
+ ...position.collateral,
46057
+ vaultAddress: data.address || position.collateral?.vaultAddress || ""
46058
+ },
46059
+ btcBalance: data.balance || void 0
46060
+ };
46061
+ });
46062
+ return {
46063
+ positions: enrichedPositions,
46064
+ total: result.total
46065
+ };
46066
+ }
45772
46067
  /**
45773
46068
  * Get position by PKP ID from subgraph
45774
46069
  */
@@ -45871,10 +46166,7 @@ var DiamondHandsGraph = class {
45871
46166
  const variables = {
45872
46167
  pkpId: pkpId.toLowerCase()
45873
46168
  };
45874
- const result = await this.client.execute(
45875
- query,
45876
- variables
45877
- );
46169
+ const result = await this.client.execute(query, variables);
45878
46170
  if (!result || !result.positions) {
45879
46171
  return null;
45880
46172
  }
@@ -45951,10 +46243,7 @@ var DiamondHandsGraph = class {
45951
46243
  const variables = {
45952
46244
  positionId: positionId.toLowerCase()
45953
46245
  };
45954
- const result = await this.client.execute(
45955
- query,
45956
- variables
45957
- );
46246
+ const result = await this.client.execute(query, variables);
45958
46247
  if (!result || !result.positions) {
45959
46248
  return null;
45960
46249
  }
@@ -46027,10 +46316,12 @@ var DiamondHandsGraph = class {
46027
46316
  }
46028
46317
  }
46029
46318
  `;
46030
- const result = await this.client.execute(
46031
- query,
46032
- { first, skip, orderBy, orderDirection }
46033
- );
46319
+ const result = await this.client.execute(query, {
46320
+ first,
46321
+ skip,
46322
+ orderBy,
46323
+ orderDirection
46324
+ });
46034
46325
  const total = await this.getTotalCountPaginated();
46035
46326
  const positions = result && result.positions || [];
46036
46327
  const transformedPositions = positions.map(
@@ -46072,10 +46363,13 @@ var DiamondHandsGraph = class {
46072
46363
  }
46073
46364
  }
46074
46365
  `;
46075
- const result = await this.client.execute(
46076
- query,
46077
- { first, skip, statuses, orderBy, orderDirection }
46078
- );
46366
+ const result = await this.client.execute(query, {
46367
+ first,
46368
+ skip,
46369
+ statuses,
46370
+ orderBy,
46371
+ orderDirection
46372
+ });
46079
46373
  const total = await this.getTotalCountPaginated(
46080
46374
  "{ status_in: $statuses }",
46081
46375
  { statuses }
@@ -46196,7 +46490,10 @@ var DiamondHandsGraph = class {
46196
46490
  `;
46197
46491
  const first = options?.first ?? this.defaultPageSize;
46198
46492
  const skip = options?.skip ?? 0;
46199
- const result = await this.client.execute(query, { first, skip });
46493
+ const result = await this.client.execute(
46494
+ query,
46495
+ { first, skip }
46496
+ );
46200
46497
  return result.loanTerms || [];
46201
46498
  }
46202
46499
  /**
@@ -46218,7 +46515,10 @@ var DiamondHandsGraph = class {
46218
46515
  }
46219
46516
  }
46220
46517
  `;
46221
- const result = await this.client.execute(query, { id: id3 });
46518
+ const result = await this.client.execute(
46519
+ query,
46520
+ { id: id3 }
46521
+ );
46222
46522
  return result.loanTerm || null;
46223
46523
  }
46224
46524
  // ============================================================================
@@ -46335,7 +46635,13 @@ var DiamondHandsGraph = class {
46335
46635
  * Get PSM transactions with filters
46336
46636
  */
46337
46637
  async getPSMTransactions(filters) {
46338
- const { user, stablecoin, type, first = this.defaultPageSize, skip = 0 } = filters || {};
46638
+ const {
46639
+ user,
46640
+ stablecoin,
46641
+ type,
46642
+ first = this.defaultPageSize,
46643
+ skip = 0
46644
+ } = filters || {};
46339
46645
  let whereConditions = [];
46340
46646
  if (user)
46341
46647
  whereConditions.push(`user: "${user.toLowerCase()}"`);
@@ -46395,7 +46701,10 @@ var DiamondHandsGraph = class {
46395
46701
  }
46396
46702
  `;
46397
46703
  const variables = { first };
46398
- const result = await this.client.execute(query, variables);
46704
+ const result = await this.client.execute(
46705
+ query,
46706
+ variables
46707
+ );
46399
46708
  return result.psmDailyMetrics || [];
46400
46709
  }
46401
46710
  // ============================================================================
@@ -46530,19 +46839,21 @@ var DiamondHandsGraph = class {
46530
46839
  orderDirection
46531
46840
  };
46532
46841
  const result = await this.client.execute(query, variables);
46533
- const payments = (result.position?.payments || []).map((p) => ({
46534
- id: p.id,
46535
- positionId,
46536
- payer: p.payer.id,
46537
- amount: p.amount,
46538
- type: p.type,
46539
- transactionHash: p.transactionHash,
46540
- timestamp: p.timestamp,
46541
- blockNumber: p.blockNumber,
46542
- logIndex: p.logIndex,
46543
- newDebt: p.newDebt,
46544
- newCollateralRatio: p.newCollateralRatio
46545
- }));
46842
+ const payments = (result.position?.payments || []).map(
46843
+ (p) => ({
46844
+ id: p.id,
46845
+ positionId,
46846
+ payer: p.payer.id,
46847
+ amount: p.amount,
46848
+ type: p.type,
46849
+ transactionHash: p.transactionHash,
46850
+ timestamp: p.timestamp,
46851
+ blockNumber: p.blockNumber,
46852
+ logIndex: p.logIndex,
46853
+ newDebt: p.newDebt,
46854
+ newCollateralRatio: p.newCollateralRatio
46855
+ })
46856
+ );
46546
46857
  const statusUpdates = (result.position?.statusUpdates || []).map((s) => ({
46547
46858
  id: s.id,
46548
46859
  positionId,
@@ -46744,10 +47055,10 @@ function createMockTokenManager(config) {
46744
47055
  var import_dh_lit_ops = require("@gvnrdao/dh-lit-ops");
46745
47056
 
46746
47057
  // src/utils/telegram-messaging.utils.ts
46747
- var import_node_telegram_bot_api = __toESM(require("node-telegram-bot-api"));
47058
+ var TelegramBot = null;
46748
47059
  async function sendTelegramMessage(chatId, chatToken, message, threadId) {
46749
47060
  try {
46750
- const bot = new import_node_telegram_bot_api.default(chatToken, { polling: false });
47061
+ const bot = new TelegramBot(chatToken, { polling: false });
46751
47062
  const options = {
46752
47063
  disable_web_page_preview: true
46753
47064
  };
@@ -46887,13 +47198,16 @@ var DiamondHandsSDK = class _DiamondHandsSDK {
46887
47198
  "Diamond Hands subgraph URL is required. Please provide config.subgraphs.diamondHandsUrl"
46888
47199
  );
46889
47200
  }
46890
- this.graphClient = new DiamondHandsGraph({
46891
- endpoint: graphEndpoint,
46892
- requestTimeoutMs: config.graphOptions?.requestTimeoutMs,
46893
- maxRetries: config.graphOptions?.maxRetries,
46894
- defaultPageSize: config.graphOptions?.pageSize,
46895
- headers: config.graphApiKey ? { Authorization: `Bearer ${config.graphApiKey}` } : void 0
46896
- });
47201
+ this.graphClient = new DiamondHandsGraph(
47202
+ {
47203
+ endpoint: graphEndpoint,
47204
+ requestTimeoutMs: config.graphOptions?.requestTimeoutMs,
47205
+ maxRetries: config.graphOptions?.maxRetries,
47206
+ defaultPageSize: config.graphOptions?.pageSize,
47207
+ headers: config.graphApiKey ? { Authorization: `Bearer ${config.graphApiKey}` } : void 0
47208
+ },
47209
+ this.bitcoinOperations
47210
+ );
46897
47211
  const loanQueryResult = createLoanQuery({
46898
47212
  graphClient: this.graphClient,
46899
47213
  bitcoinOperations: this.bitcoinOperations,
@@ -47535,6 +47849,8 @@ var DiamondHandsSDK = class _DiamondHandsSDK {
47535
47849
  log.info(` Mode: ${auth.mode}`);
47536
47850
  log.info(` Signature: ${auth.signature.substring(0, 20)}...`);
47537
47851
  }
47852
+ await waitUntilTimestamp(auth.timestamp);
47853
+ validateQuantumTiming(auth.timestamp, 30);
47538
47854
  litActionResult = await this.litOps.requestMintAuthorization({
47539
47855
  authMessage: {
47540
47856
  ...auth,
@@ -48306,6 +48622,8 @@ var DiamondHandsSDK = class _DiamondHandsSDK {
48306
48622
  log.info(` Mode: ${auth.mode}`);
48307
48623
  log.info(` Signature: ${auth.signature.substring(0, 20)}...`);
48308
48624
  }
48625
+ await waitUntilTimestamp(auth.timestamp);
48626
+ validateQuantumTiming(auth.timestamp, 30);
48309
48627
  litActionResult = await this.litOps.requestWithdrawalAuthorization({
48310
48628
  authMessage: {
48311
48629
  ...auth,