@gvnrdao/dh-sdk 0.0.130 → 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
@@ -41976,38 +42012,86 @@ var ContractManager = class {
41976
42012
  }
41977
42013
  const contractRunner = runner;
41978
42014
  const contracts = {
41979
- positionManager: PositionManager__factory.connect(
41980
- contractAddresses.positionManager,
41981
- contractRunner
41982
- ),
41983
- loanOperationsManager: ILoanOperationsManager__factory.connect(
41984
- contractAddresses.loanOperationsManager || ethers_exports.constants.AddressZero,
41985
- contractRunner
41986
- ),
41987
- ucdController: IUCDController__factory.connect(
41988
- contractAddresses.ucdToken,
41989
- contractRunner
41990
- ),
41991
- priceFeed: IPriceFeedConsumer__factory.connect(
41992
- contractAddresses.priceFeedConsumer,
41993
- contractRunner
41994
- ),
41995
- termManager: ITermManager__factory.connect(
41996
- contractAddresses.termManager || ethers_exports.constants.AddressZero,
41997
- contractRunner
41998
- ),
41999
- circuitBreaker: CircuitBreakerModule__factory.connect(
42000
- contractAddresses.circuitBreaker || ethers_exports.constants.AddressZero,
42001
- contractRunner
42002
- ),
42003
- communityManager: ICommunityManager__factory.connect(
42004
- contractAddresses.communityManager || ethers_exports.constants.AddressZero,
42005
- contractRunner
42006
- ),
42007
- liquidationManager: ILiquidationManager__factory.connect(
42008
- contractAddresses.liquidationManager || ethers_exports.constants.AddressZero,
42009
- contractRunner
42010
- )
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
+ })()
42011
42095
  };
42012
42096
  this.contracts = contracts;
42013
42097
  return success(contracts);
@@ -43687,6 +43771,55 @@ var LoanQuery = class {
43687
43771
  })
43688
43772
  );
43689
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
+ }
43690
43823
  /**
43691
43824
  * Enrich loans with vault addresses derived from PKP public keys
43692
43825
  *
@@ -44272,7 +44405,10 @@ async function getBitcoinAddressesFromPkp(pkpPublicKey) {
44272
44405
  var BitcoinUtils = class {
44273
44406
  static validateAddress(address) {
44274
44407
  const base58Pattern = /^[123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz]+$/;
44275
- 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;
44276
44412
  }
44277
44413
  static formatTransaction(hash3, amount, recipient) {
44278
44414
  return {
@@ -45654,7 +45790,8 @@ var MIN_BITCOIN_PROVIDERS_FOR_CONSENSUS = 2;
45654
45790
  var DiamondHandsGraph = class {
45655
45791
  client;
45656
45792
  defaultPageSize;
45657
- constructor(config) {
45793
+ bitcoinOps;
45794
+ constructor(config, bitcoinOps) {
45658
45795
  this.client = new GraphClient({
45659
45796
  endpoint: config.endpoint,
45660
45797
  requestTimeoutMs: config.requestTimeoutMs,
@@ -45662,6 +45799,7 @@ var DiamondHandsGraph = class {
45662
45799
  headers: config.headers
45663
45800
  });
45664
45801
  this.defaultPageSize = config.defaultPageSize ?? 100;
45802
+ this.bitcoinOps = bitcoinOps;
45665
45803
  }
45666
45804
  /**
45667
45805
  * Transform graph position data to LoanData interface
@@ -45731,10 +45869,7 @@ var DiamondHandsGraph = class {
45731
45869
  }
45732
45870
  }
45733
45871
  `;
45734
- const result = await this.client.execute(
45735
- query,
45736
- { ...variables, skip }
45737
- );
45872
+ const result = await this.client.execute(query, { ...variables, skip });
45738
45873
  const items = result && result["positions"] || [];
45739
45874
  totalCount += items.length;
45740
45875
  hasMore = items.length === batchSize;
@@ -45786,10 +45921,9 @@ var DiamondHandsGraph = class {
45786
45921
  query,
45787
45922
  variables
45788
45923
  );
45789
- const total = await this.getTotalCountPaginated(
45790
- "{ borrower: $borrower }",
45791
- { borrower: userAddress.toLowerCase() }
45792
- );
45924
+ const total = await this.getTotalCountPaginated("{ borrower: $borrower }", {
45925
+ borrower: userAddress.toLowerCase()
45926
+ });
45793
45927
  let positions = [];
45794
45928
  if (result && result.user && Array.isArray(result.user.positions)) {
45795
45929
  positions = result.user.positions.filter((p) => p != null).map((p) => this.transformGraphPositionToLoanData(p));
@@ -45799,6 +45933,137 @@ var DiamondHandsGraph = class {
45799
45933
  total
45800
45934
  };
45801
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
+ }
45802
46067
  /**
45803
46068
  * Get position by PKP ID from subgraph
45804
46069
  */
