permissionless 0.1.36 → 0.1.39

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 (35) hide show
  1. package/CHANGELOG.md +18 -0
  2. package/_cjs/accounts/kernel/signerToEcdsaKernelSmartAccount.js +2 -2
  3. package/_cjs/accounts/kernel/signerToEcdsaKernelSmartAccount.js.map +1 -1
  4. package/_cjs/accounts/safe/signerToSafeSmartAccount.js +18 -18
  5. package/_cjs/accounts/safe/signerToSafeSmartAccount.js.map +1 -1
  6. package/_cjs/actions/erc7579/supportsExecutionMode.js +2 -2
  7. package/_cjs/actions/erc7579/supportsExecutionMode.js.map +1 -1
  8. package/_cjs/actions/public/getSenderAddress.js +79 -55
  9. package/_cjs/actions/public/getSenderAddress.js.map +1 -1
  10. package/_esm/accounts/kernel/signerToEcdsaKernelSmartAccount.js +2 -2
  11. package/_esm/accounts/kernel/signerToEcdsaKernelSmartAccount.js.map +1 -1
  12. package/_esm/accounts/safe/signerToSafeSmartAccount.js +18 -18
  13. package/_esm/accounts/safe/signerToSafeSmartAccount.js.map +1 -1
  14. package/_esm/actions/erc7579/supportsExecutionMode.js +2 -2
  15. package/_esm/actions/erc7579/supportsExecutionMode.js.map +1 -1
  16. package/_esm/actions/public/getSenderAddress.js +83 -59
  17. package/_esm/actions/public/getSenderAddress.js.map +1 -1
  18. package/_types/accounts/kernel/signerToEcdsaKernelSmartAccount.d.ts +1 -1
  19. package/_types/accounts/kernel/signerToEcdsaKernelSmartAccount.d.ts.map +1 -1
  20. package/_types/accounts/safe/signerToSafeSmartAccount.d.ts +2 -1
  21. package/_types/accounts/safe/signerToSafeSmartAccount.d.ts.map +1 -1
  22. package/_types/actions/public/getSenderAddress.d.ts.map +1 -1
  23. package/accounts/kernel/signerToEcdsaKernelSmartAccount.ts +3 -3
  24. package/accounts/safe/signerToSafeSmartAccount.ts +24 -24
  25. package/actions/erc7579/installModule.test.ts +111 -1
  26. package/actions/erc7579/isModuleInstalled.test.ts +1 -1
  27. package/actions/erc7579/supportsExecutionMode.ts +2 -2
  28. package/actions/erc7579/uninstallModule.test.ts +2 -2
  29. package/actions/public/getSenderAddress.test.ts +1 -1
  30. package/actions/public/getSenderAddress.ts +104 -70
  31. package/actions/smartAccount/signMessage.test.ts +89 -6
  32. package/actions/smartAccount/signTypedData.test.ts +84 -6
  33. package/actions/smartAccount/writeContract.test.ts +84 -6
  34. package/package.json +1 -1
  35. package/utils/encode7579CallData.test.ts +1 -1
