@hyperbridge/sdk 2.8.0 → 2.8.2

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.
@@ -924,6 +924,11 @@ interface ChainConfigData {
924
924
  USDT: number;
925
925
  cNGN?: number;
926
926
  EXT?: number;
927
+ ZARP?: number;
928
+ EURC?: number;
929
+ XSGD?: number;
930
+ TRYB?: number;
931
+ USDR?: number;
927
932
  };
928
933
  tokenStorageSlots?: {
929
934
  USDT?: {
@@ -942,6 +947,30 @@ interface ChainConfigData {
942
947
  balanceSlot: number;
943
948
  allowanceSlot: number;
944
949
  };
950
+ cNGN?: {
951
+ balanceSlot: number;
952
+ allowanceSlot: number;
953
+ };
954
+ ZARP?: {
955
+ balanceSlot: number;
956
+ allowanceSlot: number;
957
+ };
958
+ EURC?: {
959
+ balanceSlot: number;
960
+ allowanceSlot: number;
961
+ };
962
+ XSGD?: {
963
+ balanceSlot: number;
964
+ allowanceSlot: number;
965
+ };
966
+ TRYB?: {
967
+ balanceSlot: number;
968
+ allowanceSlot: number;
969
+ };
970
+ USDR?: {
971
+ balanceSlot: number;
972
+ allowanceSlot: number;
973
+ };
945
974
  };
946
975
  addresses: {
947
976
  IntentGateway?: `0x${string}`;
@@ -1442,16 +1471,37 @@ declare class IntentsCoprocessor {
1442
1471
  /**
1443
1472
  * Signs and sends an extrinsic. Submissions are serialised through {@link submissionQueue} so
1444
1473
  * concurrent calls never collide on the substrate account nonce — each extrinsic reaches a block
1445
- * before the next is signed.
1474
+ * (or is confirmed still pooled and returned as `pending`) before the next is signed; auto-nonce
1475
+ * via `system.accountNextIndex` counts pooled extrinsics, so a pending one is never re-used.
1446
1476
  */
1447
1477
  private signAndSendExtrinsic;
1448
1478
  /**
1449
1479
  * Signs and sends an extrinsic, handling status updates and errors.
1450
1480
  * Implements retry logic with progressive tip increases for stuck transactions.
1481
+ *
1482
+ * A retry only happens when the previous attempt verifiably went nowhere. Once an attempt's
1483
+ * extrinsic is known to be pooled (`pending`), re-signing the same call would race our own
1484
+ * submission: the copy either bounces off the pool (1014, same nonce below the replacement
1485
+ * priority bump) or — if the original lands first, freeing the nonce — executes as a duplicate
1486
+ * and fails on-chain (e.g. `BidNotFound` for a retraction). Neither can succeed, so the pending
1487
+ * result is returned for the caller to confirm later.
1451
1488
  */
1452
1489
  private sendExtrinsicWithRetries;
1453
1490
  /**
1454
- * Sends an extrinsic with a timeout
1491
+ * Classifies a submission rejection. Codes 1013 ("already imported") and 1014 ("priority is
1492
+ * too low") both mean a copy of this account+nonce is already in the pool — almost always our
1493
+ * own earlier attempt whose watch handle didn't confirm cleanly. That extrinsic is in flight;
1494
+ * resubmitting can only bounce again or land a duplicate, so these are surfaced as `pending`
1495
+ * rather than failure.
1496
+ */
1497
+ private classifySubmissionError;
1498
+ /**
1499
+ * Sends an extrinsic with a timeout.
1500
+ *
1501
+ * A timeout is only a failure when the extrinsic never made it into the transaction pool.
1502
+ * Once a pool-entry status (Future/Ready/Broadcast/Retracted) has been seen, the extrinsic is
1503
+ * in flight and may well execute after the watch is abandoned — the result is then `pending`,
1504
+ * telling the caller to confirm the outcome later instead of re-signing the same call.
1455
1505
  */
1456
1506
  private sendWithTimeout;
1457
1507
  /**
@@ -2948,6 +2998,15 @@ interface BidSubmissionResult {
2948
2998
  * Error message if submission failed
2949
2999
  */
2950
3000
  error?: string;
3001
+ /**
3002
+ * The extrinsic is (or may still be) in the transaction pool: it was accepted but its
3003
+ * inclusion was not observed before the watch timed out, or a resubmission bounced off an
3004
+ * earlier copy already pooled (RPC 1013/1014). Only meaningful when `success` is false —
3005
+ * the operation is in flight, not failed, and must not be re-signed with the same nonce.
3006
+ * Callers should confirm the outcome later (e.g. re-check on-chain state) instead of
3007
+ * treating this as a terminal failure.
3008
+ */
3009
+ pending?: boolean;
2951
3010
  }
2952
3011
  /**
2953
3012
  * Represents a storage entry from pallet-intents Bids storage
@@ -4638,10 +4697,14 @@ interface LpBalance {
4638
4697
  tokenAddress: HexString;
4639
4698
  balance: bigint;
4640
4699
  }
4641
- /** One verified solver behind a leg's quote. */
4700
+ /** One verified solver behind a leg's quote, holding inventory to deliver it. */
4642
4701
  interface PhantomLegBidder {
4643
4702
  solver: HexString;
4644
- /** The solver's output-token inventory on the destination chain — its weight in the median. */
4703
+ /**
4704
+ * The solver's output-token inventory on the destination chain — its weight in the median.
4705
+ * Always greater than zero: a solver quoting a leg it holds none of is dropped, not recorded
4706
+ * at zero, since it can deliver nothing at any price.
4707
+ */
4645
4708
  weight: bigint;
4646
4709
  /**
4647
4710
  * Source chains the solver's signed paymasterAndData declaration accepts payment from. Null
@@ -4658,13 +4721,18 @@ interface PhantomLegAggregation {
4658
4721
  lowestPrice: bigint;
4659
4722
  highestPrice: bigint;
4660
4723
  medianPrice: bigint;
4724
+ /** Backed quotes behind the price. Quotes from solvers holding no inventory are not counted. */
4661
4725
  bidCount: number;
4662
- /** The verified solvers quoting this leg; bidCount === bidders.length. */
4726
+ /** The verified, inventory-backed solvers quoting this leg; bidCount === bidders.length. */
4663
4727
  bidders: PhantomLegBidder[];
4664
4728
  }
4665
4729
  /** The aggregated result for a single phantom order's bid window. */
4666
4730
  interface PhantomAggregation {
4667
- /** One entry per leg that at least one solver quoted; legs nobody quoted are absent. */
4731
+ /**
4732
+ * One entry per leg that at least one solver quoted AND at least one of those quotes is backed
4733
+ * by output-token inventory on the destination chain. Legs nobody quoted are absent, and so are
4734
+ * legs every bidder quoted on zero inventory — neither is a price anyone could trade against.
4735
+ */
4668
4736
  legs: PhantomLegAggregation[];
4669
4737
  lpBalances: LpBalance[];
4670
4738
  }
@@ -924,6 +924,11 @@ interface ChainConfigData {
924
924
  USDT: number;
925
925
  cNGN?: number;
926
926
  EXT?: number;
927
+ ZARP?: number;
928
+ EURC?: number;
929
+ XSGD?: number;
930
+ TRYB?: number;
931
+ USDR?: number;
927
932
  };
928
933
  tokenStorageSlots?: {
929
934
  USDT?: {
@@ -942,6 +947,30 @@ interface ChainConfigData {
942
947
  balanceSlot: number;
943
948
  allowanceSlot: number;
944
949
  };
950
+ cNGN?: {
951
+ balanceSlot: number;
952
+ allowanceSlot: number;
953
+ };
954
+ ZARP?: {
955
+ balanceSlot: number;
956
+ allowanceSlot: number;
957
+ };
958
+ EURC?: {
959
+ balanceSlot: number;
960
+ allowanceSlot: number;
961
+ };
962
+ XSGD?: {
963
+ balanceSlot: number;
964
+ allowanceSlot: number;
965
+ };
966
+ TRYB?: {
967
+ balanceSlot: number;
968
+ allowanceSlot: number;
969
+ };
970
+ USDR?: {
971
+ balanceSlot: number;
972
+ allowanceSlot: number;
973
+ };
945
974
  };
946
975
  addresses: {
947
976
  IntentGateway?: `0x${string}`;
@@ -1442,16 +1471,37 @@ declare class IntentsCoprocessor {
1442
1471
  /**
1443
1472
  * Signs and sends an extrinsic. Submissions are serialised through {@link submissionQueue} so
1444
1473
  * concurrent calls never collide on the substrate account nonce — each extrinsic reaches a block
1445
- * before the next is signed.
1474
+ * (or is confirmed still pooled and returned as `pending`) before the next is signed; auto-nonce
1475
+ * via `system.accountNextIndex` counts pooled extrinsics, so a pending one is never re-used.
1446
1476
  */
1447
1477
  private signAndSendExtrinsic;
1448
1478
  /**
1449
1479
  * Signs and sends an extrinsic, handling status updates and errors.
1450
1480
  * Implements retry logic with progressive tip increases for stuck transactions.
1481
+ *
1482
+ * A retry only happens when the previous attempt verifiably went nowhere. Once an attempt's
1483
+ * extrinsic is known to be pooled (`pending`), re-signing the same call would race our own
1484
+ * submission: the copy either bounces off the pool (1014, same nonce below the replacement
1485
+ * priority bump) or — if the original lands first, freeing the nonce — executes as a duplicate
1486
+ * and fails on-chain (e.g. `BidNotFound` for a retraction). Neither can succeed, so the pending
1487
+ * result is returned for the caller to confirm later.
1451
1488
  */
1452
1489
  private sendExtrinsicWithRetries;
1453
1490
  /**
1454
- * Sends an extrinsic with a timeout
1491
+ * Classifies a submission rejection. Codes 1013 ("already imported") and 1014 ("priority is
1492
+ * too low") both mean a copy of this account+nonce is already in the pool — almost always our
1493
+ * own earlier attempt whose watch handle didn't confirm cleanly. That extrinsic is in flight;
1494
+ * resubmitting can only bounce again or land a duplicate, so these are surfaced as `pending`
1495
+ * rather than failure.
1496
+ */
1497
+ private classifySubmissionError;
1498
+ /**
1499
+ * Sends an extrinsic with a timeout.
1500
+ *
1501
+ * A timeout is only a failure when the extrinsic never made it into the transaction pool.
1502
+ * Once a pool-entry status (Future/Ready/Broadcast/Retracted) has been seen, the extrinsic is
1503
+ * in flight and may well execute after the watch is abandoned — the result is then `pending`,
1504
+ * telling the caller to confirm the outcome later instead of re-signing the same call.
1455
1505
  */
1456
1506
  private sendWithTimeout;
1457
1507
  /**
@@ -2948,6 +2998,15 @@ interface BidSubmissionResult {
2948
2998
  * Error message if submission failed
2949
2999
  */
2950
3000
  error?: string;
3001
+ /**
3002
+ * The extrinsic is (or may still be) in the transaction pool: it was accepted but its
3003
+ * inclusion was not observed before the watch timed out, or a resubmission bounced off an
3004
+ * earlier copy already pooled (RPC 1013/1014). Only meaningful when `success` is false —
3005
+ * the operation is in flight, not failed, and must not be re-signed with the same nonce.
3006
+ * Callers should confirm the outcome later (e.g. re-check on-chain state) instead of
3007
+ * treating this as a terminal failure.
3008
+ */
3009
+ pending?: boolean;
2951
3010
  }
2952
3011
  /**
2953
3012
  * Represents a storage entry from pallet-intents Bids storage
@@ -4638,10 +4697,14 @@ interface LpBalance {
4638
4697
  tokenAddress: HexString;
4639
4698
  balance: bigint;
4640
4699
  }
4641
- /** One verified solver behind a leg's quote. */
4700
+ /** One verified solver behind a leg's quote, holding inventory to deliver it. */
4642
4701
  interface PhantomLegBidder {
4643
4702
  solver: HexString;
4644
- /** The solver's output-token inventory on the destination chain — its weight in the median. */
4703
+ /**
4704
+ * The solver's output-token inventory on the destination chain — its weight in the median.
4705
+ * Always greater than zero: a solver quoting a leg it holds none of is dropped, not recorded
4706
+ * at zero, since it can deliver nothing at any price.
4707
+ */
4645
4708
  weight: bigint;
4646
4709
  /**
4647
4710
  * Source chains the solver's signed paymasterAndData declaration accepts payment from. Null
@@ -4658,13 +4721,18 @@ interface PhantomLegAggregation {
4658
4721
  lowestPrice: bigint;
4659
4722
  highestPrice: bigint;
4660
4723
  medianPrice: bigint;
4724
+ /** Backed quotes behind the price. Quotes from solvers holding no inventory are not counted. */
4661
4725
  bidCount: number;
4662
- /** The verified solvers quoting this leg; bidCount === bidders.length. */
4726
+ /** The verified, inventory-backed solvers quoting this leg; bidCount === bidders.length. */
4663
4727
  bidders: PhantomLegBidder[];
4664
4728
  }
4665
4729
  /** The aggregated result for a single phantom order's bid window. */
4666
4730
  interface PhantomAggregation {
4667
- /** One entry per leg that at least one solver quoted; legs nobody quoted are absent. */
4731
+ /**
4732
+ * One entry per leg that at least one solver quoted AND at least one of those quotes is backed
4733
+ * by output-token inventory on the destination chain. Legs nobody quoted are absent, and so are
4734
+ * legs every bidder quoted on zero inventory — neither is a price anyone could trade against.
4735
+ */
4668
4736
  legs: PhantomLegAggregation[];
4669
4737
  lpBalances: LpBalance[];
4670
4738
  }
@@ -2651,17 +2651,28 @@ async function aggregatePhantomBids(params) {
2651
2651
  }
2652
2652
  }
2653
2653
  if (quotesByLeg.size === 0) return null;
2654
- const legs = [...quotesByLeg.entries()].sort(([a], [b]) => a - b).map(([legIndex, { outputToken, quotes, bidders }]) => {
2655
- const medianPrice = weightedMedian(quotes);
2656
- return {
2657
- legIndex,
2658
- outputToken,
2659
- lowestPrice: medianPrice,
2660
- highestPrice: medianPrice,
2661
- medianPrice,
2662
- bidCount: quotes.length,
2663
- bidders
2664
- };
2654
+ const legs = [...quotesByLeg.entries()].sort(([a], [b]) => a - b).flatMap(([legIndex, { outputToken, quotes, bidders }]) => {
2655
+ const backedQuotes = quotes.filter((quote) => quote.weight > 0n);
2656
+ const backedBidders = bidders.filter((bidder) => bidder.weight > 0n);
2657
+ if (backedQuotes.length === 0) {
2658
+ logger?.warn(
2659
+ { commitment, chain, legIndex, outputToken, quotes: quotes.length },
2660
+ "Dropping phantom leg: no bidder holds the output token on this chain, so no quote is backed"
2661
+ );
2662
+ return [];
2663
+ }
2664
+ const medianPrice = weightedMedian(backedQuotes);
2665
+ return [
2666
+ {
2667
+ legIndex,
2668
+ outputToken,
2669
+ lowestPrice: medianPrice,
2670
+ highestPrice: medianPrice,
2671
+ medianPrice,
2672
+ bidCount: backedQuotes.length,
2673
+ bidders: backedBidders
2674
+ }
2675
+ ];
2665
2676
  });
2666
2677
  return { legs, lpBalances };
2667
2678
  }