@gvnrdao/dh-sdk 0.0.130 → 0.0.132

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,12 +45799,14 @@ 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
45668
45806
  * Converts flat graph structure to nested LoanData structure
45669
45807
  */
45670
45808
  transformGraphPositionToLoanData(graphPosition) {
45809
+ const ucdDebt = graphPosition.ucdDebt ? Number(graphPosition.ucdDebt) : 0;
45671
45810
  return {
45672
45811
  id: graphPosition.id,
45673
45812
  pkpId: graphPosition.pkpId,
@@ -45680,14 +45819,16 @@ var DiamondHandsGraph = class {
45680
45819
  loan: {
45681
45820
  ucdMinted: graphPosition.ucdMinted ? Number(graphPosition.ucdMinted) : 0,
45682
45821
  ucdPaid: graphPosition.ucdPaid ? Number(graphPosition.ucdPaid) : 0,
45683
- ucdDebt: graphPosition.ucdDebt ? Number(graphPosition.ucdDebt) : 0,
45822
+ ucdDebt,
45684
45823
  selectedTerm: graphPosition.selectedTerm ? Number(graphPosition.selectedTerm) : 0,
45685
45824
  status: graphPosition.status,
45686
45825
  expiryAt: graphPosition.expiryAt ? Number(graphPosition.expiryAt) : 0
45687
45826
  },
45688
45827
  collateral: {
45689
45828
  vaultAddress: graphPosition.vaultAddress || ""
45690
- }
45829
+ },
45830
+ // Backwards compatibility: provide ucdDebt at top level for components expecting flat structure
45831
+ ucdDebt
45691
45832
  };
45692
45833
  }