@@ -45901,10 +46166,7 @@ var DiamondHandsGraph = class {
45901
46166
  const variables = {
45902
46167
  pkpId: pkpId.toLowerCase()
45903
46168
  };
45904
- const result = await this.client.execute(
45905
- query,
45906
- variables
45907
- );
46169
+ const result = await this.client.execute(query, variables);
45908
46170
  if (!result || !result.positions) {
45909
46171
  return null;
45910
46172
  }
@@ -45981,10 +46243,7 @@ var DiamondHandsGraph = class {
45981
46243
  const variables = {
45982
46244
  positionId: positionId.toLowerCase()
45983
46245
  };
45984
- const result = await this.client.execute(
45985
- query,
45986
- variables
45987
- );
46246
+ const result = await this.client.execute(query, variables);
45988
46247
  if (!result || !result.positions) {
45989
46248
  return null;
45990
46249
  }
@@ -46057,10 +46316,12 @@ var DiamondHandsGraph = class {
46057
46316
  }
46058
46317
  }
46059
46318
  `;
46060
- const result = await this.client.execute(
46061
- query,
46062
- { first, skip, orderBy, orderDirection }
46063
- );
46319
+ const result = await this.client.execute(query, {
46320
+ first,
46321
+ skip,
46322
+ orderBy,
46323
+ orderDirection
46324
+ });
46064
46325
  const total = await this.getTotalCountPaginated();
46065
46326
  const positions = result && result.positions || [];
46066
46327
  const transformedPositions = positions.map(
@@ -46102,10 +46363,13 @@ var DiamondHandsGraph = class {
46102
46363
  }
46103
46364
  }
46104
46365
  `;
46105
- const result = await this.client.execute(
46106
- query,
46107
- { first, skip, statuses, orderBy, orderDirection }
46108
- );
46366
+ const result = await this.client.execute(query, {
46367
+ first,
46368
+ skip,
46369
+ statuses,
46370
+ orderBy,
46371
+ orderDirection
46372
+ });
46109
46373
  const total = await this.getTotalCountPaginated(
46110
46374
  "{ status_in: $statuses }",
46111
46375
  { statuses }
@@ -46226,7 +46490,10 @@ var DiamondHandsGraph = class {
46226
46490
  `;
46227
46491
  const first = options?.first ?? this.defaultPageSize;
46228
46492
  const skip = options?.skip ?? 0;
46229
- const result = await this.client.execute(query, { first, skip });
46493
+ const result = await this.client.execute(
46494
+ query,
46495
+ { first, skip }
46496
+ );
46230
46497
  return result.loanTerms || [];
46231
46498
  }
46232
46499
  /**
@@ -46248,7 +46515,10 @@ var DiamondHandsGraph = class {
46248
46515
  }
46249
46516
  }
46250
46517
  `;
46251
- const result = await this.client.execute(query, { id: id3 });
46518
+ const result = await this.client.execute(
46519
+ query,
46520
+ { id: id3 }
46521
+ );
46252
46522
  return result.loanTerm || null;
46253
46523
  }
46254
46524
  // ============================================================================
@@ -46365,7 +46635,13 @@ var DiamondHandsGraph = class {
46365
46635
  * Get PSM transactions with filters
46366
46636
  */
46367
46637
  async getPSMTransactions(filters) {
46368
- 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 || {};
46369
46645
  let whereConditions = [];
46370
46646
  if (user)
46371
46647
  whereConditions.push(`user: "${user.toLowerCase()}"`);
@@ -46425,7 +46701,10 @@ var DiamondHandsGraph = class {
46425
46701
  }
46426
46702
  `;
46427
46703
  const variables = { first };
46428
- const result = await this.client.execute(query, variables);
46704
+ const result = await this.client.execute(
46705
+ query,
46706
+ variables
46707
+ );
46429
46708
  return result.psmDailyMetrics || [];
46430
46709
  }
46431
46710
  // ============================================================================
@@ -46560,19 +46839,21 @@ var DiamondHandsGraph = class {
46560
46839
  orderDirection
46561
46840
  };
46562
46841
  const result = await this.client.execute(query, variables);
46563
- const payments = (result.position?.payments || []).map((p) => ({
46564
- id: p.id,
46565
- positionId,
46566
- payer: p.payer.id,
46567
- amount: p.amount,
46568
- type: p.type,
46569
- transactionHash: p.transactionHash,
46570
- timestamp: p.timestamp,
46571
- blockNumber: p.blockNumber,
46572
- logIndex: p.logIndex,
46573
- newDebt: p.newDebt,
46574
- newCollateralRatio: p.newCollateralRatio
46575
- }));
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
+ );
46576
46857
  const statusUpdates = (result.position?.statusUpdates || []).map((s) => ({
46577
46858
  id: s.id,
46578
46859
  positionId,
@@ -46774,10 +47055,10 @@ function createMockTokenManager(config) {
46774
47055
  var import_dh_lit_ops = require("@gvnrdao/dh-lit-ops");
46775
47056
 
46776
47057
  // src/utils/telegram-messaging.utils.ts
46777
- var import_node_telegram_bot_api = __toESM(require("node-telegram-bot-api"));
47058
+ var TelegramBot = null;
46778
47059
  async function sendTelegramMessage(chatId, chatToken, message, threadId) {
46779
47060
  try {
46780
- const bot = new import_node_telegram_bot_api.default(chatToken, { polling: false });
47061
+ const bot = new TelegramBot(chatToken, { polling: false });
46781
47062
  const options = {
46782
47063
  disable_web_page_preview: true
46783
47064
  };
@@ -46917,13 +47198,16 @@ var DiamondHandsSDK = class _DiamondHandsSDK {
46917
47198
  "Diamond Hands subgraph URL is required. Please provide config.subgraphs.diamondHandsUrl"
46918
47199
  );
46919
47200
  }
46920
- this.graphClient = new DiamondHandsGraph({
46921
- endpoint: graphEndpoint,
46922
- requestTimeoutMs: config.graphOptions?.requestTimeoutMs,
46923
- maxRetries: config.graphOptions?.maxRetries,
46924
- defaultPageSize: config.graphOptions?.pageSize,
46925
- headers: config.graphApiKey ? { Authorization: `Bearer ${config.graphApiKey}` } : void 0
46926
- });
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
+ );
46927
47211
  const loanQueryResult = createLoanQuery({
46928
47212
  graphClient: this.graphClient,
46929
47213
  bitcoinOperations: this.bitcoinOperations,