@whiterresearch/litvmswap-aggregator 1.0.4

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/README.md ADDED
@@ -0,0 +1,208 @@
1
+ # litvmswap-aggregator
2
+
3
+ The official TypeScript/JavaScript SDK for building on the **LitecoinVM (LitVM)** DEX Aggregator.
4
+
5
+ Enables builders, bots, and frontends to find optimal liquidity routes across all LitecoinVM decentralized exchanges (Uniswap V2, Uniswap V3, Algebra, Curve) and execute atomic swaps in a single transaction.
6
+
7
+ ---
8
+
9
+ ## ⚡ Quickstart
10
+
11
+ ### 1. Installation
12
+
13
+ ```bash
14
+ npm install @whiterresearch/litvmswap-aggregator viem
15
+ # or
16
+ yarn add @whiterresearch/litvmswap-aggregator viem
17
+ # or
18
+ pnpm add @whiterresearch/litvmswap-aggregator viem
19
+ ```
20
+
21
+ ---
22
+
23
+ ### 2. Fetch a Swap Quote
24
+
25
+ Query the best route and expected output across all LitVM liquidity pools:
26
+
27
+ ```typescript
28
+ import { LitVMAggregator } from '@whiterresearch/litvmswap-aggregator';
29
+
30
+ const aggregator = new LitVMAggregator();
31
+
32
+ const quote = await aggregator.getQuote({
33
+ tokenIn: 'zkLTC', // Native token symbol or address
34
+ tokenOut: 'ZKUSDC', // Target token symbol or address
35
+ amountIn: '1.0', // Formatted amount (1.0 zkLTC)
36
+ slippageTolerancePercent: 0.5, // 0.5% max slippage
37
+ });
38
+
39
+ console.log(`Expected Output: ${quote.expectedAmountOutFormatted} ${quote.tokenOut.symbol}`);
40
+ console.log(`Minimum Output: ${quote.minAmountOutFormatted} ${quote.tokenOut.symbol}`);
41
+ console.log(`Route Pool: ${quote.route.dexName} (${quote.route.poolAddress})`);
42
+ ```
43
+
44
+ ---
45
+
46
+ ### 3. Build & Execute Swap Transaction
47
+
48
+ Prepare a transaction payload ready to be signed with **Viem**, **Wagmi**, or **Ethers.js**:
49
+
50
+ ```typescript
51
+ // 1. Build ready-to-sign swap transaction
52
+ const swapTx = aggregator.buildSwapTx({
53
+ quote,
54
+ userAddress: '0xYourWalletAddress...',
55
+ });
56
+
57
+ // swapTx contains:
58
+ // - to: Contract address (AGGFlowRouter / AGGFlowEntrypoint)
59
+ // - data: Calldata hex string
60
+ // - value: Native token amount in wei (0n if selling ERC-20)
61
+ // - chainId: 4441
62
+
63
+ // 2. Send transaction with Viem / Wagmi
64
+ const hash = await walletClient.sendTransaction({
65
+ account: userAddress,
66
+ to: swapTx.to,
67
+ data: swapTx.data,
68
+ value: swapTx.value,
69
+ });
70
+ ```
71
+
72
+ ---
73
+
74
+ ### 4. Handling ERC-20 Approvals
75
+
76
+ When selling an ERC-20 token, check allowance and approve if required:
77
+
78
+ ```typescript
79
+ if (!quote.tokenIn.isNative) {
80
+ const needsApproval = await aggregator.needsApproval({
81
+ tokenAddress: quote.tokenIn.address,
82
+ ownerAddress: userAddress,
83
+ amount: quote.amountIn,
84
+ });
85
+
86
+ if (needsApproval) {
87
+ const approveTx = aggregator.buildApproveTx({
88
+ tokenAddress: quote.tokenIn.address,
89
+ });
90
+
91
+ await walletClient.sendTransaction({
92
+ account: userAddress,
93
+ to: approveTx.to,
94
+ data: approveTx.data,
95
+ value: 0n,
96
+ });
97
+ }
98
+ }
99
+ ```
100
+
101
+ ---
102
+
103
+ ### 5. Monetization: Partner & Referrer Fees
104
+
105
+ Builders can earn a custom fee on every swap executed through their app, bot, or interface:
106
+
107
+ ```typescript
108
+ const swapTx = aggregator.buildSwapTx({
109
+ quote,
110
+ userAddress: userAddress,
111
+ feeConfig: {
112
+ feeCollectorAddress: '0xYourRevenueWallet...',
113
+ feeBps: 10n, // 10 bps = 0.1% of swap amount goes directly to you
114
+ isInTokenFee: true, // Fee collected in input token
115
+ },
116
+ });
117
+ ```
118
+
119
+ ---
120
+
121
+ ## 🌐 LitecoinVM Network Configuration
122
+
123
+ | Parameter | Value |
124
+ | :--- | :--- |
125
+ | **Network Name** | LitecoinVM (LitVM) |
126
+ | **Chain ID** | `4441` |
127
+ | **RPC Endpoint** | `https://liteforge.rpc.caldera.xyz/http` |
128
+ | **Secondary RPC** | `https://liteforge.rpc.caldera.xyz/infra-partner-http` |
129
+ | **Block Explorer** | `https://explorer.LitVM.network` |
130
+ | **Native Currency**| `zkLTC` (18 decimals) |
131
+
132
+ ---
133
+
134
+ ## 🔀 How a swap is routed
135
+
136
+ ```
137
+ your app → AGGFlowPointsWrapper → AGGFlowEntrypoint → AGGFlowRouter → pools
138
+ records Lit Diamonds enforces the fee executes
139
+ + NFT staking boost
140
+ ```
141
+
142
+ `buildSwapTx` targets the **wrapper** by default. Two consequences worth
143
+ knowing:
144
+
145
+ - **The protocol fee is enforced on-chain.** It must go to the DexFeeVault and be
146
+ at least `MIN_PROTOCOL_FEE_BPS` (15 = 0.15%). A swap with a lower fee, or one
147
+ pointing the fee elsewhere, reverts. The SDK applies the minimum for you when
148
+ `feeConfig.feeBps` is omitted or below it.
149
+ - **Skipping the wrapper costs your users their points.** Lit Diamonds and the NFT
150
+ staking multiplier are recorded by the wrapper, not the entrypoint.
151
+
152
+ `useDirectRouter: true` bypasses both — no protocol fee, no points. It was
153
+ previously the default whenever no `feeConfig` was passed, so integrators hit it
154
+ by accident; it is now explicit.
155
+
156
+ ---
157
+
158
+ ## 🏛️ Deployed Contracts (LitecoinVM Chain ID: 4441)
159
+
160
+ | Contract | Address |
161
+ | :--- | :--- |
162
+ | **AGGFlowPointsWrapper** — send swaps here | `0xF664B56933f3cF0d7d69982b5A8eC9101b80059D` |
163
+ | **AGGFlowEntrypoint (fee enforcement)** | `0x5E19EB2A6BA30892CCe33f93D7Fb24D498512266` |
164
+ | **AGGFlowRouter (aggregator core)** | `0x0624E93350bFfc5B3570589FCae68e2CaBe6c620` |
165
+ | ~~Legacy entrypoint (no fee enforcement)~~ | ~~`0xF69E64804000d28aA695eB5c594B996100fb3B49`~~ |
166
+ | **Wrapped Native (wzkLTC / WETH)** | `0x315374AA9b5536037Cc1Efeea2439CCC0913A77e` |
167
+ | **OurV2 Factory** | `0x4680BCe1632824d30D2F53656dD610736c3e312e` |
168
+ | **Inky UniswapV2 Factory** | `0x458C5d5B75ccBA22651D2C5b61cB1EA1e0b0f95D` |
169
+ | **UniswapV3 Factory** | `0xde6763a041f8fc94ca2ee5933736f78f6d1a11c5` |
170
+ | **UniswapV3 Router** | `0x60F8A7642F0aeC06cE628224E743326B23Fe5208` |
171
+ | **DEX Fee Vault** | `0xF2DF37067a8Af0e9ae617c96C887B2FdA8eA3f10` |
172
+
173
+ ---
174
+
175
+ ## 🪙 Pre-Configured Tokens
176
+
177
+ | Symbol | Name | Address |
178
+ | :--- | :--- | :--- |
179
+ | `zkLTC` | Native Litecoin | `0x0000000000000000000000000000000000000000` |
180
+ | `wzkLTC` | Wrapped zkLTC | `0x315374AA9b5536037Cc1Efeea2439CCC0913A77e` |
181
+ | `ZKUSDC` | ZK USD Coin | `0xdf69970B2fE416339187aA41D39882e864984CE9` |
182
+ | `ZKUSDT` | ZK Tether USD | `0xa338b743Ec494ebB8345f4B6F27ffC902b7EF5Aa` |
183
+ | `LETH` | LitVM Ethereum | `0xDF474006aa807598B616500d146FfF661d644138` |
184
+ | `ZKBTC` | ZK Bitcoin | `0xca4914407868bc37ccbE324cA149DD475d39A2Bf` |
185
+ | `LitVMSwap` | LitVMSwap Token | `0xCa4c7EdB398684cB4C5B3fD0cc6ced30b5a5f4d3` |
186
+ | `LXRP` | LitVM XRP | `0xfdf5cD6452EDC340e67cd16db6A9D74aaa4f81a3` |
187
+ | `brBNB` | Bridged BNB | `0x58B6CD7891cd0A682226E25607b958a6479195A6` |
188
+
189
+ ---
190
+
191
+ ## 📚 API Reference
192
+
193
+ ### `LitVMAggregator`
194
+ * `constructor(config?: LitVMAggregatorConfig)`
195
+ * `getQuote(params: QuoteParams): Promise<QuoteResult>`
196
+ * `buildSwapTx(params: BuildSwapTxParams): PreparedTransaction`
197
+ * `checkAllowance(params: { tokenAddress, ownerAddress, spenderAddress? }): Promise<bigint>`
198
+ * `needsApproval(params: { tokenAddress, ownerAddress, amount, spenderAddress? }): Promise<boolean>`
199
+ * `buildApproveTx(params: { tokenAddress, spenderAddress?, amount? }): PreparedTransaction`
200
+ * `getToken(addressOrSymbol: string): Promise<TokenInfo>`
201
+ * `getKnownTokens(): TokenInfo[]`
202
+ * `executeSwapWithWallet(params): Promise<Hex>`
203
+
204
+ ---
205
+
206
+ ## 📄 License
207
+ MIT
208
+
@@ -0,0 +1,190 @@
1
+ export declare const AGGFlowEntrypointABI: readonly [{
2
+ readonly type: "constructor";
3
+ readonly inputs: readonly [{
4
+ readonly name: "_owner";
5
+ readonly type: "address";
6
+ }, {
7
+ readonly name: "_AGGFlowRouter";
8
+ readonly type: "address";
9
+ }];
10
+ readonly stateMutability: "nonpayable";
11
+ }, {
12
+ readonly type: "event";
13
+ readonly name: "AGGFlowSwap";
14
+ readonly inputs: readonly [{
15
+ readonly name: "user";
16
+ readonly type: "address";
17
+ readonly indexed: true;
18
+ }, {
19
+ readonly name: "referrer";
20
+ readonly type: "address";
21
+ readonly indexed: true;
22
+ }, {
23
+ readonly name: "tokenIn";
24
+ readonly type: "address";
25
+ readonly indexed: false;
26
+ }, {
27
+ readonly name: "tokenOut";
28
+ readonly type: "address";
29
+ readonly indexed: false;
30
+ }, {
31
+ readonly name: "isFeeInInput";
32
+ readonly type: "bool";
33
+ readonly indexed: false;
34
+ }, {
35
+ readonly name: "amountIn";
36
+ readonly type: "uint256";
37
+ readonly indexed: false;
38
+ }, {
39
+ readonly name: "amountOut";
40
+ readonly type: "uint256";
41
+ readonly indexed: false;
42
+ }, {
43
+ readonly name: "referrerFeeBps";
44
+ readonly type: "uint256";
45
+ readonly indexed: false;
46
+ }, {
47
+ readonly name: "totalFeeBps";
48
+ readonly type: "uint256";
49
+ readonly indexed: false;
50
+ }];
51
+ readonly anonymous: false;
52
+ }, {
53
+ readonly type: "event";
54
+ readonly name: "FeeCollected";
55
+ readonly inputs: readonly [{
56
+ readonly name: "feeCollector";
57
+ readonly type: "address";
58
+ readonly indexed: false;
59
+ }, {
60
+ readonly name: "amount";
61
+ readonly type: "uint256";
62
+ readonly indexed: false;
63
+ }, {
64
+ readonly name: "referrer";
65
+ readonly type: "address";
66
+ readonly indexed: false;
67
+ }, {
68
+ readonly name: "referrerAmount";
69
+ readonly type: "uint256";
70
+ readonly indexed: false;
71
+ }, {
72
+ readonly name: "user";
73
+ readonly type: "address";
74
+ readonly indexed: false;
75
+ }, {
76
+ readonly name: "token";
77
+ readonly type: "address";
78
+ readonly indexed: false;
79
+ }];
80
+ readonly anonymous: false;
81
+ }, {
82
+ readonly type: "function";
83
+ readonly name: "getRouter";
84
+ readonly inputs: readonly [];
85
+ readonly outputs: readonly [{
86
+ readonly name: "";
87
+ readonly type: "address";
88
+ }];
89
+ readonly stateMutability: "view";
90
+ }, {
91
+ readonly type: "function";
92
+ readonly name: "executeSwap";
93
+ readonly inputs: readonly [{
94
+ readonly name: "swapIntent";
95
+ readonly type: "tuple";
96
+ readonly components: readonly [{
97
+ readonly name: "tokenUserBuys";
98
+ readonly type: "address";
99
+ }, {
100
+ readonly name: "minAmountUserBuys";
101
+ readonly type: "uint256";
102
+ }, {
103
+ readonly name: "tokenUserSells";
104
+ readonly type: "address";
105
+ }, {
106
+ readonly name: "amountUserSells";
107
+ readonly type: "uint256";
108
+ }];
109
+ }, {
110
+ readonly name: "feeCollection";
111
+ readonly type: "tuple";
112
+ readonly components: readonly [{
113
+ readonly name: "feeCollectorAddress";
114
+ readonly type: "address";
115
+ }, {
116
+ readonly name: "feeBps";
117
+ readonly type: "uint256";
118
+ }, {
119
+ readonly name: "referrerAddress";
120
+ readonly type: "address";
121
+ }, {
122
+ readonly name: "referrerFeeBps";
123
+ readonly type: "uint256";
124
+ }, {
125
+ readonly name: "isInTokenFee";
126
+ readonly type: "bool";
127
+ }];
128
+ }, {
129
+ readonly name: "program";
130
+ readonly type: "bytes";
131
+ }];
132
+ readonly outputs: readonly [{
133
+ readonly name: "amountOut";
134
+ readonly type: "uint256";
135
+ }];
136
+ readonly stateMutability: "payable";
137
+ }, {
138
+ readonly type: "function";
139
+ readonly name: "executeSwapWithReceiver";
140
+ readonly inputs: readonly [{
141
+ readonly name: "swapIntent";
142
+ readonly type: "tuple";
143
+ readonly components: readonly [{
144
+ readonly name: "tokenUserBuys";
145
+ readonly type: "address";
146
+ }, {
147
+ readonly name: "minAmountUserBuys";
148
+ readonly type: "uint256";
149
+ }, {
150
+ readonly name: "tokenUserSells";
151
+ readonly type: "address";
152
+ }, {
153
+ readonly name: "amountUserSells";
154
+ readonly type: "uint256";
155
+ }];
156
+ }, {
157
+ readonly name: "feeCollection";
158
+ readonly type: "tuple";
159
+ readonly components: readonly [{
160
+ readonly name: "feeCollectorAddress";
161
+ readonly type: "address";
162
+ }, {
163
+ readonly name: "feeBps";
164
+ readonly type: "uint256";
165
+ }, {
166
+ readonly name: "referrerAddress";
167
+ readonly type: "address";
168
+ }, {
169
+ readonly name: "referrerFeeBps";
170
+ readonly type: "uint256";
171
+ }, {
172
+ readonly name: "isInTokenFee";
173
+ readonly type: "bool";
174
+ }];
175
+ }, {
176
+ readonly name: "program";
177
+ readonly type: "bytes";
178
+ }, {
179
+ readonly name: "receiver";
180
+ readonly type: "address";
181
+ }];
182
+ readonly outputs: readonly [{
183
+ readonly name: "amountOut";
184
+ readonly type: "uint256";
185
+ }];
186
+ readonly stateMutability: "payable";
187
+ }, {
188
+ readonly type: "receive";
189
+ readonly stateMutability: "payable";
190
+ }];
@@ -0,0 +1,114 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.AGGFlowEntrypointABI = void 0;
4
+ exports.AGGFlowEntrypointABI = [
5
+ {
6
+ type: "constructor",
7
+ inputs: [
8
+ { name: "_owner", type: "address" },
9
+ { name: "_AGGFlowRouter", type: "address" }
10
+ ],
11
+ stateMutability: "nonpayable"
12
+ },
13
+ {
14
+ type: "event",
15
+ name: "AGGFlowSwap",
16
+ inputs: [
17
+ { name: "user", type: "address", indexed: true },
18
+ { name: "referrer", type: "address", indexed: true },
19
+ { name: "tokenIn", type: "address", indexed: false },
20
+ { name: "tokenOut", type: "address", indexed: false },
21
+ { name: "isFeeInInput", type: "bool", indexed: false },
22
+ { name: "amountIn", type: "uint256", indexed: false },
23
+ { name: "amountOut", type: "uint256", indexed: false },
24
+ { name: "referrerFeeBps", type: "uint256", indexed: false },
25
+ { name: "totalFeeBps", type: "uint256", indexed: false }
26
+ ],
27
+ anonymous: false
28
+ },
29
+ {
30
+ type: "event",
31
+ name: "FeeCollected",
32
+ inputs: [
33
+ { name: "feeCollector", type: "address", indexed: false },
34
+ { name: "amount", type: "uint256", indexed: false },
35
+ { name: "referrer", type: "address", indexed: false },
36
+ { name: "referrerAmount", type: "uint256", indexed: false },
37
+ { name: "user", type: "address", indexed: false },
38
+ { name: "token", type: "address", indexed: false }
39
+ ],
40
+ anonymous: false
41
+ },
42
+ {
43
+ type: "function",
44
+ name: "getRouter",
45
+ inputs: [],
46
+ outputs: [{ name: "", type: "address" }],
47
+ stateMutability: "view"
48
+ },
49
+ {
50
+ type: "function",
51
+ name: "executeSwap",
52
+ inputs: [
53
+ {
54
+ name: "swapIntent",
55
+ type: "tuple",
56
+ components: [
57
+ { name: "tokenUserBuys", type: "address" },
58
+ { name: "minAmountUserBuys", type: "uint256" },
59
+ { name: "tokenUserSells", type: "address" },
60
+ { name: "amountUserSells", type: "uint256" }
61
+ ]
62
+ },
63
+ {
64
+ name: "feeCollection",
65
+ type: "tuple",
66
+ components: [
67
+ { name: "feeCollectorAddress", type: "address" },
68
+ { name: "feeBps", type: "uint256" },
69
+ { name: "referrerAddress", type: "address" },
70
+ { name: "referrerFeeBps", type: "uint256" },
71
+ { name: "isInTokenFee", type: "bool" }
72
+ ]
73
+ },
74
+ { name: "program", type: "bytes" }
75
+ ],
76
+ outputs: [{ name: "amountOut", type: "uint256" }],
77
+ stateMutability: "payable"
78
+ },
79
+ {
80
+ type: "function",
81
+ name: "executeSwapWithReceiver",
82
+ inputs: [
83
+ {
84
+ name: "swapIntent",
85
+ type: "tuple",
86
+ components: [
87
+ { name: "tokenUserBuys", type: "address" },
88
+ { name: "minAmountUserBuys", type: "uint256" },
89
+ { name: "tokenUserSells", type: "address" },
90
+ { name: "amountUserSells", type: "uint256" }
91
+ ]
92
+ },
93
+ {
94
+ name: "feeCollection",
95
+ type: "tuple",
96
+ components: [
97
+ { name: "feeCollectorAddress", type: "address" },
98
+ { name: "feeBps", type: "uint256" },
99
+ { name: "referrerAddress", type: "address" },
100
+ { name: "referrerFeeBps", type: "uint256" },
101
+ { name: "isInTokenFee", type: "bool" }
102
+ ]
103
+ },
104
+ { name: "program", type: "bytes" },
105
+ { name: "receiver", type: "address" }
106
+ ],
107
+ outputs: [{ name: "amountOut", type: "uint256" }],
108
+ stateMutability: "payable"
109
+ },
110
+ {
111
+ type: "receive",
112
+ stateMutability: "payable"
113
+ }
114
+ ];
@@ -0,0 +1,69 @@
1
+ export declare const AGGFlowRouterABI: readonly [{
2
+ readonly type: "constructor";
3
+ readonly inputs: readonly [{
4
+ readonly name: "_weth";
5
+ readonly type: "address";
6
+ }];
7
+ readonly stateMutability: "nonpayable";
8
+ }, {
9
+ readonly type: "event";
10
+ readonly name: "Route";
11
+ readonly inputs: readonly [{
12
+ readonly name: "user";
13
+ readonly type: "address";
14
+ readonly indexed: true;
15
+ }, {
16
+ readonly name: "tokenIn";
17
+ readonly type: "address";
18
+ readonly indexed: false;
19
+ }, {
20
+ readonly name: "tokenOut";
21
+ readonly type: "address";
22
+ readonly indexed: false;
23
+ }, {
24
+ readonly name: "amountIn";
25
+ readonly type: "uint256";
26
+ readonly indexed: false;
27
+ }, {
28
+ readonly name: "amountOut";
29
+ readonly type: "uint256";
30
+ readonly indexed: false;
31
+ }];
32
+ readonly anonymous: false;
33
+ }, {
34
+ readonly type: "function";
35
+ readonly name: "WETH";
36
+ readonly inputs: readonly [];
37
+ readonly outputs: readonly [{
38
+ readonly name: "";
39
+ readonly type: "address";
40
+ }];
41
+ readonly stateMutability: "view";
42
+ }, {
43
+ readonly type: "function";
44
+ readonly name: "executeRoute";
45
+ readonly inputs: readonly [{
46
+ readonly name: "tokenIn";
47
+ readonly type: "address";
48
+ }, {
49
+ readonly name: "amountIn";
50
+ readonly type: "uint256";
51
+ }, {
52
+ readonly name: "tokenOut";
53
+ readonly type: "address";
54
+ }, {
55
+ readonly name: "minAmountOut";
56
+ readonly type: "uint256";
57
+ }, {
58
+ readonly name: "program";
59
+ readonly type: "bytes";
60
+ }];
61
+ readonly outputs: readonly [{
62
+ readonly name: "amountOut";
63
+ readonly type: "uint256";
64
+ }];
65
+ readonly stateMutability: "payable";
66
+ }, {
67
+ readonly type: "receive";
68
+ readonly stateMutability: "payable";
69
+ }];
@@ -0,0 +1,46 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.AGGFlowRouterABI = void 0;
4
+ exports.AGGFlowRouterABI = [
5
+ {
6
+ type: "constructor",
7
+ inputs: [{ name: "_weth", type: "address" }],
8
+ stateMutability: "nonpayable"
9
+ },
10
+ {
11
+ type: "event",
12
+ name: "Route",
13
+ inputs: [
14
+ { name: "user", type: "address", indexed: true },
15
+ { name: "tokenIn", type: "address", indexed: false },
16
+ { name: "tokenOut", type: "address", indexed: false },
17
+ { name: "amountIn", type: "uint256", indexed: false },
18
+ { name: "amountOut", type: "uint256", indexed: false }
19
+ ],
20
+ anonymous: false
21
+ },
22
+ {
23
+ type: "function",
24
+ name: "WETH",
25
+ inputs: [],
26
+ outputs: [{ name: "", type: "address" }],
27
+ stateMutability: "view"
28
+ },
29
+ {
30
+ type: "function",
31
+ name: "executeRoute",
32
+ inputs: [
33
+ { name: "tokenIn", type: "address" },
34
+ { name: "amountIn", type: "uint256" },
35
+ { name: "tokenOut", type: "address" },
36
+ { name: "minAmountOut", type: "uint256" },
37
+ { name: "program", type: "bytes" }
38
+ ],
39
+ outputs: [{ name: "amountOut", type: "uint256" }],
40
+ stateMutability: "payable"
41
+ },
42
+ {
43
+ type: "receive",
44
+ stateMutability: "payable"
45
+ }
46
+ ];