@instadapp/avocado-base 0.0.1 → 0.0.2

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.
@@ -0,0 +1,327 @@
1
+ import { ethers, utils } from "ethers";
2
+ import { Forwarder__factory } from "@/contracts";
3
+ import { toBN } from "./index";
4
+
5
+ const multiMetadataTypes = ["bytes[]"];
6
+
7
+ const metadataTypes = ["bytes32 type", "uint8 version", "bytes data"];
8
+
9
+ const actionMetadataTypes = {
10
+ transfer: ["address token", "uint256 amount", "address receiver"],
11
+ bridge: [
12
+ "uint256 amount",
13
+ "address receiver",
14
+ "address fromToken",
15
+ "address toToken",
16
+ "uint256 toChainId",
17
+ "uint256 bridgeFee",
18
+ "address nativeToken",
19
+ ],
20
+ swap: [
21
+ "address sellToken",
22
+ "address buyToken",
23
+ "uint256 sellAmount",
24
+ "uint256 buyAmount",
25
+ "address receiver",
26
+ "bytes32 protocol",
27
+ ],
28
+ "gas-topup": ["uint256 amount", "address token", "address onBehalf"],
29
+ upgrade: ["bytes32 version", "address walletImpl"],
30
+ dapp: ["string name", "string url"],
31
+ deploy: [],
32
+ permit2: [
33
+ "address token",
34
+ "address spender",
35
+ "uint160 amount",
36
+ "uint48 expiration",
37
+ ],
38
+ };
39
+
40
+ const encodeMetadata = (props: MetadataProps) => {
41
+ return ethers.utils.defaultAbiCoder.encode(metadataTypes, [
42
+ ethers.utils.formatBytes32String(props.type),
43
+ props.version || "1",
44
+ props.encodedData,
45
+ ]);
46
+ };
47
+
48
+ export const encodeDappMetadata = (
49
+ params: DappMetadataProps,
50
+ single = true
51
+ ) => {
52
+ const encodedData = ethers.utils.defaultAbiCoder.encode(
53
+ actionMetadataTypes.dapp,
54
+ [params.name, params.url]
55
+ );
56
+
57
+ const data = encodeMetadata({
58
+ type: "dapp",
59
+ encodedData,
60
+ });
61
+
62
+ return single ? encodeMultipleActions(data) : data;
63
+ };
64
+
65
+ export const encodeTransferMetadata = (
66
+ params: SendMetadataProps,
67
+ single = true
68
+ ) => {
69
+ const encodedData = ethers.utils.defaultAbiCoder.encode(
70
+ actionMetadataTypes.transfer,
71
+ [params.token, params.amount, params.receiver]
72
+ );
73
+
74
+ const data = encodeMetadata({
75
+ type: "transfer",
76
+ encodedData,
77
+ });
78
+
79
+ return single ? encodeMultipleActions(data) : data;
80
+ };
81
+
82
+ export const encodeDeployMetadata = (single = true) => {
83
+ const data = encodeMetadata({
84
+ type: "deploy",
85
+ encodedData: "0x",
86
+ });
87
+
88
+ return single ? encodeMultipleActions(data) : data;
89
+ };
90
+
91
+ export const encodeWCSignMetadata = (
92
+ params: SignMetadataProps,
93
+ single = true
94
+ ) => {
95
+ const encodedData = ethers.utils.defaultAbiCoder.encode(
96
+ actionMetadataTypes["permit2"],
97
+ [params.token, params.spender, params.amount, params.expiration]
98
+ );
99
+
100
+ const data = encodeMetadata({
101
+ type: "permit2",
102
+ encodedData,
103
+ });
104
+
105
+ return single ? encodeMultipleActions(data) : data;
106
+ };
107
+
108
+ export const encodeUpgradeMetadata = (
109
+ params: UpgradeMetadataProps,
110
+ single = true
111
+ ) => {
112
+ const encodedData = ethers.utils.defaultAbiCoder.encode(
113
+ actionMetadataTypes.upgrade,
114
+ [params.version, params.walletImpl]
115
+ );
116
+
117
+ const data = encodeMetadata({
118
+ type: "upgrade",
119
+ encodedData,
120
+ });
121
+
122
+ return single ? encodeMultipleActions(data) : data;
123
+ };
124
+
125
+ export const encodeSwapMetadata = (
126
+ params: SwapMetadataProps,
127
+ single = true
128
+ ) => {
129
+ const encodedData = ethers.utils.defaultAbiCoder.encode(
130
+ actionMetadataTypes.swap,
131
+ [
132
+ params.sellToken,
133
+ params.buyToken,
134
+ params.sellAmount,
135
+ params.buyAmount,
136
+ params.receiver,
137
+ params.protocol,
138
+ ]
139
+ );
140
+
141
+ const data = encodeMetadata({
142
+ type: "swap",
143
+ encodedData,
144
+ });
145
+
146
+ return single ? encodeMultipleActions(data) : data;
147
+ };
148
+
149
+ export const encodeTopupMetadata = (
150
+ params: TopupMetadataProps,
151
+ single = true
152
+ ) => {
153
+ const encodedData = ethers.utils.defaultAbiCoder.encode(
154
+ actionMetadataTypes["gas-topup"],
155
+ [params.amount, params.token, params.onBehalf]
156
+ );
157
+
158
+ console.log(params);
159
+
160
+ const data = encodeMetadata({
161
+ type: "gas-topup",
162
+ encodedData,
163
+ });
164
+
165
+ return single ? encodeMultipleActions(data) : data;
166
+ };
167
+
168
+ export const encodeBridgeMetadata = (
169
+ params: BridgeMetadataProps,
170
+ single = true
171
+ ) => {
172
+ const encodedData = ethers.utils.defaultAbiCoder.encode(
173
+ actionMetadataTypes.bridge,
174
+ [
175
+ params.amount,
176
+ params.receiver,
177
+ params.fromToken,
178
+ params.toToken,
179
+ params.toChainId,
180
+ params.bridgeFee,
181
+ params.nativeToken,
182
+ ]
183
+ );
184
+
185
+ const data = encodeMetadata({
186
+ type: "bridge",
187
+ encodedData,
188
+ });
189
+
190
+ return single ? encodeMultipleActions(data) : data;
191
+ };
192
+
193
+ export const encodeMultipleActions = (...actionData: string[]) => {
194
+ return ethers.utils.defaultAbiCoder.encode(multiMetadataTypes, [actionData]);
195
+ };
196
+
197
+ export const decodeMetadata = (data: string) => {
198
+ try {
199
+ const iface = Forwarder__factory.createInterface();
200
+ let metadata = "0x";
201
+ let payload = {};
202
+
203
+ if (!data) return payload;
204
+
205
+ if (data.startsWith("0x18e7f485")) {
206
+ const executeData = iface.decodeFunctionData("execute", data);
207
+ if (executeData.metadata_ === "0x" || !executeData.metadata_) {
208
+ return null;
209
+ } else {
210
+ metadata = executeData.metadata_;
211
+ }
212
+ } else {
213
+ const executeDataV2 = iface.decodeFunctionData("executeV2", data);
214
+ if (
215
+ executeDataV2.params_.metadata === "0x" ||
216
+ !executeDataV2.params_.metadata
217
+ ) {
218
+ return null;
219
+ } else {
220
+ metadata = executeDataV2.params_.metadata;
221
+ }
222
+ }
223
+
224
+ const metadataArr = [];
225
+
226
+ const [decodedMultiMetadata = []] =
227
+ (ethers.utils.defaultAbiCoder.decode(
228
+ multiMetadataTypes,
229
+ metadata
230
+ ) as string[]) || [];
231
+
232
+ for (let metadata of decodedMultiMetadata) {
233
+ const decodedMetadata = ethers.utils.defaultAbiCoder.decode(
234
+ metadataTypes,
235
+ metadata
236
+ );
237
+
238
+ const type = ethers.utils.parseBytes32String(
239
+ decodedMetadata.type
240
+ ) as keyof typeof actionMetadataTypes;
241
+
242
+ const decodedData = ethers.utils.defaultAbiCoder.decode(
243
+ actionMetadataTypes[type],
244
+ decodedMetadata.data
245
+ );
246
+
247
+ switch (type) {
248
+ case "transfer":
249
+ payload = {
250
+ type,
251
+ token: decodedData.token,
252
+ amount: toBN(decodedData.amount).toFixed(),
253
+ receiver: decodedData.receiver,
254
+ };
255
+ break;
256
+ case "bridge":
257
+ payload = {
258
+ type,
259
+ amount: toBN(decodedData.amount).toFixed(),
260
+ receiver: decodedData.receiver,
261
+ toToken: decodedData.toToken,
262
+ fromToken: decodedData.fromToken,
263
+ toChainId: decodedData.toChainId
264
+ ? decodedData.toChainId.toString()
265
+ : null,
266
+ bridgeFee: toBN(decodedData.bridgeFee).toFixed(),
267
+ };
268
+ break;
269
+ case "swap":
270
+ payload = {
271
+ type,
272
+ buyAmount: toBN(decodedData.buyAmount).toFixed(),
273
+ sellAmount: toBN(decodedData.sellAmount).toFixed(),
274
+ buyToken: decodedData.buyToken,
275
+ sellToken: decodedData.sellToken,
276
+ receiver: decodedData.receiver,
277
+ protocol: utils.parseBytes32String(decodedData?.protocol || ""),
278
+ };
279
+ break;
280
+ case "upgrade":
281
+ payload = {
282
+ type,
283
+ version: utils.parseBytes32String(decodedData?.version || ""),
284
+ walletImpl: decodedData?.walletImpl,
285
+ };
286
+ break;
287
+ case "gas-topup":
288
+ payload = {
289
+ type,
290
+ amount: toBN(decodedData.amount).toFixed(),
291
+ token: decodedData.token,
292
+ onBehalf: decodedData.onBehalf,
293
+ };
294
+ break;
295
+ case "dapp":
296
+ payload = {
297
+ type,
298
+ name: decodedData?.name,
299
+ url: decodedData?.url,
300
+ };
301
+ break;
302
+ case "deploy":
303
+ payload = {
304
+ type,
305
+ };
306
+
307
+ case "permit2":
308
+ payload = {
309
+ type,
310
+ token: decodedData.token,
311
+ spender: decodedData.spender,
312
+ amount: toBN(decodedData.amount).toFixed(),
313
+ expiration: decodedData.expiration,
314
+ };
315
+
316
+ break;
317
+ }
318
+
319
+ metadataArr.push(payload);
320
+ }
321
+
322
+ return metadataArr;
323
+ } catch (e) {
324
+ console.log(e);
325
+ return null;
326
+ }
327
+ };
package/utils/network.ts CHANGED
@@ -1,21 +1,21 @@
1
1
  import { ethers } from "ethers";
