@defuse-protocol/intents-sdk 0.41.1 → 0.42.0

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.
@@ -9,7 +9,8 @@ const HotBridgeChains = [
9
9
  require_caip2.Chains.Avalanche,
10
10
  require_caip2.Chains.Monad,
11
11
  require_caip2.Chains.Stellar,
12
- require_caip2.Chains.LayerX
12
+ require_caip2.Chains.LayerX,
13
+ require_caip2.Chains.Adi
13
14
  ];
14
15
  const HotBridgeEVMChains = HotBridgeChains.filter((a) => a.startsWith("eip155:"));
15
16
 
@@ -1,6 +1,6 @@
1
1
  //#region src/bridges/hot-bridge/hot-bridge-chains.d.ts
2
2
  type HotBridgeChain = (typeof HotBridgeChains)[number];
3
3
  type HotBridgeEVMChain = Extract<HotBridgeChain, `eip155:${string}`>;
4
- declare const HotBridgeChains: ("eip155:10" | "eip155:56" | "eip155:137" | "eip155:143" | "eip155:196" | "eip155:43114" | "tvm:-239" | "stellar:pubnet")[];
4
+ declare const HotBridgeChains: ("eip155:10" | "eip155:56" | "eip155:137" | "eip155:143" | "eip155:196" | "eip155:36900" | "eip155:43114" | "tvm:-239" | "stellar:pubnet")[];
5
5
  //#endregion
6
6
  export { HotBridgeEVMChain };
@@ -1,6 +1,6 @@
1
1
  //#region src/bridges/hot-bridge/hot-bridge-chains.d.ts
2
2
  type HotBridgeChain = (typeof HotBridgeChains)[number];
3
3
  type HotBridgeEVMChain = Extract<HotBridgeChain, `eip155:${string}`>;
4
- declare const HotBridgeChains: ("eip155:10" | "eip155:56" | "eip155:137" | "eip155:143" | "eip155:196" | "eip155:43114" | "tvm:-239" | "stellar:pubnet")[];
4
+ declare const HotBridgeChains: ("eip155:10" | "eip155:56" | "eip155:137" | "eip155:143" | "eip155:196" | "eip155:36900" | "eip155:43114" | "tvm:-239" | "stellar:pubnet")[];
5
5
  //#endregion
6
6
  export { HotBridgeEVMChain };
@@ -9,7 +9,8 @@ const HotBridgeChains = [
9
9
  Chains.Avalanche,
10
10
  Chains.Monad,
11
11
  Chains.Stellar,
12
- Chains.LayerX
12
+ Chains.LayerX,
13
+ Chains.Adi
13
14
  ];
14
15
  const HotBridgeEVMChains = HotBridgeChains.filter((a) => a.startsWith("eip155:"));
15
16
 
@@ -6,6 +6,7 @@ let __hot_labs_omni_sdk = require("@hot-labs/omni-sdk");
6
6
 
7
7
  //#region src/bridges/hot-bridge/hot-bridge-utils.ts
8
8
  const MONAD_MAINNET_NETWORK_ID = 143;