45693
45834
  /**
@@ -45731,10 +45872,7 @@ var DiamondHandsGraph = class {
45731
45872
  }
45732
45873
  }
45733
45874
  `;
45734
- const result = await this.client.execute(
45735
- query,
45736
- { ...variables, skip }
45737
- );
45875
+ const result = await this.client.execute(query, { ...variables, skip });
45738
45876
  const items = result && result["positions"] || [];
45739
45877
  totalCount += items.length;
45740
45878
  hasMore = items.length === batchSize;
@@ -45786,10 +45924,9 @@ var DiamondHandsGraph = class {
45786
45924
  query,
45787
45925
  variables
45788
45926
  );
45789
- const total = await this.getTotalCountPaginated(
45790
- "{ borrower: $borrower }",
45791
- { borrower: userAddress.toLowerCase() }
45792
- );
45927
+ const total = await this.getTotalCountPaginated("{ borrower: $borrower }", {
45928
+ borrower: userAddress.toLowerCase()
45929
+ });
45793
45930
  let positions = [];
45794
45931
  if (result && result.user && Array.isArray(result.user.positions)) {
45795
45932
  positions = result.user.positions.filter((p) => p != null).map((p) => this.transformGraphPositionToLoanData(p));
@@ -45799,6 +45936,137 @@ var DiamondHandsGraph = class {
45799
45936
  total
45800
45937
  };
45801
45938
  }
45939
+ /**
45940
+ * Get user positions with enriched Bitcoin balance data
45941
+ *
45942
+ * Same as getUserPositions but queries actual BTC balance from Bitcoin network
45943
+ * for each vault address in parallel.
45944
+ *
45945
+ * @param userAddress - User's Ethereum address
45946
+ * @param first - Optional: max number of positions to return (default: 10)
45947
+ * @param skip - Optional: number of positions to skip (default: 0)
45948
+ * @param orderBy - Optional: field to order by (default: "createdAt")
45949
+ * @param orderDirection - Optional: asc or desc (default: "desc" - most recent first)
45950
+ * @returns Positions with actual BTC balances from Bitcoin network
45951
+ */
45952
+ async getUserPositionsWithBtc(userAddress, first = 10, skip = 0, orderBy = "createdAt", orderDirection = "desc") {
45953
+ const result = await this.getUserPositions(
45954
+ userAddress,
45955
+ first,
45956
+ skip,
45957
+ orderBy,
45958
+ orderDirection
45959
+ );
45960
+ if (!this.bitcoinOps) {
45961
+ console.warn(
45962
+ "[DiamondHandsGraph] BitcoinOperations not available - returning positions without BTC balance"
45963
+ );
45964
+ return result;
45965
+ }
45966
+ const positionsWithPkp = result.positions.filter(
45967
+ (p) => p.pkpId && p.pkpId !== ""
45968
+ );
45969
+ if (positionsWithPkp.length === 0) {
45970
+ console.log("[DiamondHandsGraph] No positions with PKP IDs to check");
45971
+ return result;
45972
+ }
45973
+ console.log(
45974
+ `[DiamondHandsGraph] Deriving Bitcoin addresses and querying balances for ${positionsWithPkp.length} positions in parallel...`
45975
+ );
45976
+ const balancePromises = positionsWithPkp.map(async (position) => {
45977
+ try {
45978
+ const pkpPublicKey = await getPKPPublicKeyFromTokenId(position.pkpId);
45979
+ const addressResult = await this.bitcoinOps.deriveAddresses(
45980
+ pkpPublicKey
45981
+ );
45982
+ if (!addressResult.success) {
45983
+ console.warn(
45984
+ `[DiamondHandsGraph] Failed to derive address for PKP public key ${pkpPublicKey}:`,
45985
+ addressResult.error
45986
+ );
45987
+ return {
45988
+ pkpId: position.pkpId,
45989
+ address: null,
45990
+ balance: null,
45991
+ addresses: null
45992
+ };
45993
+ }
45994
+ const addresses = addressResult.value;
45995
+ const btcAddress = addresses.regtest || addresses.testnet || addresses.mainnet;
45996
+ if (!btcAddress) {
45997
+ console.warn(
45998
+ `[DiamondHandsGraph] No Bitcoin address available for PKP ${position.pkpId}`
45999
+ );
46000
+ return {
46001
+ pkpId: position.pkpId,
46002
+ address: null,
46003
+ balance: null,
46004
+ addresses
46005
+ };
46006
+ }
46007
+ const balanceResult = await this.bitcoinOps.getBalance(btcAddress);
46008
+ if (balanceResult.success) {
46009
+ return {
46010
+ pkpId: position.pkpId,
46011
+ address: btcAddress,
46012
+ balance: balanceResult.value,
46013
+ addresses
46014
+ };
46015
+ } else {
46016
+ console.warn(
46017
+ `[DiamondHandsGraph] Failed to get balance for ${btcAddress}:`,
46018
+ balanceResult.error
46019
+ );
46020
+ return {
46021
+ pkpId: position.pkpId,
46022
+ address: btcAddress,
46023
+ balance: null,
46024
+ addresses
46025
+ };
46026
+ }
46027
+ } catch (error) {
46028
+ console.error(
46029
+ `[DiamondHandsGraph] Error processing PKP ${position.pkpId}:`,
46030
+ error
46031
+ );
46032
+ return {
46033
+ pkpId: position.pkpId,
46034
+ address: null,
46035
+ balance: null,
46036
+ addresses: null
46037
+ };
46038
+ }
46039
+ });
46040
+ const balanceResults = await Promise.all(balancePromises);
46041
+ const balanceMap = /* @__PURE__ */ new Map();
46042
+ balanceResults.forEach(({ pkpId, address, balance, addresses }) => {
46043
+ balanceMap.set(pkpId, { address, balance, addresses });
46044
+ });
46045
+ console.log(
46046
+ `[DiamondHandsGraph] Retrieved ${balanceResults.length} BTC balances`
46047
+ );
46048
+ const enrichedPositions = result.positions.map((position) => {
46049
+ if (!position.pkpId) {
46050
+ return position;
46051
+ }
46052
+ const data = balanceMap.get(position.pkpId);
46053
+ if (!data) {
46054
+ return position;
46055
+ }
46056
+ return {
46057
+ ...position,
46058
+ collateral: {
46059
+ ...position.collateral,
46060
+ vaultAddress: data.address || position.collateral?.vaultAddress || ""
46061
+ },
46062
+ btcBalance: data.balance || void 0
46063
+ };
46064
+ });
46065
+ return {
46066
+ positions: enrichedPositions,
46067
+ total: result.total
46068
+ };
46069
+ }
45802
46070
  /**
45803
46071
  * Get position by PKP ID from subgraph
45804
46072
  */
