@pushchain/core 5.1.7 → 5.1.9

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.
Files changed (30) hide show
  1. package/package.json +1 -1
  2. package/src/lib/constants/abi/feeLocker.json +1 -2579
  3. package/src/lib/constants/abi/universalGatewayV0.json +1 -3009
  4. package/src/lib/constants/chain.d.ts +3 -0
  5. package/src/lib/constants/chain.js +54 -1
  6. package/src/lib/constants/tokens.js +25 -0
  7. package/src/lib/generated/uexecutor/v1/types.d.ts +0 -6
  8. package/src/lib/generated/uexecutor/v1/types.js +0 -267
  9. package/src/lib/generated/uexecutor/v2/index.d.ts +1 -1
  10. package/src/lib/generated/uexecutor/v2/index.js +1 -9
  11. package/src/lib/generated/uexecutor/v2/types.d.ts +1 -7
  12. package/src/lib/generated/uexecutor/v2/types.js +1 -287
  13. package/src/lib/generated/v1/tx.d.ts +0 -4
  14. package/src/lib/generated/v1/tx.js +0 -205
  15. package/src/lib/orchestrator/internals/cascade.js +3 -3
  16. package/src/lib/orchestrator/internals/route-handlers.js +5 -5
  17. package/src/lib/orchestrator/orchestrator.types.d.ts +0 -7
  18. package/src/lib/orchestrator/payload-builders.d.ts +0 -45
  19. package/src/lib/orchestrator/payload-builders.js +1 -111
  20. package/src/lib/push-client/push-client.js +12 -11
  21. package/src/lib/universal/account/account.js +10 -2
  22. package/src/lib/utils.d.ts +14 -10
  23. package/src/lib/utils.js +45 -23
  24. package/src/lib/vm-client/evm-client.d.ts +1 -1
  25. package/src/lib/vm-client/evm-client.js +2 -1
  26. package/src/lib/vm-client/vm-client.types.d.ts +2 -1
  27. package/src/lib/universal-tx-detector/__tests__/fixtures/builders.d.ts +0 -32
  28. package/src/lib/universal-tx-detector/__tests__/fixtures/builders.js +0 -65
  29. package/src/lib/universal-tx-detector/__tests__/fixtures/scenarios.d.ts +0 -72
  30. package/src/lib/universal-tx-detector/__tests__/fixtures/scenarios.js +0 -669
@@ -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
  }
@@ -705,13 +705,6 @@ export interface OutboundTxDetails {
705
705
  /** Asset address on external chain (address(0) for native) */
706
706
  assetAddr: string;
707
707
  }
708
- /**
709
- * Progress event for outbound sync operations
710
- */
711
- export interface OutboundSyncProgress {
712
- status: 'waiting' | 'polling' | 'success' | 'failed' | 'timeout';
713
- elapsed: number;
714
- }
715
708
  /**
716
709
  * Options for waitForOutboundTx polling
717
710
  */
