@hyperbridge/sdk 2.8.11 → 2.8.13

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.
@@ -20557,13 +20557,116 @@ var IntentGateway = class _IntentGateway {
20557
20557
  }
20558
20558
  }
20559
20559
  };
20560
-
20561
- // src/protocols/intents/phantom-aggregation.ts
20560
+ function rpcFetch() {
20561
+ const f = globalThis.fetch;
20562
+ if (typeof f !== "function") {
20563
+ throw new Error("No fetch available; call setAggregationFetch() before using the aggregation helpers");
20564
+ }
20565
+ return f;
20566
+ }
20567
+ var PhantomRpcError = class extends Error {
20568
+ constructor(message, cause) {
20569
+ super(message);
20570
+ this.cause = cause;
20571
+ this.name = "PhantomRpcError";
20572
+ }
20573
+ cause;
20574
+ };
20575
+ async function rpcCall(url, payload) {
20576
+ let lastErr;
20577
+ for (let attempt = 0; attempt < 4; attempt++) {
20578
+ if (attempt > 0) await new Promise((resolve) => setTimeout(resolve, 150 * attempt));
20579
+ let timer;
20580
+ try {
20581
+ const timeout = new Promise((_, reject) => {
20582
+ timer = setTimeout(() => reject(new Error(`rpc timeout: ${url}`)), 12e3);
20583
+ });
20584
+ const response = await Promise.race([
20585
+ rpcFetch()(url, {
20586
+ method: "POST",
20587
+ headers: { accept: "application/json", "content-type": "application/json" },
20588
+ body: JSON.stringify(payload)
20589
+ }),
20590
+ timeout
20591
+ ]);
20592
+ const body = await response.json();
20593
+ if (body?.error) {
20594
+ lastErr = new Error(`rpc error: ${JSON.stringify(body.error).slice(0, 200)}`);
20595
+ continue;
20596
+ }
20597
+ return body;
20598
+ } catch (err) {
20599
+ lastErr = err;
20600
+ } finally {
20601
+ if (timer) clearTimeout(timer);
20602
+ }
20603
+ }
20604
+ throw new PhantomRpcError(`RPC call failed after 4 attempts: ${url}`, lastErr);
20605
+ }
20562
20606
  var FILL_ORDER_ABI = IntentGatewayV2_default.ABI;
20563
20607
  var DECLARATION_V1 = 1;
20564
20608
  var DECLARATION_V2 = 2;
20609
+ var PAYMASTER_ADDRESS_BYTES = 20;
20610
+ var PAYMASTER_GAS_LIMIT_BYTES = 16;
20611
+ var PAYMASTER_DATA_OFFSET = PAYMASTER_ADDRESS_BYTES + 2 * PAYMASTER_GAS_LIMIT_BYTES;
20612
+ var SIMPLEX_MODE_PERMIT2 = 2;
20613
+ var PERMIT2_DATA_BYTES = 1 + 20 + 32 + 32 + 32 + 1 + 32 + 32;
20614
+ var PERMIT2_SPONSORSHIP_BYTES = PAYMASTER_DATA_OFFSET + PERMIT2_DATA_BYTES;
20565
20615
  var MAX_DECLARED_ENTRIES = 255;
20566
20616
  var MAX_TOKEN_ID_BYTES = 32;