@@ -551,7 +551,7 @@ export type SafeSmartAccount<
551
551
  const get7579LaunchPadInitData = ({
552
552
  safe4337ModuleAddress,
553
553
  safeSingletonAddress,
554
- erc7569LaunchpadAddress,
554
+ erc7579LaunchpadAddress,
555
555
  owner,
556
556
  validators,
557
557
  executors,
@@ -562,7 +562,7 @@ const get7579LaunchPadInitData = ({
562
562
  }: {
563
563
  safe4337ModuleAddress: Address
564
564
  safeSingletonAddress: Address
565
- erc7569LaunchpadAddress: Address
565
+ erc7579LaunchpadAddress: Address
566
566
  owner: Address
567
567
  executors: {
568
568
  address: Address
@@ -578,7 +578,7 @@ const get7579LaunchPadInitData = ({
578
578
  singleton: safeSingletonAddress,
579
579
  owners: [owner],
580
580
  threshold: BigInt(1),
581
- setupTo: erc7569LaunchpadAddress,
581
+ setupTo: erc7579LaunchpadAddress,
582
582
  setupData: encodeFunctionData({
583
583
  abi: initSafe7579Abi,
584
584
  functionName: "initSafe7579",
@@ -613,7 +613,7 @@ const getInitializerCode = async ({
613
613
  safe4337ModuleAddress,
614
614
  multiSendAddress,
615
615
  safeSingletonAddress,
616
- erc7569LaunchpadAddress,
616
+ erc7579LaunchpadAddress,
617
617
  setupTransactions = [],
618
618
  safeModules = [],
619
619
  validators = [],
@@ -628,7 +628,7 @@ const getInitializerCode = async ({
628
628
  safeModuleSetupAddress: Address
629
629
  safe4337ModuleAddress: Address
630
630
  multiSendAddress: Address
631
- erc7569LaunchpadAddress?: Address
631
+ erc7579LaunchpadAddress?: Address
632
632
  setupTransactions?: {
633
633
  to: Address
634
634
  data: Address
@@ -645,11 +645,11 @@ const getInitializerCode = async ({
645
645
  attesters?: Address[]
646
646
  attestersThreshold?: number
647
647
  }) => {
648
- if (erc7569LaunchpadAddress) {
648
+ if (erc7579LaunchpadAddress) {
649
649
  const initData = get7579LaunchPadInitData({
650
650
  safe4337ModuleAddress,
651
651
  safeSingletonAddress,
652
- erc7569LaunchpadAddress,
652
+ erc7579LaunchpadAddress,
653
653
  owner,
654
654
  validators,
655
655
  executors,
@@ -793,7 +793,7 @@ const getAccountInitCode = async ({
793
793
  safeModuleSetupAddress,
794
794
  safe4337ModuleAddress,
795
795
  safeSingletonAddress,
796
- erc7569LaunchpadAddress,
796
+ erc7579LaunchpadAddress,
797
797
  multiSendAddress,
798
798
  saltNonce = BigInt(0),
799
799
  setupTransactions = [],
@@ -810,7 +810,7 @@ const getAccountInitCode = async ({
810
810
  safe4337ModuleAddress: Address
811
811
  safeSingletonAddress: Address
812
812
  multiSendAddress: Address
813
- erc7569LaunchpadAddress?: Address
813
+ erc7579LaunchpadAddress?: Address
814
814
  saltNonce?: bigint
815
815
  setupTransactions?: {
816
816
  to: Address
@@ -840,7 +840,7 @@ const getAccountInitCode = async ({
840
840
  setupTransactions,
841
841
  safeSingletonAddress,
842
842
  safeModules,
843
- erc7569LaunchpadAddress,
843
+ erc7579LaunchpadAddress,
844
844
  validators,
845
845
  executors,
846
846
  fallbacks,
@@ -853,7 +853,7 @@ const getAccountInitCode = async ({
853
853
  abi: createProxyWithNonceAbi,
854
854
  functionName: "createProxyWithNonce",
855
855
  args: [
856
- erc7569LaunchpadAddress ?? safeSingletonAddress,
856
+ erc7579LaunchpadAddress ?? safeSingletonAddress,
857
857
  initializer,
858
858
  saltNonce
859
859
  ]
@@ -873,7 +873,7 @@ const getAccountAddress = async <
873
873
  safeProxyFactoryAddress,
874
874
  safeSingletonAddress,
875
875
  multiSendAddress,
876
- erc7569LaunchpadAddress,
876
+ erc7579LaunchpadAddress,
877
877
  setupTransactions = [],
878
878
  safeModules = [],
879
879
  saltNonce = BigInt(0),
@@ -898,7 +898,7 @@ const getAccountAddress = async <
898
898
  }[]
899
899
  safeModules?: Address[]
900
900
  saltNonce?: bigint
901
- erc7569LaunchpadAddress?: Address
901
+ erc7579LaunchpadAddress?: Address
902
902
  validators?: { address: Address; context: Address }[]
903
903
  executors?: {
904
904
  address: Address
@@ -923,7 +923,7 @@ const getAccountAddress = async <
923
923
  setupTransactions,
924
924
  safeSingletonAddress,
925
925
  safeModules,
926
- erc7569LaunchpadAddress,
926
+ erc7579LaunchpadAddress,
927
927
  validators,
928
928
  executors,
929
929
  fallbacks,
@@ -936,7 +936,7 @@ const getAccountAddress = async <
936
936
  ["bytes", "uint256"],
937
937
  [
938
938
  proxyCreationCode,
939
- hexToBigInt(erc7569LaunchpadAddress ?? safeSingletonAddress)
939
+ hexToBigInt(erc7579LaunchpadAddress ?? safeSingletonAddress)
940
940
  ]
941
941
  )
942
942
 
@@ -1051,7 +1051,8 @@ export type SignerToSafeSmartAccountParameters<
1051
1051
  safeVersion: SafeVersion
1052
1052
  entryPoint: entryPoint
1053
1053
  safe4337ModuleAddress?: Address
1054
- erc7569LaunchpadAddress?: TErc7579
1054
+ erc7569LaunchpadAddress?: Address
1055
+ erc7579LaunchpadAddress?: TErc7579
1055
1056
  safeProxyFactoryAddress?: Address
1056
1057
  safeSingletonAddress?: Address
1057
1058
  address?: Address
@@ -1074,7 +1075,7 @@ function isErc7579Args(
1074
1075
  Address,
1075
1076
  Address
1076
1077
  > {
1077
- return args.erc7569LaunchpadAddress !== undefined
1078
+ return args.erc7579LaunchpadAddress !== undefined
1078
1079
  }
1079
1080
 
1080
1081
  /**
@@ -1114,7 +1115,7 @@ export async function signerToSafeSmartAccount<
1114
1115
  safe4337ModuleAddress: _safe4337ModuleAddress,
1115
1116
  safeProxyFactoryAddress: _safeProxyFactoryAddress,
1116
1117
  safeSingletonAddress: _safeSingletonAddress,
1117
- erc7569LaunchpadAddress,
1118
+ erc7579LaunchpadAddress = args.erc7579LaunchpadAddress,
1118
1119
  saltNonce = BigInt(0),
1119
1120
  validUntil = 0,
1120
1121
  validAfter = 0,
@@ -1187,7 +1188,7 @@ export async function signerToSafeSmartAccount<
1187
1188
  safeProxyFactoryAddress,
1188
1189
  safeSingletonAddress,
1189
1190
  multiSendAddress,
1190
- erc7569LaunchpadAddress,
1191
+ erc7579LaunchpadAddress,
1191
1192
  saltNonce,
1192
1193
  setupTransactions,
1193
1194
  safeModules,
@@ -1316,7 +1317,7 @@ export async function signerToSafeSmartAccount<
1316
1317
 
1317
1318
  let verifyingContract = safe4337ModuleAddress
1318
1319
 
1319
- if (erc7569LaunchpadAddress && !isDeployed) {
1320
+ if (erc7579LaunchpadAddress && !isDeployed) {
1320
1321
  verifyingContract = userOperation.sender
1321
1322
  }
1322
1323
 
@@ -1387,7 +1388,7 @@ export async function signerToSafeSmartAccount<
1387
1388
  safe4337ModuleAddress,
1388
1389
  safeSingletonAddress,
1389
1390
  multiSendAddress,
1390
- erc7569LaunchpadAddress,
1391
+ erc7579LaunchpadAddress,
1391
1392
  saltNonce,
1392
1393
  setupTransactions,
1393
1394
  safeModules,
@@ -1407,9 +1408,8 @@ export async function signerToSafeSmartAccount<
1407
1408
  async encodeCallData(args) {
1408
1409
  const isArray = Array.isArray(args)
1409
1410
 
1410
- if (erc7569LaunchpadAddress) {
1411
+ if (erc7579LaunchpadAddress) {
1411
1412
  // First transaction will be slower because we need to enable 7579 modules
1412
-
1413
1413
  safeDeployed =
1414
1414
  safeDeployed ||
1415
1415
  (await isSmartAccountDeployed(client, accountAddress))
@@ -1418,7 +1418,7 @@ export async function signerToSafeSmartAccount<
1418
1418
  const initData = get7579LaunchPadInitData({
1419
1419
  safe4337ModuleAddress,
1420
1420
  safeSingletonAddress,
1421
- erc7569LaunchpadAddress,
1421
+ erc7579LaunchpadAddress,
1422
1422
  owner: viemSigner.address,
1423
1423
  validators,
1424
1424
  executors,
@@ -68,7 +68,117 @@ describe.each(getCoreSmartAccounts())(
68
68
  type: "executor",
69
69
  address: "0xc98B026383885F41d9a995f85FC480E9bb8bB891",
70
70
  context:
71
- name === "Kernel"
71
+ name === "Kernel 7579"
72
+ ? encodePacked(
73
+ ["address", "bytes"],
74
+ [
75
+ zeroAddress,
76
+ encodeAbiParameters(
77
+ [
78
+ { type: "bytes" },
79
+ { type: "bytes" }
80
+ ],
81
+ [moduleData, "0x"]
82
+ )
83
+ ]
84
+ )
85
+ : moduleData
86
+ })
87
+
88
+ const bundlerClientV07 = createBundlerClient({
89
+ transport: http(altoRpc),
90
+ entryPoint: ENTRYPOINT_ADDRESS_V07
91
+ })
92
+
93
+ expect(isHash(opHash)).toBe(true)
94
+
95
+ const userOperationReceipt =
96
+ await bundlerClientV07.waitForUserOperationReceipt({
97
+ hash: opHash,
98
+ timeout: 100000
99
+ })
100
+ expect(userOperationReceipt).not.toBeNull()
101
+ expect(userOperationReceipt?.userOpHash).toBe(opHash)
102
+ expect(
103
+ userOperationReceipt?.receipt.transactionHash
104
+ ).toBeTruthy()
105
+
106
+ const receipt = await bundlerClientV07.getUserOperationReceipt({
107
+ hash: opHash
108
+ })
109
+
110
+ expect(receipt?.receipt.transactionHash).toBe(
111
+ userOperationReceipt?.receipt.transactionHash
112
+ )
113
+
114
+ const isModuleInstalled = await smartClient.isModuleInstalled({
115
+ type: "executor",
116
+ address: "0xc98B026383885F41d9a995f85FC480E9bb8bB891",
117
+ context: "0x"
118
+ })
119
+
120
+ expect(isModuleInstalled).toBe(true)
121
+ }
122
+ )
123
+ testWithRpc.skipIf(!getErc7579SmartAccountClient)(
124
+ "installModule",
125
+ async ({ rpc }) => {
126
+ const { anvilRpc, altoRpc, paymasterRpc } = rpc
127
+
128
+ if (!getErc7579SmartAccountClient) {
129
+ throw new Error("getErc7579SmartAccountClient not defined")
130
+ }
131
+
132
+ const privateKey = generatePrivateKey()
133
+
134
+ const smartClientWithoutExtend: SmartAccountClient<
135
+ ENTRYPOINT_ADDRESS_V07_TYPE,
136
+ Transport,
137
+ Chain,
138
+ SmartAccount<ENTRYPOINT_ADDRESS_V07_TYPE>
139
+ > = await getErc7579SmartAccountClient({
140
+ entryPoint: ENTRYPOINT_ADDRESS_V07,
141
+ privateKey: privateKey,
142
+ altoRpc: altoRpc,
143
+ anvilRpc: anvilRpc,
144
+ paymasterClient: getPimlicoPaymasterClient({
145
+ entryPoint: ENTRYPOINT_ADDRESS_V07,
146
+ paymasterRpc
147
+ })
148
+ })
149
+
150
+ const smartClient = smartClientWithoutExtend.extend(
151
+ erc7579Actions({
152
+ entryPoint: ENTRYPOINT_ADDRESS_V07
153
+ })
154
+ )
155
+
156
+ await smartClient.sendTransactions({
157
+ transactions: [
158
+ {
159
+ to: smartClient.account.address,
160
+ value: 0n,
161
+ data: "0x"
162
+ },
163
+ {
164
+ to: smartClient.account.address,
165
+ value: 0n,
166
+ data: "0x"
167
+ }
168
+ ]
169
+ })
170
+
171
+ const moduleData = encodePacked(
172
+ ["address"],
173
+ [smartClient.account.address]
174
+ )
175
+
176
+ const opHash = await installModule(smartClient as any, {
177
+ account: smartClient.account as any,
178
+ type: "executor",
179
+ address: "0xc98B026383885F41d9a995f85FC480E9bb8bB891",
180
+ context:
181
+ name === "Kernel 7579"
72
182
  ? encodePacked(
73
183
  ["address", "bytes"],
74
184
  [
@@ -67,7 +67,7 @@ describe.each(getCoreSmartAccounts())(
67
67
  type: "executor",
68
68
  address: "0xc98B026383885F41d9a995f85FC480E9bb8bB891",
69
69
  context:
70
- name === "Kernel"
70
+ name === "Kernel 7579"
71
71
  ? encodePacked(
72
72
  ["address", "bytes"],
73
73
  [
@@ -37,9 +37,9 @@ function parseCallType(callType: CallType) {
37
37
  switch (callType) {
38
38
  case "call":
39
39
  return "0x00"
40
- case "delegatecall":
41
- return "0x01"
42
40
  case "batchcall":
41
+ return "0x01"
42
+ case "delegatecall":
43
43
  return "0xff"
44
44
  }
45
45
  }
@@ -77,7 +77,7 @@ describe.each(getCoreSmartAccounts())(
77
77
  type: "executor",
78
78
  address: "0xc98B026383885F41d9a995f85FC480E9bb8bB891",
79
79
  context:
80
- name === "Kernel"
80
+ name === "Kernel 7579"
81
81
  ? encodePacked(
82
82
  ["address", "bytes"],
83
83
  [
@@ -111,7 +111,7 @@ describe.each(getCoreSmartAccounts())(
111
111
  type: "executor",
112
112
  address: "0xc98B026383885F41d9a995f85FC480E9bb8bB891",
113
113
  context:
114
- name === "Kernel"
114
+ name === "Kernel 7579"
115
115
  ? "0x"
116
116
  : encodeAbiParameters(
117
117
  [
@@ -3,7 +3,7 @@ import { generatePrivateKey } from "viem/accounts"
3
3
  import { describe, expect } from "vitest"
4
4
  import { testWithRpc } from "../../../permissionless-test/src/testWithRpc"
5
5
  import { getSimpleAccountClient } from "../../../permissionless-test/src/utils"
6
- import type { ENTRYPOINT_ADDRESS_V06_TYPE } from "../../_types/types"
6
+ import type { ENTRYPOINT_ADDRESS_V06_TYPE } from "../../types"
7
7
  import { ENTRYPOINT_ADDRESS_V06, ENTRYPOINT_ADDRESS_V07 } from "../../utils"
8
8
  import { getSenderAddress } from "./getSenderAddress"
9
9
 
@@ -1,14 +1,15 @@
1
1
  import {
2
2
  type Address,
3
3
  BaseError,
4
- type CallExecutionErrorType,
5
4
  type Chain,
6
5
  type Client,
7
6
  type ContractFunctionExecutionErrorType,
8
- type ContractFunctionRevertedErrorType,
7
+ ContractFunctionRevertedError,
9
8
  type Hex,
10
- type RpcRequestErrorType,
9
+ InvalidInputRpcError,
10
+ RpcRequestError,
11
11
  type Transport,
12
+ UnknownRpcError,
12
13
  concat,
13
14
  decodeErrorResult
14
15
  } from "viem"
@@ -132,10 +133,15 @@ export const getSenderAddress = async <
132
133
  args: [initCode || concat([factory as Hex, factoryData as Hex])]
133
134
  })
134
135
  } catch (e) {
135
- const err = e as ContractFunctionExecutionErrorType
136
+ const revertError = (e as ContractFunctionExecutionErrorType).walk(
137
+ (err) =>
138
+ err instanceof ContractFunctionRevertedError ||
139
+ err instanceof RpcRequestError ||
140
+ err instanceof InvalidInputRpcError ||
141
+ err instanceof UnknownRpcError
142
+ )
136
143
 
137
- if (err.cause.name === "ContractFunctionRevertedError") {
138
- const revertError = err.cause as ContractFunctionRevertedErrorType
144
+ if (revertError instanceof ContractFunctionRevertedError) {
139
145
  const errorName = revertError.data?.errorName ?? ""
140
146
  if (
141
147
  errorName === "SenderAddressResult" &&
@@ -146,84 +152,112 @@ export const getSenderAddress = async <
146
152
  }
147
153
  }
148
154
 
149
- if (err.cause.name === "CallExecutionError") {
150
- const callExecutionError = err.cause as CallExecutionErrorType
151
- if (callExecutionError.cause.name === "RpcRequestError") {
152
- const revertError =
153
- callExecutionError.cause as RpcRequestErrorType
155
+ if (revertError instanceof RpcRequestError) {
156
+ const hexStringRegex = /0x[a-fA-F0-9]+/
157
+ // biome-ignore lint/suspicious/noExplicitAny:
158
+ const match = (revertError as unknown as any).cause.data.match(
159
+ hexStringRegex
160
+ )
154
161
 
155
- const hexStringRegex = /0x[a-fA-F0-9]+/
156
- // biome-ignore lint/suspicious/noExplicitAny:
157
- const match = (revertError as unknown as any).cause.data.match(
158
- hexStringRegex
162
+ if (!match) {
163
+ throw new Error(
164
+ "Failed to parse revert bytes from RPC response"
159
165
  )
166
+ }
160
167
 
161
- if (!match) {
162
- throw new Error(
163
- "Failed to parse revert bytes from RPC response"
164
- )
165
- }
168
+ const data: Hex = match[0]
166
169
 
167
- const data: Hex = match[0]
170
+ const error = decodeErrorResult({
171
+ abi: [
172
+ {
173
+ inputs: [
174
+ {
175
+ internalType: "address",
176
+ name: "sender",
177
+ type: "address"
178
+ }
179
+ ],
180
+ name: "SenderAddressResult",
181
+ type: "error"
182
+ }
183
+ ],
184
+ data
185
+ })
168
186
 
169
- const error = decodeErrorResult({
170
- abi: [
171
- {
172
- inputs: [
173
- {
174
- internalType: "address",
175
- name: "sender",
176
- type: "address"
177
- }
178
- ],
179
- name: "SenderAddressResult",
180
- type: "error"
181
- }
182
- ],
183
- data
184
- })
187
+ return error.args[0] as Address
188
+ }
189
+
190
+ if (revertError instanceof InvalidInputRpcError) {
191
+ const hexStringRegex = /0x[a-fA-F0-9]+/
192
+ // biome-ignore lint/suspicious/noExplicitAny:
193
+ const match = (revertError as unknown as any).cause.data.match(
194
+ hexStringRegex
195
+ )
185
196
 
186
- return error.args[0] as Address
197
+ if (!match) {
198
+ throw new Error(
199
+ "Failed to parse revert bytes from RPC response"
200
+ )
187
201
  }
188
202
 
189
- if (callExecutionError.cause.name === "InvalidInputRpcError") {
190
- //Ganache local testing returns "InvalidInputRpcError" with data in regular format
191
- const revertError =
192
- callExecutionError.cause as RpcRequestErrorType
203
+ const data: Hex = match[0]
193
204
 
194
- const hexStringRegex = /0x[a-fA-F0-9]+/
195
- // biome-ignore lint/suspicious/noExplicitAny:
196
- const match = (revertError as unknown as any).cause.data.match(
197
- hexStringRegex
198
- )
205
+ const error = decodeErrorResult({
206
+ abi: [
207
+ {
208
+ inputs: [
209
+ {
210
+ internalType: "address",
211
+ name: "sender",
212
+ type: "address"
213
+ }
214
+ ],
215
+ name: "SenderAddressResult",
216
+ type: "error"
217
+ }
218
+ ],
219
+ data
220
+ })
199
221
 
200
- if (!match) {
201
- throw new Error(
202
- "Failed to parse revert bytes from RPC response"
203
- )
204
- }
222
+ return error.args[0] as Address
223
+ }
205
224
 
206
- const data: Hex = match[0]
225
+ if (revertError instanceof UnknownRpcError) {
226
+ const parsedBody = JSON.parse(
227
+ (revertError as unknown as any).cause.body
228
+ )
229
+ const revertData = parsedBody.error.data
207
230
 
208
- const error = decodeErrorResult({
209
- abi: [
210
- {
211
- inputs: [
212
- {
213
- internalType: "address",
214
- name: "sender",
215
- type: "address"
216
- }
217
- ],
218
- name: "SenderAddressResult",
219
- type: "error"
220
- }
221
- ],
222
- data
223
- })
231
+ const hexStringRegex = /0x[a-fA-F0-9]+/
232
+ // biome-ignore lint/suspicious/noExplicitAny:
233
+ const match = revertData.match(hexStringRegex)
224
234
 
225
- return error.args[0] as Address
235
+ if (!match) {
236
+ throw new Error(
237
+ "Failed to parse revert bytes from RPC response"
238
+ )
226
239
  }
240
+
241
+ const data: Hex = match[0]
242
+
243
+ const error = decodeErrorResult({
244
+ abi: [
245
+ {
246
+ inputs: [
247
+ {
248
+ internalType: "address",
249
+ name: "sender",
250
+ type: "address"
251
+ }
252
+ ],
253
+ name: "SenderAddressResult",
254
+ type: "error"
255
+ }
256
+ ],
257
+ data
258
+ })
259
+
260
+ return error.args[0] as Address
227
261
  }
228
262
 
229
263
  throw e