@@ -52,39 +52,6 @@ export declare function buildInboundUniversalPayload(multicallData: `0x${string}
52
52
  nonce?: bigint;
53
53
  deadline?: bigint;
54
54
  }): `0x${string}`;
55
- /**
56
- * Build a single call as CEA multicall payload
57
- *
58
- * @param target - Target contract address
59
- * @param value - Native value to send
60
- * @param data - Calldata to execute
61
- * @returns Encoded payload with selector prefix
62
- */
63
- export declare function buildSingleCeaCall(target: `0x${string}`, value: bigint, data: `0x${string}`): `0x${string}`;
64
- /**
65
- * Build approve + interact pattern for ERC20 operations on external chains
66
- *
67
- * @param tokenAddress - ERC20 token address
68
- * @param spender - Address to approve (e.g., DEX router)
69
- * @param amount - Amount to approve
70
- * @param interactCall - The interaction call (e.g., swap)
71
- * @returns Array of multicall operations
72
- */
73
- export declare function buildApproveAndInteract(tokenAddress: `0x${string}`, spender: `0x${string}`, amount: bigint, interactCall: MultiCall): MultiCall[];
74
- /**
75
- * Build sendUniversalTxFromCEA call for CEA → Push routing (Route 3)
76
- *
77
- * @param gatewayAddress - UniversalGateway address on external chain
78
- * @param recipient - Recipient on Push Chain (usually UEA)
79
- * @param token - Token address (address(0) for native)
80
- * @param amount - Amount to send
81
- * @param payload - Payload for Push Chain execution
82
- * @param revertRecipient - Address to receive funds on revert
83
- * @param signatureData - Signature data (usually empty for CEA calls)
84
- * @param nativeValue - Native value to send with the call
85
- * @returns MultiCall for sendUniversalTxFromCEA
86
- */
87
- export declare function buildSendUniversalTxFromCEA(gatewayAddress: `0x${string}`, recipient: `0x${string}`, token: `0x${string}`, amount: bigint, payload: `0x${string}`, revertRecipient: `0x${string}`, signatureData?: `0x${string}`, nativeValue?: bigint): MultiCall;
88
55
  /**
89
56
  * Build sendUniversalTxToUEA call for CEA self-call (Route 3)
90
57
  *
@@ -115,14 +82,6 @@ export declare function buildSendUniversalTxToUEA(ceaAddress: `0x${string}`, tok
115
82
  * @returns UniversalOutboundTxRequest object
116
83
  */
117
84
  export declare function buildOutboundRequest(target: `0x${string}`, prc20Token: `0x${string}`, amount: bigint, gasLimit: bigint, payload: `0x${string}`, revertRecipient: `0x${string}`): UniversalOutboundTxRequest;
118
- /**
119
- * Build native transfer multicall
120
- *
121
- * @param to - Recipient address
122
- * @param value - Native value to transfer
123
- * @returns MultiCall for native transfer
124
- */
125
- export declare function buildNativeTransfer(to: `0x${string}`, value: bigint): MultiCall;
126
85
  /**
127
86
  * Build ERC20 transfer multicall
128
87
  *
@@ -150,10 +109,6 @@ export declare function buildErc20WithdrawalMulticall(tokenAddress: `0x${string}
150
109
  * @returns 4-byte hex string `0xcac656d6`
151
110
  */
152
111
  export declare function buildMigrationPayload(): `0x${string}`;
153
- /**
154
- * Check if an address is the zero address
155
- */
156
- export declare function isZeroAddress(address: `0x${string}`): boolean;
157
112
  /**
158
113
  * Build approval multicalls + sendUniversalTxOutbound call for Push Chain.
159
114
  *
@@ -4,16 +4,11 @@ exports.MULTICALL_TUPLE_TYPE = void 0;
4
4
  exports.buildExecuteMulticall = buildExecuteMulticall;
5
5
  exports.buildCeaMulticallPayload = buildCeaMulticallPayload;
6
6
  exports.buildInboundUniversalPayload = buildInboundUniversalPayload;
7
- exports.buildSingleCeaCall = buildSingleCeaCall;
8
- exports.buildApproveAndInteract = buildApproveAndInteract;
9
- exports.buildSendUniversalTxFromCEA = buildSendUniversalTxFromCEA;
10
7
  exports.buildSendUniversalTxToUEA = buildSendUniversalTxToUEA;
11
8
  exports.buildOutboundRequest = buildOutboundRequest;
12
- exports.buildNativeTransfer = buildNativeTransfer;
13
9
  exports.buildErc20Transfer = buildErc20Transfer;
14
10
  exports.buildErc20WithdrawalMulticall = buildErc20WithdrawalMulticall;
15
11
  exports.buildMigrationPayload = buildMigrationPayload;
16
- exports.isZeroAddress = isZeroAddress;
17
12
  exports.buildOutboundApprovalAndCall = buildOutboundApprovalAndCall;
18
13
  exports.isSvmChain = isSvmChain;
19
14
  exports.isValidSolanaHexAddress = isValidSolanaHexAddress;
@@ -23,7 +18,6 @@ const viem_1 = require("viem");
23
18
  const push_chain_1 = require("../push-chain/push-chain");
24
19
  const cea_evm_1 = require("../constants/abi/cea.evm");
25
20
  const erc20_evm_1 = require("../constants/abi/erc20.evm");
26
- const universalGatewayV0_evm_1 = require("../constants/abi/universalGatewayV0.evm");
27
21
  const universalGatewayPC_evm_1 = require("../constants/abi/universalGatewayPC.evm");
28
22
  const selectors_1 = require("../constants/selectors");
29
23
  const chain_1 = require("../constants/chain");
@@ -74,7 +68,7 @@ function buildExecuteMulticall({ execute, ueaAddress, logger, }) {
74
68
  functionName: 'transfer',
75
69
  args: [execute.to, (_q = execute.funds) === null || _q === void 0 ? void 0 : _q.amount],
76
70
  });
77
- const pushChainTo = push_chain_1.PushChain.utils.tokens.getPRC20Address(token);
71
+ const { address: pushChainTo } = push_chain_1.PushChain.utils.tokens.getPRC20Address(token);
78
72
  multicallData.push({
79
73
  to: pushChainTo,
80
74
  value: BigInt(0),
@@ -202,90 +196,6 @@ function buildInboundUniversalPayload(multicallData, opts) {
202
196
  },
203
197
  ]);
204
198
  }
205
- /**
206
- * Build a single call as CEA multicall payload
207
- *
208
- * @param target - Target contract address
209
- * @param value - Native value to send
210
- * @param data - Calldata to execute
211
- * @returns Encoded payload with selector prefix
212
- */
213
- function buildSingleCeaCall(target, value, data) {
214
- return buildCeaMulticallPayload([{ to: target, value, data }]);
215
- }
216
- /**
217
- * Build approve + interact pattern for ERC20 operations on external chains
218
- *
219
- * @param tokenAddress - ERC20 token address
220
- * @param spender - Address to approve (e.g., DEX router)
221
- * @param amount - Amount to approve
222
- * @param interactCall - The interaction call (e.g., swap)
223
- * @returns Array of multicall operations
224
- */
225
- function buildApproveAndInteract(tokenAddress, spender, amount, interactCall) {
226
- // Reset allowance to 0 first to handle non-standard ERC-20 tokens (e.g. USDT)
227
- // that revert if approve is called with non-zero value when current allowance is non-zero.
228
- const approveZeroData = (0, viem_1.encodeFunctionData)({
229
- abi: erc20_evm_1.ERC20_EVM,
230
- functionName: 'approve',
231
- args: [spender, BigInt(0)],
232
- });
233
- const approveData = (0, viem_1.encodeFunctionData)({
234
- abi: erc20_evm_1.ERC20_EVM,
235
- functionName: 'approve',
236
- args: [spender, amount],
237
- });
238
- return [
239
- {
240
- to: tokenAddress,
241
- value: BigInt(0),
242
- data: approveZeroData,
243
- },
244
- {
245
- to: tokenAddress,
246
- value: BigInt(0),
247
- data: approveData,
248
- },
249
- interactCall,
250
- ];
251
- }
252
- /**
253
- * Build sendUniversalTxFromCEA call for CEA → Push routing (Route 3)
254
- *
255
- * @param gatewayAddress - UniversalGateway address on external chain
256
- * @param recipient - Recipient on Push Chain (usually UEA)
257
- * @param token - Token address (address(0) for native)
258
- * @param amount - Amount to send
259
- * @param payload - Payload for Push Chain execution
260
- * @param revertRecipient - Address to receive funds on revert
261
- * @param signatureData - Signature data (usually empty for CEA calls)
262
- * @param nativeValue - Native value to send with the call
263
- * @returns MultiCall for sendUniversalTxFromCEA
264
- */
265
- function buildSendUniversalTxFromCEA(gatewayAddress, recipient, token, amount, payload, revertRecipient, signatureData = '0x', nativeValue = BigInt(0)) {
266
- const calldata = (0, viem_1.encodeFunctionData)({
267
- abi: universalGatewayV0_evm_1.UNIVERSAL_GATEWAY_V0,
268
- functionName: 'sendUniversalTxFromCEA',
269
- args: [
270
- {
271
- recipient,
272
- token,
273
- amount,
274
- payload,
275
- revertInstruction: {
276
- fundRecipient: revertRecipient,
277
- revertMsg: '0x',
278
- },
279
- signatureData,
280
- },
281
- ],
282
- });
283
- return {
284
- to: gatewayAddress,
285
- value: nativeValue,
286
- data: calldata,
287
- };
288
- }
289
199
  /**
290
200
  * Build sendUniversalTxToUEA call for CEA self-call (Route 3)
291
201
  *
@@ -336,20 +246,6 @@ function buildOutboundRequest(target, prc20Token, amount, gasLimit, payload, rev
336
246
  revertRecipient,
337
247
  };
338
248
  }
339
- /**
340
- * Build native transfer multicall
341
- *
342
- * @param to - Recipient address
343
- * @param value - Native value to transfer
344
- * @returns MultiCall for native transfer
345
- */
346
- function buildNativeTransfer(to, value) {
347
- return {
348
- to,
349
- value,
350
- data: '0x',
351
- };
352
- }
353
249
  /**
354
250
  * Build ERC20 transfer multicall
355
251
  *
@@ -392,12 +288,6 @@ function buildErc20WithdrawalMulticall(tokenAddress, recipientAddress, amount) {
392
288
  function buildMigrationPayload() {
393
289
  return selectors_1.MIGRATION_SELECTOR;
394
290
  }
395
- /**
396
- * Check if an address is the zero address
397
- */
398
- function isZeroAddress(address) {
399
- return address.toLowerCase() === selectors_1.ZERO_ADDRESS.toLowerCase();
400
- }
401
291
  // ============================================================================
402
292
  // Cascade Composition Helpers
403
293
  // ============================================================================
@@ -17,20 +17,21 @@ const encoding_1 = require("@cosmjs/encoding");
17
17
  const evm_client_1 = require("../vm-client/evm-client");
18
18
  const chain_1 = require("../constants/chain");
19
19
  const enums_1 = require("../constants/enums");
20
+ function pushNetworkToChain(network) {
21
+ if (network === enums_1.PUSH_NETWORK.MAINNET)
22
+ return enums_1.CHAIN.PUSH_MAINNET;
23
+ if (network === enums_1.PUSH_NETWORK.TESTNET_DONUT ||
24
+ network === enums_1.PUSH_NETWORK.TESTNET)
25
+ return enums_1.CHAIN.PUSH_TESTNET_DONUT;
26
+ return enums_1.CHAIN.PUSH_LOCALNET;
27
+ }
20
28
  class PushClient extends evm_client_1.EvmClient {
21
29
  constructor(clientOptions) {
22
- super(clientOptions);
30
+ var _a;
31
+ const pushChainKey = pushNetworkToChain(clientOptions.network);
32
+ super(Object.assign(Object.assign({}, clientOptions), { chain: (_a = clientOptions.chain) !== null && _a !== void 0 ? _a : (0, chain_1.getPushViemChain)(pushChainKey) }));
23
33
  this.currentRpcIndex = 0;
24
- if (clientOptions.network === enums_1.PUSH_NETWORK.MAINNET) {
25
- this.pushChainInfo = chain_1.PUSH_CHAIN_INFO[enums_1.CHAIN.PUSH_MAINNET];
26
- }
27
- else if (clientOptions.network === enums_1.PUSH_NETWORK.TESTNET_DONUT ||
28
- clientOptions.network === enums_1.PUSH_NETWORK.TESTNET) {
29
- this.pushChainInfo = chain_1.PUSH_CHAIN_INFO[enums_1.CHAIN.PUSH_TESTNET_DONUT];
30
- }
31
- else {
32
- this.pushChainInfo = chain_1.PUSH_CHAIN_INFO[enums_1.CHAIN.PUSH_LOCALNET];
33
- }
34
+ this.pushChainInfo = chain_1.PUSH_CHAIN_INFO[pushChainKey];
34
35
  this.ephemeralKey = (0, accounts_1.generatePrivateKey)();
35
36
  this.ephemeralAccount = (0, accounts_1.privateKeyToAccount)(this.ephemeralKey);
36
37
  }
@@ -294,6 +294,7 @@ function convertExecutorToOriginAccount(ueaAddress, options) {
294
294
  const FACTORY_ADDRESS = chain_1.PUSH_CHAIN_INFO[pushChainKey].factoryAddress;
295
295
  // Create viem public client
296
296
  const client = (0, viem_1.createPublicClient)({
297
+ chain: (0, chain_1.getPushViemChain)(pushChainKey),
297
298
  transport: (0, viem_1.http)(RPC_URL),
298
299
  });
299
300
  const originResult = (yield client.readContract({
@@ -377,6 +378,7 @@ function convertExecutorToOrigin(executorAddress, options) {
377
378
  const RPC_URL = chain_1.PUSH_CHAIN_INFO[pushChainKey].defaultRPC[0];
378
379
  const FACTORY_ADDRESS = chain_1.PUSH_CHAIN_INFO[pushChainKey].factoryAddress;
379
380
  const client = (0, viem_1.createPublicClient)({
381
+ chain: (0, chain_1.getPushViemChain)(pushChainKey),
380
382
  transport: (0, viem_1.http)(RPC_URL),
381
383
  });
382
384
  const originResult = (yield client.readContract({
@@ -600,7 +602,10 @@ function resolveControllerAccount(address, options) {
600
602
  const pushChainId = pushChainKey;
601
603
  const RPC_URL = chain_1.PUSH_CHAIN_INFO[pushChainKey].defaultRPC[0];
602
604
  const FACTORY_ADDRESS = chain_1.PUSH_CHAIN_INFO[pushChainKey].factoryAddress;
603
- const client = (0, viem_1.createPublicClient)({ transport: (0, viem_1.http)(RPC_URL) });
605
+ const client = (0, viem_1.createPublicClient)({
606
+ chain: (0, chain_1.getPushViemChain)(pushChainKey),
607
+ transport: (0, viem_1.http)(RPC_URL),
608
+ });
604
609
  const originResult = (yield client.readContract({
605
610
  address: FACTORY_ADDRESS,
606
611
  abi: factoryV1_1.FACTORY_V1,
@@ -648,7 +653,10 @@ function resolveControllerAccount(address, options) {
648
653
  const pushChainId = pushChainKey;
649
654
  const RPC_URL = chain_1.PUSH_CHAIN_INFO[pushChainKey].defaultRPC[0];
650
655
  const FACTORY_ADDRESS = chain_1.PUSH_CHAIN_INFO[pushChainKey].factoryAddress;
651
- const client = (0, viem_1.createPublicClient)({ transport: (0, viem_1.http)(RPC_URL) });
656
+ const client = (0, viem_1.createPublicClient)({
657
+ chain: (0, chain_1.getPushViemChain)(pushChainKey),
658
+ transport: (0, viem_1.http)(RPC_URL),
659
+ });
652
660
  const originResult = (yield client.readContract({
653
661
  address: FACTORY_ADDRESS,
654
662
  abi: factoryV1_1.FACTORY_V1,
@@ -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;
@@ -716,7 +732,13 @@ Utils.tokens = {
716
732
  default:
717
733
  throw new Error(`Unsupported token symbol: ${tokenSymbol}`);
718
734
  }
719
- return map[key];
735
+ return {
736
+ address: assertDeployed(map[key], `${tokenSymbol} on ${originChain}`),
737
+ chain: originChain,
738
+ symbol: tokenSymbol,
739
+ decimals: tokenDecimals,
740
+ network,
741
+ };
720
742
  },
721
743
  };
722
744
  //# sourceMappingURL=utils.js.map
@@ -12,7 +12,7 @@ import { PublicClient, Hex } from 'viem';
12
12
  */
13
13
  export declare class EvmClient {
14
14
  publicClient: PublicClient;
15
- constructor({ rpcUrls }: ClientOptions);
15
+ constructor({ rpcUrls, chain }: ClientOptions);
16
16
  /**
17
17
  * Returns the balance (in wei) of an EVM address.
18
18
  *
@@ -13,9 +13,10 @@ const viem_1 = require("viem");
13
13
  * });
14
14
  */
15
15
  class EvmClient {
16
- constructor({ rpcUrls }) {
16
+ constructor({ rpcUrls, chain }) {
17
17
  const transports = rpcUrls.map((rpcUrl) => (0, viem_1.http)(rpcUrl));
18
18
  this.publicClient = (0, viem_1.createPublicClient)({
19
+ chain,
19
20
  transport: (0, viem_1.fallback)(transports),
20
21
  });
21
22
  }
@@ -1,11 +1,12 @@
1
1
  import { UniversalSigner } from '../universal/universal.types';
2
- import { Abi, Transaction, TransactionReceipt } from 'viem';
2
+ import { Abi, Chain, Transaction, TransactionReceipt } from 'viem';
3
3
  import { Keypair, PublicKey } from '@solana/web3.js';
4
4
  /**
5
5
  * Common options used by all VM clients (EVM, SVM, etc.)
6
6
  */
7
7
  export interface ClientOptions {
8
8
  rpcUrls: string[];
9
+ chain?: Chain;
9
10
  }
10
11
  /**
11
12
  * Parameters for reading from a smart contract (read-only call).
@@ -1,32 +0,0 @@
1
- /**
2
- * Shared fixture builders for universal-tx-detector specs.
3
- *
4
- * These helpers encode viem-compatible logs and receipts so every spec
5
- * (classify, detector, cascade, scenarios) can build test data uniformly.
6
- *
7
- * Keep these pure — no jest mocks, no module-level state.
8
- */
9
- import { type TransactionReceipt } from 'viem';
10
- export type EventDef = {
11
- name: string;
12
- inputs: readonly {
13
- indexed: boolean;
14
- type: string;
15
- name: string;
16
- components?: readonly unknown[];
17
- }[];
18
- };
19
- export type BuiltLog = {
20
- address: `0x${string}`;
21
- topics: ReadonlyArray<`0x${string}` | null>;
22
- data: `0x${string}`;
23
- blockNumber: bigint;
24
- transactionHash: `0x${string}`;
25
- transactionIndex: number;
26
- blockHash: `0x${string}`;
27
- logIndex: number;
28
- removed: false;
29
- };
30
- export declare function indexedArgs(event: EventDef, argsObj: Record<string, unknown>): Record<string, unknown>;
31
- export declare function buildLog(event: EventDef, argsObj: Record<string, unknown>, address: `0x${string}`, logIndex: number, txHash?: `0x${string}`): BuiltLog;
32
- export declare function buildReceipt(logs: BuiltLog[], to: `0x${string}`, txHash?: `0x${string}`): TransactionReceipt;
@@ -1,65 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.indexedArgs = indexedArgs;
4
- exports.buildLog = buildLog;
5
- exports.buildReceipt = buildReceipt;
6
- /**
7
- * Shared fixture builders for universal-tx-detector specs.
8
- *
9
- * These helpers encode viem-compatible logs and receipts so every spec
10
- * (classify, detector, cascade, scenarios) can build test data uniformly.
11
- *
12
- * Keep these pure — no jest mocks, no module-level state.
13
- */
14
- const viem_1 = require("viem");
15
- const ZERO_HASH = '0x0000000000000000000000000000000000000000000000000000000000000000';
16
- function indexedArgs(event, argsObj) {
17
- const out = {};
18
- for (const i of event.inputs)
19
- if (i.indexed)
20
- out[i.name] = argsObj[i.name];
21
- return out;
22
- }
23
- function buildLog(event, argsObj, address, logIndex, txHash = ZERO_HASH) {
24
- const topics = (0, viem_1.encodeEventTopics)({
25
- abi: [
26
- event,
27
- ],
28
- eventName: event.name,
29
- args: indexedArgs(event, argsObj),
30
- });
31
- const nonIndexed = event.inputs.filter((i) => !i.indexed);
32
- const data = nonIndexed.length === 0
33
- ? '0x'
34
- : (0, viem_1.encodeAbiParameters)(nonIndexed, nonIndexed.map((i) => argsObj[i.name]));
35
- return {
36
- address,
37
- topics,
38
- data,
39
- blockNumber: BigInt(1),
40
- transactionHash: txHash,
41
- transactionIndex: 0,
42
- blockHash: ZERO_HASH,
43
- logIndex,
44
- removed: false,
45
- };
46
- }
47
- function buildReceipt(logs, to, txHash = ZERO_HASH) {
48
- return {
49
- status: 'success',
50
- logs,
51
- blockNumber: BigInt(1),
52
- blockHash: ZERO_HASH,
53
- contractAddress: null,
54
- cumulativeGasUsed: BigInt(0),
55
- effectiveGasPrice: BigInt(0),
56
- from: to,
57
- gasUsed: BigInt(0),
58
- logsBloom: '0x',
59
- to,
60
- transactionHash: txHash,
61
- transactionIndex: 0,
62
- type: 'eip1559',
63
- };
64
- }
65
- //# sourceMappingURL=builders.js.map