9
+ const ADI_NETWORK_ID = 36900;
9
10
  const nativeTokenMapping = {
10
11
  [require_caip2.Chains.BNB]: "nep245:v2_1.omni.hot.tg:56_11111111111111111111",
11
12
  [require_caip2.Chains.Polygon]: "nep245:v2_1.omni.hot.tg:137_11111111111111111111",
@@ -14,7 +15,8 @@ const nativeTokenMapping = {
14
15
  [require_caip2.Chains.Optimism]: "nep245:v2_1.omni.hot.tg:10_11111111111111111111",
15
16
  [require_caip2.Chains.Avalanche]: "nep245:v2_1.omni.hot.tg:43114_11111111111111111111",
16
17
  [require_caip2.Chains.Stellar]: "nep245:v2_1.omni.hot.tg:1100_111bzQBB5v7AhLyPMDwS8uJgQV24KaAPXtwyVWu2KXbbfQU6NXRCz",
17
- [require_caip2.Chains.LayerX]: "nep245:v2_1.omni.hot.tg:196_11111111111111111111"
18
+ [require_caip2.Chains.LayerX]: "nep245:v2_1.omni.hot.tg:196_11111111111111111111",
19
+ [require_caip2.Chains.Adi]: "nep245:v2_1.omni.hot.tg:36900_11111111111111111111"
18
20
  };
19
21
  const caip2NetworkIdMapping = {
20
22
  [require_caip2.Chains.BNB]: __hot_labs_omni_sdk.Network.Bnb,
@@ -24,7 +26,8 @@ const caip2NetworkIdMapping = {
24
26
  [require_caip2.Chains.Optimism]: __hot_labs_omni_sdk.Network.Optimism,
25
27
  [require_caip2.Chains.Avalanche]: __hot_labs_omni_sdk.Network.Avalanche,
26
28
  [require_caip2.Chains.Stellar]: __hot_labs_omni_sdk.Network.Stellar,
27
- [require_caip2.Chains.LayerX]: __hot_labs_omni_sdk.Network.Xlayer
29
+ [require_caip2.Chains.LayerX]: __hot_labs_omni_sdk.Network.Xlayer,
30
+ [require_caip2.Chains.Adi]: ADI_NETWORK_ID
28
31
  };
29
32
  const networkIdCAIP2Mapping = Object.fromEntries(Object.entries(caip2NetworkIdMapping).map(([k, v]) => [v, k]));
30
33
  function getFeeAssetIdForChain(caip2) {
@@ -5,6 +5,7 @@ import { Network } from "@hot-labs/omni-sdk";
5
5
 
6
6
  //#region src/bridges/hot-bridge/hot-bridge-utils.ts
7
7
  const MONAD_MAINNET_NETWORK_ID = 143;
8
+ const ADI_NETWORK_ID = 36900;
8
9
  const nativeTokenMapping = {
9
10
  [Chains.BNB]: "nep245:v2_1.omni.hot.tg:56_11111111111111111111",
10
11
  [Chains.Polygon]: "nep245:v2_1.omni.hot.tg:137_11111111111111111111",
@@ -13,7 +14,8 @@ const nativeTokenMapping = {
13
14
  [Chains.Optimism]: "nep245:v2_1.omni.hot.tg:10_11111111111111111111",
14
15
  [Chains.Avalanche]: "nep245:v2_1.omni.hot.tg:43114_11111111111111111111",
15
16
  [Chains.Stellar]: "nep245:v2_1.omni.hot.tg:1100_111bzQBB5v7AhLyPMDwS8uJgQV24KaAPXtwyVWu2KXbbfQU6NXRCz",
16
- [Chains.LayerX]: "nep245:v2_1.omni.hot.tg:196_11111111111111111111"
17
+ [Chains.LayerX]: "nep245:v2_1.omni.hot.tg:196_11111111111111111111",
18
+ [Chains.Adi]: "nep245:v2_1.omni.hot.tg:36900_11111111111111111111"
17
19
  };
18
20
  const caip2NetworkIdMapping = {
19
21
  [Chains.BNB]: Network.Bnb,
@@ -23,7 +25,8 @@ const caip2NetworkIdMapping = {
23
25
  [Chains.Optimism]: Network.Optimism,
24
26
  [Chains.Avalanche]: Network.Avalanche,
25
27
  [Chains.Stellar]: Network.Stellar,
26
- [Chains.LayerX]: Network.Xlayer
28
+ [Chains.LayerX]: Network.Xlayer,
29
+ [Chains.Adi]: ADI_NETWORK_ID
27
30
  };
28
31
  const networkIdCAIP2Mapping = Object.fromEntries(Object.entries(caip2NetworkIdMapping).map(([k, v]) => [v, k]));
29
32
  function getFeeAssetIdForChain(caip2) {
@@ -17,7 +17,7 @@ function createWithdrawIntentPrimitive(params) {
17
17
  };
18
18
  }
19
19
  function createWithdrawMemo({ receiverAddress, xrpMemo }) {
20
- const memo = ["WITHDRAW_TO", receiverAddress];
20
+ const memo = ["WITHDRAW_TO", receiverAddress.toLowerCase().startsWith("bitcoincash:") ? receiverAddress.slice(12) : receiverAddress];
21
21
  if (xrpMemo != null && xrpMemo !== "") memo.push(xrpMemo);
22
22
  return memo.join(":");
23
23
  }
@@ -26,6 +26,7 @@ const caip2Mapping = {
26
26
  [require_caip2.Chains.Base]: "eth:8453",
27
27
  [require_caip2.Chains.Arbitrum]: "eth:42161",
28
28
  [require_caip2.Chains.Bitcoin]: "btc:mainnet",
29
+ [require_caip2.Chains.BitcoinCash]: "bch:mainnet",
29
30
  [require_caip2.Chains.Solana]: "sol:mainnet",
30
31
  [require_caip2.Chains.Dogecoin]: "doge:mainnet",
31
32
  [require_caip2.Chains.XRPL]: "xrp:mainnet",
@@ -36,7 +37,8 @@ const caip2Mapping = {
36
37
  [require_caip2.Chains.Sui]: "sui:mainnet",
37
38
  [require_caip2.Chains.Aptos]: "aptos:mainnet",
38
39
  [require_caip2.Chains.Cardano]: "cardano:mainnet",
39
- [require_caip2.Chains.Litecoin]: "ltc:mainnet"
40
+ [require_caip2.Chains.Litecoin]: "ltc:mainnet",
41
+ [require_caip2.Chains.Starknet]: "starknet:mainnet"
40
42
  };
41
43
  function toPoaNetwork(caip2) {
42
44
  if (caip2Mapping[caip2] == null) throw new Error(`Unsupported POA Bridge chain = ${caip2}`);
@@ -47,6 +49,7 @@ const tokenPrefixMapping = {
47
49
  base: require_caip2.Chains.Base,
48
50
  arb: require_caip2.Chains.Arbitrum,
49
51
  btc: require_caip2.Chains.Bitcoin,
52
+ bch: require_caip2.Chains.BitcoinCash,
50
53
  sol: require_caip2.Chains.Solana,
51
54
  doge: require_caip2.Chains.Dogecoin,
52
55
  xrp: require_caip2.Chains.XRPL,
@@ -57,7 +60,8 @@ const tokenPrefixMapping = {
57
60
  sui: require_caip2.Chains.Sui,
58
61
  aptos: require_caip2.Chains.Aptos,
59
62
  cardano: require_caip2.Chains.Cardano,
60
- ltc: require_caip2.Chains.Litecoin
63
+ ltc: require_caip2.Chains.Litecoin,
64
+ starknet: require_caip2.Chains.Starknet
61
65
  };
62
66
  function contractIdToCaip2(contractId) {
63
67
  for (const [prefix, caip2] of Object.entries(tokenPrefixMapping)) if (contractId.startsWith(`${prefix}.`) || contractId.startsWith(`${prefix}-`)) return caip2;
@@ -16,7 +16,7 @@ function createWithdrawIntentPrimitive(params) {
16
16
  };
17
17
  }
18
18
  function createWithdrawMemo({ receiverAddress, xrpMemo }) {
19
- const memo = ["WITHDRAW_TO", receiverAddress];
19
+ const memo = ["WITHDRAW_TO", receiverAddress.toLowerCase().startsWith("bitcoincash:") ? receiverAddress.slice(12) : receiverAddress];
20
20
  if (xrpMemo != null && xrpMemo !== "") memo.push(xrpMemo);
21
21
  return memo.join(":");
22
22
  }
@@ -25,6 +25,7 @@ const caip2Mapping = {
25
25
  [Chains.Base]: "eth:8453",
26
26
  [Chains.Arbitrum]: "eth:42161",
27
27
  [Chains.Bitcoin]: "btc:mainnet",
28
+ [Chains.BitcoinCash]: "bch:mainnet",
28
29
  [Chains.Solana]: "sol:mainnet",
29
30
  [Chains.Dogecoin]: "doge:mainnet",
30
31
  [Chains.XRPL]: "xrp:mainnet",
@@ -35,7 +36,8 @@ const caip2Mapping = {
35
36
  [Chains.Sui]: "sui:mainnet",
36
37
  [Chains.Aptos]: "aptos:mainnet",
37
38
  [Chains.Cardano]: "cardano:mainnet",
38
- [Chains.Litecoin]: "ltc:mainnet"
39
+ [Chains.Litecoin]: "ltc:mainnet",
40
+ [Chains.Starknet]: "starknet:mainnet"
39
41
  };
40
42
  function toPoaNetwork(caip2) {
41
43
  if (caip2Mapping[caip2] == null) throw new Error(`Unsupported POA Bridge chain = ${caip2}`);
@@ -46,6 +48,7 @@ const tokenPrefixMapping = {
46
48
  base: Chains.Base,
47
49
  arb: Chains.Arbitrum,
48
50
  btc: Chains.Bitcoin,
51
+ bch: Chains.BitcoinCash,
49
52
  sol: Chains.Solana,
50
53
  doge: Chains.Dogecoin,
51
54
  xrp: Chains.XRPL,
@@ -56,7 +59,8 @@ const tokenPrefixMapping = {
56
59
  sui: Chains.Sui,
57
60
  aptos: Chains.Aptos,
58
61
  cardano: Chains.Cardano,
59
- ltc: Chains.Litecoin
62
+ ltc: Chains.Litecoin,
63
+ starknet: Chains.Starknet
60
64
  };
61
65
  function contractIdToCaip2(contractId) {
62
66
  for (const [prefix, caip2] of Object.entries(tokenPrefixMapping)) if (contractId.startsWith(`${prefix}.`) || contractId.startsWith(`${prefix}-`)) return caip2;
@@ -10,7 +10,8 @@ const PUBLIC_EVM_RPC_URLS = {
10
10
  [require_caip2.Chains.Monad]: ["https://rpc.monad.xyz"],
11
11
  [require_caip2.Chains.Optimism]: ["https://optimism-rpc.publicnode.com"],
12
12
  [require_caip2.Chains.Avalanche]: ["https://avalanche-c-chain-rpc.publicnode.com"],
13
- [require_caip2.Chains.LayerX]: ["https://rpc.xlayer.tech"]
13
+ [require_caip2.Chains.LayerX]: ["https://rpc.xlayer.tech"],
14
+ [require_caip2.Chains.Adi]: ["https://rpc.adifoundation.ai"]
14
15
  };
15
16
  const PUBLIC_STELLAR_RPC_URLS = {
16
17
  soroban: ["https://mainnet.sorobanrpc.com"],
@@ -10,7 +10,8 @@ const PUBLIC_EVM_RPC_URLS = {
10
10
  [Chains.Monad]: ["https://rpc.monad.xyz"],
11
11
  [Chains.Optimism]: ["https://optimism-rpc.publicnode.com"],
12
12
  [Chains.Avalanche]: ["https://avalanche-c-chain-rpc.publicnode.com"],
13
- [Chains.LayerX]: ["https://rpc.xlayer.tech"]
13
+ [Chains.LayerX]: ["https://rpc.xlayer.tech"],
14
+ [Chains.Adi]: ["https://rpc.adifoundation.ai"]
14
15
  };
15
16
  const PUBLIC_STELLAR_RPC_URLS = {
16
17
  soroban: ["https://mainnet.sorobanrpc.com"],
@@ -7,6 +7,7 @@ let __defuse_protocol_internal_utils = require("@defuse-protocol/internal-utils"
7
7
  */
8
8
  const Chains = {
9
9
  Bitcoin: "bip122:000000000019d6689c085ae165831e93",
10
+ BitcoinCash: "bip122:000000000000000000651ef99cb9fcbe",
10
11
  Zcash: "bip122:00040fe8ec8471911baa1db1266ea15d",
11
12
  Dogecoin: "bip122:1a91e3dace36e2be3bf030a65679fe82",
12
13
  Litecoin: "bip122:12a765e31ffd4059bada1e25190f6e98",
@@ -17,6 +18,7 @@ const Chains = {
17
18
  Polygon: "eip155:137",
18
19
  Monad: "eip155:143",
19
20
  LayerX: "eip155:196",
21
+ Adi: "eip155:36900",
20
22
  Base: "eip155:8453",
21
23
  Arbitrum: "eip155:42161",
22
24
  Avalanche: "eip155:43114",
@@ -29,7 +31,8 @@ const Chains = {
29
31
  Sui: "sui:mainnet",
30
32
  Aptos: "aptos:mainnet",
31
33
  Stellar: "stellar:pubnet",
32
- Cardano: "cip34:1-764824073"
34
+ Cardano: "cip34:1-764824073",
35
+ Starknet: "starknet:SN_MAIN"
33
36
  };
34
37
  function getEIP155ChainId(chain) {
35
38
  (0, __defuse_protocol_internal_utils.assert)(chain.startsWith("eip155:"), "Chain is not an EIP-155 chain");
@@ -4,6 +4,7 @@
4
4
  */
5
5
  declare const Chains: {
6
6
  readonly Bitcoin: "bip122:000000000019d6689c085ae165831e93";
7
+ readonly BitcoinCash: "bip122:000000000000000000651ef99cb9fcbe";
7
8
  readonly Zcash: "bip122:00040fe8ec8471911baa1db1266ea15d";
8
9
  readonly Dogecoin: "bip122:1a91e3dace36e2be3bf030a65679fe82";
9
10
  readonly Litecoin: "bip122:12a765e31ffd4059bada1e25190f6e98";
@@ -14,6 +15,7 @@ declare const Chains: {
14
15
  readonly Polygon: "eip155:137";
15
16
  readonly Monad: "eip155:143";
16
17
  readonly LayerX: "eip155:196";
18
+ readonly Adi: "eip155:36900";
17
19
  readonly Base: "eip155:8453";
18
20
  readonly Arbitrum: "eip155:42161";
19
21
  readonly Avalanche: "eip155:43114";
@@ -27,6 +29,7 @@ declare const Chains: {
27
29
  readonly Aptos: "aptos:mainnet";
28
30
  readonly Stellar: "stellar:pubnet";
29
31
  readonly Cardano: "cip34:1-764824073";
32
+ readonly Starknet: "starknet:SN_MAIN";
30
33
  };
31
34
  type Chain = (typeof Chains)[keyof typeof Chains];
32
35
  //#endregion
@@ -4,6 +4,7 @@
4
4
  */
5
5
  declare const Chains: {
6
6
  readonly Bitcoin: "bip122:000000000019d6689c085ae165831e93";
7
+ readonly BitcoinCash: "bip122:000000000000000000651ef99cb9fcbe";
7
8
  readonly Zcash: "bip122:00040fe8ec8471911baa1db1266ea15d";
8
9
  readonly Dogecoin: "bip122:1a91e3dace36e2be3bf030a65679fe82";
9
10
  readonly Litecoin: "bip122:12a765e31ffd4059bada1e25190f6e98";
@@ -14,6 +15,7 @@ declare const Chains: {
14
15
  readonly Polygon: "eip155:137";
15
16
  readonly Monad: "eip155:143";
16
17
  readonly LayerX: "eip155:196";
18
+ readonly Adi: "eip155:36900";
17
19
  readonly Base: "eip155:8453";
18
20
  readonly Arbitrum: "eip155:42161";
19
21
  readonly Avalanche: "eip155:43114";
@@ -27,6 +29,7 @@ declare const Chains: {
27
29
  readonly Aptos: "aptos:mainnet";
28
30
  readonly Stellar: "stellar:pubnet";
29
31
  readonly Cardano: "cip34:1-764824073";
32
+ readonly Starknet: "starknet:SN_MAIN";
30
33
  };
31
34
  type Chain = (typeof Chains)[keyof typeof Chains];
32
35
  //#endregion
@@ -6,6 +6,7 @@ import { assert } from "@defuse-protocol/internal-utils";
6
6
  */
7
7
  const Chains = {
8
8
  Bitcoin: "bip122:000000000019d6689c085ae165831e93",
9
+ BitcoinCash: "bip122:000000000000000000651ef99cb9fcbe",
9
10
  Zcash: "bip122:00040fe8ec8471911baa1db1266ea15d",
10
11
  Dogecoin: "bip122:1a91e3dace36e2be3bf030a65679fe82",
11
12
  Litecoin: "bip122:12a765e31ffd4059bada1e25190f6e98",
@@ -16,6 +17,7 @@ const Chains = {
16
17
  Polygon: "eip155:137",
17
18
  Monad: "eip155:143",
18
19
  LayerX: "eip155:196",
20
+ Adi: "eip155:36900",
19
21
  Base: "eip155:8453",
20
22
  Arbitrum: "eip155:42161",
21
23
  Avalanche: "eip155:43114",
@@ -28,7 +30,8 @@ const Chains = {
28
30
  Sui: "sui:mainnet",
29
31
  Aptos: "aptos:mainnet",
30
32
  Stellar: "stellar:pubnet",
31
- Cardano: "cip34:1-764824073"
33
+ Cardano: "cip34:1-764824073",
34
+ Starknet: "starknet:SN_MAIN"
32
35
  };
33
36
  function getEIP155ChainId(chain) {
34
37
  assert(chain.startsWith("eip155:"), "Chain is not an EIP-155 chain");
@@ -12,6 +12,7 @@ function validateAddress(address, blockchain) {
12
12
  switch (blockchain) {
13
13
  case require_caip2.Chains.Near: return __defuse_protocol_internal_utils.utils.validateNearAddress(address);
14
14
  case require_caip2.Chains.Bitcoin: return validateBtcAddress(address);
15
+ case require_caip2.Chains.BitcoinCash: return validateBchAddress(address);
15
16
  case require_caip2.Chains.Solana: return validateSolAddress(address);
16
17
  case require_caip2.Chains.Dogecoin: return validateDogeAddress(address);
17
18
  case require_caip2.Chains.Litecoin: return validateLitecoinAddress(address);
@@ -23,6 +24,7 @@ function validateAddress(address, blockchain) {
23
24
  case require_caip2.Chains.Stellar: return validateStellarAddress(address);
24
25
  case require_caip2.Chains.Aptos: return validateAptosAddress(address);
25
26
  case require_caip2.Chains.Cardano: return validateCardanoAddress(address);
27
+ case require_caip2.Chains.Starknet: return validateStarknetAddress(address);
26
28
  case require_caip2.Chains.Ethereum:
27
29
  case require_caip2.Chains.Optimism:
28
30
  case require_caip2.Chains.BNB:
@@ -30,6 +32,7 @@ function validateAddress(address, blockchain) {
30
32
  case require_caip2.Chains.Polygon:
31
33
  case require_caip2.Chains.Monad:
32
34
  case require_caip2.Chains.LayerX:
35
+ case require_caip2.Chains.Adi:
33
36
  case require_caip2.Chains.Base:
34
37
  case require_caip2.Chains.Arbitrum:
35
38
  case require_caip2.Chains.Avalanche:
@@ -43,6 +46,62 @@ function validateEthAddress(address) {
43
46
  function validateBtcAddress(address) {
44
47
  return /^1[1-9A-HJ-NP-Za-km-z]{25,34}$/.test(address) || /^3[1-9A-HJ-NP-Za-km-z]{25,34}$/.test(address) || /^bc1[02-9ac-hj-np-z]{11,87}$/.test(address) || /^bc1p[02-9ac-hj-np-z]{42,87}$/.test(address);
45
48
  }
49
+ /**
50
+ * Validates Bitcoin Cash addresses
51
+ * Supports:
52
+ * - Legacy addresses (1... for P2PKH, 3... for P2SH) - shared with Bitcoin
53
+ * - CashAddr format (bitcoincash:q... or q... for P2PKH, bitcoincash:p... or p... for P2SH)
54
+ *
55
+ * CashAddr checksum implementation based on:
56
+ * @see https://github.com/ealmansi/cashaddrjs (MIT License)
57
+ * @see https://github.com/bitcoincashorg/bitcoincash.org/blob/master/spec/cashaddr.md
58
+ */
59
+ function validateBchAddress(address) {
60
+ if (/^1[1-9A-HJ-NP-Za-km-z]{25,34}$/.test(address) || /^3[1-9A-HJ-NP-Za-km-z]{25,34}$/.test(address)) return true;
61
+ return validateBchCashAddr(address);
62
+ }
63
+ /**
64
+ * Validates Bitcoin Cash CashAddr format
65
+ * CashAddr uses a modified Bech32 encoding with polymod checksum
66
+ */
67
+ function validateBchCashAddr(address) {
68
+ let normalized = address.toLowerCase();
69
+ if (!normalized.includes(":")) normalized = `bitcoincash:${normalized}`;
70
+ if (!normalized.startsWith("bitcoincash:")) return false;
71
+ const payload = normalized.slice(12);
72
+ if (!payload.startsWith("q") && !payload.startsWith("p")) return false;
73
+ const CHARSET = "qpzry9x8gf2tvdw0s3jn54khce6mua7l";
74
+ for (const char of payload) if (!CHARSET.includes(char)) return false;
75
+ if (payload.length !== 42 && payload.length !== 61) return false;
76
+ return verifyBchChecksum(normalized);
77
+ }
78
+ function verifyBchChecksum(address) {
79
+ const CHARSET = "qpzry9x8gf2tvdw0s3jn54khce6mua7l";
80
+ const colonIndex = address.indexOf(":");
81
+ const prefix = address.slice(0, colonIndex);
82
+ const payload = address.slice(colonIndex + 1);
83
+ const prefixData = [];
84
+ for (const char of prefix) prefixData.push(char.charCodeAt(0) & 31);
85
+ prefixData.push(0);
86
+ const payloadData = [];
87
+ for (const char of payload) {
88
+ const idx = CHARSET.indexOf(char);
89
+ if (idx === -1) return false;
90
+ payloadData.push(idx);
91
+ }
92
+ const values = [...prefixData, ...payloadData];
93
+ let c = 1n;
94
+ for (const d of values) {
95
+ const c0 = c >> 35n;
96
+ c = (c & 34359738367n) << 5n ^ BigInt(d);
97
+ if (c0 & 1n) c ^= 656907472481n;
98
+ if (c0 & 2n) c ^= 522768456162n;
99
+ if (c0 & 4n) c ^= 1044723512260n;
100
+ if (c0 & 8n) c ^= 748107326120n;
101
+ if (c0 & 16n) c ^= 130178868336n;
102
+ }
103
+ return (c ^ 1n) === 0n;
104
+ }
46
105
  function validateSolAddress(address) {
47
106
  try {
48
107
  return __solana_web3_js.PublicKey.isOnCurve(address);
@@ -137,6 +196,14 @@ function validateCardanoAddress(address) {
137
196
  return false;
138
197
  }
139
198
  }
199
+ /**
200
+ * Validates Starknet addresses
201
+ * Starknet addresses are felt252 (252-bit field elements) represented as
202
+ * hex strings with 0x prefix (up to 64 hex characters)
203
+ */
204
+ function validateStarknetAddress(address) {
205
+ return /^0x[a-fA-F0-9]{1,64}$/.test(address);
206
+ }
140
207
  function validateLitecoinAddress(address) {
141
208
  const first = address[0];
142
209
  if (first === "L") return validateLitecoinBase58Address(address, 48);
@@ -11,6 +11,7 @@ function validateAddress(address, blockchain) {
11
11
  switch (blockchain) {
12
12
  case Chains.Near: return utils.validateNearAddress(address);
13
13
  case Chains.Bitcoin: return validateBtcAddress(address);
14
+ case Chains.BitcoinCash: return validateBchAddress(address);
14
15
  case Chains.Solana: return validateSolAddress(address);
15
16
  case Chains.Dogecoin: return validateDogeAddress(address);
16
17
  case Chains.Litecoin: return validateLitecoinAddress(address);
@@ -22,6 +23,7 @@ function validateAddress(address, blockchain) {
22
23
  case Chains.Stellar: return validateStellarAddress(address);
23
24
  case Chains.Aptos: return validateAptosAddress(address);
24
25
  case Chains.Cardano: return validateCardanoAddress(address);
26
+ case Chains.Starknet: return validateStarknetAddress(address);
25
27
  case Chains.Ethereum:
26
28
  case Chains.Optimism:
27
29
  case Chains.BNB:
@@ -29,6 +31,7 @@ function validateAddress(address, blockchain) {
29
31
  case Chains.Polygon:
30
32
  case Chains.Monad:
31
33
  case Chains.LayerX:
34
+ case Chains.Adi:
32
35
  case Chains.Base:
33
36
  case Chains.Arbitrum:
34
37
  case Chains.Avalanche:
@@ -42,6 +45,62 @@ function validateEthAddress(address) {
42
45
  function validateBtcAddress(address) {
43
46
  return /^1[1-9A-HJ-NP-Za-km-z]{25,34}$/.test(address) || /^3[1-9A-HJ-NP-Za-km-z]{25,34}$/.test(address) || /^bc1[02-9ac-hj-np-z]{11,87}$/.test(address) || /^bc1p[02-9ac-hj-np-z]{42,87}$/.test(address);
44
47
  }
48
+ /**
49
+ * Validates Bitcoin Cash addresses
50
+ * Supports:
51
+ * - Legacy addresses (1... for P2PKH, 3... for P2SH) - shared with Bitcoin
52
+ * - CashAddr format (bitcoincash:q... or q... for P2PKH, bitcoincash:p... or p... for P2SH)
53
+ *
54
+ * CashAddr checksum implementation based on:
55
+ * @see https://github.com/ealmansi/cashaddrjs (MIT License)
56
+ * @see https://github.com/bitcoincashorg/bitcoincash.org/blob/master/spec/cashaddr.md
57
+ */
58
+ function validateBchAddress(address) {
59
+ if (/^1[1-9A-HJ-NP-Za-km-z]{25,34}$/.test(address) || /^3[1-9A-HJ-NP-Za-km-z]{25,34}$/.test(address)) return true;
60
+ return validateBchCashAddr(address);
61
+ }
62
+ /**
63
+ * Validates Bitcoin Cash CashAddr format
64
+ * CashAddr uses a modified Bech32 encoding with polymod checksum
65
+ */
66
+ function validateBchCashAddr(address) {
67
+ let normalized = address.toLowerCase();
68
+ if (!normalized.includes(":")) normalized = `bitcoincash:${normalized}`;
69
+ if (!normalized.startsWith("bitcoincash:")) return false;
70
+ const payload = normalized.slice(12);
71
+ if (!payload.startsWith("q") && !payload.startsWith("p")) return false;
72
+ const CHARSET = "qpzry9x8gf2tvdw0s3jn54khce6mua7l";
73
+ for (const char of payload) if (!CHARSET.includes(char)) return false;
74
+ if (payload.length !== 42 && payload.length !== 61) return false;
75
+ return verifyBchChecksum(normalized);
76
+ }
77
+ function verifyBchChecksum(address) {
78
+ const CHARSET = "qpzry9x8gf2tvdw0s3jn54khce6mua7l";
79
+ const colonIndex = address.indexOf(":");
80
+ const prefix = address.slice(0, colonIndex);
81
+ const payload = address.slice(colonIndex + 1);
82
+ const prefixData = [];
83
+ for (const char of prefix) prefixData.push(char.charCodeAt(0) & 31);
84
+ prefixData.push(0);
85
+ const payloadData = [];
86
+ for (const char of payload) {
87
+ const idx = CHARSET.indexOf(char);
88
+ if (idx === -1) return false;
89
+ payloadData.push(idx);
90
+ }
91
+ const values = [...prefixData, ...payloadData];
92
+ let c = 1n;
93
+ for (const d of values) {
94
+ const c0 = c >> 35n;
95
+ c = (c & 34359738367n) << 5n ^ BigInt(d);
96
+ if (c0 & 1n) c ^= 656907472481n;
97
+ if (c0 & 2n) c ^= 522768456162n;
98
+ if (c0 & 4n) c ^= 1044723512260n;
99
+ if (c0 & 8n) c ^= 748107326120n;
100
+ if (c0 & 16n) c ^= 130178868336n;
101
+ }
102
+ return (c ^ 1n) === 0n;
103
+ }
45
104
  function validateSolAddress(address) {
46
105
  try {
47
106
  return PublicKey.isOnCurve(address);
@@ -136,6 +195,14 @@ function validateCardanoAddress(address) {
136
195
  return false;
137
196
  }
138
197
  }
198
+ /**
199
+ * Validates Starknet addresses
200
+ * Starknet addresses are felt252 (252-bit field elements) represented as
201
+ * hex strings with 0x prefix (up to 64 hex characters)
202
+ */
203
+ function validateStarknetAddress(address) {
204
+ return /^0x[a-fA-F0-9]{1,64}$/.test(address);
205
+ }
139
206
  function validateLitecoinAddress(address) {
140
207
  const first = address[0];
141
208
  if (first === "L") return validateLitecoinBase58Address(address, 48);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@defuse-protocol/intents-sdk",
3
- "version": "0.41.1",
3
+ "version": "0.42.0",
4
4
  "private": false,
5
5
  "type": "module",
6
6
  "sideEffects": false,
@@ -39,7 +39,7 @@
39
39
  "valibot": "^1.0.0",
40
40
  "viem": "^2.0.0",
41
41
  "@defuse-protocol/contract-types": "0.4.3",
42
- "@defuse-protocol/internal-utils": "0.20.0"
42
+ "@defuse-protocol/internal-utils": "0.21.0"
43
43
  },
44
44
  "devDependencies": {
45
45
  "tsdown": "0.15.5",