20617
+ function utf8Encode(text) {
20618
+ const bytes = [];
20619
+ for (const char of text) {
20620
+ const codePoint = char.codePointAt(0);
20621
+ if (codePoint < 128) bytes.push(codePoint);
20622
+ else if (codePoint < 2048) bytes.push(192 | codePoint >> 6, 128 | codePoint & 63);
20623
+ else if (codePoint < 65536) {
20624
+ bytes.push(224 | codePoint >> 12, 128 | codePoint >> 6 & 63, 128 | codePoint & 63);
20625
+ } else {
20626
+ bytes.push(
20627
+ 240 | codePoint >> 18,
20628
+ 128 | codePoint >> 12 & 63,
20629
+ 128 | codePoint >> 6 & 63,
20630
+ 128 | codePoint & 63
20631
+ );
20632
+ }
20633
+ }
20634
+ return bytes;
20635
+ }
20636
+ function utf8Decode(bytes) {
20637
+ let text = "";
20638
+ for (let offset = 0; offset < bytes.length; ) {
20639
+ const lead = bytes[offset];
20640
+ let codePoint;
20641
+ let continuations;
20642
+ if (lead < 128) {
20643
+ codePoint = lead;
20644
+ continuations = 0;
20645
+ } else if ((lead & 224) === 192) {
20646
+ codePoint = lead & 31;
20647
+ continuations = 1;
20648
+ } else if ((lead & 240) === 224) {
20649
+ codePoint = lead & 15;
20650
+ continuations = 2;
20651
+ } else if ((lead & 248) === 240) {
20652
+ codePoint = lead & 7;
20653
+ continuations = 3;
20654
+ } else {
20655
+ return null;
20656
+ }
20657
+ if (offset + continuations >= bytes.length) return null;
20658
+ for (let index = 1; index <= continuations; index++) {
20659
+ const byte = bytes[offset + index];
20660
+ if ((byte & 192) !== 128) return null;
20661
+ codePoint = codePoint << 6 | byte & 63;
20662
+ }
20663
+ const overlong = continuations === 1 && codePoint < 128 || continuations === 2 && codePoint < 2048 || continuations === 3 && codePoint < 65536;
20664
+ if (overlong || codePoint > 1114111 || codePoint >= 55296 && codePoint <= 57343) return null;
20665
+ text += String.fromCodePoint(codePoint);
20666
+ offset += continuations + 1;
20667
+ }
20668
+ return text;
20669
+ }
20567
20670
  function tokenIdToBytes(tokenId) {
20568
20671
  if (tokenId < 0n) throw new Error(`Uniswap V4 tokenId cannot be negative: ${tokenId}`);
20569
20672
  const bytes = [];
@@ -20586,7 +20689,7 @@ function encodePhantomBidDeclaration(declaration) {
20586
20689
  const version = positions.length > 0 ? DECLARATION_V2 : DECLARATION_V1;
20587
20690
  const bytes = [version, chains2.length];
20588
20691
  for (const chain of chains2) {
20589
- const encoded = util.stringToU8a(chain);
20692
+ const encoded = utf8Encode(chain);
20590
20693
  if (encoded.length === 0 || encoded.length > 255) {
20591
20694
  throw new Error(`Invalid state machine id in source chain declaration: ${chain}`);
20592
20695
  }
@@ -20604,42 +20707,94 @@ function encodePhantomBidDeclaration(declaration) {
20604
20707
  }
20605
20708
  return util.u8aToHex(new Uint8Array(bytes));
20606
20709
  }
20607
- function decodePhantomBidDeclaration(paymasterAndData) {
20608
- const absent = { acceptedSources: null, uniswapV4Positions: [] };
20609
- if (!paymasterAndData || !util.isHex(paymasterAndData)) return absent;
20610
- const bytes = util.hexToU8a(paymasterAndData);
20611
- if (bytes.length < 2) return absent;
20612
- const version = bytes[0];
20613
- if (version !== DECLARATION_V1 && version !== DECLARATION_V2) return absent;
20710
+ function parseDeclaration(bytes, start) {
20711
+ if (bytes.length - start < 2) return null;
20712
+ const version = bytes[start];
20713
+ if (version !== DECLARATION_V1 && version !== DECLARATION_V2) return null;
20614
20714
  const chains2 = [];
20615
- let offset = 2;
20616
- for (let entry = 0; entry < bytes[1]; entry++) {
20617
- if (offset >= bytes.length) return absent;
20715
+ let offset = start + 2;
20716
+ for (let entry = 0; entry < bytes[start + 1]; entry++) {
20717
+ if (offset >= bytes.length) return null;
20618
20718
  const length = bytes[offset];
20619
20719
  offset += 1;
20620
- if (length === 0 || offset + length > bytes.length) return absent;
20621
- chains2.push(util.u8aToString(bytes.subarray(offset, offset + length)));
20720
+ if (length === 0 || offset + length > bytes.length) return null;
20721
+ const chain = utf8Decode(bytes.subarray(offset, offset + length));
20722
+ if (chain === null) return null;
20723
+ chains2.push(chain);
20622
20724
  offset += length;
20623
20725
  }
20624
20726
  const positions = [];
20625
20727
  if (version === DECLARATION_V2) {
20626
- if (offset >= bytes.length) return absent;
20728
+ if (offset >= bytes.length) return null;
20627
20729
  const count = bytes[offset];
20628
20730
  offset += 1;
20629
20731
  for (let entry = 0; entry < count; entry++) {
20630
- if (offset >= bytes.length) return absent;
20732
+ if (offset >= bytes.length) return null;
20631
20733
  const length = bytes[offset];
20632
20734
  offset += 1;
20633
- if (length === 0 || length > MAX_TOKEN_ID_BYTES || offset + length > bytes.length) return absent;
20634
- let tokenId = 0n;
20635
- for (const byte of bytes.subarray(offset, offset + length)) tokenId = tokenId << 8n | BigInt(byte);
20636
- positions.push(tokenId);
20735
+ if (length === 0 || length > MAX_TOKEN_ID_BYTES || offset + length > bytes.length) return null;
20736
+ positions.push(bytesToBigInt3(bytes.subarray(offset, offset + length)));
20637
20737
  offset += length;
20638
20738
  }
20639
20739
  }
20640
- if (offset !== bytes.length) return absent;
20740
+ if (offset !== bytes.length) return null;
20641
20741
  return { acceptedSources: chains2, uniswapV4Positions: positions };
20642
20742
  }
20743
+ function bytesToBigInt3(bytes) {
20744
+ let value = 0n;
20745
+ for (const byte of bytes) value = value << 8n | BigInt(byte);
20746
+ return value;
20747
+ }
20748
+ function bytesToAddress(bytes) {
20749
+ return util.u8aToHex(bytes);
20750
+ }
20751
+ function hasPermit2Sponsorship(bytes) {
20752
+ return bytes.length >= PERMIT2_SPONSORSHIP_BYTES && bytes[PAYMASTER_DATA_OFFSET] === SIMPLEX_MODE_PERMIT2;
20753
+ }
20754
+ function parseSponsorship(bytes) {
20755
+ let offset = 0;
20756
+ const take = (length) => {
20757
+ const slice = bytes.subarray(offset, offset + length);
20758
+ offset += length;
20759
+ return slice;
20760
+ };
20761
+ const paymaster = bytesToAddress(take(PAYMASTER_ADDRESS_BYTES));
20762
+ take(2 * PAYMASTER_GAS_LIMIT_BYTES);
20763
+ take(1);
20764
+ const token = bytesToAddress(take(20));
20765
+ const permitAmount = bytesToBigInt3(take(32));
20766
+ const nonce = bytesToBigInt3(take(32));
20767
+ const deadline = bytesToBigInt3(take(32));
20768
+ return { paymaster, token, permitAmount, nonce, deadline };
20769
+ }
20770
+ var absentDeclaration = () => ({ acceptedSources: null, uniswapV4Positions: [] });
20771
+ function decodePhantomBidPaymasterAndData(paymasterAndData) {
20772
+ const none = { mode: "none", declaration: absentDeclaration(), sponsorship: null };
20773
+ if (!paymasterAndData || !util.isHex(paymasterAndData)) return none;
20774
+ const bytes = util.hexToU8a(paymasterAndData);
20775
+ const bare = parseDeclaration(bytes, 0);
20776
+ if (bare) return { mode: "declaration", declaration: bare, sponsorship: null };
20777
+ if (!hasPermit2Sponsorship(bytes)) return none;
20778
+ const sponsorship = parseSponsorship(bytes);
20779
+ const tail = bytes.length > PERMIT2_SPONSORSHIP_BYTES ? parseDeclaration(bytes, PERMIT2_SPONSORSHIP_BYTES) : null;
20780
+ return { mode: "permit2", declaration: tail ?? absentDeclaration(), sponsorship };
20781
+ }
20782
+ function decodePhantomBidDeclaration(paymasterAndData) {
20783
+ return decodePhantomBidPaymasterAndData(paymasterAndData).declaration;
20784
+ }
20785
+ function encodePhantomBidPaymasterAndData(bid) {
20786
+ const declaration = encodePhantomBidDeclaration(bid);
20787
+ const sponsorship = bid.sponsorship;
20788
+ if (!sponsorship || sponsorship === "0x") return declaration;
20789
+ if (!util.isHex(sponsorship)) throw new Error("Phantom bid sponsorship is not hex");
20790
+ const bytes = util.hexToU8a(sponsorship);
20791
+ if (bytes.length !== PERMIT2_SPONSORSHIP_BYTES || !hasPermit2Sponsorship(bytes)) {
20792
+ throw new Error(
20793
+ `Phantom bid sponsorship must be a ${PERMIT2_SPONSORSHIP_BYTES}-byte Permit2-mode paymasterAndData, got ${bytes.length} bytes`
20794
+ );
20795
+ }
20796
+ return `${sponsorship}${declaration.slice(2)}`;
20797
+ }
20643
20798
  function encodeAcceptedSourceChains(chains2) {
20644
20799
  return encodePhantomBidDeclaration({ acceptedSourceChains: chains2 });
20645
20800
  }
@@ -20647,15 +20802,35 @@ function decodeAcceptedSourceChains(paymasterAndData) {
20647
20802
  return decodePhantomBidDeclaration(paymasterAndData).acceptedSources;
20648
20803
  }
20649
20804
  var UNISWAP_QUOTE_HAIRCUT_BPS = 10n;
20650
- var PHANTOM_QUOTE_HAIRCUT_BPS = 5n;
20651
20805
  function haircut(amount, bps) {
20652
20806
  return amount * (10000n - bps) / 10000n;
20653
20807
  }
20654
20808
  function applyUniswapQuoteHaircut(amount) {
20655
20809
  return haircut(amount, UNISWAP_QUOTE_HAIRCUT_BPS);
20656
20810
  }
20657
- function applyPhantomQuoteHaircut(amount) {
20658
- return haircut(amount, PHANTOM_QUOTE_HAIRCUT_BPS);
20811
+ var SELECTOR_GATEWAY_PARAMS = "0xcff0ab96";
20812
+ var GATEWAY_PARAMS_WORDS = 6;
20813
+ var GATEWAY_PARAMS_FEE_WORD = 4;
20814
+ async function readProtocolFeeHaircutBps(evmRpcUrl, gatewayAddress) {
20815
+ const result = await rpcCall(evmRpcUrl, {
20816
+ id: 1,
20817
+ jsonrpc: "2.0",
20818
+ method: "eth_call",
20819
+ params: [{ to: gatewayAddress, data: SELECTOR_GATEWAY_PARAMS }, "latest"]
20820
+ });
20821
+ const hex = result.result;
20822
+ if (typeof hex !== "string" || hex.length < 2 + 64 * GATEWAY_PARAMS_WORDS) {
20823
+ throw new PhantomRpcError(`IntentGateway.params() returned no usable result from ${gatewayAddress} on ${evmRpcUrl}`);
20824
+ }
20825
+ const start = 2 + 64 * GATEWAY_PARAMS_FEE_WORD;
20826
+ const protocolFeeBps = BigInt(`0x${hex.slice(start, start + 64)}`);
20827
+ if (protocolFeeBps >= 10000n) {
20828
+ throw new PhantomRpcError(`IntentGateway ${gatewayAddress} reports an implausible protocol fee: ${protocolFeeBps} bps`);
20829
+ }
20830
+ return protocolFeeBps;
20831
+ }
20832
+ function applyProtocolFeeHaircut(amount, protocolFeeBps) {
20833
+ return haircut(amount, protocolFeeBps);
20659
20834
  }
20660
20835
  FILL_ORDER_ABI.find(
20661
20836
  (item) => item?.type === "function" && item?.name === "fillOrder"
@@ -25165,7 +25340,7 @@ exports.ORDER_V2_PARAM_TYPE = ORDER_V2_PARAM_TYPE;
25165
25340
  exports.OrderStatus = OrderStatus;
25166
25341
  exports.OrderStatusChecker = OrderStatusChecker;
25167
25342
  exports.PACKED_USEROP_TYPEHASH = PACKED_USEROP_TYPEHASH;
25168
- exports.PHANTOM_QUOTE_HAIRCUT_BPS = PHANTOM_QUOTE_HAIRCUT_BPS;
25343
+ exports.PERMIT2_SPONSORSHIP_BYTES = PERMIT2_SPONSORSHIP_BYTES;
25169
25344
  exports.PLACE_ORDER_SELECTOR = PLACE_ORDER_SELECTOR;
25170
25345
  exports.PhantomSnapshotUnavailableError = PhantomSnapshotUnavailableError;
25171
25346
  exports.PharosChain = PharosChain;
@@ -25194,7 +25369,7 @@ exports.UnsupportedLiquidityChainError = UnsupportedLiquidityChainError;
25194
25369
  exports.WrappedHyperFungibleTokenABI = WrappedHyperFungibleTokenABI;
25195
25370
  exports.__test = __test;
25196
25371
  exports.adjustDecimals = adjustDecimals;
25197
- exports.applyPhantomQuoteHaircut = applyPhantomQuoteHaircut;
25372
+ exports.applyProtocolFeeHaircut = applyProtocolFeeHaircut;
25198
25373
  exports.applyUniswapQuoteHaircut = applyUniswapQuoteHaircut;
25199
25374
  exports.bytes20ToBytes32 = bytes20ToBytes32;
25200
25375
  exports.bytes32ToBytes20 = bytes32ToBytes20;
@@ -25216,6 +25391,7 @@ exports.decodeAcceptedSourceChains = decodeAcceptedSourceChains;
25216
25391
  exports.decodeERC7821ExecuteBatch = decodeERC7821ExecuteBatch;
25217
25392
  exports.decodeFillOrder = decodeFillOrder;
25218
25393
  exports.decodePhantomBidDeclaration = decodePhantomBidDeclaration;
25394
+ exports.decodePhantomBidPaymasterAndData = decodePhantomBidPaymasterAndData;
25219
25395
  exports.decodeUserOpScale = decodeUserOpScale;
25220
25396
  exports.deriveHttpUrl = deriveHttpUrl;
25221
25397
  exports.encodeAcceptedSourceChains = encodeAcceptedSourceChains;
@@ -25223,6 +25399,7 @@ exports.encodeERC7821ExecuteBatch = encodeERC7821ExecuteBatch;
25223
25399
  exports.encodeFillOrder = encodeFillOrder;
25224
25400
  exports.encodeISMPMessage = encodeISMPMessage;
25225
25401
  exports.encodePhantomBidDeclaration = encodePhantomBidDeclaration;
25402
+ exports.encodePhantomBidPaymasterAndData = encodePhantomBidPaymasterAndData;
25226
25403
  exports.encodeStateMachineId = encodeStateMachineId;
25227
25404
  exports.encodeUserOpScale = encodeUserOpScale;
25228
25405
  exports.encodeWithdrawalRequest = encodeWithdrawalRequest;
@@ -25265,6 +25442,7 @@ exports.queryAssetTeleported = queryAssetTeleported;
25265
25442
  exports.queryGetRequest = queryGetRequest;
25266
25443
  exports.queryPostRequest = queryPostRequest;
25267
25444
  exports.quoteUniswap = quoteUniswap;
25445
+ exports.readProtocolFeeHaircutBps = readProtocolFeeHaircutBps;
25268
25446
  exports.requestCommitmentKey = requestCommitmentKey;
25269
25447
  exports.resetFillOptionsVersionCache = resetFillOptionsVersionCache;
25270
25448
  exports.responseCommitmentKey = responseCommitmentKey;