@dynamic-labs/ethereum-core 4.96.4 → 4.98.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.
package/CHANGELOG.md CHANGED
@@ -1,4 +1,29 @@
1
1
 
2
+ ## [4.98.0](https://github.com/dynamic-labs/dynamic-auth/compare/v4.97.0...v4.98.0) (2026-09-02)
3
+
4
+
5
+ ### Features
6
+
7
+ * **waas-evm:** route embedded EVM sends through gas sponsorship when enabled (V4) ([#12307](https://github.com/dynamic-labs/dynamic-auth/issues/12307)) ([d8e6b94](https://github.com/dynamic-labs/dynamic-auth/commit/d8e6b94dc86e1d48b66a246bf8bf0b857e7e69c4))
8
+
9
+
10
+ ### Bug Fixes
11
+
12
+ * **sdk-react-core:** send a css overrides summary in sdkSettings telemetry (v4) ([#12330](https://github.com/dynamic-labs/dynamic-auth/issues/12330)) ([8547ee7](https://github.com/dynamic-labs/dynamic-auth/commit/8547ee7a7c3fef8de0ff384778f86542b809e7aa))
13
+ * **waas-svm:** apply overrideBlockhash before sponsorship [v4 backport] ([#12320](https://github.com/dynamic-labs/dynamic-auth/issues/12320)) ([0551f01](https://github.com/dynamic-labs/dynamic-auth/commit/0551f01953f5e623ac113b03e1b010d3dc58a81e)), closes [#10599](https://github.com/dynamic-labs/dynamic-auth/issues/10599) [#10599](https://github.com/dynamic-labs/dynamic-auth/issues/10599) [#10599](https://github.com/dynamic-labs/dynamic-auth/issues/10599) [#10599](https://github.com/dynamic-labs/dynamic-auth/issues/10599)
14
+
15
+ ## [4.97.0](https://github.com/dynamic-labs/dynamic-auth/compare/v4.96.4...v4.97.0) (2026-08-27)
16
+
17
+
18
+ ### Features
19
+
20
+ * **screening:** connected-wallet transaction screening [v4 backport] (DYNT-1663) ([#12284](https://github.com/dynamic-labs/dynamic-auth/issues/12284)) ([294adba](https://github.com/dynamic-labs/dynamic-auth/commit/294adba7dba8f321f3b1e8413f73545701e51252)), closes [#12160](https://github.com/dynamic-labs/dynamic-auth/issues/12160) [#12167](https://github.com/dynamic-labs/dynamic-auth/issues/12167) [#12168](https://github.com/dynamic-labs/dynamic-auth/issues/12168) [#12169](https://github.com/dynamic-labs/dynamic-auth/issues/12169) [#12172](https://github.com/dynamic-labs/dynamic-auth/issues/12172)
21
+
22
+
23
+ ### Bug Fixes
24
+
25
+ * **screening:** wire connected-wallet screening into the Send Balance UI (DYNT-1663) ([#12289](https://github.com/dynamic-labs/dynamic-auth/issues/12289)) ([1587cd8](https://github.com/dynamic-labs/dynamic-auth/commit/1587cd833370e18fa383f942521500e4c1576390))
26
+
2
27
  ### [4.96.4](https://github.com/dynamic-labs/dynamic-auth/compare/v4.96.3...v4.96.4) (2026-08-26)
3
28
 
4
29
 
package/package.cjs CHANGED
@@ -3,6 +3,6 @@
3
3
 
4
4
  Object.defineProperty(exports, '__esModule', { value: true });
5
5
 
6
- var version = "4.96.4";
6
+ var version = "4.98.0";
7
7
 
8
8
  exports.version = version;
package/package.js CHANGED
@@ -1,4 +1,4 @@
1
1
  'use client'
2
- var version = "4.96.4";
2
+ var version = "4.98.0";
3
3
 
4
4
  export { version };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@dynamic-labs/ethereum-core",
3
- "version": "4.96.4",
3
+ "version": "4.98.0",
4
4
  "description": "Core package for utilities and types for viem",
5
5
  "author": "Dynamic Labs, Inc.",
6
6
  "license": "MIT",
@@ -19,13 +19,13 @@
19
19
  "homepage": "https://www.dynamic.xyz/",
20
20
  "dependencies": {
21
21
  "@dynamic-labs/sdk-api-core": "0.12.0",
22
- "@dynamic-labs/assert-package-version": "4.96.4",
23
- "@dynamic-labs/logger": "4.96.4",
24
- "@dynamic-labs/rpc-providers": "4.96.4",
25
- "@dynamic-labs/types": "4.96.4",
26
- "@dynamic-labs/utils": "4.96.4",
27
- "@dynamic-labs/wallet-book": "4.96.4",
28
- "@dynamic-labs/wallet-connector-core": "4.96.4"
22
+ "@dynamic-labs/assert-package-version": "4.98.0",
23
+ "@dynamic-labs/logger": "4.98.0",
24
+ "@dynamic-labs/rpc-providers": "4.98.0",
25
+ "@dynamic-labs/types": "4.98.0",
26
+ "@dynamic-labs/utils": "4.98.0",
27
+ "@dynamic-labs/wallet-book": "4.98.0",
28
+ "@dynamic-labs/wallet-connector-core": "4.98.0"
29
29
  },
30
30
  "peerDependencies": {
31
31
  "viem": "^2.45.3"
@@ -15,6 +15,7 @@ var createViemUiTransaction = require('../utils/viem/createViemUiTransaction/cre
15
15
  var getOrMapViemChain = require('../utils/viem/getOrMapViemChain/getOrMapViemChain.cjs');
16
16
  var hasAtomicStatusCapability = require('../utils/viem/hasAtomicStatusCapability/hasAtomicStatusCapability.cjs');
17
17
  var hasPaymasterServiceCapability = require('../utils/viem/hasPaymasterServiceCapability/hasPaymasterServiceCapability.cjs');
18
+ require('@dynamic-labs/types');
18
19
  var findEvmNetwork = require('../utils/findEvmNetwork/findEvmNetwork.cjs');
19
20
  var getNameservice = require('../utils/getNameservice/getNameservice.cjs');
20
21
  var EthereumWallet = require('../wallet/EthereumWallet.cjs');
@@ -307,6 +308,7 @@ class EthereumWalletConnector extends walletConnectorCore.WalletConnectorBase {
307
308
  return createViemUiTransaction.createViemUiTransaction({
308
309
  from,
309
310
  publicClient,
311
+ transactionScreening: this.transactionScreening,
310
312
  walletClient,
311
313
  });
312
314
  });
@@ -11,6 +11,7 @@ import { createViemUiTransaction } from '../utils/viem/createViemUiTransaction/c
11
11
  import { getOrMapViemChain } from '../utils/viem/getOrMapViemChain/getOrMapViemChain.js';
12
12
  import { hasAtomicStatusCapability } from '../utils/viem/hasAtomicStatusCapability/hasAtomicStatusCapability.js';
13
13
  import { hasPaymasterServiceCapability } from '../utils/viem/hasPaymasterServiceCapability/hasPaymasterServiceCapability.js';
14
+ import '@dynamic-labs/types';
14
15
  import { findEvmNetwork } from '../utils/findEvmNetwork/findEvmNetwork.js';
15
16
  import { getNameservice } from '../utils/getNameservice/getNameservice.js';
16
17
  import { EthereumWallet } from '../wallet/EthereumWallet.js';
@@ -303,6 +304,7 @@ class EthereumWalletConnector extends WalletConnectorBase {
303
304
  return createViemUiTransaction({
304
305
  from,
305
306
  publicClient,
307
+ transactionScreening: this.transactionScreening,
306
308
  walletClient,
307
309
  });
308
310
  });
package/src/index.cjs CHANGED
@@ -24,6 +24,7 @@ var hasPaymasterServiceCapability = require('./utils/viem/hasPaymasterServiceCap
24
24
  var unFormatTransaction = require('./utils/viem/unFormatTransaction/unFormatTransaction.cjs');
25
25
  var abi = require('./utils/viem/erc20/abi.cjs');
26
26
  var interceptTransport = require('./utils/viem/interceptTransport/interceptTransport.cjs');
27
+ var screenEvmTransaction = require('./utils/viem/screenEvmTransaction/screenEvmTransaction.cjs');
27
28
  var findEvmNetwork = require('./utils/findEvmNetwork/findEvmNetwork.cjs');
28
29
  var getNameservice = require('./utils/getNameservice/getNameservice.cjs');
29
30
  var validateAddressFormat = require('./utils/validateAddressFormat/validateAddressFormat.cjs');
@@ -53,6 +54,7 @@ exports.hasPaymasterServiceCapability = hasPaymasterServiceCapability.hasPaymast
53
54
  exports.unFormatTransaction = unFormatTransaction.unFormatTransaction;
54
55
  exports.erc20Abi = abi.erc20Abi;
55
56
  exports.interceptTransport = interceptTransport.interceptTransport;
57
+ exports.screenEvmTransaction = screenEvmTransaction.screenEvmTransaction;
56
58
  exports.findEvmNetwork = findEvmNetwork.findEvmNetwork;
57
59
  exports.getNameservice = getNameservice.getNameservice;
58
60
  exports.validateAddressFormat = validateAddressFormat.validateAddressFormat;
package/src/index.js CHANGED
@@ -20,6 +20,7 @@ export { hasPaymasterServiceCapability } from './utils/viem/hasPaymasterServiceC
20
20
  export { unFormatTransaction } from './utils/viem/unFormatTransaction/unFormatTransaction.js';
21
21
  export { erc20Abi } from './utils/viem/erc20/abi.js';
22
22
  export { interceptTransport } from './utils/viem/interceptTransport/interceptTransport.js';
23
+ export { screenEvmTransaction } from './utils/viem/screenEvmTransaction/screenEvmTransaction.js';
23
24
  export { findEvmNetwork } from './utils/findEvmNetwork/findEvmNetwork.js';
24
25
  export { getNameservice } from './utils/getNameservice/getNameservice.js';
25
26
  export { validateAddressFormat } from './utils/validateAddressFormat/validateAddressFormat.js';
@@ -14,7 +14,7 @@ var formatEther = require('../formatEther/formatEther.cjs');
14
14
  var getTransactionRecipient = require('../getTransactionRecipient.cjs');
15
15
 
16
16
  class ViemUiTransaction extends Eip1559FeeFeed.Eip1559FeeFeed {
17
- constructor({ transaction, onSubmit, publicClient, account, }) {
17
+ constructor({ transaction, onSubmit, publicClient, account, isGasSponsored = false, }) {
18
18
  super({
19
19
  initialGasLimit: transaction.gas,
20
20
  initialMaxFeePerGas: transaction.maxFeePerGas,
@@ -26,16 +26,11 @@ class ViemUiTransaction extends Eip1559FeeFeed.Eip1559FeeFeed {
26
26
  this.parseNonNativeToken = (amount, decimals) => viem.parseUnits(amount, decimals);
27
27
  this.format = formatEther.formatEther;
28
28
  this.formatNonNativeToken = (value, decimals) => viem.formatUnits(value, decimals);
29
- /**
30
- * Whether the transaction is gas sponsored.
31
- * Returns false by default for EVM transactions.
32
- * Can be overridden for chains like Tempo where fees are paid differently.
33
- */
34
- this.isGasSponsored = () => false;
35
29
  this.transaction = transaction;
36
30
  this.onSubmit = onSubmit;
37
31
  this.publicClient = publicClient;
38
32
  this.address = account;
33
+ this.isGasSponsored = () => isGasSponsored;
39
34
  }
40
35
  get to() {
41
36
  return this.transaction.to || undefined;
@@ -13,6 +13,7 @@ type ViemUiTransactionProps = {
13
13
  transaction: TransactionSerializable & NonNativeTransaction;
14
14
  onSubmit: (transaction: TransactionSerializable & NonNativeTransaction) => Promise<string>;
15
15
  publicClient: PublicClient<Transport, Chain>;
16
+ isGasSponsored?: boolean;
16
17
  };
17
18
  export interface IUIEvmTransaction {
18
19
  nonNativeValue: bigint | undefined;
@@ -28,7 +29,7 @@ export declare class ViemUiTransaction extends Eip1559FeeFeed implements IUITran
28
29
  private address;
29
30
  protected publicClient: PublicClient<Transport, Chain>;
30
31
  private onSubmit;
31
- constructor({ transaction, onSubmit, publicClient, account, }: ViemUiTransactionProps);
32
+ constructor({ transaction, onSubmit, publicClient, account, isGasSponsored, }: ViemUiTransactionProps);
32
33
  nativePrice?: number | undefined;
33
34
  validateAddressFormat: (address: string) => boolean;
34
35
  parse: (input: string) => bigint;
@@ -57,9 +58,8 @@ export declare class ViemUiTransaction extends Eip1559FeeFeed implements IUITran
57
58
  private convertBigIntToHex;
58
59
  getTransactionRecipient(): `0x${string}` | undefined;
59
60
  /**
60
- * Whether the transaction is gas sponsored.
61
- * Returns false by default for EVM transactions.
62
- * Can be overridden for chains like Tempo where fees are paid differently.
61
+ * Whether the transaction is gas sponsored. Sponsored transactions are
62
+ * excluded from the native balance checks in the confirmation UI.
63
63
  */
64
64
  isGasSponsored: () => boolean;
65
65
  estimateL1Fee(): Promise<bigint>;
@@ -10,7 +10,7 @@ import { formatEther } from '../formatEther/formatEther.js';
10
10
  import { getTransactionRecipient } from '../getTransactionRecipient.js';
11
11
 
12
12
  class ViemUiTransaction extends Eip1559FeeFeed {
13
- constructor({ transaction, onSubmit, publicClient, account, }) {
13
+ constructor({ transaction, onSubmit, publicClient, account, isGasSponsored = false, }) {
14
14
  super({
15
15
  initialGasLimit: transaction.gas,
16
16
  initialMaxFeePerGas: transaction.maxFeePerGas,
@@ -22,16 +22,11 @@ class ViemUiTransaction extends Eip1559FeeFeed {
22
22
  this.parseNonNativeToken = (amount, decimals) => parseUnits(amount, decimals);
23
23
  this.format = formatEther;
24
24
  this.formatNonNativeToken = (value, decimals) => formatUnits(value, decimals);
25
- /**
26
- * Whether the transaction is gas sponsored.
27
- * Returns false by default for EVM transactions.
28
- * Can be overridden for chains like Tempo where fees are paid differently.
29
- */
30
- this.isGasSponsored = () => false;
31
25
  this.transaction = transaction;
32
26
  this.onSubmit = onSubmit;
33
27
  this.publicClient = publicClient;
34
28
  this.address = account;
29
+ this.isGasSponsored = () => isGasSponsored;
35
30
  }
36
31
  get to() {
37
32
  return this.transaction.to || undefined;
@@ -5,12 +5,26 @@ Object.defineProperty(exports, '__esModule', { value: true });
5
5
 
6
6
  var _tslib = require('../../../../_virtual/_tslib.cjs');
7
7
  var abi = require('../erc20/abi.cjs');
8
+ var screenEvmTransaction = require('../screenEvmTransaction/screenEvmTransaction.cjs');
8
9
  var ViemUiTransaction = require('../ViemUiTransaction/ViemUiTransaction.cjs');
9
10
 
10
- const createViemUiTransaction = (_a) => _tslib.__awaiter(void 0, [_a], void 0, function* ({ from, publicClient, walletClient, }) {
11
+ const createViemUiTransaction = (_a) => _tslib.__awaiter(void 0, [_a], void 0, function* ({ from, publicClient, walletClient, transactionScreening, }) {
11
12
  return new ViemUiTransaction.ViemUiTransaction({
12
13
  account: from,
13
14
  onSubmit: (transaction) => _tslib.__awaiter(void 0, void 0, void 0, function* () {
15
+ var _b, _c;
16
+ // Screened here, at submit time, rather than when the transaction is
17
+ // built: the UI mutates `to`/`value` after construction, so screening
18
+ // the live values is the only way to catch a destination the user
19
+ // edited in after the fact. `to` is the actual recipient in both
20
+ // branches below — for the non-native case `nonNativeAddress` is the
21
+ // token contract being called, not the destination.
22
+ yield screenEvmTransaction.screenEvmTransaction({
23
+ chainId: (_b = walletClient.chain) === null || _b === void 0 ? void 0 : _b.id,
24
+ senderAddress: from,
25
+ to: (_c = transaction.to) !== null && _c !== void 0 ? _c : undefined,
26
+ transactionScreening,
27
+ });
14
28
  // Non native token
15
29
  if (transaction.nonNativeAddress) {
16
30
  return walletClient.writeContract({
@@ -1,9 +1,11 @@
1
1
  import { Chain, PublicClient, Transport, WalletClient } from 'viem';
2
+ import { TransactionScreeningService } from '@dynamic-labs/types';
2
3
  import { ViemUiTransaction } from '../ViemUiTransaction';
3
4
  type CreateViemUiTransactionProps = {
4
5
  publicClient: PublicClient<Transport, Chain>;
5
6
  walletClient: WalletClient<Transport, Chain>;
6
7
  from: string;
8
+ transactionScreening?: TransactionScreeningService;
7
9
  };
8
- export declare const createViemUiTransaction: ({ from, publicClient, walletClient, }: CreateViemUiTransactionProps) => Promise<ViemUiTransaction>;
10
+ export declare const createViemUiTransaction: ({ from, publicClient, walletClient, transactionScreening, }: CreateViemUiTransactionProps) => Promise<ViemUiTransaction>;
9
11
  export {};
@@ -1,12 +1,26 @@
1
1
  'use client'
2
2
  import { __awaiter } from '../../../../_virtual/_tslib.js';
3
3
  import { erc20Abi } from '../erc20/abi.js';
4
+ import { screenEvmTransaction } from '../screenEvmTransaction/screenEvmTransaction.js';
4
5
  import { ViemUiTransaction } from '../ViemUiTransaction/ViemUiTransaction.js';
5
6
 
6
- const createViemUiTransaction = (_a) => __awaiter(void 0, [_a], void 0, function* ({ from, publicClient, walletClient, }) {
7
+ const createViemUiTransaction = (_a) => __awaiter(void 0, [_a], void 0, function* ({ from, publicClient, walletClient, transactionScreening, }) {
7
8
  return new ViemUiTransaction({
8
9
  account: from,
9
10
  onSubmit: (transaction) => __awaiter(void 0, void 0, void 0, function* () {
11
+ var _b, _c;
12
+ // Screened here, at submit time, rather than when the transaction is
13
+ // built: the UI mutates `to`/`value` after construction, so screening
14
+ // the live values is the only way to catch a destination the user
15
+ // edited in after the fact. `to` is the actual recipient in both
16
+ // branches below — for the non-native case `nonNativeAddress` is the
17
+ // token contract being called, not the destination.
18
+ yield screenEvmTransaction({
19
+ chainId: (_b = walletClient.chain) === null || _b === void 0 ? void 0 : _b.id,
20
+ senderAddress: from,
21
+ to: (_c = transaction.to) !== null && _c !== void 0 ? _c : undefined,
22
+ transactionScreening,
23
+ });
10
24
  // Non native token
11
25
  if (transaction.nonNativeAddress) {
12
26
  return walletClient.writeContract({
@@ -11,3 +11,4 @@ export * from './hasPaymasterServiceCapability';
11
11
  export * from './unFormatTransaction';
12
12
  export * from './erc20';
13
13
  export * from './interceptTransport';
14
+ export * from './screenEvmTransaction';
@@ -65,7 +65,7 @@ const interceptTransport = ({ getAccounts, onPersonalSign, onSendTransaction, on
65
65
  }
66
66
  if (onSendCalls && method === 'wallet_sendCalls') {
67
67
  const [callParams] = params;
68
- return onSendCalls({ callParams, provider });
68
+ return onSendCalls({ args, callParams, provider });
69
69
  }
70
70
  return provider.request(args);
71
71
  }),
@@ -29,6 +29,7 @@ export type InterceptTransportProps = {
29
29
  provider: Provider;
30
30
  }) => Promise<GetCapabilitiesReturnType>;
31
31
  onSendCalls?: (props: {
32
+ args: Args;
32
33
  callParams: SendCallsParameters;
33
34
  provider: Provider;
34
35
  }) => Promise<SendCallsReturnType>;
@@ -61,7 +61,7 @@ const interceptTransport = ({ getAccounts, onPersonalSign, onSendTransaction, on
61
61
  }
62
62
  if (onSendCalls && method === 'wallet_sendCalls') {
63
63
  const [callParams] = params;
64
- return onSendCalls({ callParams, provider });
64
+ return onSendCalls({ args, callParams, provider });
65
65
  }
66
66
  return provider.request(args);
67
67
  }),
@@ -0,0 +1 @@
1
+ export * from './screenEvmTransaction';
@@ -0,0 +1,20 @@
1
+ 'use client'
2
+ 'use strict';
3
+
4
+ Object.defineProperty(exports, '__esModule', { value: true });
5
+
6
+ var _tslib = require('../../../../_virtual/_tslib.cjs');
7
+ var types = require('@dynamic-labs/types');
8
+
9
+ const screenEvmTransaction = (_a) => _tslib.__awaiter(void 0, [_a], void 0, function* ({ transactionScreening, chainId, senderAddress, to, }) {
10
+ if (!transactionScreening)
11
+ return;
12
+ yield transactionScreening.screenTransaction({
13
+ chain: types.TransactionScreeningChain.EVM,
14
+ chainId: chainId === null || chainId === void 0 ? void 0 : chainId.toString(),
15
+ context: { evmTransaction: { to } },
16
+ senderAddress,
17
+ });
18
+ });
19
+
20
+ exports.screenEvmTransaction = screenEvmTransaction;
@@ -0,0 +1,8 @@
1
+ import { TransactionScreeningService } from '@dynamic-labs/types';
2
+ export type ScreenEvmTransactionParams = {
3
+ transactionScreening: TransactionScreeningService | undefined;
4
+ chainId: number | string | undefined;
5
+ senderAddress: string | undefined;
6
+ to: string | undefined;
7
+ };
8
+ export declare const screenEvmTransaction: ({ transactionScreening, chainId, senderAddress, to, }: ScreenEvmTransactionParams) => Promise<void>;
@@ -0,0 +1,16 @@
1
+ 'use client'
2
+ import { __awaiter } from '../../../../_virtual/_tslib.js';
3
+ import { TransactionScreeningChain } from '@dynamic-labs/types';
4
+
5
+ const screenEvmTransaction = (_a) => __awaiter(void 0, [_a], void 0, function* ({ transactionScreening, chainId, senderAddress, to, }) {
6
+ if (!transactionScreening)
7
+ return;
8
+ yield transactionScreening.screenTransaction({
9
+ chain: TransactionScreeningChain.EVM,
10
+ chainId: chainId === null || chainId === void 0 ? void 0 : chainId.toString(),
11
+ context: { evmTransaction: { to } },
12
+ senderAddress,
13
+ });
14
+ });
15
+
16
+ export { screenEvmTransaction };
@@ -12,10 +12,28 @@ require('../utils/viem/estimateL1Fee/opStack/estimateL1Fee.cjs');
12
12
  require('../utils/viem/chainsMap/chainsMap.cjs');
13
13
  var interceptTransport = require('../utils/viem/interceptTransport/interceptTransport.cjs');
14
14
  var abi = require('../utils/viem/erc20/abi.cjs');
15
+ var screenEvmTransaction = require('../utils/viem/screenEvmTransaction/screenEvmTransaction.cjs');
15
16
  require('viem/accounts');
16
17
  var getOrMapViemChain = require('../utils/viem/getOrMapViemChain/getOrMapViemChain.cjs');
17
18
  var parseAddress = require('../utils/parseAddress/parseAddress.cjs');
18
19
 
20
+ /**
21
+ * Resolves the chain a batch is screened against. EIP-5792 carries the target
22
+ * chain in the request itself, so that wins over the connected client's chain.
23
+ * Never throws: screening is fail-open, so an unparseable value degrades to the
24
+ * client's chain rather than failing a send.
25
+ */
26
+ const screeningChainId = (requestChainId, clientChainId) => {
27
+ try {
28
+ if (requestChainId) {
29
+ return viem.hexToNumber(requestChainId).toString();
30
+ }
31
+ }
32
+ catch (_a) {
33
+ // Unparseable chain id; fall through to the connected client's chain.
34
+ }
35
+ return clientChainId === null || clientChainId === void 0 ? void 0 : clientChainId.toString();
36
+ };
19
37
  class EthereumWallet extends walletConnectorCore.Wallet {
20
38
  constructor(props) {
21
39
  super(Object.assign(Object.assign({}, props), { address: parseAddress.parseAddress(props.address) }));
@@ -94,11 +112,38 @@ class EthereumWallet extends walletConnectorCore.Wallet {
94
112
  yield this.sync();
95
113
  return provider.request(args);
96
114
  }),
97
- onSendTransaction: (_b) => _tslib.__awaiter(this, [_b], void 0, function* ({ provider, args }) {
115
+ onSendCalls: (_b) => _tslib.__awaiter(this, [_b], void 0, function* ({ args, callParams, provider }) {
116
+ var _c;
117
+ yield this.sync();
118
+ // Nothing here may throw: a raw wallet_sendCalls can carry
119
+ // anything, and screening is fail-open by contract, so a malformed
120
+ // request must still reach the wallet and get its own RPC error.
121
+ const calls = Array.isArray(callParams === null || callParams === void 0 ? void 0 : callParams.calls)
122
+ ? callParams.calls
123
+ : [];
124
+ const chainId = screeningChainId(callParams === null || callParams === void 0 ? void 0 : callParams.chainId, (_c = walletClient.chain) === null || _c === void 0 ? void 0 : _c.id);
125
+ yield Promise.all(calls.map((call) => screenEvmTransaction.screenEvmTransaction({
126
+ chainId,
127
+ senderAddress: this.address,
128
+ to: call === null || call === void 0 ? void 0 : call.to,
129
+ transactionScreening: this._connector.transactionScreening,
130
+ })));
131
+ return provider.request(args);
132
+ }),
133
+ onSendTransaction: (_d) => _tslib.__awaiter(this, [_d], void 0, function* ({ provider, args, transaction }) {
134
+ var _e, _f;
98
135
  yield this.sync();
136
+ // eth_sendTransaction carries no chain id: the wallet sends on the
137
+ // chain it is currently on, so the client's chain is the target.
138
+ yield screenEvmTransaction.screenEvmTransaction({
139
+ chainId: (_e = walletClient.chain) === null || _e === void 0 ? void 0 : _e.id,
140
+ senderAddress: transaction === null || transaction === void 0 ? void 0 : transaction.from,
141
+ to: (_f = transaction === null || transaction === void 0 ? void 0 : transaction.to) !== null && _f !== void 0 ? _f : undefined,
142
+ transactionScreening: this._connector.transactionScreening,
143
+ });
99
144
  return provider.request(args);
100
145
  }),
101
- onSignTypedData: (_c) => _tslib.__awaiter(this, [_c], void 0, function* ({ provider, args }) {
146
+ onSignTypedData: (_g) => _tslib.__awaiter(this, [_g], void 0, function* ({ provider, args }) {
102
147
  yield this.sync();
103
148
  return provider.request(args);
104
149
  }),
@@ -1,6 +1,6 @@
1
1
  'use client'
2
2
  import { __awaiter } from '../../_virtual/_tslib.js';
3
- import { getContract, parseUnits, parseEther, createWalletClient, custom } from 'viem';
3
+ import { getContract, parseUnits, parseEther, createWalletClient, custom, hexToNumber } from 'viem';
4
4
  import { Wallet } from '@dynamic-labs/wallet-connector-core';
5
5
  import '@dynamic-labs/utils';
6
6
  import { logger } from '../utils/logger.js';
@@ -8,10 +8,28 @@ import '../utils/viem/estimateL1Fee/opStack/estimateL1Fee.js';
8
8
  import '../utils/viem/chainsMap/chainsMap.js';
9
9
  import { interceptTransport } from '../utils/viem/interceptTransport/interceptTransport.js';
10
10
  import { erc20Abi } from '../utils/viem/erc20/abi.js';
11
+ import { screenEvmTransaction } from '../utils/viem/screenEvmTransaction/screenEvmTransaction.js';
11
12
  import 'viem/accounts';
12
13
  import { getChain } from '../utils/viem/getOrMapViemChain/getOrMapViemChain.js';
13
14
  import { parseAddress } from '../utils/parseAddress/parseAddress.js';
14
15
 
16
+ /**
17
+ * Resolves the chain a batch is screened against. EIP-5792 carries the target
18
+ * chain in the request itself, so that wins over the connected client's chain.
19
+ * Never throws: screening is fail-open, so an unparseable value degrades to the
20
+ * client's chain rather than failing a send.
21
+ */
22
+ const screeningChainId = (requestChainId, clientChainId) => {
23
+ try {
24
+ if (requestChainId) {
25
+ return hexToNumber(requestChainId).toString();
26
+ }
27
+ }
28
+ catch (_a) {
29
+ // Unparseable chain id; fall through to the connected client's chain.
30
+ }
31
+ return clientChainId === null || clientChainId === void 0 ? void 0 : clientChainId.toString();
32
+ };
15
33
  class EthereumWallet extends Wallet {
16
34
  constructor(props) {
17
35
  super(Object.assign(Object.assign({}, props), { address: parseAddress(props.address) }));
@@ -90,11 +108,38 @@ class EthereumWallet extends Wallet {
90
108
  yield this.sync();
91
109
  return provider.request(args);
92
110
  }),
93
- onSendTransaction: (_b) => __awaiter(this, [_b], void 0, function* ({ provider, args }) {
111
+ onSendCalls: (_b) => __awaiter(this, [_b], void 0, function* ({ args, callParams, provider }) {
112
+ var _c;
113
+ yield this.sync();
114
+ // Nothing here may throw: a raw wallet_sendCalls can carry
115
+ // anything, and screening is fail-open by contract, so a malformed
116
+ // request must still reach the wallet and get its own RPC error.
117
+ const calls = Array.isArray(callParams === null || callParams === void 0 ? void 0 : callParams.calls)
118
+ ? callParams.calls
119
+ : [];
120
+ const chainId = screeningChainId(callParams === null || callParams === void 0 ? void 0 : callParams.chainId, (_c = walletClient.chain) === null || _c === void 0 ? void 0 : _c.id);
121
+ yield Promise.all(calls.map((call) => screenEvmTransaction({
122
+ chainId,
123
+ senderAddress: this.address,
124
+ to: call === null || call === void 0 ? void 0 : call.to,
125
+ transactionScreening: this._connector.transactionScreening,
126
+ })));
127
+ return provider.request(args);
128
+ }),
129
+ onSendTransaction: (_d) => __awaiter(this, [_d], void 0, function* ({ provider, args, transaction }) {
130
+ var _e, _f;
94
131
  yield this.sync();
132
+ // eth_sendTransaction carries no chain id: the wallet sends on the
133
+ // chain it is currently on, so the client's chain is the target.
134
+ yield screenEvmTransaction({
135
+ chainId: (_e = walletClient.chain) === null || _e === void 0 ? void 0 : _e.id,
136
+ senderAddress: transaction === null || transaction === void 0 ? void 0 : transaction.from,
137
+ to: (_f = transaction === null || transaction === void 0 ? void 0 : transaction.to) !== null && _f !== void 0 ? _f : undefined,
138
+ transactionScreening: this._connector.transactionScreening,
139
+ });
95
140
  return provider.request(args);
96
141
  }),
97
- onSignTypedData: (_c) => __awaiter(this, [_c], void 0, function* ({ provider, args }) {
142
+ onSignTypedData: (_g) => __awaiter(this, [_g], void 0, function* ({ provider, args }) {
98
143
  yield this.sync();
99
144
  return provider.request(args);
100
145
  }),