@@ -45901,10 +46169,7 @@ var DiamondHandsGraph = class {
45901
46169
  const variables = {
45902
46170
  pkpId: pkpId.toLowerCase()
45903
46171
  };
45904
- const result = await this.client.execute(
45905
- query,
45906
- variables
45907
- );
46172
+ const result = await this.client.execute(query, variables);
45908
46173
  if (!result || !result.positions) {
45909
46174
  return null;
45910
46175
  }
@@ -45981,10 +46246,7 @@ var DiamondHandsGraph = class {
45981
46246
  const variables = {
45982
46247
  positionId: positionId.toLowerCase()
45983
46248
  };
45984
- const result = await this.client.execute(
45985
- query,
45986
- variables
45987
- );
46249
+ const result = await this.client.execute(query, variables);
45988
46250
  if (!result || !result.positions) {
45989
46251
  return null;
45990
46252
  }
@@ -46057,10 +46319,12 @@ var DiamondHandsGraph = class {
46057
46319
  }
46058
46320
  }
46059
46321
  `;
46060
- const result = await this.client.execute(
46061
- query,
46062
- { first, skip, orderBy, orderDirection }
46063
- );
46322
+ const result = await this.client.execute(query, {
46323
+ first,
46324
+ skip,
46325
+ orderBy,
46326
+ orderDirection
46327
+ });
46064
46328
  const total = await this.getTotalCountPaginated();
46065
46329
  const positions = result && result.positions || [];
46066
46330
  const transformedPositions = positions.map(
@@ -46102,10 +46366,13 @@ var DiamondHandsGraph = class {
46102
46366
  }
46103
46367
  }
46104
46368
  `;
46105
- const result = await this.client.execute(
46106
- query,
46107
- { first, skip, statuses, orderBy, orderDirection }
46108
- );
46369
+ const result = await this.client.execute(query, {
46370
+ first,
46371
+ skip,
46372
+ statuses,
46373
+ orderBy,
46374
+ orderDirection
46375
+ });
46109
46376
  const total = await this.getTotalCountPaginated(
46110
46377
  "{ status_in: $statuses }",
46111
46378
  { statuses }
@@ -46226,7 +46493,10 @@ var DiamondHandsGraph = class {
46226
46493
  `;
46227
46494
  const first = options?.first ?? this.defaultPageSize;
46228
46495
  const skip = options?.skip ?? 0;
46229
- const result = await this.client.execute(query, { first, skip });
46496
+ const result = await this.client.execute(
46497
+ query,
46498
+ { first, skip }
46499
+ );
46230
46500
  return result.loanTerms || [];
46231
46501
  }
46232
46502
  /**
@@ -46248,7 +46518,10 @@ var DiamondHandsGraph = class {
46248
46518
  }
46249
46519
  }
46250
46520
  `;
46251
- const result = await this.client.execute(query, { id: id3 });
46521
+ const result = await this.client.execute(
46522
+ query,
46523
+ { id: id3 }
46524
+ );
46252
46525
  return result.loanTerm || null;
46253
46526
  }
46254
46527
  // ============================================================================
@@ -46365,7 +46638,13 @@ var DiamondHandsGraph = class {
46365
46638
  * Get PSM transactions with filters
46366
46639
  */
46367
46640
  async getPSMTransactions(filters) {
46368
- const { user, stablecoin, type, first = this.defaultPageSize, skip = 0 } = filters || {};
46641
+ const {
46642
+ user,
46643
+ stablecoin,
46644
+ type,
46645
+ first = this.defaultPageSize,
46646
+ skip = 0
46647
+ } = filters || {};
46369
46648
  let whereConditions = [];
46370
46649
  if (user)
46371
46650
  whereConditions.push(`user: "${user.toLowerCase()}"`);
@@ -46425,7 +46704,10 @@ var DiamondHandsGraph = class {
46425
46704
  }
46426
46705
  `;
46427
46706
  const variables = { first };
46428
- const result = await this.client.execute(query, variables);
46707
+ const result = await this.client.execute(
46708
+ query,
46709
+ variables
46710
+ );
46429
46711
  return result.psmDailyMetrics || [];
46430
46712
  }
46431
46713
  // ============================================================================
@@ -46560,19 +46842,21 @@ var DiamondHandsGraph = class {
46560
46842
  orderDirection
46561
46843
  };
46562
46844
  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
- }));
46845
+ const payments = (result.position?.payments || []).map(
46846
+ (p) => ({
46847
+ id: p.id,
46848
+ positionId,
46849
+ payer: p.payer.id,
46850
+ amount: p.amount,
46851
+ type: p.type,
46852
+ transactionHash: p.transactionHash,
46853
+ timestamp: p.timestamp,
46854
+ blockNumber: p.blockNumber,
46855
+ logIndex: p.logIndex,
46856
+ newDebt: p.newDebt,
46857
+ newCollateralRatio: p.newCollateralRatio
46858
+ })
46859
+ );
46576
46860
  const statusUpdates = (result.position?.statusUpdates || []).map((s) => ({
46577
46861
  id: s.id,
46578
46862
  positionId,
@@ -46774,10 +47058,10 @@ function createMockTokenManager(config) {
46774
47058
  var import_dh_lit_ops = require("@gvnrdao/dh-lit-ops");
46775
47059
 
46776
47060
  // src/utils/telegram-messaging.utils.ts
46777
- var import_node_telegram_bot_api = __toESM(require("node-telegram-bot-api"));
47061
+ var TelegramBot = null;
46778
47062
  async function sendTelegramMessage(chatId, chatToken, message, threadId) {
46779
47063
  try {
46780
- const bot = new import_node_telegram_bot_api.default(chatToken, { polling: false });
47064
+ const bot = new TelegramBot(chatToken, { polling: false });
46781
47065
  const options = {
46782
47066
  disable_web_page_preview: true
46783
47067
  };
@@ -46917,13 +47201,16 @@ var DiamondHandsSDK = class _DiamondHandsSDK {
46917
47201
  "Diamond Hands subgraph URL is required. Please provide config.subgraphs.diamondHandsUrl"
46918
47202
  );
46919
47203
  }
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
- });
47204
+ this.graphClient = new DiamondHandsGraph(
47205
+ {
47206
+ endpoint: graphEndpoint,
47207
+ requestTimeoutMs: config.graphOptions?.requestTimeoutMs,
47208
+ maxRetries: config.graphOptions?.maxRetries,
47209
+ defaultPageSize: config.graphOptions?.pageSize,
47210
+ headers: config.graphApiKey ? { Authorization: `Bearer ${config.graphApiKey}` } : void 0
47211
+ },
47212
+ this.bitcoinOperations
47213
+ );
46927
47214
  const loanQueryResult = createLoanQuery({
46928
47215
  graphClient: this.graphClient,
46929
47216
  bitcoinOperations: this.bitcoinOperations,
@@ -47746,7 +48033,7 @@ var DiamondHandsSDK = class _DiamondHandsSDK {
47746
48033
  validationResponse.timestamp,
47747
48034
  signatureBytes
47748
48035
  );
47749
- const receipt = await tx.wait();
48036
+ const receipt = await tx.wait(1, 3e5);
47750
48037
  let amountMinted;
47751
48038
  let positionId;
47752
48039
  if (receipt && receipt.logs && receipt.logs.length > 0) {