@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.mjs CHANGED
@@ -12754,48 +12754,48 @@ var init_deployment_addresses = __esm({
12754
12754
  LOCALHOST_DEPLOYMENT = {
12755
12755
  "network": "localhost",
12756
12756
  "chainId": 31337,
12757
- "timestamp": "2025-12-05T21:33:05.298Z",
12757
+ "timestamp": "2025-12-11T16:44:37.280Z",
12758
12758
  "deployer": "",
12759
12759
  "contracts": {
12760
- "UpgradeValidator": "0x0DCd1Bf9A1b36cE34237eEaFef220932846BCD82",
12760
+ "UpgradeValidator": "0x2279B7A0a67DB372996a5FaB50D91eAA73d2eBe6",
12761
12761
  "UCDToken": "0xe7f1725E7734CE288F8367e1Bb143E90bb3F0512",
12762
12762
  "UCDController": "0xCf7Ed3AccA5a467e9e704C703E8D87F634fB0Fc9",
12763
- "PriceFeedConsumer": "0x0B306BF915C4d645ff596e518fAf3F9669b97016",
12764
- "BTCProofValidator": "0x9A9f2CCfdE556A7E9Ff0848998Aa4a0CFD8863AE",
12765
- "UCDMintingRewards": "0x3Aa5ebB10DC797CAC828524e59A333d0A371443c",
12766
- "PositionManagerCoreModule": "0x59b670e9fA9D0A427751Af201D676719a970857b",
12767
- "TermManagerModule": "0x322813Fd9A801c5507c9de605d63CEA4f2CE6c44",
12768
- "LoanOperationsManagerModule": "0x09635F643e140090A9A8Dcd712eD6285858ceBef",
12769
- "CollateralManagerModule": "0x67d269191c92Caf3cD7723F116c85e6E9bf55933",
12770
- "LiquidationManagerModule": "0xc3e53F4d16Ae77Db1c982e75a937B9f60FE63690",
12771
- "CircuitBreakerModule": "0x4A679253410272dd5232B3Ff7cF5dbB88f295319",
12772
- "CommunityManagerModule": "0x9E545E3C0baAB3E08CdfD552C960A1050f373042",
12773
- "AdminModule": "0x1613beB3B2C4f22Ee086B2b38C1476A3cE7f78E8",
12774
- "PositionManagerViews": "0x851356ae760d987E095750cCeb3bC6014560891C",
12775
- "PositionManager": "0x95401dc811bb5740090279Ba06cfA8fcF6113778",
12776
- "OperationAuthorizationRegistry": "0x5f3f1dBD7B74C6B46e8c44f98792A1dAf8d69154",
12777
- "PKPValidation": "0x82e01223d51Eb87e16A03E24687EDF0F294da6f1"
12763
+ "PriceFeedConsumer": "0x610178dA211FEF7D417bC0e6FeD39F05609AD788",
12764
+ "BTCProofValidator": "0xA51c1fc2f0D1a1b8494Ed1FE312d7C3a78Ed91C0",
12765
+ "UCDMintingRewards": "0x9A676e781A523b5d0C0e43731313A708CB607508",
12766
+ "PositionManagerCoreModule": "0x959922bE3CAee4b8Cd9a407cc3ac1C251C2007B1",
12767
+ "TermManagerModule": "0x68B1D87F95878fE05B998F19b66F4baba5De1aed",
12768
+ "LoanOperationsManagerModule": "0x4ed7c70F96B99c776995fB64377f0d4aB3B0e1C1",
12769
+ "CollateralManagerModule": "0xa85233C63b9Ee964Add6F2cffe00Fd84eb32338f",
12770
+ "LiquidationManagerModule": "0x7a2088a1bFc9d81c55368AE168C2C02570cB814F",
12771
+ "CircuitBreakerModule": "0xc6e7DF5E7b4f2A278906862b61205850344D4e7d",
12772
+ "CommunityManagerModule": "0xc5a5C42992dECbae36851359345FE25997F5C42d",
12773
+ "AdminModule": "0xE6E340D132b5f46d1e472DebcD681B2aBc16e57E",
12774
+ "PositionManagerViews": "0xc3e53F4d16Ae77Db1c982e75a937B9f60FE63690",
12775
+ "PositionManager": "0x9E545E3C0baAB3E08CdfD552C960A1050f373042",
12776
+ "OperationAuthorizationRegistry": "0x5eb3Bc0a489C5A8288765d2336659EbCA68FCd00",
12777
+ "PKPValidation": "0x4c5859f0F772848b2D91F1D83E2Fe57935348029"
12778
12778
  }
12779
12779
  };
12780
12780
  LOCALHOST_CONTRACTS = {
12781
- "UpgradeValidator": "0x0DCd1Bf9A1b36cE34237eEaFef220932846BCD82",
12781
+ "UpgradeValidator": "0x2279B7A0a67DB372996a5FaB50D91eAA73d2eBe6",
12782
12782
  "UCDToken": "0xe7f1725E7734CE288F8367e1Bb143E90bb3F0512",
12783
12783
  "UCDController": "0xCf7Ed3AccA5a467e9e704C703E8D87F634fB0Fc9",
12784
- "PriceFeedConsumer": "0x0B306BF915C4d645ff596e518fAf3F9669b97016",
12785
- "BTCProofValidator": "0x9A9f2CCfdE556A7E9Ff0848998Aa4a0CFD8863AE",
12786
- "UCDMintingRewards": "0x3Aa5ebB10DC797CAC828524e59A333d0A371443c",
12787
- "PositionManagerCoreModule": "0x59b670e9fA9D0A427751Af201D676719a970857b",
12788
- "TermManagerModule": "0x322813Fd9A801c5507c9de605d63CEA4f2CE6c44",
12789
- "LoanOperationsManagerModule": "0x09635F643e140090A9A8Dcd712eD6285858ceBef",
12790
- "CollateralManagerModule": "0x67d269191c92Caf3cD7723F116c85e6E9bf55933",
12791
- "LiquidationManagerModule": "0xc3e53F4d16Ae77Db1c982e75a937B9f60FE63690",
12792
- "CircuitBreakerModule": "0x4A679253410272dd5232B3Ff7cF5dbB88f295319",
12793
- "CommunityManagerModule": "0x9E545E3C0baAB3E08CdfD552C960A1050f373042",
12794
- "AdminModule": "0x1613beB3B2C4f22Ee086B2b38C1476A3cE7f78E8",
12795
- "PositionManagerViews": "0x851356ae760d987E095750cCeb3bC6014560891C",
12796
- "PositionManager": "0x95401dc811bb5740090279Ba06cfA8fcF6113778",
12797
- "OperationAuthorizationRegistry": "0x5f3f1dBD7B74C6B46e8c44f98792A1dAf8d69154",
12798
- "PKPValidation": "0x82e01223d51Eb87e16A03E24687EDF0F294da6f1"
12784
+ "PriceFeedConsumer": "0x610178dA211FEF7D417bC0e6FeD39F05609AD788",
12785
+ "BTCProofValidator": "0xA51c1fc2f0D1a1b8494Ed1FE312d7C3a78Ed91C0",
12786
+ "UCDMintingRewards": "0x9A676e781A523b5d0C0e43731313A708CB607508",
12787
+ "PositionManagerCoreModule": "0x959922bE3CAee4b8Cd9a407cc3ac1C251C2007B1",
12788
+ "TermManagerModule": "0x68B1D87F95878fE05B998F19b66F4baba5De1aed",
12789
+ "LoanOperationsManagerModule": "0x4ed7c70F96B99c776995fB64377f0d4aB3B0e1C1",
12790
+ "CollateralManagerModule": "0xa85233C63b9Ee964Add6F2cffe00Fd84eb32338f",
12791
+ "LiquidationManagerModule": "0x7a2088a1bFc9d81c55368AE168C2C02570cB814F",
12792
+ "CircuitBreakerModule": "0xc6e7DF5E7b4f2A278906862b61205850344D4e7d",
12793
+ "CommunityManagerModule": "0xc5a5C42992dECbae36851359345FE25997F5C42d",
12794
+ "AdminModule": "0xE6E340D132b5f46d1e472DebcD681B2aBc16e57E",
12795
+ "PositionManagerViews": "0xc3e53F4d16Ae77Db1c982e75a937B9f60FE63690",
12796
+ "PositionManager": "0x9E545E3C0baAB3E08CdfD552C960A1050f373042",
12797
+ "OperationAuthorizationRegistry": "0x5eb3Bc0a489C5A8288765d2336659EbCA68FCd00",
12798
+ "PKPValidation": "0x4c5859f0F772848b2D91F1D83E2Fe57935348029"
12799
12799
  };
12800
12800
  ALL_DEPLOYMENTS = {
12801
12801
  sepolia: SEPOLIA_DEPLOYMENT,
@@ -12943,7 +12943,7 @@ function getSepoliaConfig() {
12943
12943
  operationAuthorizationRegistry: SEPOLIA_CONTRACTS.OperationAuthorizationRegistry || ""
12944
12944
  },
12945
12945
  subgraphs: {
12946
- diamondHandsUrl: "https://api.studio.thegraph.com/query/65258/diamond-hands/version/latest"
12946
+ diamondHandsUrl: "https://api.studio.thegraph.com/query/65258/diamond-hands/v0.3.0-1765544881"
12947
12947
  },
12948
12948
  // litNetwork: "datil-test",
12949
12949
  debug: true
@@ -12997,8 +12997,14 @@ function getLocalhostConfig() {
12997
12997
  );
12998
12998
  logNetworkConfig("log", "[NetworkConfig] Localhost contracts:", {
12999
12999
  PositionManager: getAddress3("POSITION_MANAGER_ADDRESS", "PositionManager"),
13000
- PositionManagerCore: getAddress3("POSITION_MANAGER_CORE_ADDRESS", "PositionManagerCoreModule"),
13001
- LoanOperationsManagerModule: getAddress3("LOAN_OPERATIONS_MANAGER_ADDRESS", "LoanOperationsManagerModule"),
13000
+ PositionManagerCore: getAddress3(
13001
+ "POSITION_MANAGER_CORE_ADDRESS",
13002
+ "PositionManagerCoreModule"
13003
+ ),
13004
+ LoanOperationsManagerModule: getAddress3(
13005
+ "LOAN_OPERATIONS_MANAGER_ADDRESS",
13006
+ "LoanOperationsManagerModule"
13007
+ ),
13002
13008
  TermManagerModule: getAddress3("TERM_MANAGER_ADDRESS", "TermManagerModule"),
13003
13009
  UCDToken: getAddress3("UCD_TOKEN_ADDRESS", "UCDToken")
13004
13010
  });
@@ -13009,23 +13015,53 @@ function getLocalhostConfig() {
13009
13015
  name: "localhost",
13010
13016
  rpcUrls: ["http://localhost:8545"],
13011
13017
  contractAddresses: {
13012
- positionManager: getAddress3("POSITION_MANAGER_ADDRESS", "PositionManager"),
13013
- positionManagerCore: getAddress3("POSITION_MANAGER_CORE_ADDRESS", "PositionManagerCoreModule"),
13014
- positionManagerViews: getAddress3("POSITION_MANAGER_VIEWS_ADDRESS", "PositionManagerViews"),
13018
+ positionManager: getAddress3(
13019
+ "POSITION_MANAGER_ADDRESS",
13020
+ "PositionManager"
13021
+ ),
13022
+ positionManagerCore: getAddress3(
13023
+ "POSITION_MANAGER_CORE_ADDRESS",
13024
+ "PositionManagerCoreModule"
13025
+ ),
13026
+ positionManagerViews: getAddress3(
13027
+ "POSITION_MANAGER_VIEWS_ADDRESS",
13028
+ "PositionManagerViews"
13029
+ ),
13015
13030
  simplePsmV2: getAddress3("SIMPLE_PSM_V2_ADDRESS", "SimplePSMV2"),
13016
- loanOperationsManager: getAddress3("LOAN_OPERATIONS_MANAGER_ADDRESS", "LoanOperationsManagerModule"),
13031
+ loanOperationsManager: getAddress3(
13032
+ "LOAN_OPERATIONS_MANAGER_ADDRESS",
13033
+ "LoanOperationsManagerModule"
13034
+ ),
13017
13035
  termManager: getAddress3("TERM_MANAGER_ADDRESS", "TermManagerModule"),
13018
- circuitBreaker: getAddress3("CIRCUIT_BREAKER_ADDRESS", "CircuitBreakerModule"),
13019
- communityManager: getAddress3("COMMUNITY_MANAGER_ADDRESS", "CommunityManagerModule"),
13020
- liquidationManager: getAddress3("LIQUIDATION_MANAGER_ADDRESS", "LiquidationManagerModule"),
13036
+ circuitBreaker: getAddress3(
13037
+ "CIRCUIT_BREAKER_ADDRESS",
13038
+ "CircuitBreakerModule"
13039
+ ),
13040
+ communityManager: getAddress3(
13041
+ "COMMUNITY_MANAGER_ADDRESS",
13042
+ "CommunityManagerModule"
13043
+ ),
13044
+ liquidationManager: getAddress3(
13045
+ "LIQUIDATION_MANAGER_ADDRESS",
13046
+ "LiquidationManagerModule"
13047
+ ),
13021
13048
  ucdToken: getAddress3("UCD_TOKEN_ADDRESS", "UCDToken"),
13022
13049
  ucdController: getAddress3("UCD_CONTROLLER_ADDRESS", "UCDController"),
13023
- btcProofValidator: getAddress3("BTC_PROOF_VALIDATOR_ADDRESS", "BTCProofValidator"),
13024
- priceFeedConsumer: getAddress3("PRICE_FEED_CONSUMER_ADDRESS", "PriceFeedConsumer"),
13025
- operationAuthorizationRegistry: getAddress3("OPERATION_AUTHORIZATION_REGISTRY_ADDRESS", "OperationAuthorizationRegistry")
13050
+ btcProofValidator: getAddress3(
13051
+ "BTC_PROOF_VALIDATOR_ADDRESS",
13052
+ "BTCProofValidator"
13053
+ ),
13054
+ priceFeedConsumer: getAddress3(
13055
+ "PRICE_FEED_CONSUMER_ADDRESS",
13056
+ "PriceFeedConsumer"
13057
+ ),
13058
+ operationAuthorizationRegistry: getAddress3(
13059
+ "OPERATION_AUTHORIZATION_REGISTRY_ADDRESS",
13060
+ "OperationAuthorizationRegistry"
13061
+ )
13026
13062
  },
13027
13063
  subgraphs: {
13028
- diamondHandsUrl: "https://api.studio.thegraph.com/query/65258/diamond-hands/version/latest"
13064
+ diamondHandsUrl: "https://api.studio.thegraph.com/query/65258/diamond-hands/v0.3.0-1765544881"
13029
13065
  },
13030
13066
  litNetwork: "datil",
13031
13067
  debug: true
@@ -29068,42 +29104,70 @@ function validateSDKConfig(config) {
29068
29104
  }
29069
29105
 
29070
29106
  // src/utils/quantum-timing.ts
29071
- async function calculateValidQuantumTimestamp() {
29072
- console.log(" \u{1F3AF} Finding OPTIMAL quantum moment for signature...");
29073
- let now2 = Math.floor(Date.now() / 1e3);
29074
- let timeInQuantum = now2 % 100;
29075
- if (timeInQuantum !== 16) {
29076
- let waitSeconds;
29077
- if (timeInQuantum < 16) {
29078
- waitSeconds = 16 - timeInQuantum;
29079
- console.log(
29080
- ` \u23F3 Current: second ${timeInQuantum} - waiting ${waitSeconds}s for optimal moment (second 16)...`
29081
- );
29082
- } else {
29083
- waitSeconds = 100 - timeInQuantum + 16;
29084
- console.log(
29085
- ` \u23F3 Current: second ${timeInQuantum} - waiting ${waitSeconds}s for next optimal moment (second 16)...`
29086
- );
29087
- }
29088
- await new Promise((resolve) => setTimeout(resolve, waitSeconds * 1e3));
29089
- now2 = Math.floor(Date.now() / 1e3);
29090
- timeInQuantum = now2 % 100;
29091
- console.log(` \u2705 Optimal moment reached: second ${timeInQuantum}`);
29107
+ function calculateNextQuantumTimestamp() {
29108
+ const now2 = Math.floor(Date.now() / 1e3);
29109
+ const timeInQuantum = now2 % 100;
29110
+ const currentQuantum = Math.floor(now2 / 100) * 100;
29111
+ let targetTimestamp;
29112
+ if (timeInQuantum >= 16 && timeInQuantum <= 30) {
29113
+ targetTimestamp = now2;
29114
+ console.log(
29115
+ "[Quantum Timing] Already at optimal moment in current quantum"
29116
+ );
29117
+ } else if (timeInQuantum < 16 && timeInQuantum >= 8) {
29118
+ targetTimestamp = currentQuantum + 16;
29119
+ console.log("[Quantum Timing] Targeting second 16 of CURRENT quantum");
29092
29120
  } else {
29093
- console.log(` \u2705 Already at optimal moment: second ${timeInQuantum}`);
29094
- }
29095
- const timestamp = Math.floor(Date.now() / 1e3);
29096
- const quantumWindow = Math.floor(timestamp / 100) * 100;
29097
- const timeInQuantumNow = timestamp % 100;
29098
- console.log(" \u{1F4DD} Timestamp Details:");
29099
- console.log(" Timestamp:", timestamp);
29100
- console.log(" Quantum window:", quantumWindow);
29121
+ const nextQuantum = currentQuantum + 100;
29122
+ targetTimestamp = nextQuantum + 16;
29123
+ console.log("[Quantum Timing] Targeting second 16 of NEXT quantum");
29124
+ }
29125
+ console.log("[Quantum Timing] Calculated quantum timing:");
29126
+ console.log(" Current time:", now2);
29127
+ console.log(" Time in quantum:", timeInQuantum);
29128
+ console.log(" Target timestamp:", targetTimestamp);
29129
+ console.log(" Seconds until target:", targetTimestamp - now2);
29130
+ return targetTimestamp;
29131
+ }
29132
+ async function waitUntilTimestamp(targetTimestamp) {
29133
+ const now2 = Math.floor(Date.now() / 1e3);
29134
+ const waitSeconds = targetTimestamp - now2;
29135
+ if (waitSeconds <= 0) {
29136
+ console.log("[Quantum Timing] Target timestamp already reached");
29137
+ return;
29138
+ }
29101
29139
  console.log(
29102
- " Time in quantum:",
29103
- timeInQuantumNow,
29104
- "seconds (OPTIMAL: 16)"
29140
+ `[Quantum Timing] Waiting ${waitSeconds}s until timestamp ${targetTimestamp}...`
29105
29141
  );
29106
- return timestamp;
29142
+ await new Promise((resolve) => setTimeout(resolve, waitSeconds * 1e3));
29143
+ console.log("[Quantum Timing] Target timestamp reached");
29144
+ }
29145
+ function validateQuantumTiming(signedTimestamp, bufferSeconds = 30) {
29146
+ const now2 = Math.floor(Date.now() / 1e3);
29147
+ const signedQuantum = Math.floor(signedTimestamp / 100) * 100;
29148
+ const currentQuantum = Math.floor(now2 / 100) * 100;
29149
+ if (currentQuantum !== signedQuantum) {
29150
+ throw new Error(
29151
+ `Quantum window expired. User took too long to sign. Signed quantum: ${signedQuantum}, Current quantum: ${currentQuantum}`
29152
+ );
29153
+ }
29154
+ const timeInQuantum = now2 % 100;
29155
+ const isInDeadZone = timeInQuantum < 8 || timeInQuantum >= 92;
29156
+ if (isInDeadZone) {
29157
+ throw new Error(
29158
+ `Current time (${timeInQuantum}s in quantum) is in dead zone. Operation cannot proceed safely.`
29159
+ );
29160
+ }
29161
+ const secondsRemaining = 92 - timeInQuantum;
29162
+ if (secondsRemaining < bufferSeconds) {
29163
+ throw new Error(
29164
+ `Insufficient time remaining in quantum. Required: ${bufferSeconds}s, Available: ${secondsRemaining}s`
29165
+ );
29166
+ }
29167
+ console.log("[Quantum Timing] Validation passed:");
29168
+ console.log(" Time in quantum:", timeInQuantum);
29169
+ console.log(" Seconds remaining:", secondsRemaining);
29170
+ console.log(" Required buffer:", bufferSeconds);
29107
29171
  }
29108
29172
 
29109
29173
  // src/utils/mint-authorization.utils.ts
@@ -29117,7 +29181,7 @@ var PKP_NFT_ADDRESSES = {
29117
29181
  // Yellowstone/Datil (PKP native network) - same as Datil testnet
29118
29182
  };
29119
29183
  async function generateMintAuthorization(positionId, amount, chainId, mode, signer) {
29120
- const timestamp = await calculateValidQuantumTimestamp();
29184
+ const timestamp = calculateNextQuantumTimestamp();
29121
29185
  const action = "mint-ucd";
29122
29186
  const actionHash = ethers_exports.utils.keccak256(ethers_exports.utils.toUtf8Bytes(action));
29123
29187
  const types = [
@@ -29151,7 +29215,8 @@ async function generateMintAuthorization(positionId, amount, chainId, mode, sign
29151
29215
  console.log(" Action Hash:", actionHash);
29152
29216
  console.log(" Message Hash (solidityKeccak256):", messageHash);
29153
29217
  console.log(" Message Hash Bytes Length:", messageHashBytes.length);
29154
- console.log(" Signer Address:", signer.address);
29218
+ const signerAddress = await signer.getAddress();
29219
+ console.log(" Signer Address:", signerAddress);
29155
29220
  const signature2 = await signer.signMessage(messageHashBytes);
29156
29221
  return {
29157
29222
  positionId,
@@ -29195,7 +29260,7 @@ async function getPKPPublicKeyFromTokenId(pkpTokenId, provider) {
29195
29260
  return pubkeyBytes.startsWith("0x") ? pubkeyBytes : `0x${pubkeyBytes}`;
29196
29261
  }
29197
29262
  async function generateWithdrawAuthorization(positionId, amount, chainId, mode, signer, destinationAddress) {
29198
- const timestamp = await calculateValidQuantumTimestamp();
29263
+ const timestamp = calculateNextQuantumTimestamp();
29199
29264
  const action = "withdraw-btc";
29200
29265
  const actionHash = ethers_exports.utils.keccak256(ethers_exports.utils.toUtf8Bytes(action));
29201
29266
  const types = [
@@ -29231,7 +29296,8 @@ async function generateWithdrawAuthorization(positionId, amount, chainId, mode,
29231
29296
  console.log(" Action:", action);
29232
29297
  console.log(" Action Hash:", actionHash);
29233
29298
  console.log(" Message Hash (solidityKeccak256):", messageHash);
29234
- console.log(" Signer Address:", signer.address);
29299
+ const signerAddress = await signer.getAddress();
29300
+ console.log(" Signer Address:", signerAddress);
29235
29301
  const signature2 = await signer.signMessage(messageHashBytes);
29236
29302
  console.log("[SDK Withdrawal Authorization] Signature generated:");
29237
29303
  console.log(" Signature:", signature2);
@@ -29240,7 +29306,7 @@ async function generateWithdrawAuthorization(positionId, amount, chainId, mode,
29240
29306
  console.log(" Recovered Address (for verification):", recovered);
29241
29307
  console.log(
29242
29308
  " Signer Matches Recovered:",
29243
- recovered.toLowerCase() === signer.address.toLowerCase() ? "\u2705 YES" : "\u274C NO"
29309
+ recovered.toLowerCase() === signerAddress.toLowerCase() ? "\u2705 YES" : "\u274C NO"
29244
29310
  );
29245
29311
  return {
29246
29312
  positionId,
@@ -41851,38 +41917,86 @@ var ContractManager = class {
41851
41917
  }
41852
41918
  const contractRunner = runner;
41853
41919
  const contracts = {
41854
- positionManager: PositionManager__factory.connect(
41855
- contractAddresses.positionManager,
41856
- contractRunner
41857
- ),
41858
- loanOperationsManager: ILoanOperationsManager__factory.connect(
41859
- contractAddresses.loanOperationsManager || ethers_exports.constants.AddressZero,
41860
- contractRunner
41861
- ),
41862
- ucdController: IUCDController__factory.connect(
41863
- contractAddresses.ucdToken,
41864
- contractRunner
41865
- ),
41866
- priceFeed: IPriceFeedConsumer__factory.connect(
41867
- contractAddresses.priceFeedConsumer,
41868
- contractRunner
41869
- ),
41870
- termManager: ITermManager__factory.connect(
41871
- contractAddresses.termManager || ethers_exports.constants.AddressZero,
41872
- contractRunner
41873
- ),
41874
- circuitBreaker: CircuitBreakerModule__factory.connect(
41875
- contractAddresses.circuitBreaker || ethers_exports.constants.AddressZero,
41876
- contractRunner
41877
- ),
41878
- communityManager: ICommunityManager__factory.connect(
41879
- contractAddresses.communityManager || ethers_exports.constants.AddressZero,
41880
- contractRunner
41881
- ),
41882
- liquidationManager: ILiquidationManager__factory.connect(
41883
- contractAddresses.liquidationManager || ethers_exports.constants.AddressZero,
41884
- contractRunner
41885
- )
41920
+ positionManager: (() => {
41921
+ try {
41922
+ return PositionManager__factory.connect(
41923
+ contractAddresses.positionManager,
41924
+ contractRunner
41925
+ );
41926
+ } catch (error) {
41927
+ throw new Error(`Failed to connect to PositionManager at ${contractAddresses.positionManager}: ${error}`);
41928
+ }
41929
+ })(),
41930
+ loanOperationsManager: (() => {
41931
+ try {
41932
+ return ILoanOperationsManager__factory.connect(
41933
+ contractAddresses.loanOperationsManager || ethers_exports.constants.AddressZero,
41934
+ contractRunner
41935
+ );
41936
+ } catch (error) {
41937
+ throw new Error(`Failed to connect to LoanOperationsManager at ${contractAddresses.loanOperationsManager}: ${error}`);
41938
+ }
41939
+ })(),
41940
+ ucdController: (() => {
41941
+ try {
41942
+ return IUCDController__factory.connect(
41943
+ contractAddresses.ucdToken,
41944
+ contractRunner
41945
+ );
41946
+ } catch (error) {
41947
+ throw new Error(`Failed to connect to UCDController at ${contractAddresses.ucdToken}: ${error}`);
41948
+ }
41949
+ })(),
41950
+ priceFeed: (() => {
41951
+ try {
41952
+ return IPriceFeedConsumer__factory.connect(
41953
+ contractAddresses.priceFeedConsumer,
41954
+ contractRunner
41955
+ );
41956
+ } catch (error) {
41957
+ throw new Error(`Failed to connect to PriceFeed at ${contractAddresses.priceFeedConsumer}: ${error}`);
41958
+ }
41959
+ })(),
41960
+ termManager: (() => {
41961
+ try {
41962
+ return ITermManager__factory.connect(
41963
+ contractAddresses.termManager || ethers_exports.constants.AddressZero,
41964
+ contractRunner
41965
+ );
41966
+ } catch (error) {
41967
+ throw new Error(`Failed to connect to TermManager at ${contractAddresses.termManager}: ${error}`);
41968
+ }
41969
+ })(),
41970
+ circuitBreaker: (() => {
41971
+ try {
41972
+ return CircuitBreakerModule__factory.connect(
41973
+ contractAddresses.circuitBreaker || ethers_exports.constants.AddressZero,
41974
+ contractRunner
41975
+ );
41976
+ } catch (error) {
41977
+ throw new Error(`Failed to connect to CircuitBreaker at ${contractAddresses.circuitBreaker}: ${error}`);
41978
+ }
41979
+ })(),
41980
+ communityManager: (() => {
41981
+ try {
41982
+ return ICommunityManager__factory.connect(
41983
+ contractAddresses.communityManager || ethers_exports.constants.AddressZero,
41984
+ contractRunner
41985
+ );
41986
+ } catch (error) {
41987
+ throw new Error(`Failed to connect to CommunityManager at ${contractAddresses.communityManager}: ${error}`);
41988
+ }
41989
+ })(),
41990
+ liquidationManager: (() => {
41991
+ try {
41992
+ return ILiquidationManager__factory.connect(
41993
+ contractAddresses.liquidationManager || ethers_exports.constants.AddressZero,
41994
+ contractRunner
41995
+ );
41996
+ } catch (error) {
41997
+ throw new Error(`Failed to connect to LiquidationManager at ${contractAddresses.liquidationManager}: ${error}`);
41998
+ }
41999
+ })()
41886
42000
  };
41887
42001
  this.contracts = contracts;
41888
42002
  return success(contracts);
@@ -43562,6 +43676,55 @@ var LoanQuery = class {
43562
43676
  })
43563
43677
  );
43564
43678
  }
43679
+ /**
43680
+ * Get loans with BTC balance data from Bitcoin network
43681
+ *
43682
+ * Same as getLoans but includes actual Bitcoin balance for each position's vault.
43683
+ * Queries BTC balances in parallel for performance.
43684
+ *
43685
+ * @param filters - Query filters
43686
+ * @param pagination - Pagination parameters
43687
+ * @returns Paginated loans response with BTC balance data
43688
+ */
43689
+ async getLoansWithBtc(filters = {}, pagination) {
43690
+ const page = pagination?.page || 0;
43691
+ const pageSize = pagination?.pageSize || this.defaultPageSize;
43692
+ const skip = page * pageSize;
43693
+ if (!filters.borrower) {
43694
+ if (this.config.debug) {
43695
+ log.info("\u26A0\uFE0F getLoansWithBtc only supports borrower filter, falling back to getLoans");
43696
+ }
43697
+ return this.getLoans(filters, pagination);
43698
+ }
43699
+ if (this.config.debug) {
43700
+ log.info("\u{1F50D} Querying loans with BTC balance data", { filters, page, pageSize, skip });
43701
+ }
43702
+ return tryCatchAsync(
43703
+ async () => {
43704
+ const result = await this.config.graphClient.getUserPositionsWithBtc(
43705
+ filters.borrower,
43706
+ pageSize,
43707
+ skip,
43708
+ filters.orderBy || "createdAt",
43709
+ filters.orderDirection || "desc"
43710
+ );
43711
+ const enrichedLoans = await this.enrichLoansWithVaultAddresses(result.positions);
43712
+ return {
43713
+ loans: enrichedLoans,
43714
+ page,
43715
+ maxRows: pageSize,
43716
+ totalLoans: result.total
43717
+ };
43718
+ },
43719
+ (error) => new SDKError({
43720
+ message: "Failed to query loans with BTC balance",
43721
+ category: "SUBGRAPH" /* SUBGRAPH */,
43722
+ severity: "MEDIUM" /* MEDIUM */,
43723
+ originalError: error instanceof Error ? error : new Error(String(error)),
43724
+ context: { filters, page, pageSize }
43725
+ })
43726
+ );
43727
+ }
43565
43728
  /**
43566
43729
  * Enrich loans with vault addresses derived from PKP public keys
43567
43730
  *
@@ -44147,7 +44310,10 @@ async function getBitcoinAddressesFromPkp(pkpPublicKey) {
44147
44310
  var BitcoinUtils = class {
44148
44311
  static validateAddress(address) {
44149
44312
  const base58Pattern = /^[123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz]+$/;
44150
- return base58Pattern.test(address) && address.length >= 26 && address.length <= 35;
44313
+ const isBase58 = base58Pattern.test(address) && address.length >= 26 && address.length <= 35;
44314
+ const bech32Pattern = /^(bc1|tb1|bcrt1)[a-z0-9]{39,87}$/;
44315
+ const isBech32 = bech32Pattern.test(address);
44316
+ return isBase58 || isBech32;
44151
44317
  }
44152
44318
  static formatTransaction(hash3, amount, recipient) {
44153
44319
  return {
@@ -45529,7 +45695,8 @@ var MIN_BITCOIN_PROVIDERS_FOR_CONSENSUS = 2;
45529
45695
  var DiamondHandsGraph = class {
45530
45696
  client;
45531
45697
  defaultPageSize;
45532
- constructor(config) {
45698
+ bitcoinOps;
45699
+ constructor(config, bitcoinOps) {
45533
45700
  this.client = new GraphClient({
45534
45701
  endpoint: config.endpoint,
45535
45702
  requestTimeoutMs: config.requestTimeoutMs,
@@ -45537,6 +45704,7 @@ var DiamondHandsGraph = class {
45537
45704
  headers: config.headers
45538
45705
  });
45539
45706
  this.defaultPageSize = config.defaultPageSize ?? 100;
45707
+ this.bitcoinOps = bitcoinOps;
45540
45708
  }
45541
45709
  /**
45542
45710
  * Transform graph position data to LoanData interface
@@ -45606,10 +45774,7 @@ var DiamondHandsGraph = class {
45606
45774
  }
45607
45775
  }
45608
45776
  `;
45609
- const result = await this.client.execute(
45610
- query,
45611
- { ...variables, skip }
45612
- );
45777
+ const result = await this.client.execute(query, { ...variables, skip });
45613
45778
  const items = result && result["positions"] || [];
45614
45779
  totalCount += items.length;
45615
45780
  hasMore = items.length === batchSize;
@@ -45661,10 +45826,9 @@ var DiamondHandsGraph = class {
45661
45826
  query,
45662
45827
  variables
45663
45828
  );
45664
- const total = await this.getTotalCountPaginated(
45665
- "{ borrower: $borrower }",
45666
- { borrower: userAddress.toLowerCase() }
45667
- );
45829
+ const total = await this.getTotalCountPaginated("{ borrower: $borrower }", {
45830
+ borrower: userAddress.toLowerCase()
45831
+ });
45668
45832
  let positions = [];
45669
45833
  if (result && result.user && Array.isArray(result.user.positions)) {
45670
45834
  positions = result.user.positions.filter((p) => p != null).map((p) => this.transformGraphPositionToLoanData(p));
@@ -45674,6 +45838,137 @@ var DiamondHandsGraph = class {
45674
45838
  total
45675
45839
  };
45676
45840
  }
45841
+ /**
45842
+ * Get user positions with enriched Bitcoin balance data
45843
+ *
45844
+ * Same as getUserPositions but queries actual BTC balance from Bitcoin network
45845
+ * for each vault address in parallel.
45846
+ *
45847
+ * @param userAddress - User's Ethereum address
45848
+ * @param first - Optional: max number of positions to return (default: 10)
45849
+ * @param skip - Optional: number of positions to skip (default: 0)
45850
+ * @param orderBy - Optional: field to order by (default: "createdAt")
45851
+ * @param orderDirection - Optional: asc or desc (default: "desc" - most recent first)
45852
+ * @returns Positions with actual BTC balances from Bitcoin network
45853
+ */
45854
+ async getUserPositionsWithBtc(userAddress, first = 10, skip = 0, orderBy = "createdAt", orderDirection = "desc") {
45855
+ const result = await this.getUserPositions(
45856
+ userAddress,
45857
+ first,
45858
+ skip,
45859
+ orderBy,
45860
+ orderDirection
45861
+ );
45862
+ if (!this.bitcoinOps) {
45863
+ console.warn(
45864
+ "[DiamondHandsGraph] BitcoinOperations not available - returning positions without BTC balance"
45865
+ );
45866
+ return result;
45867
+ }
45868
+ const positionsWithPkp = result.positions.filter(
45869
+ (p) => p.pkpId && p.pkpId !== ""
45870
+ );
45871
+ if (positionsWithPkp.length === 0) {
45872
+ console.log("[DiamondHandsGraph] No positions with PKP IDs to check");
45873
+ return result;
45874
+ }
45875
+ console.log(
45876
+ `[DiamondHandsGraph] Deriving Bitcoin addresses and querying balances for ${positionsWithPkp.length} positions in parallel...`
45877
+ );
45878
+ const balancePromises = positionsWithPkp.map(async (position) => {
45879
+ try {
45880
+ const pkpPublicKey = await getPKPPublicKeyFromTokenId(position.pkpId);
45881
+ const addressResult = await this.bitcoinOps.deriveAddresses(
45882
+ pkpPublicKey
45883
+ );
45884
+ if (!addressResult.success) {
45885
+ console.warn(
45886
+ `[DiamondHandsGraph] Failed to derive address for PKP public key ${pkpPublicKey}:`,
45887
+ addressResult.error
45888
+ );
45889
+ return {
45890
+ pkpId: position.pkpId,
45891
+ address: null,
45892
+ balance: null,
45893
+ addresses: null
45894
+ };
45895
+ }
45896
+ const addresses = addressResult.value;
45897
+ const btcAddress = addresses.regtest || addresses.testnet || addresses.mainnet;
45898
+ if (!btcAddress) {
45899
+ console.warn(
45900
+ `[DiamondHandsGraph] No Bitcoin address available for PKP ${position.pkpId}`
45901
+ );
45902
+ return {
45903
+ pkpId: position.pkpId,
45904
+ address: null,
45905
+ balance: null,
45906
+ addresses
45907
+ };
45908
+ }
45909
+ const balanceResult = await this.bitcoinOps.getBalance(btcAddress);
45910
+ if (balanceResult.success) {
45911
+ return {
45912
+ pkpId: position.pkpId,
45913
+ address: btcAddress,
45914
+ balance: balanceResult.value,
45915
+ addresses
45916
+ };
45917
+ } else {
45918
+ console.warn(
45919
+ `[DiamondHandsGraph] Failed to get balance for ${btcAddress}:`,
45920
+ balanceResult.error
45921
+ );
45922
+ return {
45923
+ pkpId: position.pkpId,
45924
+ address: btcAddress,
45925
+ balance: null,
45926
+ addresses
45927
+ };
45928
+ }
45929
+ } catch (error) {
45930
+ console.error(
45931
+ `[DiamondHandsGraph] Error processing PKP ${position.pkpId}:`,
45932
+ error
45933
+ );
45934
+ return {
45935
+ pkpId: position.pkpId,
45936
+ address: null,
45937
+ balance: null,
45938
+ addresses: null
45939
+ };
45940
+ }
45941
+ });
45942
+ const balanceResults = await Promise.all(balancePromises);
45943
+ const balanceMap = /* @__PURE__ */ new Map();
45944
+ balanceResults.forEach(({ pkpId, address, balance, addresses }) => {
45945
+ balanceMap.set(pkpId, { address, balance, addresses });
45946
+ });
45947
+ console.log(
45948
+ `[DiamondHandsGraph] Retrieved ${balanceResults.length} BTC balances`
45949
+ );
45950
+ const enrichedPositions = result.positions.map((position) => {
45951
+ if (!position.pkpId) {
45952
+ return position;
45953
+ }
45954
+ const data = balanceMap.get(position.pkpId);
45955
+ if (!data) {
45956
+ return position;
45957
+ }
45958
+ return {
45959
+ ...position,
45960
+ collateral: {
45961
+ ...position.collateral,
45962
+ vaultAddress: data.address || position.collateral?.vaultAddress || ""
45963
+ },
45964
+ btcBalance: data.balance || void 0
45965
+ };
45966
+ });
45967
+ return {
45968
+ positions: enrichedPositions,
45969
+ total: result.total
45970
+ };
45971
+ }
45677
45972
  /**
45678
45973
  * Get position by PKP ID from subgraph
45679
45974
  */
@@ -45776,10 +46071,7 @@ var DiamondHandsGraph = class {
45776
46071
  const variables = {
45777
46072
  pkpId: pkpId.toLowerCase()
45778
46073
  };
45779
- const result = await this.client.execute(
45780
- query,
45781
- variables
45782
- );
46074
+ const result = await this.client.execute(query, variables);
45783
46075
  if (!result || !result.positions) {
45784
46076
  return null;
45785
46077
  }
@@ -45856,10 +46148,7 @@ var DiamondHandsGraph = class {
45856
46148
  const variables = {
45857
46149
  positionId: positionId.toLowerCase()
45858
46150
  };
45859
- const result = await this.client.execute(
45860
- query,
45861
- variables
45862
- );
46151
+ const result = await this.client.execute(query, variables);
45863
46152
  if (!result || !result.positions) {
45864
46153
  return null;
45865
46154
  }
@@ -45932,10 +46221,12 @@ var DiamondHandsGraph = class {
45932
46221
  }
45933
46222
  }
45934
46223
  `;
45935
- const result = await this.client.execute(
45936
- query,
45937
- { first, skip, orderBy, orderDirection }
45938
- );
46224
+ const result = await this.client.execute(query, {
46225
+ first,
46226
+ skip,
46227
+ orderBy,
46228
+ orderDirection
46229
+ });
45939
46230
  const total = await this.getTotalCountPaginated();
45940
46231
  const positions = result && result.positions || [];
45941
46232
  const transformedPositions = positions.map(
@@ -45977,10 +46268,13 @@ var DiamondHandsGraph = class {
45977
46268
  }
45978
46269
  }
45979
46270
  `;
45980
- const result = await this.client.execute(
45981
- query,
45982
- { first, skip, statuses, orderBy, orderDirection }
45983
- );
46271
+ const result = await this.client.execute(query, {
46272
+ first,
46273
+ skip,
46274
+ statuses,
46275
+ orderBy,
46276
+ orderDirection
46277
+ });
45984
46278
  const total = await this.getTotalCountPaginated(
45985
46279
  "{ status_in: $statuses }",
45986
46280
  { statuses }
@@ -46101,7 +46395,10 @@ var DiamondHandsGraph = class {
46101
46395
  `;
46102
46396
  const first = options?.first ?? this.defaultPageSize;
46103
46397
  const skip = options?.skip ?? 0;
46104
- const result = await this.client.execute(query, { first, skip });
46398
+ const result = await this.client.execute(
46399
+ query,
46400
+ { first, skip }
46401
+ );
46105
46402
  return result.loanTerms || [];
46106
46403
  }
46107
46404
  /**
@@ -46123,7 +46420,10 @@ var DiamondHandsGraph = class {
46123
46420
  }
46124
46421
  }
46125
46422
  `;
46126
- const result = await this.client.execute(query, { id: id3 });
46423
+ const result = await this.client.execute(
46424
+ query,
46425
+ { id: id3 }
46426
+ );
46127
46427
  return result.loanTerm || null;
46128
46428
  }
46129
46429
  // ============================================================================
@@ -46240,7 +46540,13 @@ var DiamondHandsGraph = class {
46240
46540
  * Get PSM transactions with filters
46241
46541
  */
46242
46542
  async getPSMTransactions(filters) {
46243
- const { user, stablecoin, type, first = this.defaultPageSize, skip = 0 } = filters || {};
46543
+ const {
46544
+ user,
46545
+ stablecoin,
46546
+ type,
46547
+ first = this.defaultPageSize,
46548
+ skip = 0
46549
+ } = filters || {};
46244
46550
  let whereConditions = [];
46245
46551
  if (user)
46246
46552
  whereConditions.push(`user: "${user.toLowerCase()}"`);
@@ -46300,7 +46606,10 @@ var DiamondHandsGraph = class {
46300
46606
  }
46301
46607
  `;
46302
46608
  const variables = { first };
46303
- const result = await this.client.execute(query, variables);
46609
+ const result = await this.client.execute(
46610
+ query,
46611
+ variables
46612
+ );
46304
46613
  return result.psmDailyMetrics || [];
46305
46614
  }
46306
46615
  // ============================================================================
@@ -46435,19 +46744,21 @@ var DiamondHandsGraph = class {
46435
46744
  orderDirection
46436
46745
  };
46437
46746
  const result = await this.client.execute(query, variables);
46438
- const payments = (result.position?.payments || []).map((p) => ({
46439
- id: p.id,
46440
- positionId,
46441
- payer: p.payer.id,
46442
- amount: p.amount,
46443
- type: p.type,
46444
- transactionHash: p.transactionHash,
46445
- timestamp: p.timestamp,
46446
- blockNumber: p.blockNumber,
46447
- logIndex: p.logIndex,
46448
- newDebt: p.newDebt,
46449
- newCollateralRatio: p.newCollateralRatio
46450
- }));
46747
+ const payments = (result.position?.payments || []).map(
46748
+ (p) => ({
46749
+ id: p.id,
46750
+ positionId,
46751
+ payer: p.payer.id,
46752
+ amount: p.amount,
46753
+ type: p.type,
46754
+ transactionHash: p.transactionHash,
46755
+ timestamp: p.timestamp,
46756
+ blockNumber: p.blockNumber,
46757
+ logIndex: p.logIndex,
46758
+ newDebt: p.newDebt,
46759
+ newCollateralRatio: p.newCollateralRatio
46760
+ })
46761
+ );
46451
46762
  const statusUpdates = (result.position?.statusUpdates || []).map((s) => ({
46452
46763
  id: s.id,
46453
46764
  positionId,
@@ -46649,7 +46960,7 @@ function createMockTokenManager(config) {
46649
46960
  import { LitOps } from "@gvnrdao/dh-lit-ops";
46650
46961
 
46651
46962
  // src/utils/telegram-messaging.utils.ts
46652
- import TelegramBot from "node-telegram-bot-api";
46963
+ var TelegramBot = null;
46653
46964
  async function sendTelegramMessage(chatId, chatToken, message, threadId) {
46654
46965
  try {
46655
46966
  const bot = new TelegramBot(chatToken, { polling: false });
@@ -46792,13 +47103,16 @@ var DiamondHandsSDK = class _DiamondHandsSDK {
46792
47103
  "Diamond Hands subgraph URL is required. Please provide config.subgraphs.diamondHandsUrl"
46793
47104
  );
46794
47105
  }
46795
- this.graphClient = new DiamondHandsGraph({
46796
- endpoint: graphEndpoint,
46797
- requestTimeoutMs: config.graphOptions?.requestTimeoutMs,
46798
- maxRetries: config.graphOptions?.maxRetries,
46799
- defaultPageSize: config.graphOptions?.pageSize,
46800
- headers: config.graphApiKey ? { Authorization: `Bearer ${config.graphApiKey}` } : void 0
46801
- });
47106
+ this.graphClient = new DiamondHandsGraph(
47107
+ {
47108
+ endpoint: graphEndpoint,
47109
+ requestTimeoutMs: config.graphOptions?.requestTimeoutMs,
47110
+ maxRetries: config.graphOptions?.maxRetries,
47111
+ defaultPageSize: config.graphOptions?.pageSize,
47112
+ headers: config.graphApiKey ? { Authorization: `Bearer ${config.graphApiKey}` } : void 0
47113
+ },
47114
+ this.bitcoinOperations
47115
+ );
46802
47116
  const loanQueryResult = createLoanQuery({
46803
47117
  graphClient: this.graphClient,
46804
47118
  bitcoinOperations: this.bitcoinOperations,
@@ -47440,6 +47754,8 @@ var DiamondHandsSDK = class _DiamondHandsSDK {
47440
47754
  log.info(` Mode: ${auth.mode}`);
47441
47755
  log.info(` Signature: ${auth.signature.substring(0, 20)}...`);
47442
47756
  }
47757
+ await waitUntilTimestamp(auth.timestamp);
47758
+ validateQuantumTiming(auth.timestamp, 30);
47443
47759
  litActionResult = await this.litOps.requestMintAuthorization({
47444
47760
  authMessage: {
47445
47761
  ...auth,
@@ -48211,6 +48527,8 @@ var DiamondHandsSDK = class _DiamondHandsSDK {
48211
48527
  log.info(` Mode: ${auth.mode}`);
48212
48528
  log.info(` Signature: ${auth.signature.substring(0, 20)}...`);
48213
48529
  }
48530
+ await waitUntilTimestamp(auth.timestamp);
48531
+ validateQuantumTiming(auth.timestamp, 30);
48214
48532
  litActionResult = await this.litOps.requestWithdrawalAuthorization({
48215
48533
  authMessage: {
48216
48534
  ...auth,