@pushchain/core 5.1.8 → 5.1.10

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pushchain/core",
3
- "version": "5.1.8",
3
+ "version": "5.1.10",
4
4
  "homepage": "https://push.org",
5
5
  "keywords": [
6
6
  "pushchain",
@@ -28,7 +28,7 @@ export declare const SYNTHETIC_PUSH_ERC20: Record<PUSH_NETWORK, {
28
28
  pETH: `0x${string}`;
29
29
  pETH_ARB: `0x${string}`;
30
30
  pETH_BASE: `0x${string}`;
31
- pETH_BNB: `0x${string}`;
31
+ pBNB: `0x${string}`;
32
32
  pSOL: `0x${string}`;
33
33
  USDT_ETH: `0x${string}`;
34
34
  USDC_ETH: `0x${string}`;
@@ -40,6 +40,9 @@ export declare const SYNTHETIC_PUSH_ERC20: Record<PUSH_NETWORK, {
40
40
  USDC_BNB: `0x${string}`;
41
41
  USDT_BASE: `0x${string}`;
42
42
  USDC_BASE: `0x${string}`;
43
+ WETH_ETH: `0x${string}`;
44
+ stETH_ETH: `0x${string}`;
45
+ DAI_SOL: `0x${string}`;
43
46
  }>;
44
47
  /**
45
48
  * Canonical metadata for each chain supported by the SDK.
@@ -54,7 +54,7 @@ exports.SYNTHETIC_PUSH_ERC20 = {
54
54
  pETH: '0x2971824Db68229D087931155C2b8bB820B275809',
55
55
  pETH_ARB: '0xc0a821a1AfEd1322c5e15f1F4586C0B8cE65400e',
56
56
  pETH_BASE: '0xc7007af2B24D4eb963fc9633B0c66e1d2D90Fc21',
57
- pETH_BNB: '0x7a9082dA308f3fa005beA7dB0d203b3b86664E36',
57
+ pBNB: '0x7a9082dA308f3fa005beA7dB0d203b3b86664E36',
58
58
  pSOL: '0x5D525Df2bD99a6e7ec58b76aF2fd95F39874EBed',
59
59
  USDT_ETH: '0xCA0C5E6F002A389E1580F0DB7cd06e4549B5F9d3',
60
60
  USDC_ETH: '0x7A58048036206bB898008b5bBDA85697DB1e5d66',
@@ -66,12 +66,15 @@ exports.SYNTHETIC_PUSH_ERC20 = {
66
66
  USDC_BNB: '0xTBD',
67
67
  USDT_BASE: '0x2C455189D2af6643B924A981a9080CcC63d5a567',
68
68
  USDC_BASE: '0xD7C6cA1e2c0CE260BE0c0AD39C1540de460e3Be1',
69
+ WETH_ETH: '0x0d0dF7E8807430A81104EA84d926139816eC7586',
70
+ stETH_ETH: '0xaf89E805949c628ebde3262e91dc4ab9eA12668E',
71
+ DAI_SOL: '0x5861f56A556c990358cc9cccd8B5baa3767982A8',
69
72
  },
70
73
  [enums_1.PUSH_NETWORK.TESTNET]: {
71
74
  pETH: '0x2971824Db68229D087931155C2b8bB820B275809',
72
75
  pETH_ARB: '0xc0a821a1AfEd1322c5e15f1F4586C0B8cE65400e',
73
76
  pETH_BASE: '0xc7007af2B24D4eb963fc9633B0c66e1d2D90Fc21',
74
- pETH_BNB: '0x7a9082dA308f3fa005beA7dB0d203b3b86664E36',
77
+ pBNB: '0x7a9082dA308f3fa005beA7dB0d203b3b86664E36',
75
78
  pSOL: '0x5D525Df2bD99a6e7ec58b76aF2fd95F39874EBed',
76
79
  USDT_ETH: '0xCA0C5E6F002A389E1580F0DB7cd06e4549B5F9d3',
77
80
  USDC_ETH: '0x7A58048036206bB898008b5bBDA85697DB1e5d66',
@@ -83,12 +86,15 @@ exports.SYNTHETIC_PUSH_ERC20 = {
83
86
  USDC_BNB: '0xTBD',
84
87
  USDT_BASE: '0x2C455189D2af6643B924A981a9080CcC63d5a567',
85
88
  USDC_BASE: '0xD7C6cA1e2c0CE260BE0c0AD39C1540de460e3Be1',
89
+ WETH_ETH: '0x0d0dF7E8807430A81104EA84d926139816eC7586',
90
+ stETH_ETH: '0xaf89E805949c628ebde3262e91dc4ab9eA12668E',
91
+ DAI_SOL: '0x5861f56A556c990358cc9cccd8B5baa3767982A8',
86
92
  },
87
93
  [enums_1.PUSH_NETWORK.LOCALNET]: {
88
94
  pETH: '0xTBD',
89
95
  pETH_ARB: '0xTBD',
90
96
  pETH_BASE: '0xTBD',
91
- pETH_BNB: '0xTBD',
97
+ pBNB: '0xTBD',
92
98
  pSOL: '0xTBD',
93
99
  USDT_ETH: '0xTBD',
94
100
  USDC_ETH: '0xTBD',
@@ -100,12 +106,15 @@ exports.SYNTHETIC_PUSH_ERC20 = {
100
106
  USDC_BNB: '0xTBD',
101
107
  USDT_BASE: '0xTBD',
102
108
  USDC_BASE: '0xTBD',
109
+ WETH_ETH: '0xTBD',
110
+ stETH_ETH: '0xTBD',
111
+ DAI_SOL: '0xTBD',
103
112
  },
104
113
  [enums_1.PUSH_NETWORK.MAINNET]: {
105
114
  pETH: '0xTBD',
106
115
  pETH_ARB: '0xTBD',
107
116
  pETH_BASE: '0xTBD',
108
- pETH_BNB: '0xTBD',
117
+ pBNB: '0xTBD',
109
118
  pSOL: '0xTBD',
110
119
  USDT_ETH: '0xTBD',
111
120
  USDC_ETH: '0xTBD',
@@ -117,6 +126,9 @@ exports.SYNTHETIC_PUSH_ERC20 = {
117
126
  USDC_BNB: '0xTBD',
118
127
  USDT_BASE: '0xTBD',
119
128
  USDC_BASE: '0xTBD',
129
+ WETH_ETH: '0xTBD',
130
+ stETH_ETH: '0xTBD',
131
+ DAI_SOL: '0xTBD',
120
132
  },
121
133
  };
122
134
  /**
@@ -206,8 +218,8 @@ exports.CHAIN_INFO = {
206
218
  timeout: 30000,
207
219
  explorerUrl: 'https://sepolia.arbiscan.io',
208
220
  dex: {
209
- uniV3Factory: '0x4752ba5DBc23f44D87826276BF6Fd6b1C372aD24',
210
- uniV3QuoterV2: '0xTBD',
221
+ uniV3Factory: '0x248AB79Bbb9bC29bB72f7Cd42F17e054Fc40188e',
222
+ uniV3QuoterV2: '0x2779a0CC1c3e0E44D2542EC3e79e3864Ae93Ef0B',
211
223
  weth: '0x980B62Da83eFf3D4576C647993b0c1D7faf17c73',
212
224
  },
213
225
  },
@@ -226,7 +238,7 @@ exports.CHAIN_INFO = {
226
238
  explorerUrl: 'https://sepolia.basescan.org',
227
239
  dex: {
228
240
  uniV3Factory: '0x4752ba5DBc23f44D87826276BF6Fd6b1C372aD24',
229
- uniV3QuoterV2: '0xTBD',
241
+ uniV3QuoterV2: '0xC5290058841028F1614F3A6F0F5816cAd0df5E27',
230
242
  weth: '0x4200000000000000000000000000000000000006',
231
243
  },
232
244
  },
@@ -14,17 +14,21 @@ export interface PayableToken {
14
14
  export type MoveableTokenMap = Partial<{
15
15
  ETH: MoveableToken;
16
16
  SOL: MoveableToken;
17
+ BNB: MoveableToken;
17
18
  USDT: MoveableToken;
18
19
  USDC: MoveableToken;
19
20
  WETH: MoveableToken;
20
21
  stETH: MoveableToken;
22
+ DAI: MoveableToken;
21
23
  }>;
22
24
  export type PayableTokenMap = Partial<{
23
25
  ETH: PayableToken;
26
+ BNB: PayableToken;
24
27
  USDT: PayableToken;
25
28
  USDC: PayableToken;
26
29
  WETH: PayableToken;
27
30
  stETH: PayableToken;
31
+ DAI: PayableToken;
28
32
  }>;
29
33
  export declare class MoveableTokenAccessor {
30
34
  private readonly tokens;
@@ -32,16 +36,19 @@ export declare class MoveableTokenAccessor {
32
36
  private require;
33
37
  get ETH(): MoveableToken;
34
38
  get SOL(): MoveableToken;
39
+ get BNB(): MoveableToken;
35
40
  get USDT(): MoveableToken;
36
41
  get WETH(): MoveableToken;
37
42
  get USDC(): MoveableToken;
38
43
  get stETH(): MoveableToken;
44
+ get DAI(): MoveableToken;
39
45
  }
40
46
  export declare class PayableTokenAccessor {
41
47
  private readonly tokens;
42
48
  constructor(tokens: Record<string, PayableToken>);
43
49
  private require;
44
50
  get ETH(): PayableToken;
51
+ get BNB(): PayableToken;
45
52
  get USDT(): PayableToken;
46
53
  get USDC(): PayableToken;
47
54
  get WETH(): PayableToken;
@@ -73,8 +80,11 @@ export interface PushChainMoveableTokenAccessor {
73
80
  readonly pEth: PushChainMoveableToken;
74
81
  readonly pEthArb: PushChainMoveableToken;
75
82
  readonly pEthBase: PushChainMoveableToken;
76
- readonly pEthBnb: PushChainMoveableToken;
83
+ readonly pBnb: PushChainMoveableToken;
77
84
  readonly pSol: PushChainMoveableToken;
85
+ readonly pWeth: PushChainMoveableToken;
86
+ readonly pStEth: PushChainMoveableToken;
87
+ readonly pDai: PushChainMoveableToken;
78
88
  readonly USDT: ChainSuffixAccessor;
79
89
  readonly USDC: ChainSuffixAccessor;
80
90
  }
@@ -21,6 +21,9 @@ class MoveableTokenAccessor {
21
21
  get SOL() {
22
22
  return this.require('SOL');
23
23
  }
24
+ get BNB() {
25
+ return this.require('BNB');
26
+ }
24
27
  get USDT() {
25
28
  return this.require('USDT');
26
29
  }
@@ -33,6 +36,9 @@ class MoveableTokenAccessor {
33
36
  get stETH() {
34
37
  return this.require('stETH');
35
38
  }
39
+ get DAI() {
40
+ return this.require('DAI');
41
+ }
36
42
  }
37
43
  exports.MoveableTokenAccessor = MoveableTokenAccessor;
38
44
  class PayableTokenAccessor {
@@ -48,6 +54,9 @@ class PayableTokenAccessor {
48
54
  get ETH() {
49
55
  return this.require('ETH');
50
56
  }
57
+ get BNB() {
58
+ return this.require('BNB');
59
+ }
51
60
  get USDT() {
52
61
  return this.require('USDT');
53
62
  }
@@ -175,25 +184,24 @@ const TOKEN_META = {
175
184
  },
176
185
  // BNB Testnet
177
186
  [enums_1.CHAIN.BNB_TESTNET]: {
178
- // NOTE: Both symbols are provided to mirror existing usage across maps
179
187
  BNB: {
180
188
  symbol: 'BNB',
181
189
  decimals: 18,
182
190
  address: NATIVE,
183
191
  mechanism: 'native',
184
192
  },
185
- ETH: {
186
- symbol: 'ETH',
187
- decimals: 18,
188
- address: NATIVE,
189
- mechanism: 'native',
190
- },
191
193
  USDT: {
192
194
  symbol: 'USDT',
193
195
  decimals: 6,
194
196
  address: '0xBC14F348BC9667be46b35Edc9B68653d86013DC5',
195
197
  mechanism: 'approve',
196
198
  },
199
+ USDC: {
200
+ symbol: 'USDC',
201
+ decimals: 6,
202
+ address: '0x64544969ed7EBf5f083679233325356EbE738930',
203
+ mechanism: 'approve',
204
+ },
197
205
  },
198
206
  // Solana Devnet
199
207
  [enums_1.CHAIN.SOLANA_DEVNET]: {
@@ -215,6 +223,12 @@ const TOKEN_META = {
215
223
  address: '4zMMC9srt5Ri5X14GAgXhaHii3GnPAEERYPJgZJDncDU',
216
224
  mechanism: 'approve',
217
225
  },
226
+ DAI: {
227
+ symbol: 'DAI',
228
+ decimals: 18,
229
+ address: 'G2ZLaRhpohW23KTEX3fBjZXtNTFFwemqCaWWnWVTj4TB',
230
+ mechanism: 'approve',
231
+ },
218
232
  },
219
233
  };
220
234
  function makeToken(chain, symbol) {
@@ -239,7 +253,7 @@ function buildPushChainMoveableTokenList() {
239
253
  mk('pETH', 18, s.pETH),
240
254
  mk('pETH_ARB', 18, s.pETH_ARB),
241
255
  mk('pETH_BASE', 18, s.pETH_BASE),
242
- mk('pETH_BNB', 18, s.pETH_BNB),
256
+ mk('pBNB', 18, s.pBNB),
243
257
  mk('pSOL', 9, s.pSOL),
244
258
  mk('USDT', 6, s.USDT_ETH),
245
259
  mk('USDT', 6, s.USDT_ARB),
@@ -251,6 +265,9 @@ function buildPushChainMoveableTokenList() {
251
265
  mk('USDC', 6, s.USDC_BASE),
252
266
  mk('USDC', 6, s.USDC_BNB),
253
267
  mk('USDC', 6, s.USDC_SOL),
268
+ mk('WETH', 18, s.WETH_ETH),
269
+ mk('stETH', 18, s.stETH_ETH),
270
+ mk('DAI', 18, s.DAI_SOL),
254
271
  ];
255
272
  }
256
273
  // Minimal initial registries. These can be extended safely without breaking the API.
@@ -281,13 +298,15 @@ exports.MOVEABLE_TOKENS = {
281
298
  makeToken(enums_1.CHAIN.BASE_SEPOLIA, 'WETH'),
282
299
  ],
283
300
  [enums_1.CHAIN.BNB_TESTNET]: [
284
- makeToken(enums_1.CHAIN.BNB_TESTNET, 'ETH'),
301
+ makeToken(enums_1.CHAIN.BNB_TESTNET, 'BNB'),
285
302
  makeToken(enums_1.CHAIN.BNB_TESTNET, 'USDT'),
303
+ makeToken(enums_1.CHAIN.BNB_TESTNET, 'USDC'),
286
304
  ],
287
305
  [enums_1.CHAIN.SOLANA_DEVNET]: [
288
306
  makeToken(enums_1.CHAIN.SOLANA_DEVNET, 'SOL'),
289
307
  makeToken(enums_1.CHAIN.SOLANA_DEVNET, 'USDT'),
290
308
  makeToken(enums_1.CHAIN.SOLANA_DEVNET, 'USDC'),
309
+ makeToken(enums_1.CHAIN.SOLANA_DEVNET, 'DAI'),
291
310
  ],
292
311
  };
293
312
  exports.PAYABLE_TOKENS = {
@@ -342,8 +361,11 @@ function buildPushChainMoveableTokenAccessor() {
342
361
  pEth: mk('pETH', 18, s.pETH, enums_1.CHAIN.ETHEREUM_SEPOLIA),
343
362
  pEthArb: mk('pETH_ARB', 18, s.pETH_ARB, enums_1.CHAIN.ARBITRUM_SEPOLIA),
344
363
  pEthBase: mk('pETH_BASE', 18, s.pETH_BASE, enums_1.CHAIN.BASE_SEPOLIA),
345
- pEthBnb: mk('pETH_BNB', 18, s.pETH_BNB, enums_1.CHAIN.BNB_TESTNET),
364
+ pBnb: mk('pBNB', 18, s.pBNB, enums_1.CHAIN.BNB_TESTNET),
346
365
  pSol: mk('pSOL', 9, s.pSOL, enums_1.CHAIN.SOLANA_DEVNET),
366
+ pWeth: mk('WETH', 18, s.WETH_ETH, enums_1.CHAIN.ETHEREUM_SEPOLIA),
367
+ pStEth: mk('stETH', 18, s.stETH_ETH, enums_1.CHAIN.ETHEREUM_SEPOLIA),
368
+ pDai: mk('DAI', 18, s.DAI_SOL, enums_1.CHAIN.SOLANA_DEVNET),
347
369
  USDT: {
348
370
  eth: mk('USDT', 6, s.USDT_ETH, enums_1.CHAIN.ETHEREUM_SEPOLIA),
349
371
  arb: mk('USDT', 6, s.USDT_ARB, enums_1.CHAIN.ARBITRUM_SEPOLIA),
@@ -127,7 +127,7 @@ function buildHopDescriptor(ctx, params, route, ueaAddress) {
127
127
  if ((_b = params.funds) === null || _b === void 0 ? void 0 : _b.amount) {
128
128
  const token = params.funds.token;
129
129
  if (token) {
130
- prc20Token = push_chain_1.PushChain.utils.tokens.getPRC20Address(token);
130
+ prc20Token = push_chain_1.PushChain.utils.tokens.getPRC20Address(token).address;
131
131
  burnAmount = params.funds.amount;
132
132
  }
133
133
  }
@@ -233,7 +233,7 @@ function buildHopDescriptor(ctx, params, route, ueaAddress) {
233
233
  if ((_f = params.funds) === null || _f === void 0 ? void 0 : _f.amount) {
234
234
  const token = params.funds.token;
235
235
  if (token) {
236
- prc20Token = push_chain_1.PushChain.utils.tokens.getPRC20Address(token);
236
+ prc20Token = push_chain_1.PushChain.utils.tokens.getPRC20Address(token).address;
237
237
  burnAmount = params.funds.amount;
238
238
  }
239
239
  }
@@ -292,7 +292,7 @@ function buildHopDescriptor(ctx, params, route, ueaAddress) {
292
292
  amount = params.funds.amount;
293
293
  const token = params.funds.token;
294
294
  if (token && token.address) {
295
- prc20Token = push_chain_1.PushChain.utils.tokens.getPRC20Address(token);
295
+ prc20Token = push_chain_1.PushChain.utils.tokens.getPRC20Address(token).address;
296
296
  }
297
297
  else {
298
298
  prc20Token = (0, helpers_1.getNativePRC20ForChain)(sourceChain, ctx.pushNetwork);
@@ -75,7 +75,7 @@ function getNativePRC20ForChain(targetChain, pushNetwork) {
75
75
  case enums_1.CHAIN.BASE_SEPOLIA:
76
76
  return synthetics.pETH_BASE;
77
77
  case enums_1.CHAIN.BNB_TESTNET:
78
- return synthetics.pETH_BNB;
78
+ return synthetics.pBNB;
79
79
  case enums_1.CHAIN.SOLANA_DEVNET:
80
80
  case enums_1.CHAIN.SOLANA_TESTNET:
81
81
  case enums_1.CHAIN.SOLANA_MAINNET:
@@ -62,7 +62,7 @@ function resolveR2Prc20TokenEvm(params, targetChain, pushNetwork) {
62
62
  // User explicitly specified funds with token
63
63
  const token = params.funds.token;
64
64
  if (token) {
65
- prc20Token = push_chain_1.PushChain.utils.tokens.getPRC20Address(token);
65
+ prc20Token = push_chain_1.PushChain.utils.tokens.getPRC20Address(token).address;
66
66
  burnAmount = params.funds.amount;
67
67
  }
68
68
  }
@@ -90,7 +90,7 @@ function resolveR2Prc20TokenSvm(params, targetChain, pushNetwork, hasSvmExecute)
90
90
  if ((_a = params.funds) === null || _a === void 0 ? void 0 : _a.amount) {
91
91
  const token = params.funds.token;
92
92
  if (token) {
93
- prc20Token = push_chain_1.PushChain.utils.tokens.getPRC20Address(token);
93
+ prc20Token = push_chain_1.PushChain.utils.tokens.getPRC20Address(token).address;
94
94
  burnAmount = params.funds.amount;
95
95
  }
96
96
  }
@@ -101,7 +101,7 @@ function resolveR2Prc20TokenSvm(params, targetChain, pushNetwork, hasSvmExecute)
101
101
  else if (hasSvmExecute) {
102
102
  const token = params.funds && params.funds.token;
103
103
  if (token) {
104
- prc20Token = push_chain_1.PushChain.utils.tokens.getPRC20Address(token);
104
+ prc20Token = push_chain_1.PushChain.utils.tokens.getPRC20Address(token).address;
105
105
  }
106
106
  else {
107
107
  prc20Token = (0, helpers_1.getNativePRC20ForChain)(targetChain, pushNetwork);
@@ -1269,7 +1269,7 @@ function buildPayloadForRoute(ctx, params, route, nonce) {
1269
1269
  if ((_a = params.funds) === null || _a === void 0 ? void 0 : _a.amount) {
1270
1270
  const token = params.funds.token;
1271
1271
  if (token) {
1272
- prc20Token = push_chain_1.PushChain.utils.tokens.getPRC20Address(token);
1272
+ prc20Token = push_chain_1.PushChain.utils.tokens.getPRC20Address(token).address;
1273
1273
  burnAmount = params.funds.amount;
1274
1274
  }
1275
1275
  }
@@ -1321,7 +1321,7 @@ function buildPayloadForRoute(ctx, params, route, nonce) {
1321
1321
  if ((_d = params.funds) === null || _d === void 0 ? void 0 : _d.amount) {
1322
1322
  const token = params.funds.token;
1323
1323
  if (token) {
1324
- prc20Token = push_chain_1.PushChain.utils.tokens.getPRC20Address(token);
1324
+ prc20Token = push_chain_1.PushChain.utils.tokens.getPRC20Address(token).address;
1325
1325
  burnAmount = params.funds.amount;
1326
1326
  }
1327
1327
  }
@@ -68,7 +68,7 @@ function buildExecuteMulticall({ execute, ueaAddress, logger, }) {
68
68
  functionName: 'transfer',
69
69
  args: [execute.to, (_q = execute.funds) === null || _q === void 0 ? void 0 : _q.amount],
70
70
  });
71
- const pushChainTo = push_chain_1.PushChain.utils.tokens.getPRC20Address(token);
71
+ const { address: pushChainTo } = push_chain_1.PushChain.utils.tokens.getPRC20Address(token);
72
72
  multicallData.push({
73
73
  to: pushChainTo,
74
74
  value: BigInt(0),
@@ -212,7 +212,7 @@ function detectRoute(params) {
212
212
  * @throws ChainNotSupportedError if chain is not supported
213
213
  */
214
214
  function validateRouteParams(params, context) {
215
- var _a, _b, _c, _d;
215
+ var _a, _b;
216
216
  const route = detectRoute(params);
217
217
  // Validate from.chain is supported external chain (Routes 3, 4)
218
218
  if ((_a = params.from) === null || _a === void 0 ? void 0 : _a.chain) {
@@ -254,51 +254,45 @@ function validateRouteParams(params, context) {
254
254
  throw new RouteValidationError('migration is not supported on SVM chains');
255
255
  }
256
256
  }
257
- // Validate funds token symbol is available on target chain (Route 2 outbound).
258
- // A PushChainMoveableToken (e.g. pSOL, pETH_BNB) carries a `sourceChain` pointing at
259
- // the external chain it mirrors — bridging it to that chain is always valid since
260
- // the target receives the underlying asset (SOL, ETH, etc.).
261
- if (((_b = params.funds) === null || _b === void 0 ? void 0 : _b.token) && isChainTarget(params.to)) {
262
- const targetChain = params.to.chain;
263
- if (!isPushChain(targetChain)) {
264
- const tokenSourceChain = params.funds.token.sourceChain;
265
- const isBridgeBack = tokenSourceChain === targetChain;
266
- const targetTokens = tokens_1.MOVEABLE_TOKENS[targetChain] || [];
267
- const hasSymbolOnTarget = targetTokens.some(t => t.symbol === params.funds.token.symbol);
268
- if (!hasSymbolOnTarget && !isBridgeBack) {
269
- const tokenChain = findTokenChain(params.funds.token);
270
- const tokenLabel = tokenChain
271
- ? `${chainEnumToName(tokenChain)}.${params.funds.token.symbol}`
272
- : params.funds.token.symbol;
273
- const clientLabel = (context === null || context === void 0 ? void 0 : context.clientChain)
274
- ? chainEnumToName(context.clientChain)
275
- : 'unknown';
257
+ // Validate funds.token against the route-relevant chain.
258
+ // - Route 1 (UOA_TO_PUSH): no bridging, nothing to validate here.
259
+ // - Route 2 (UOA_TO_CEA): validate against to.chain.
260
+ // - Route 3/4 (CEA_TO_PUSH, CEA_TO_CEA): validate against from.chain.
261
+ // For a Push-registered PRC-20 the token's own `sourceChain` must match; for a
262
+ // non-Push token, the token's symbol must be registered on the chain.
263
+ if ((_b = params.funds) === null || _b === void 0 ? void 0 : _b.token) {
264
+ const token = params.funds.token;
265
+ const clientLabel = (context === null || context === void 0 ? void 0 : context.clientChain)
266
+ ? chainEnumToName(context.clientChain)
267
+ : 'unknown';
268
+ const registeredOn = findTokenChain(token);
269
+ const tokenLabel = registeredOn
270
+ ? `${chainEnumToName(registeredOn)}.${token.symbol}`
271
+ : token.symbol;
272
+ const isPushToken = registeredOn !== undefined && isPushChain(registeredOn);
273
+ const validateAgainst = (chain, direction) => {
274
+ if (isPushChain(chain))
275
+ return;
276
+ const ok = isPushToken
277
+ ? token.sourceChain === chain
278
+ : (tokens_1.MOVEABLE_TOKENS[chain] || []).some(t => t.symbol === token.symbol);
279
+ if (!ok) {
276
280
  throw new RouteValidationError(`Unsupported moveable token for current client and route:\n` +
277
281
  `token=${tokenLabel}\n` +
278
282
  `clientChain=${clientLabel}\n` +
279
- `destination=${chainEnumToName(targetChain)}`);
280
- }
281
- }
282
- }
283
- // Validate funds token is available on source chain (Route 3 inbound)
284
- if (((_c = params.funds) === null || _c === void 0 ? void 0 : _c.token) && ((_d = params.from) === null || _d === void 0 ? void 0 : _d.chain)) {
285
- const sourceChain = params.from.chain;
286
- if (!isPushChain(sourceChain)) {
287
- const sourceTokens = tokens_1.MOVEABLE_TOKENS[sourceChain] || [];
288
- const hasSymbolOnSource = sourceTokens.some(t => t.symbol === params.funds.token.symbol);
289
- if (!hasSymbolOnSource) {
290
- const tokenChain = findTokenChain(params.funds.token);
291
- const tokenLabel = tokenChain
292
- ? `${chainEnumToName(tokenChain)}.${params.funds.token.symbol}`
293
- : params.funds.token.symbol;
294
- const clientLabel = (context === null || context === void 0 ? void 0 : context.clientChain)
295
- ? chainEnumToName(context.clientChain)
296
- : 'unknown';
297
- throw new RouteValidationError(`Unsupported moveable token for current client and route:\n` +
298
- `token=${tokenLabel}\n` +
299
- `clientChain=${clientLabel}\n` +
300
- `source=${chainEnumToName(sourceChain)}`);
283
+ `${direction}=${chainEnumToName(chain)}`);
301
284
  }
285
+ };
286
+ switch (route) {
287
+ case TransactionRoute.UOA_TO_PUSH:
288
+ break;
289
+ case TransactionRoute.UOA_TO_CEA:
290
+ validateAgainst(params.to.chain, 'destination');
291
+ break;
292
+ case TransactionRoute.CEA_TO_PUSH:
293
+ case TransactionRoute.CEA_TO_CEA:
294
+ validateAgainst(params.from.chain, 'source');
295
+ break;
302
296
  }
303
297
  }
304
298
  // Validate address format
@@ -256,21 +256,19 @@ export declare class Utils {
256
256
  }>;
257
257
  };
258
258
  /**
259
- * Convert any supported origin-chain token into its mapped PRC20 token address on Push Chain.
259
+ * Convert any supported origin-chain token into its mapped PRC20 token on Push Chain.
260
260
  *
261
261
  * @param token - Either a MoveableToken from `pushChainClient.moveable.token.*`
262
262
  * or an object with the origin chain and token address.
263
- * @returns {`0x${string}`} The synthetic asset address on Push Chain.
263
+ * @returns An object describing the synthetic PRC-20 on Push Chain.
264
264
  *
265
265
  * @example
266
266
  * ```jsx
267
- * PushChain.utils.tokens.getPRC20Address(
268
- * token: MoveableToken | {
269
- * chain: CONSTANTS.CHAIN.ETHEREUM_SEPOLIA;
270
- * address: `0x${string}`;
271
- * }
272
- * );
273
- * // → `0x...`
267
+ * const { address, chain, symbol, decimals, network } =
268
+ * PushChain.utils.tokens.getPRC20Address({
269
+ * chain: CONSTANTS.CHAIN.ETHEREUM_SEPOLIA,
270
+ * address: '0x...',
271
+ * });
274
272
  * ```
275
273
  */
276
274
  getPRC20Address(token: MoveableToken | {
@@ -278,7 +276,13 @@ export declare class Utils {
278
276
  address: string;
279
277
  }, options?: {
280
278
  network?: PUSH_NETWORK;
281
- }): `0x${string}`;
279
+ }): {
280
+ address: `0x${string}`;
281
+ chain: CHAIN;
282
+ symbol: string;
283
+ decimals: number;
284
+ network: PUSH_NETWORK;
285
+ };
282
286
  };
283
287
  /**
284
288
  * Internal: resolves a CHAIN enum from either a CHAIN value or a PushChain client instance.
package/src/lib/utils.js CHANGED
@@ -601,42 +601,55 @@ Utils.tokens = {
601
601
  return { tokens };
602
602
  },
603
603
  /**
604
- * Convert any supported origin-chain token into its mapped PRC20 token address on Push Chain.
604
+ * Convert any supported origin-chain token into its mapped PRC20 token on Push Chain.
605
605
  *
606
606
  * @param token - Either a MoveableToken from `pushChainClient.moveable.token.*`
607
607
  * or an object with the origin chain and token address.
608
- * @returns {`0x${string}`} The synthetic asset address on Push Chain.
608
+ * @returns An object describing the synthetic PRC-20 on Push Chain.
609
609
  *
610
610
  * @example
611
611
  * ```jsx
612
- * PushChain.utils.tokens.getPRC20Address(
613
- * token: MoveableToken | {
614
- * chain: CONSTANTS.CHAIN.ETHEREUM_SEPOLIA;
615
- * address: `0x${string}`;
616
- * }
617
- * );
618
- * // → `0x...`
612
+ * const { address, chain, symbol, decimals, network } =
613
+ * PushChain.utils.tokens.getPRC20Address({
614
+ * chain: CONSTANTS.CHAIN.ETHEREUM_SEPOLIA,
615
+ * address: '0x...',
616
+ * });
619
617
  * ```
620
618
  */
621
619
  getPRC20Address(token, options) {
622
- var _a, _b;
620
+ var _a, _b, _c, _d;
621
+ const network = (_a = options === null || options === void 0 ? void 0 : options.network) !== null && _a !== void 0 ? _a : enums_1.PUSH_NETWORK.TESTNET_DONUT;
622
+ const assertDeployed = (addr, ctx) => {
623
+ if (!addr || addr === '0xTBD') {
624
+ throw new Error(`PRC20 address not available for ${ctx} on network ${network}`);
625
+ }
626
+ return addr;
627
+ };
623
628
  // PushChainMoveableToken (pETH, pSOL, pUSDT(BNB), …) carries its PRC-20 address
624
- // directly. Return it as-is — no registry lookup needed.
625
- const maybePrc20 = token.prc20Address;
626
- if (maybePrc20) {
627
- return maybePrc20;
629
+ // and origin `sourceChain` directly — no registry lookup needed.
630
+ const pcToken = token;
631
+ if (pcToken.prc20Address) {
632
+ return {
633
+ address: assertDeployed(pcToken.prc20Address, `${(_b = pcToken.symbol) !== null && _b !== void 0 ? _b : 'token'} (${(_c = pcToken.sourceChain) !== null && _c !== void 0 ? _c : 'unknown'})`),
634
+ chain: pcToken.sourceChain,
635
+ symbol: pcToken.symbol,
636
+ decimals: pcToken.decimals,
637
+ network,
638
+ };
628
639
  }
629
- // Infer origin chain and symbol by matching against the MOVEABLE_TOKENS registry
640
+ // Infer origin chain, symbol, decimals by matching against MOVEABLE_TOKENS
630
641
  let originChain;
631
642
  let tokenSymbol;
643
+ let tokenDecimals;
632
644
  if ('symbol' in token) {
633
645
  // MoveableToken path: infer chain by symbol + address
634
646
  for (const [key, list] of Object.entries(tokens_1.MOVEABLE_TOKENS)) {
635
647
  const k = key;
636
- const found = (list !== null && list !== void 0 ? list : []).some((t) => t.symbol === token.symbol && t.address === token.address);
637
- if (found) {
648
+ const match = (list !== null && list !== void 0 ? list : []).find((t) => t.symbol === token.symbol && t.address === token.address);
649
+ if (match) {
638
650
  originChain = k;
639
- tokenSymbol = token.symbol;
651
+ tokenSymbol = match.symbol;
652
+ tokenDecimals = match.decimals;
640
653
  break;
641
654
  }
642
655
  }
@@ -644,17 +657,20 @@ Utils.tokens = {
644
657
  else {
645
658
  // { chain, address } path: trust the provided chain and resolve symbol via registry
646
659
  originChain = token.chain;
647
- const list = (_a = tokens_1.MOVEABLE_TOKENS[originChain]) !== null && _a !== void 0 ? _a : [];
648
- const match = (list !== null && list !== void 0 ? list : []).find((t) => t.address === token.address);
660
+ const list = (_d = tokens_1.MOVEABLE_TOKENS[originChain]) !== null && _d !== void 0 ? _d : [];
661
+ const match = list.find((t) => t.address === token.address);
649
662
  if (match) {
650
663
  tokenSymbol = match.symbol;
664
+ tokenDecimals = match.decimals;
651
665
  }
652
666
  }
653
- if (!originChain || !tokenSymbol) {
667
+ if (!originChain || !tokenSymbol || tokenDecimals === undefined) {
654
668
  throw new Error('Unable to infer origin chain or token symbol for token');
655
669
  }
656
- const network = (_b = options === null || options === void 0 ? void 0 : options.network) !== null && _b !== void 0 ? _b : enums_1.PUSH_NETWORK.TESTNET_DONUT;
657
670
  const map = chain_1.SYNTHETIC_PUSH_ERC20[network];
671
+ if (!map) {
672
+ throw new Error(`No PRC20 address map configured for network: ${network}`);
673
+ }
658
674
  // Map token → synthetic key by origin chain family
659
675
  const isEthFamily = originChain === enums_1.CHAIN.ETHEREUM_MAINNET ||
660
676
  originChain === enums_1.CHAIN.ETHEREUM_SEPOLIA;
@@ -671,8 +687,6 @@ Utils.tokens = {
671
687
  key = 'pETH_ARB';
672
688
  else if (isBaseFamily)
673
689
  key = 'pETH_BASE';
674
- else if (isBnbFamily)
675
- key = 'pETH_BNB';
676
690
  else
677
691
  throw new Error('Unsupported ETH origin chain for synthetic mapping');
678
692
  break;
@@ -683,6 +697,12 @@ Utils.tokens = {
683
697
  key = 'pSOL';
684
698
  break;
685
699
  }
700
+ case 'BNB': {
701
+ if (!isBnbFamily)
702
+ throw new Error('BNB token provided but origin is not BNB Testnet');
703
+ key = 'pBNB';
704
+ break;
705
+ }
686
706
  case 'USDT': {
687
707
  if (isEthFamily)
688
708
  key = 'USDT_ETH';
@@ -716,7 +736,13 @@ Utils.tokens = {
716
736
  default:
717
737
  throw new Error(`Unsupported token symbol: ${tokenSymbol}`);
718
738
  }
719
- return map[key];
739
+ return {
740
+ address: assertDeployed(map[key], `${tokenSymbol} on ${originChain}`),
741
+ chain: originChain,
742
+ symbol: tokenSymbol,
743
+ decimals: tokenDecimals,
744
+ network,
745
+ };
720
746
  },
721
747
  };
722
748
  //# sourceMappingURL=utils.js.map