2
- import {
3
- AVO_PROD_CHAIN_NAME,
4
- AVO_PROD_CHAIN_ID,
5
- AVO_STAGING_CHAIN_NAME,
6
- AVO_STAGING_RPC_URL,
7
- AVO_PROD_RPC_URL,
8
- AVO_STAGING_CHAIN_ID,
9
- } from "./avocado";
10
2
 
11
3
  export const bridgeDisabledNetworks = [1101];
12
4
 
13
5
  export const networks: Network[] = [
14
6
  {
15
7
  name: "Mainnet",
8
+ debankName: "eth",
9
+ ankrName: "eth",
16
10
  chainId: 1,
17
11
  params: {
18
12
  rpcUrls: ["https://rpc.ankr.com/eth"],
13
+ explorerUrl: "https://etherscan.io",
14
+ get serverRpcUrl() {
15
+ return process.env?.MAINNET_RPC_URL || this.rpcUrls[0];
16
+ },
17
+ balanceResolverAddress: "0x5b7D61b389D12e1f5873d0cCEe7E675915AB5F43",
18
+ usdcAddress: "0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48",
19
19
  nativeCurrency: {
20
20
  name: "Ethereum",
21
21
  symbol: "ETH",
@@ -25,6 +25,8 @@ export const networks: Network[] = [
25
25
  },
26
26
  {
27
27
  name: "Polygon",
28
+ debankName: "matic",
29
+ ankrName: "polygon",
28
30
  chainId: 137,
29
31
  params: {
30
32
  chainName: "Matic(Polygon) Mainnet",
@@ -33,12 +35,19 @@ export const networks: Network[] = [
33
35
  symbol: "MATIC",
34
36
  decimals: 18,
35
37
  },
38
+ balanceResolverAddress: "0x58632D23120b20650262b8A629a14e4F4043E0D9",
39
+ usdcAddress: "0x2791Bca1f2de4661ED88A30C99A7a9449Aa84174",
36
40
  rpcUrls: ["https://polygon-rpc.com"],
37
- blockExplorerUrls: ["https://polygonscan.com/"],
41
+ get serverRpcUrl() {
42
+ return process.env?.POLYGON_RPC_URL || this.rpcUrls[0];
43
+ },
44
+ explorerUrl: "https://polygonscan.com",
38
45
  },
39
46
  },
40
47
  {
41
48
  name: "Arbitrum",
49
+ debankName: "arb",
50
+ ankrName: "arbitrum",
42
51
  chainId: 42161,
43
52
  params: {
44
53
  chainName: "Arbitrum One",
@@ -47,12 +56,19 @@ export const networks: Network[] = [
47
56
  symbol: "ETH",
48
57
  decimals: 18,
49
58
  },
59
+ usdcAddress: "0xff970a61a04b1ca14834a43f5de4533ebddb5cc8",
60
+ balanceResolverAddress: "0xca5f37e6D8bB24c5A7958d5eccE7Bd9Aacc944f2",
61
+ get serverRpcUrl() {
62
+ return process.env?.ARBITRUM_RPC_URL || this.rpcUrls[0];
63
+ },
50
64
  rpcUrls: ["https://arb1.arbitrum.io/rpc"],
51
- blockExplorerUrls: ["https://arbiscan.io"],
65
+ explorerUrl: "https://arbiscan.io",
52
66
  },
53
67
  },
54
68
  {
55
69
  name: "Optimism",
70
+ debankName: "op",
71
+ ankrName: "optimism",
56
72
  chainId: 10,
57
73
  params: {
58
74
  chainName: "Optimistic Ethereum",
@@ -61,30 +77,50 @@ export const networks: Network[] = [
61
77
  symbol: "ETH",
62
78
  decimals: 18,
63
79
  },
80
+ usdcAddress: "0x7f5c764cbc14f9669b88837ca1490cca17c31607",
81
+ balanceResolverAddress: "0xca5f37e6D8bB24c5A7958d5eccE7Bd9Aacc944f2",
82
+ get serverRpcUrl() {
83
+ return process.env?.OPTIMISM_RPC_URL || this.rpcUrls[0];
84
+ },
64
85
  rpcUrls: ["https://mainnet.optimism.io"],
65
- blockExplorerUrls: ["https://optimistic.etherscan.io"],
86
+ explorerUrl: "https://optimistic.etherscan.io",
66
87
  },
67
88
  },
68
89
  {
69
90
  name: "Avalanche",
91
+ debankName: "avax",
92
+ ankrName: "avalanche",
70
93
  chainId: 43114,
71
94
  params: {
72
95
  chainName: "Avalanche Network",
96
+ get serverRpcUrl() {
97
+ return process.env?.AVALANCHE_RPC_URL || this.rpcUrls[0];
98
+ },
73
99
  nativeCurrency: {
74
100
  name: "Avalanche",
75
101
  symbol: "AVAX",
76
102
  decimals: 18,
77
103
  },
104
+ usdcAddress: "0xb97ef9ef8734c71904d8002f8b6bc66dd9c48a6e",
105
+ balanceResolverAddress: "0x63009f31D054E0ac9F321Cf0D642375236A4Bf1E",
78
106
  rpcUrls: ["https://api.avax.network/ext/bc/C/rpc"],
79
- blockExplorerUrls: ["https://snowtrace.io/"],
107
+ explorerUrl: "https://snowtrace.io",
80
108
  },
81
109
  },
82
110
  {
83
111
  name: "BSC",
112
+ debankName: "bsc",
113
+ ankrName: "bsc",
84
114
  chainId: 56,
85
115
  params: {
86
116
  chainName: "Binance Smart Chain",
117
+ explorerUrl: "https://bscscan.com",
87
118
  rpcUrls: ["https://rpc.ankr.com/bsc"],
119
+ get serverRpcUrl() {
120
+ return process.env?.BSC_RPC_URL || this.rpcUrls[0];
121
+ },
122
+ usdcAddress: "0x8ac76a51cc950d9822d68b83fe1ad97b32cd580d",
123
+ balanceResolverAddress: "0xb808cff38706e267067b0af427726aa099f69f89",
88
124
  nativeCurrency: {
89
125
  name: "Binance Coin",
90
126
  symbol: "BNB",
@@ -94,10 +130,18 @@ export const networks: Network[] = [
94
130
  },
95
131
  {
96
132
  name: "Gnosis",
133
+ debankName: "xdai",
134
+ ankrName: "gnosis",
97
135
  chainId: 100,
98
136
  params: {
99
137
  chainName: "Gnosis Safe",
138
+ explorerUrl: "https://gnosisscan.io",
100
139
  rpcUrls: ["https://rpc.ankr.com/gnosis"],
140
+ get serverRpcUrl() {
141
+ return process.env?.GNOSIS_RPC_URL || this.rpcUrls[0];
142
+ },
143
+ balanceResolverAddress: "0xfaa244e276b1597f663975ed007ee4ff70d27849",
144
+ usdcAddress: "0xddafbb505ad214d7b80b1f830fccc89b60fb7a83",
101
145
  nativeCurrency: {
102
146
  name: "xdaistable",
103
147
  symbol: "xDAI",
@@ -110,7 +154,13 @@ export const networks: Network[] = [
110
154
  chainId: 1101,
111
155
  params: {
112
156
  chainName: "polygon zkEVM",
157
+ explorerUrl: "https://zkevm.polygonscan.com",
113
158
  rpcUrls: ["https://rpc.ankr.com/polygon_zkevm"],
159
+ get serverRpcUrl() {
160
+ return process.env?.POLYGON_ZKEVM_RPC_URL || this.rpcUrls[0];
161
+ },
162
+ balanceResolverAddress: "0x48D1Fa5Ee6691a1E0B45d2B515650997BEA27a01",
163
+ usdcAddress: "0xa8ce8aee21bc2a48a5ef670afcc9274c7bbbc035",
114
164
  nativeCurrency: {
115
165
  name: "Ethereum",
116
166
  symbol: "ETH",
@@ -121,6 +171,7 @@ export const networks: Network[] = [
121
171
  {
122
172
  name: AVO_PROD_CHAIN_NAME,
123
173
  chainId: AVO_PROD_CHAIN_ID,
174
+ isAvocado: true,
124
175
  params: {
125
176
  chainName: AVO_PROD_CHAIN_NAME,
126
177
  nativeCurrency: {
@@ -129,13 +180,17 @@ export const networks: Network[] = [
129
180
  decimals: 18,
130
181
  },
131
182
  iconUrls: ["https://avocado.instadapp.io/logo.svg"],
183
+ balanceResolverAddress: "",
184
+ usdcAddress: "",
185
+ serverRpcUrl: AVO_PROD_RPC_URL,
132
186
  rpcUrls: [AVO_PROD_RPC_URL],
133
- blockExplorerUrls: ["https://avocado.instadapp.io"],
187
+ explorerUrl: AVO_PROD_EXPLORER_URL,
134
188
  },
135
189
  },
136
190
  {
137
191
  name: AVO_STAGING_CHAIN_NAME,
138
192
  chainId: AVO_STAGING_CHAIN_ID,
193
+ isAvocado: true,
139
194
  params: {
140
195
  chainName: AVO_STAGING_CHAIN_NAME,
141
196
  nativeCurrency: {
@@ -143,23 +198,24 @@ export const networks: Network[] = [
143
198
  symbol: "USDC",
144
199
  decimals: 18,
145
200
  },
201
+ serverRpcUrl: AVO_STAGING_RPC_URL,
202
+ balanceResolverAddress: "",
203
+ usdcAddress: "",
146
204
  iconUrls: ["https://avocado.instadapp.io/logo.svg"],
147
205
  rpcUrls: [AVO_STAGING_RPC_URL],
148
- blockExplorerUrls: ["https://avocado.instadapp.io"],
206
+ explorerUrl: AVO_STAGING_EXPLORER_URL,
149
207
  },
150
208
  },
151
209
  ];
152
210
 
153
211
  export const getNetworkByChainId = (
154
- chainId: Network["chainId"] | number | string
155
- ) => {
156
- return networks.find((i) => i.chainId === Number(chainId))!;
212
+ chainId: ChainId | number | string
213
+ ): Network => {
214
+ return networks.find((i) => i.chainId == chainId)!;
157
215
  };
158
216
 
159
217
  export const availableNetworks = networks.filter(
160
- (network) =>
161
- network.chainId != AVO_STAGING_CHAIN_ID &&
162
- network.chainId != AVO_PROD_CHAIN_ID
218
+ (network) => !network.isAvocado
163
219
  );
164
220
 
165
221
  export const chainIdToName = (chainId: ChainId | number | string) => {
@@ -180,6 +236,18 @@ export const RPCMap = networks.reduce((acc, network) => {
180
236
  export const networkIds = networks.map((network) => network.chainId);
181
237
 
182
238
  const rpcInstances: Record<string, ethers.providers.JsonRpcProvider> = {};
239
+ const serverRpcInstances: Record<string, ethers.providers.JsonRpcProvider> = {};
240
+
241
+ export const getServerRpcProvider = (chainId: number | string) => {
242
+ if (!rpcInstances[chainId]) {
243
+ const network = networks.find((n) => n.chainId == chainId);
244
+ serverRpcInstances[chainId] = new ethers.providers.JsonRpcProvider(
245
+ network?.params.serverRpcUrl
246
+ );
247
+ }
248
+
249
+ return serverRpcInstances[chainId];
250
+ };
183
251
 
184
252
  export const getRpcProvider = (chainId: number | string) => {
185
253
  if (!rpcInstances[chainId]) {
@@ -190,3 +258,11 @@ export const getRpcProvider = (chainId: number | string) => {
190
258
 
191
259
  return rpcInstances[chainId];
192
260
  };
261
+
262
+ export const getExplorerUrl = (
263
+ chainId: ChainId | number | string,
264
+ suffix: `/${string}` = "/"
265
+ ) => {
266
+ const network = getNetworkByChainId(chainId);
267
+ return `${network.params.explorerUrl}${suffix}`;
268
+ };
package/utils/utils.d.ts CHANGED
@@ -1,12 +1,20 @@
1
1
  type ChainId = 1 | 137 | 42161 | 10 | 56 | 43114 | 100 | 1101 | 634 | 63400;
2
2
 
3
+ type ISlackMessageType = "danger" | "error" | "success" | "banner";
4
+
3
5
  interface Network {
4
6
  name: string;
7
+ debankName?: string;
8
+ ankrName?: string;
5
9
  chainId: ChainId;
10
+ isAvocado?: boolean;
6
11
  params: {
7
12
  chainName?: string;
8
13
  rpcUrls: string[];
9
- blockExplorerUrls?: string[];
14
+ serverRpcUrl: string | undefined;
15
+ balanceResolverAddress?: string;
16
+ usdcAddress: string;
17
+ explorerUrl: string;
10
18
  iconUrls?: string[];
11
19
  nativeCurrency?: {
12
20
  name: string;
@@ -15,3 +23,66 @@ interface Network {
15
23
  };
16
24
  };
17
25
  }
26
+
27
+ type SignMetadataProps = {
28
+ token: string;
29
+ spender: string;
30
+ amount: string;
31
+ expiration: string;
32
+ };
33
+
34
+ type DappMetadataProps = {
35
+ name: string;
36
+ url: string;
37
+ };
38
+
39
+ type SendMetadataProps = {
40
+ token: string;
41
+ amount: string;
42
+ receiver: string;
43
+ };
44
+
45
+ type UpgradeMetadataProps = {
46
+ version: string;
47
+ walletImpl: string;
48
+ };
49
+
50
+ type TopupMetadataProps = {
51
+ amount: string;
52
+ token: string;
53
+ onBehalf: string;
54
+ };
55
+
56
+ type BridgeMetadataProps = {
57
+ amount: string;
58
+ receiver: string;
59
+ fromToken: string;
60
+ toToken: string;
61
+ toChainId: string;
62
+ bridgeFee: string;
63
+ nativeToken: string;
64
+ };
65
+
66
+ type SwapMetadataProps = {
67
+ sellToken: string;
68
+ buyToken: string;
69
+ sellAmount: string;
70
+ buyAmount: string;
71
+ receiver: string;
72
+ protocol?: string;
73
+ };
74
+
75
+ type MetadataProps = {
76
+ type:
77
+ | "transfer"
78
+ | "bridge"
79
+ | "swap"
80
+ | "multi"
81
+ | "gas-topup"
82
+ | "upgrade"
83
+ | "dapp"
84
+ | "deploy"
85
+ | "permit2";
86
+ encodedData: string;
87
+ version?: string;
88
+ };