@megaflow-labs/sdk 0.1.0 → 0.1.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.
- package/CHANGELOG.md +48 -0
- package/README.md +67 -17
- package/dist/index.d.mts +52 -24
- package/dist/index.d.ts +52 -24
- package/dist/index.js +101 -4
- package/dist/index.mjs +77 -3
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -6,6 +6,54 @@ This project adheres to [Semantic Versioning](https://semver.org/).
|
|
|
6
6
|
|
|
7
7
|
---
|
|
8
8
|
|
|
9
|
+
## [0.1.2] – 2026-02-28
|
|
10
|
+
|
|
11
|
+
### Improvements — Developer Experience
|
|
12
|
+
|
|
13
|
+
#### Added `connectWithPrivateKey` convenience method
|
|
14
|
+
- You can now connect the `MegaFlowBuilder` and `MegaFlowClient` directly with a private key hex string, without needing to manually import `privateKeyToAccount` or create account objects.
|
|
15
|
+
|
|
16
|
+
#### Expanded viem re-exports
|
|
17
|
+
- Re-exported `parseAbi`, `parseAbiItem`, `parseAbiParameters` (ABI helpers)
|
|
18
|
+
- Re-exported `createPublicClient`, `createWalletClient`, `http`, `webSocket` (Client factories)
|
|
19
|
+
- Re-exported `Chain`, `decodeAbiParameters` (Types and Encoding)
|
|
20
|
+
- This allows developers to rely **entirely** on the SDK imports for script and dapp building, eliminating duplicate `viem` dependencies.
|
|
21
|
+
|
|
22
|
+
---
|
|
23
|
+
|
|
24
|
+
## [0.1.1] – 2026-02-26
|
|
25
|
+
|
|
26
|
+
### Improvements — Developer Experience
|
|
27
|
+
|
|
28
|
+
#### Zero external imports (single SDK import pattern)
|
|
29
|
+
- Added `MegaFlowClient.fromPrivateKey(privateKey)` static factory — no need to import `privateKeyToAccount` from viem
|
|
30
|
+
- Added `MegaFlowClient.fromMnemonic(mnemonic)` static factory — create a client from a BIP-39 phrase in one line
|
|
31
|
+
- Added `client.address` getter — access the connected account's address without reaching into viem internals
|
|
32
|
+
|
|
33
|
+
#### viem re-exports
|
|
34
|
+
The most commonly needed viem utilities are now re-exported from `@megaflow-labs/sdk` directly:
|
|
35
|
+
- **Account factories**: `privateKeyToAccount`, `mnemonicToAccount`, `hdKeyToAccount`
|
|
36
|
+
- **Unit helpers**: `parseUnits`, `parseEther`, `formatUnits`, `formatEther`
|
|
37
|
+
- **Address utilities**: `isAddress`, `getAddress`, `zeroAddress`
|
|
38
|
+
- **Encoding**: `encodeFunctionData`, `decodeFunctionData`, `encodeAbiParameters`, `decodeAbiParameters`
|
|
39
|
+
- **Types**: `Address`, `Hash`, `Hex`, `PublicClient`, `WalletClient`, `Account`, `TransactionReceipt`
|
|
40
|
+
|
|
41
|
+
Before (v0.1.0):
|
|
42
|
+
```typescript
|
|
43
|
+
import { MegaFlowClient } from '@megaflow-labs/sdk';
|
|
44
|
+
import { privateKeyToAccount } from 'viem/accounts';
|
|
45
|
+
import { parseUnits } from 'viem';
|
|
46
|
+
const client = new MegaFlowClient().connectWithAccount(privateKeyToAccount('0x...'));
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
After (v0.1.1):
|
|
50
|
+
```typescript
|
|
51
|
+
import { MegaFlowClient, parseUnits } from '@megaflow-labs/sdk';
|
|
52
|
+
const client = MegaFlowClient.fromPrivateKey('0x...');
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
---
|
|
56
|
+
|
|
9
57
|
## [0.1.0] – 2026-02-26
|
|
10
58
|
|
|
11
59
|
### Initial release
|
package/README.md
CHANGED
|
@@ -26,25 +26,21 @@ On standard EVM chains, sending multiple transactions requires multiple wallet c
|
|
|
26
26
|
npm install @megaflow-labs/sdk
|
|
27
27
|
```
|
|
28
28
|
|
|
29
|
-
>
|
|
29
|
+
> **Node.js ≥ 18** required. `viem` is a peer dependency — but all commonly used viem utilities are **re-exported from the SDK** so you rarely need to install it separately.
|
|
30
30
|
|
|
31
31
|
---
|
|
32
32
|
|
|
33
33
|
## Quick Start
|
|
34
34
|
|
|
35
35
|
```typescript
|
|
36
|
-
import { MegaFlowClient, MEGAETH_TOKENS } from '@megaflow-labs/sdk';
|
|
37
|
-
import { privateKeyToAccount } from 'viem/accounts';
|
|
38
|
-
import { parseUnits, parseEther } from 'viem';
|
|
36
|
+
import { MegaFlowClient, MEGAETH_TOKENS, parseUnits, parseEther } from '@megaflow-labs/sdk';
|
|
39
37
|
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
// Zero-config: connects to MegaETH Mainnet automatically
|
|
43
|
-
const client = new MegaFlowClient().connectWithAccount(account);
|
|
38
|
+
// fromPrivateKey() creates a fully connected client in one line
|
|
39
|
+
const client = MegaFlowClient.fromPrivateKey('0xYOUR_PRIVATE_KEY');
|
|
44
40
|
|
|
45
41
|
// Read on-chain state
|
|
46
|
-
const balance = await client.getTokenBalance(MEGAETH_TOKENS.WETH,
|
|
47
|
-
const allowance = await client.getAllowance(USDC,
|
|
42
|
+
const balance = await client.getTokenBalance(MEGAETH_TOKENS.WETH, client.address!);
|
|
43
|
+
const allowance = await client.getAllowance(USDC, client.address!, DEX_ROUTER);
|
|
48
44
|
|
|
49
45
|
// Build, simulate, and execute — all in one chain
|
|
50
46
|
const result = await client
|
|
@@ -55,7 +51,7 @@ const result = await client
|
|
|
55
51
|
amountIn: parseUnits('100', 6),
|
|
56
52
|
amountOutMin: parseEther('0.03'),
|
|
57
53
|
path: [USDC, MEGAETH_TOKENS.WETH],
|
|
58
|
-
to:
|
|
54
|
+
to: client.address!,
|
|
59
55
|
})
|
|
60
56
|
.executeSync(); // instant receipt on MegaETH (~10ms)
|
|
61
57
|
|
|
@@ -63,6 +59,13 @@ console.log(`Tx hash: ${result.receipt.transactionHash}`);
|
|
|
63
59
|
console.log(`Gas used: ${result.gasUsed}`);
|
|
64
60
|
```
|
|
65
61
|
|
|
62
|
+
> **Using an existing viem account or WalletClient?** Both still work:
|
|
63
|
+
> ```typescript
|
|
64
|
+
> import { MegaFlowClient, privateKeyToAccount } from '@megaflow-labs/sdk';
|
|
65
|
+
> const client = new MegaFlowClient().connectWithAccount(privateKeyToAccount('0x...'));
|
|
66
|
+
> // or: .connect(myExistingWalletClient)
|
|
67
|
+
> ```
|
|
68
|
+
|
|
66
69
|
---
|
|
67
70
|
|
|
68
71
|
## Core Concepts
|
|
@@ -94,15 +97,16 @@ const result = await builder.execute();
|
|
|
94
97
|
|
|
95
98
|
Stateful high-level client. Extends MegaFlowBuilder with token reads, nonce management, and WebSocket support.
|
|
96
99
|
|
|
100
|
+
**Factory methods (v0.1.1+):**
|
|
101
|
+
|
|
97
102
|
```typescript
|
|
98
|
-
import { MegaFlowClient } from '@megaflow-labs/sdk';
|
|
103
|
+
import { MegaFlowClient, parseUnits } from '@megaflow-labs/sdk';
|
|
99
104
|
|
|
100
|
-
|
|
101
|
-
client.
|
|
105
|
+
// From private key
|
|
106
|
+
const client = MegaFlowClient.fromPrivateKey('0xYOUR_KEY');
|
|
102
107
|
|
|
103
|
-
//
|
|
104
|
-
const
|
|
105
|
-
const allowance = await client.getAllowance(token, address, spender);
|
|
108
|
+
// From mnemonic
|
|
109
|
+
const client2 = MegaFlowClient.fromMnemonic('word1 word2 ... word12');
|
|
106
110
|
|
|
107
111
|
// Batch transfers to multiple recipients in one tx
|
|
108
112
|
const result = await client
|
|
@@ -116,6 +120,22 @@ const result = await client
|
|
|
116
120
|
|
|
117
121
|
---
|
|
118
122
|
|
|
123
|
+
## What's re-exported from viem
|
|
124
|
+
|
|
125
|
+
You can import all of these directly from `@megaflow-labs/sdk` — **no separate `viem` install needed**:
|
|
126
|
+
|
|
127
|
+
| Category | Exports |
|
|
128
|
+
|---|---|
|
|
129
|
+
| **Account factories** | `privateKeyToAccount`, `mnemonicToAccount`, `hdKeyToAccount` |
|
|
130
|
+
| **Unit helpers** | `parseUnits`, `parseEther`, `formatUnits`, `formatEther` |
|
|
131
|
+
| **ABI helpers** | `parseAbi`, `parseAbiItem`, `parseAbiParameters` |
|
|
132
|
+
| **Client factories** | `createPublicClient`, `createWalletClient`, `http`, `webSocket` |
|
|
133
|
+
| **Address utilities** | `isAddress`, `getAddress`, `zeroAddress` |
|
|
134
|
+
| **Encoding** | `encodeFunctionData`, `decodeFunctionData`, `encodeAbiParameters`, `decodeAbiParameters` |
|
|
135
|
+
| **Types** | `Address`, `Hash`, `Hex`, `Chain`, `PublicClient`, `WalletClient`, `Account`, `TransactionReceipt` |
|
|
136
|
+
|
|
137
|
+
---
|
|
138
|
+
|
|
119
139
|
## API Reference
|
|
120
140
|
|
|
121
141
|
### Execution Methods
|
|
@@ -246,11 +266,41 @@ const client = new MegaFlowClient({ rpcUrl: 'https://your-rpc.example.com' });
|
|
|
246
266
|
|
|
247
267
|
---
|
|
248
268
|
|
|
269
|
+
## Examples
|
|
270
|
+
|
|
271
|
+
See the **[megaflow-labs/examples](https://github.com/megaflow-labs/examples)** repository for 14 working TypeScript scripts covering real DeFi patterns:
|
|
272
|
+
|
|
273
|
+
| Script | Pattern |
|
|
274
|
+
|---|---|
|
|
275
|
+
| `04-yield-optimizer` | Wrap + Approve + Supply to Aave in one tx |
|
|
276
|
+
| `05-leverage-loop` | Flashloan-style leverage loop without smart contracts |
|
|
277
|
+
| `06-nft-sweep-and-stake` | Buy NFT + stake atomically |
|
|
278
|
+
| `07-token-snipe-and-protect` | Snipe + stop-loss authorization |
|
|
279
|
+
| `08-bridge-intent` | Swap + bridge to L1 in one signature |
|
|
280
|
+
| `09-flash-arbitrage` | Zero-risk EOA arbitrage across two DEXes |
|
|
281
|
+
| `10-debt-repayment` | Liquidation rescue (swap illiquid → repay) |
|
|
282
|
+
| `11-airdrop-claim-and-sell` | Claim + sell before price collapses |
|
|
283
|
+
| `12-payroll-batch` | Treasury swap + pay 50 contributors |
|
|
284
|
+
| `13-portfolio-rebalance` | Multi-sell → single target buy |
|
|
285
|
+
| `14-options-payoff` | Conditional options exercise |
|
|
286
|
+
|
|
287
|
+
**Clone and run:**
|
|
288
|
+
```bash
|
|
289
|
+
git clone https://github.com/megaflow-labs/examples
|
|
290
|
+
cd examples && npm install
|
|
291
|
+
cp .env.example .env # add your PRIVATE_KEY
|
|
292
|
+
npm run 04-yield
|
|
293
|
+
```
|
|
294
|
+
|
|
295
|
+
---
|
|
296
|
+
|
|
249
297
|
## Links
|
|
250
298
|
|
|
251
299
|
- **Website:** [megaflow.space](https://megaflow.space)
|
|
300
|
+
- **Examples:** [github.com/megaflow-labs/examples](https://github.com/megaflow-labs/examples)
|
|
252
301
|
- **GitHub:** [github.com/megaflow-labs](https://github.com/megaflow-labs)
|
|
253
302
|
- **NPM:** [@megaflow-labs/sdk](https://www.npmjs.com/package/@megaflow-labs/sdk)
|
|
303
|
+
- **AI Context:** [llms.txt](https://github.com/megaflow-labs/sdk/blob/main/llms.txt)
|
|
254
304
|
|
|
255
305
|
---
|
|
256
306
|
|
package/dist/index.d.mts
CHANGED
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
import { Chain, Address, Hex, Hash, TransactionReceipt, PublicClient, WalletClient, Account } from 'viem';
|
|
2
|
+
export { Account, Address, Chain, Hash, Hex, PublicClient, TransactionReceipt, WalletClient, createPublicClient, createWalletClient, decodeAbiParameters, decodeFunctionData, encodeAbiParameters, encodeFunctionData, formatEther, formatUnits, getAddress, hexToBigInt, http, isAddress, numberToHex, parseAbi, parseAbiItem, parseAbiParameters, parseEther, parseUnits, webSocket, zeroAddress } from 'viem';
|
|
3
|
+
export { hdKeyToAccount, mnemonicToAccount, privateKeyToAccount } from 'viem/accounts';
|
|
2
4
|
|
|
3
5
|
/**
|
|
4
6
|
* MegaETH Chain Definitions
|
|
@@ -1288,8 +1290,13 @@ declare class MegaFlowBuilder {
|
|
|
1288
1290
|
*/
|
|
1289
1291
|
connectWithAccount(account: Account, rpcUrl?: string): this;
|
|
1290
1292
|
/**
|
|
1291
|
-
*
|
|
1293
|
+
* Connect using a raw private key hex string.
|
|
1294
|
+
* The most convenient way to connect in scripts — no viem import needed.
|
|
1295
|
+
*
|
|
1296
|
+
* @example
|
|
1297
|
+
* builder.connectWithPrivateKey(process.env.PRIVATE_KEY!)
|
|
1292
1298
|
*/
|
|
1299
|
+
connectWithPrivateKey(privateKey: `0x${string}`, rpcUrl?: string): this;
|
|
1293
1300
|
disconnect(): this;
|
|
1294
1301
|
/**
|
|
1295
1302
|
* Add a raw call (pre-encoded calldata).
|
|
@@ -1472,26 +1479,26 @@ declare class MegaFlowBuilder {
|
|
|
1472
1479
|
* - ERC20 balance/allowance reads
|
|
1473
1480
|
* - Multicall token state fetching
|
|
1474
1481
|
*
|
|
1475
|
-
* @example
|
|
1482
|
+
* @example Zero-config (recommended)
|
|
1476
1483
|
* ```typescript
|
|
1477
|
-
* import { MegaFlowClient } from '@megaflow-labs/sdk';
|
|
1478
|
-
* import { privateKeyToAccount } from 'viem/accounts';
|
|
1479
|
-
*
|
|
1480
|
-
* const account = privateKeyToAccount('0x...');
|
|
1481
|
-
*
|
|
1482
|
-
* // Zero-config: uses MegaETH Mainnet by default
|
|
1483
|
-
* const client = new MegaFlowClient().connectWithAccount(account);
|
|
1484
|
+
* import { MegaFlowClient, parseUnits } from '@megaflow-labs/sdk';
|
|
1484
1485
|
*
|
|
1485
|
-
* //
|
|
1486
|
-
* const
|
|
1487
|
-
* const allowance = await client.getAllowance(USDC, account.address, DEX_ROUTER);
|
|
1486
|
+
* // One import, no viem required
|
|
1487
|
+
* const client = MegaFlowClient.fromPrivateKey('0xYOUR_PRIVATE_KEY');
|
|
1488
1488
|
*
|
|
1489
|
-
* // Build + execute in one call
|
|
1490
1489
|
* const result = await client.batch()
|
|
1491
|
-
* .safeApprove(USDC, DEX_ROUTER,
|
|
1490
|
+
* .safeApprove(USDC, DEX_ROUTER, parseUnits('100', 6), 0n)
|
|
1492
1491
|
* .swapExactTokensForTokens({ ... })
|
|
1493
1492
|
* .executeSync(); // instant receipt on MegaETH
|
|
1494
1493
|
* ```
|
|
1494
|
+
*
|
|
1495
|
+
* @example With existing viem account
|
|
1496
|
+
* ```typescript
|
|
1497
|
+
* import { MegaFlowClient } from '@megaflow-labs/sdk';
|
|
1498
|
+
* import { privateKeyToAccount } from 'viem/accounts';
|
|
1499
|
+
*
|
|
1500
|
+
* const client = new MegaFlowClient().connectWithAccount(privateKeyToAccount('0x...'));
|
|
1501
|
+
* ```
|
|
1495
1502
|
*/
|
|
1496
1503
|
|
|
1497
1504
|
declare class MegaFlowClient {
|
|
@@ -1501,6 +1508,30 @@ declare class MegaFlowClient {
|
|
|
1501
1508
|
private wsClient?;
|
|
1502
1509
|
private nonceCache;
|
|
1503
1510
|
constructor(config?: MegaFlowClientConfig);
|
|
1511
|
+
/**
|
|
1512
|
+
* Create a client from a raw private key.
|
|
1513
|
+
* Eliminates the need to import `privateKeyToAccount` from viem/accounts.
|
|
1514
|
+
*
|
|
1515
|
+
* @example
|
|
1516
|
+
* ```typescript
|
|
1517
|
+
* import { MegaFlowClient, parseUnits } from '@megaflow-labs/sdk';
|
|
1518
|
+
* const client = MegaFlowClient.fromPrivateKey('0xYOUR_PRIVATE_KEY');
|
|
1519
|
+
* ```
|
|
1520
|
+
*/
|
|
1521
|
+
static fromPrivateKey(privateKey: Hex, config?: MegaFlowClientConfig): MegaFlowClient;
|
|
1522
|
+
/**
|
|
1523
|
+
* Create a client from a BIP-39 mnemonic phrase.
|
|
1524
|
+
*
|
|
1525
|
+
* @example
|
|
1526
|
+
* ```typescript
|
|
1527
|
+
* const client = MegaFlowClient.fromMnemonic('word1 word2 ... word12');
|
|
1528
|
+
* ```
|
|
1529
|
+
*/
|
|
1530
|
+
static fromMnemonic(mnemonic: string, config?: MegaFlowClientConfig): MegaFlowClient;
|
|
1531
|
+
/**
|
|
1532
|
+
* The connected account's address, or undefined if not yet connected.
|
|
1533
|
+
*/
|
|
1534
|
+
get address(): Address | undefined;
|
|
1504
1535
|
connectWithAccount(account: Account, rpcUrl?: string): this;
|
|
1505
1536
|
connect(walletClient: WalletClient): this;
|
|
1506
1537
|
/**
|
|
@@ -1588,26 +1619,23 @@ declare class MegaFlowClient {
|
|
|
1588
1619
|
* atomic transaction through the MegaRouter contract. All operations
|
|
1589
1620
|
* either succeed together or revert together.
|
|
1590
1621
|
*
|
|
1591
|
-
* @example Quick start
|
|
1622
|
+
* @example Quick start — single import
|
|
1592
1623
|
* ```typescript
|
|
1593
|
-
* import { MegaFlowClient } from '@megaflow-labs/sdk';
|
|
1594
|
-
* import { privateKeyToAccount } from 'viem/accounts';
|
|
1595
|
-
*
|
|
1596
|
-
* const account = privateKeyToAccount('0x...');
|
|
1624
|
+
* import { MegaFlowClient, parseUnits } from '@megaflow-labs/sdk';
|
|
1597
1625
|
*
|
|
1598
|
-
* //
|
|
1599
|
-
* const client =
|
|
1626
|
+
* // No viem import needed — fromPrivateKey handles it internally
|
|
1627
|
+
* const client = MegaFlowClient.fromPrivateKey('0xYOUR_PRIVATE_KEY');
|
|
1600
1628
|
*
|
|
1601
|
-
* const allowance = await client.getAllowance(USDC,
|
|
1629
|
+
* const allowance = await client.getAllowance(USDC, client.address!, DEX_ROUTER);
|
|
1602
1630
|
*
|
|
1603
1631
|
* const result = await client.batch()
|
|
1604
1632
|
* .safeApprove(USDC, DEX_ROUTER, parseUnits('100', 6), allowance)
|
|
1605
1633
|
* .swapExactTokensForTokens({
|
|
1606
1634
|
* router: DEX_ROUTER,
|
|
1607
1635
|
* amountIn: parseUnits('100', 6),
|
|
1608
|
-
* amountOutMin:
|
|
1636
|
+
* amountOutMin: parseUnits('0.03', 18),
|
|
1609
1637
|
* path: [USDC, WETH],
|
|
1610
|
-
* to:
|
|
1638
|
+
* to: client.address!,
|
|
1611
1639
|
* })
|
|
1612
1640
|
* .executeSync(); // instant receipt on MegaETH
|
|
1613
1641
|
* ```
|
package/dist/index.d.ts
CHANGED
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
import { Chain, Address, Hex, Hash, TransactionReceipt, PublicClient, WalletClient, Account } from 'viem';
|
|
2
|
+
export { Account, Address, Chain, Hash, Hex, PublicClient, TransactionReceipt, WalletClient, createPublicClient, createWalletClient, decodeAbiParameters, decodeFunctionData, encodeAbiParameters, encodeFunctionData, formatEther, formatUnits, getAddress, hexToBigInt, http, isAddress, numberToHex, parseAbi, parseAbiItem, parseAbiParameters, parseEther, parseUnits, webSocket, zeroAddress } from 'viem';
|
|
3
|
+
export { hdKeyToAccount, mnemonicToAccount, privateKeyToAccount } from 'viem/accounts';
|
|
2
4
|
|
|
3
5
|
/**
|
|
4
6
|
* MegaETH Chain Definitions
|
|
@@ -1288,8 +1290,13 @@ declare class MegaFlowBuilder {
|
|
|
1288
1290
|
*/
|
|
1289
1291
|
connectWithAccount(account: Account, rpcUrl?: string): this;
|
|
1290
1292
|
/**
|
|
1291
|
-
*
|
|
1293
|
+
* Connect using a raw private key hex string.
|
|
1294
|
+
* The most convenient way to connect in scripts — no viem import needed.
|
|
1295
|
+
*
|
|
1296
|
+
* @example
|
|
1297
|
+
* builder.connectWithPrivateKey(process.env.PRIVATE_KEY!)
|
|
1292
1298
|
*/
|
|
1299
|
+
connectWithPrivateKey(privateKey: `0x${string}`, rpcUrl?: string): this;
|
|
1293
1300
|
disconnect(): this;
|
|
1294
1301
|
/**
|
|
1295
1302
|
* Add a raw call (pre-encoded calldata).
|
|
@@ -1472,26 +1479,26 @@ declare class MegaFlowBuilder {
|
|
|
1472
1479
|
* - ERC20 balance/allowance reads
|
|
1473
1480
|
* - Multicall token state fetching
|
|
1474
1481
|
*
|
|
1475
|
-
* @example
|
|
1482
|
+
* @example Zero-config (recommended)
|
|
1476
1483
|
* ```typescript
|
|
1477
|
-
* import { MegaFlowClient } from '@megaflow-labs/sdk';
|
|
1478
|
-
* import { privateKeyToAccount } from 'viem/accounts';
|
|
1479
|
-
*
|
|
1480
|
-
* const account = privateKeyToAccount('0x...');
|
|
1481
|
-
*
|
|
1482
|
-
* // Zero-config: uses MegaETH Mainnet by default
|
|
1483
|
-
* const client = new MegaFlowClient().connectWithAccount(account);
|
|
1484
|
+
* import { MegaFlowClient, parseUnits } from '@megaflow-labs/sdk';
|
|
1484
1485
|
*
|
|
1485
|
-
* //
|
|
1486
|
-
* const
|
|
1487
|
-
* const allowance = await client.getAllowance(USDC, account.address, DEX_ROUTER);
|
|
1486
|
+
* // One import, no viem required
|
|
1487
|
+
* const client = MegaFlowClient.fromPrivateKey('0xYOUR_PRIVATE_KEY');
|
|
1488
1488
|
*
|
|
1489
|
-
* // Build + execute in one call
|
|
1490
1489
|
* const result = await client.batch()
|
|
1491
|
-
* .safeApprove(USDC, DEX_ROUTER,
|
|
1490
|
+
* .safeApprove(USDC, DEX_ROUTER, parseUnits('100', 6), 0n)
|
|
1492
1491
|
* .swapExactTokensForTokens({ ... })
|
|
1493
1492
|
* .executeSync(); // instant receipt on MegaETH
|
|
1494
1493
|
* ```
|
|
1494
|
+
*
|
|
1495
|
+
* @example With existing viem account
|
|
1496
|
+
* ```typescript
|
|
1497
|
+
* import { MegaFlowClient } from '@megaflow-labs/sdk';
|
|
1498
|
+
* import { privateKeyToAccount } from 'viem/accounts';
|
|
1499
|
+
*
|
|
1500
|
+
* const client = new MegaFlowClient().connectWithAccount(privateKeyToAccount('0x...'));
|
|
1501
|
+
* ```
|
|
1495
1502
|
*/
|
|
1496
1503
|
|
|
1497
1504
|
declare class MegaFlowClient {
|
|
@@ -1501,6 +1508,30 @@ declare class MegaFlowClient {
|
|
|
1501
1508
|
private wsClient?;
|
|
1502
1509
|
private nonceCache;
|
|
1503
1510
|
constructor(config?: MegaFlowClientConfig);
|
|
1511
|
+
/**
|
|
1512
|
+
* Create a client from a raw private key.
|
|
1513
|
+
* Eliminates the need to import `privateKeyToAccount` from viem/accounts.
|
|
1514
|
+
*
|
|
1515
|
+
* @example
|
|
1516
|
+
* ```typescript
|
|
1517
|
+
* import { MegaFlowClient, parseUnits } from '@megaflow-labs/sdk';
|
|
1518
|
+
* const client = MegaFlowClient.fromPrivateKey('0xYOUR_PRIVATE_KEY');
|
|
1519
|
+
* ```
|
|
1520
|
+
*/
|
|
1521
|
+
static fromPrivateKey(privateKey: Hex, config?: MegaFlowClientConfig): MegaFlowClient;
|
|
1522
|
+
/**
|
|
1523
|
+
* Create a client from a BIP-39 mnemonic phrase.
|
|
1524
|
+
*
|
|
1525
|
+
* @example
|
|
1526
|
+
* ```typescript
|
|
1527
|
+
* const client = MegaFlowClient.fromMnemonic('word1 word2 ... word12');
|
|
1528
|
+
* ```
|
|
1529
|
+
*/
|
|
1530
|
+
static fromMnemonic(mnemonic: string, config?: MegaFlowClientConfig): MegaFlowClient;
|
|
1531
|
+
/**
|
|
1532
|
+
* The connected account's address, or undefined if not yet connected.
|
|
1533
|
+
*/
|
|
1534
|
+
get address(): Address | undefined;
|
|
1504
1535
|
connectWithAccount(account: Account, rpcUrl?: string): this;
|
|
1505
1536
|
connect(walletClient: WalletClient): this;
|
|
1506
1537
|
/**
|
|
@@ -1588,26 +1619,23 @@ declare class MegaFlowClient {
|
|
|
1588
1619
|
* atomic transaction through the MegaRouter contract. All operations
|
|
1589
1620
|
* either succeed together or revert together.
|
|
1590
1621
|
*
|
|
1591
|
-
* @example Quick start
|
|
1622
|
+
* @example Quick start — single import
|
|
1592
1623
|
* ```typescript
|
|
1593
|
-
* import { MegaFlowClient } from '@megaflow-labs/sdk';
|
|
1594
|
-
* import { privateKeyToAccount } from 'viem/accounts';
|
|
1595
|
-
*
|
|
1596
|
-
* const account = privateKeyToAccount('0x...');
|
|
1624
|
+
* import { MegaFlowClient, parseUnits } from '@megaflow-labs/sdk';
|
|
1597
1625
|
*
|
|
1598
|
-
* //
|
|
1599
|
-
* const client =
|
|
1626
|
+
* // No viem import needed — fromPrivateKey handles it internally
|
|
1627
|
+
* const client = MegaFlowClient.fromPrivateKey('0xYOUR_PRIVATE_KEY');
|
|
1600
1628
|
*
|
|
1601
|
-
* const allowance = await client.getAllowance(USDC,
|
|
1629
|
+
* const allowance = await client.getAllowance(USDC, client.address!, DEX_ROUTER);
|
|
1602
1630
|
*
|
|
1603
1631
|
* const result = await client.batch()
|
|
1604
1632
|
* .safeApprove(USDC, DEX_ROUTER, parseUnits('100', 6), allowance)
|
|
1605
1633
|
* .swapExactTokensForTokens({
|
|
1606
1634
|
* router: DEX_ROUTER,
|
|
1607
1635
|
* amountIn: parseUnits('100', 6),
|
|
1608
|
-
* amountOutMin:
|
|
1636
|
+
* amountOutMin: parseUnits('0.03', 18),
|
|
1609
1637
|
* path: [USDC, WETH],
|
|
1610
|
-
* to:
|
|
1638
|
+
* to: client.address!,
|
|
1611
1639
|
* })
|
|
1612
1640
|
* .executeSync(); // instant receipt on MegaETH
|
|
1613
1641
|
* ```
|
package/dist/index.js
CHANGED
|
@@ -45,17 +45,40 @@ __export(index_exports, {
|
|
|
45
45
|
createMegaFlowClientTestnet: () => createMegaFlowClientTestnet,
|
|
46
46
|
createMegaFlowMainnet: () => createMegaFlowMainnet,
|
|
47
47
|
createMegaFlowTestnet: () => createMegaFlowTestnet,
|
|
48
|
+
createPublicClient: () => import_viem8.createPublicClient,
|
|
49
|
+
createWalletClient: () => import_viem8.createWalletClient,
|
|
48
50
|
deadlineInMinutes: () => deadlineInMinutes,
|
|
51
|
+
decodeAbiParameters: () => import_viem9.decodeAbiParameters,
|
|
52
|
+
decodeFunctionData: () => import_viem9.decodeFunctionData,
|
|
53
|
+
encodeAbiParameters: () => import_viem9.encodeAbiParameters,
|
|
54
|
+
encodeFunctionData: () => import_viem9.encodeFunctionData,
|
|
55
|
+
formatEther: () => import_viem5.formatEther,
|
|
56
|
+
formatUnits: () => import_viem5.formatUnits,
|
|
57
|
+
getAddress: () => import_viem7.getAddress,
|
|
49
58
|
getKyberQuote: () => getKyberQuote,
|
|
59
|
+
hdKeyToAccount: () => import_accounts3.hdKeyToAccount,
|
|
60
|
+
hexToBigInt: () => import_viem5.hexToBigInt,
|
|
61
|
+
http: () => import_viem8.http,
|
|
62
|
+
isAddress: () => import_viem7.isAddress,
|
|
50
63
|
isUserRejection: () => isUserRejection,
|
|
51
64
|
isValidAddress: () => isValidAddress,
|
|
52
65
|
isValidHex: () => isValidHex,
|
|
53
66
|
megaethChains: () => megaethChains,
|
|
54
67
|
megaethMainnet: () => megaethMainnet,
|
|
55
68
|
megaethTestnet: () => megaethTestnet,
|
|
69
|
+
mnemonicToAccount: () => import_accounts3.mnemonicToAccount,
|
|
70
|
+
numberToHex: () => import_viem5.numberToHex,
|
|
71
|
+
parseAbi: () => import_viem6.parseAbi,
|
|
72
|
+
parseAbiItem: () => import_viem6.parseAbiItem,
|
|
73
|
+
parseAbiParameters: () => import_viem6.parseAbiParameters,
|
|
56
74
|
parseBatchExecutedEvent: () => parseBatchExecutedEvent,
|
|
57
75
|
parseCallExecutedEvents: () => parseCallExecutedEvents,
|
|
58
|
-
parseCallResults: () => parseCallResults
|
|
76
|
+
parseCallResults: () => parseCallResults,
|
|
77
|
+
parseEther: () => import_viem5.parseEther,
|
|
78
|
+
parseUnits: () => import_viem5.parseUnits,
|
|
79
|
+
privateKeyToAccount: () => import_accounts3.privateKeyToAccount,
|
|
80
|
+
webSocket: () => import_viem8.webSocket,
|
|
81
|
+
zeroAddress: () => import_viem7.zeroAddress
|
|
59
82
|
});
|
|
60
83
|
module.exports = __toCommonJS(index_exports);
|
|
61
84
|
|
|
@@ -494,6 +517,7 @@ var MegaFlowError = class extends Error {
|
|
|
494
517
|
|
|
495
518
|
// src/builder.ts
|
|
496
519
|
var import_viem3 = require("viem");
|
|
520
|
+
var import_accounts = require("viem/accounts");
|
|
497
521
|
var MegaFlowBuilder = class {
|
|
498
522
|
constructor(config = {}) {
|
|
499
523
|
this.calls = [];
|
|
@@ -533,8 +557,16 @@ var MegaFlowBuilder = class {
|
|
|
533
557
|
return this;
|
|
534
558
|
}
|
|
535
559
|
/**
|
|
536
|
-
*
|
|
560
|
+
* Connect using a raw private key hex string.
|
|
561
|
+
* The most convenient way to connect in scripts — no viem import needed.
|
|
562
|
+
*
|
|
563
|
+
* @example
|
|
564
|
+
* builder.connectWithPrivateKey(process.env.PRIVATE_KEY!)
|
|
537
565
|
*/
|
|
566
|
+
connectWithPrivateKey(privateKey, rpcUrl) {
|
|
567
|
+
const account = (0, import_accounts.privateKeyToAccount)(privateKey);
|
|
568
|
+
return this.connectWithAccount(account, rpcUrl);
|
|
569
|
+
}
|
|
538
570
|
disconnect() {
|
|
539
571
|
this.walletClient = void 0;
|
|
540
572
|
return this;
|
|
@@ -1078,7 +1110,8 @@ var MegaFlowBuilder = class {
|
|
|
1078
1110
|
// src/client.ts
|
|
1079
1111
|
var import_viem4 = require("viem");
|
|
1080
1112
|
var import_actions = require("viem/actions");
|
|
1081
|
-
var
|
|
1113
|
+
var import_accounts2 = require("viem/accounts");
|
|
1114
|
+
var MegaFlowClient = class _MegaFlowClient {
|
|
1082
1115
|
constructor(config = {}) {
|
|
1083
1116
|
// Local nonce cache: address → last used nonce
|
|
1084
1117
|
this.nonceCache = /* @__PURE__ */ new Map();
|
|
@@ -1100,8 +1133,43 @@ var MegaFlowClient = class {
|
|
|
1100
1133
|
}
|
|
1101
1134
|
}
|
|
1102
1135
|
// ==========================================================================
|
|
1136
|
+
// Static factories — zero external imports needed
|
|
1137
|
+
// ==========================================================================
|
|
1138
|
+
/**
|
|
1139
|
+
* Create a client from a raw private key.
|
|
1140
|
+
* Eliminates the need to import `privateKeyToAccount` from viem/accounts.
|
|
1141
|
+
*
|
|
1142
|
+
* @example
|
|
1143
|
+
* ```typescript
|
|
1144
|
+
* import { MegaFlowClient, parseUnits } from '@megaflow-labs/sdk';
|
|
1145
|
+
* const client = MegaFlowClient.fromPrivateKey('0xYOUR_PRIVATE_KEY');
|
|
1146
|
+
* ```
|
|
1147
|
+
*/
|
|
1148
|
+
static fromPrivateKey(privateKey, config = {}) {
|
|
1149
|
+
const account = (0, import_accounts2.privateKeyToAccount)(privateKey);
|
|
1150
|
+
return new _MegaFlowClient(config).connectWithAccount(account);
|
|
1151
|
+
}
|
|
1152
|
+
/**
|
|
1153
|
+
* Create a client from a BIP-39 mnemonic phrase.
|
|
1154
|
+
*
|
|
1155
|
+
* @example
|
|
1156
|
+
* ```typescript
|
|
1157
|
+
* const client = MegaFlowClient.fromMnemonic('word1 word2 ... word12');
|
|
1158
|
+
* ```
|
|
1159
|
+
*/
|
|
1160
|
+
static fromMnemonic(mnemonic, config = {}) {
|
|
1161
|
+
const account = (0, import_accounts2.mnemonicToAccount)(mnemonic);
|
|
1162
|
+
return new _MegaFlowClient(config).connectWithAccount(account);
|
|
1163
|
+
}
|
|
1164
|
+
// ==========================================================================
|
|
1103
1165
|
// Connection
|
|
1104
1166
|
// ==========================================================================
|
|
1167
|
+
/**
|
|
1168
|
+
* The connected account's address, or undefined if not yet connected.
|
|
1169
|
+
*/
|
|
1170
|
+
get address() {
|
|
1171
|
+
return this.walletClient?.account?.address;
|
|
1172
|
+
}
|
|
1105
1173
|
connectWithAccount(account, rpcUrl) {
|
|
1106
1174
|
const chain = this.config.chain ?? megaethMainnet;
|
|
1107
1175
|
this.walletClient = (0, import_viem4.createWalletClient)({
|
|
@@ -1316,6 +1384,12 @@ var MegaFlowClient = class {
|
|
|
1316
1384
|
};
|
|
1317
1385
|
|
|
1318
1386
|
// src/index.ts
|
|
1387
|
+
var import_accounts3 = require("viem/accounts");
|
|
1388
|
+
var import_viem5 = require("viem");
|
|
1389
|
+
var import_viem6 = require("viem");
|
|
1390
|
+
var import_viem7 = require("viem");
|
|
1391
|
+
var import_viem8 = require("viem");
|
|
1392
|
+
var import_viem9 = require("viem");
|
|
1319
1393
|
function createMegaFlow(config) {
|
|
1320
1394
|
return new MegaFlowBuilder(config);
|
|
1321
1395
|
}
|
|
@@ -1361,15 +1435,38 @@ function createMegaFlowClientTestnet(routerAddress, rpcUrl) {
|
|
|
1361
1435
|
createMegaFlowClientTestnet,
|
|
1362
1436
|
createMegaFlowMainnet,
|
|
1363
1437
|
createMegaFlowTestnet,
|
|
1438
|
+
createPublicClient,
|
|
1439
|
+
createWalletClient,
|
|
1364
1440
|
deadlineInMinutes,
|
|
1441
|
+
decodeAbiParameters,
|
|
1442
|
+
decodeFunctionData,
|
|
1443
|
+
encodeAbiParameters,
|
|
1444
|
+
encodeFunctionData,
|
|
1445
|
+
formatEther,
|
|
1446
|
+
formatUnits,
|
|
1447
|
+
getAddress,
|
|
1365
1448
|
getKyberQuote,
|
|
1449
|
+
hdKeyToAccount,
|
|
1450
|
+
hexToBigInt,
|
|
1451
|
+
http,
|
|
1452
|
+
isAddress,
|
|
1366
1453
|
isUserRejection,
|
|
1367
1454
|
isValidAddress,
|
|
1368
1455
|
isValidHex,
|
|
1369
1456
|
megaethChains,
|
|
1370
1457
|
megaethMainnet,
|
|
1371
1458
|
megaethTestnet,
|
|
1459
|
+
mnemonicToAccount,
|
|
1460
|
+
numberToHex,
|
|
1461
|
+
parseAbi,
|
|
1462
|
+
parseAbiItem,
|
|
1463
|
+
parseAbiParameters,
|
|
1372
1464
|
parseBatchExecutedEvent,
|
|
1373
1465
|
parseCallExecutedEvents,
|
|
1374
|
-
parseCallResults
|
|
1466
|
+
parseCallResults,
|
|
1467
|
+
parseEther,
|
|
1468
|
+
parseUnits,
|
|
1469
|
+
privateKeyToAccount,
|
|
1470
|
+
webSocket,
|
|
1471
|
+
zeroAddress
|
|
1375
1472
|
});
|
package/dist/index.mjs
CHANGED
|
@@ -441,6 +441,7 @@ import {
|
|
|
441
441
|
encodeFunctionData,
|
|
442
442
|
http
|
|
443
443
|
} from "viem";
|
|
444
|
+
import { privateKeyToAccount } from "viem/accounts";
|
|
444
445
|
var MegaFlowBuilder = class {
|
|
445
446
|
constructor(config = {}) {
|
|
446
447
|
this.calls = [];
|
|
@@ -480,8 +481,16 @@ var MegaFlowBuilder = class {
|
|
|
480
481
|
return this;
|
|
481
482
|
}
|
|
482
483
|
/**
|
|
483
|
-
*
|
|
484
|
+
* Connect using a raw private key hex string.
|
|
485
|
+
* The most convenient way to connect in scripts — no viem import needed.
|
|
486
|
+
*
|
|
487
|
+
* @example
|
|
488
|
+
* builder.connectWithPrivateKey(process.env.PRIVATE_KEY!)
|
|
484
489
|
*/
|
|
490
|
+
connectWithPrivateKey(privateKey, rpcUrl) {
|
|
491
|
+
const account = privateKeyToAccount(privateKey);
|
|
492
|
+
return this.connectWithAccount(account, rpcUrl);
|
|
493
|
+
}
|
|
485
494
|
disconnect() {
|
|
486
495
|
this.walletClient = void 0;
|
|
487
496
|
return this;
|
|
@@ -1030,7 +1039,8 @@ import {
|
|
|
1030
1039
|
webSocket as webSocket2
|
|
1031
1040
|
} from "viem";
|
|
1032
1041
|
import { multicall } from "viem/actions";
|
|
1033
|
-
|
|
1042
|
+
import { privateKeyToAccount as privateKeyToAccount2, mnemonicToAccount } from "viem/accounts";
|
|
1043
|
+
var MegaFlowClient = class _MegaFlowClient {
|
|
1034
1044
|
constructor(config = {}) {
|
|
1035
1045
|
// Local nonce cache: address → last used nonce
|
|
1036
1046
|
this.nonceCache = /* @__PURE__ */ new Map();
|
|
@@ -1052,8 +1062,43 @@ var MegaFlowClient = class {
|
|
|
1052
1062
|
}
|
|
1053
1063
|
}
|
|
1054
1064
|
// ==========================================================================
|
|
1065
|
+
// Static factories — zero external imports needed
|
|
1066
|
+
// ==========================================================================
|
|
1067
|
+
/**
|
|
1068
|
+
* Create a client from a raw private key.
|
|
1069
|
+
* Eliminates the need to import `privateKeyToAccount` from viem/accounts.
|
|
1070
|
+
*
|
|
1071
|
+
* @example
|
|
1072
|
+
* ```typescript
|
|
1073
|
+
* import { MegaFlowClient, parseUnits } from '@megaflow-labs/sdk';
|
|
1074
|
+
* const client = MegaFlowClient.fromPrivateKey('0xYOUR_PRIVATE_KEY');
|
|
1075
|
+
* ```
|
|
1076
|
+
*/
|
|
1077
|
+
static fromPrivateKey(privateKey, config = {}) {
|
|
1078
|
+
const account = privateKeyToAccount2(privateKey);
|
|
1079
|
+
return new _MegaFlowClient(config).connectWithAccount(account);
|
|
1080
|
+
}
|
|
1081
|
+
/**
|
|
1082
|
+
* Create a client from a BIP-39 mnemonic phrase.
|
|
1083
|
+
*
|
|
1084
|
+
* @example
|
|
1085
|
+
* ```typescript
|
|
1086
|
+
* const client = MegaFlowClient.fromMnemonic('word1 word2 ... word12');
|
|
1087
|
+
* ```
|
|
1088
|
+
*/
|
|
1089
|
+
static fromMnemonic(mnemonic, config = {}) {
|
|
1090
|
+
const account = mnemonicToAccount(mnemonic);
|
|
1091
|
+
return new _MegaFlowClient(config).connectWithAccount(account);
|
|
1092
|
+
}
|
|
1093
|
+
// ==========================================================================
|
|
1055
1094
|
// Connection
|
|
1056
1095
|
// ==========================================================================
|
|
1096
|
+
/**
|
|
1097
|
+
* The connected account's address, or undefined if not yet connected.
|
|
1098
|
+
*/
|
|
1099
|
+
get address() {
|
|
1100
|
+
return this.walletClient?.account?.address;
|
|
1101
|
+
}
|
|
1057
1102
|
connectWithAccount(account, rpcUrl) {
|
|
1058
1103
|
const chain = this.config.chain ?? megaethMainnet;
|
|
1059
1104
|
this.walletClient = createWalletClient2({
|
|
@@ -1268,6 +1313,12 @@ var MegaFlowClient = class {
|
|
|
1268
1313
|
};
|
|
1269
1314
|
|
|
1270
1315
|
// src/index.ts
|
|
1316
|
+
import { privateKeyToAccount as privateKeyToAccount3, mnemonicToAccount as mnemonicToAccount2, hdKeyToAccount } from "viem/accounts";
|
|
1317
|
+
import { parseUnits, parseEther as parseEther2, formatUnits, formatEther, hexToBigInt, numberToHex } from "viem";
|
|
1318
|
+
import { parseAbi as parseAbi2, parseAbiItem, parseAbiParameters } from "viem";
|
|
1319
|
+
import { isAddress, getAddress, zeroAddress } from "viem";
|
|
1320
|
+
import { createPublicClient as createPublicClient3, createWalletClient as createWalletClient3, http as http3, webSocket as webSocket3 } from "viem";
|
|
1321
|
+
import { encodeFunctionData as encodeFunctionData2, decodeFunctionData, encodeAbiParameters, decodeAbiParameters as decodeAbiParameters2 } from "viem";
|
|
1271
1322
|
function createMegaFlow(config) {
|
|
1272
1323
|
return new MegaFlowBuilder(config);
|
|
1273
1324
|
}
|
|
@@ -1312,15 +1363,38 @@ export {
|
|
|
1312
1363
|
createMegaFlowClientTestnet,
|
|
1313
1364
|
createMegaFlowMainnet,
|
|
1314
1365
|
createMegaFlowTestnet,
|
|
1366
|
+
createPublicClient3 as createPublicClient,
|
|
1367
|
+
createWalletClient3 as createWalletClient,
|
|
1315
1368
|
deadlineInMinutes,
|
|
1369
|
+
decodeAbiParameters2 as decodeAbiParameters,
|
|
1370
|
+
decodeFunctionData,
|
|
1371
|
+
encodeAbiParameters,
|
|
1372
|
+
encodeFunctionData2 as encodeFunctionData,
|
|
1373
|
+
formatEther,
|
|
1374
|
+
formatUnits,
|
|
1375
|
+
getAddress,
|
|
1316
1376
|
getKyberQuote,
|
|
1377
|
+
hdKeyToAccount,
|
|
1378
|
+
hexToBigInt,
|
|
1379
|
+
http3 as http,
|
|
1380
|
+
isAddress,
|
|
1317
1381
|
isUserRejection,
|
|
1318
1382
|
isValidAddress,
|
|
1319
1383
|
isValidHex,
|
|
1320
1384
|
megaethChains,
|
|
1321
1385
|
megaethMainnet,
|
|
1322
1386
|
megaethTestnet,
|
|
1387
|
+
mnemonicToAccount2 as mnemonicToAccount,
|
|
1388
|
+
numberToHex,
|
|
1389
|
+
parseAbi2 as parseAbi,
|
|
1390
|
+
parseAbiItem,
|
|
1391
|
+
parseAbiParameters,
|
|
1323
1392
|
parseBatchExecutedEvent,
|
|
1324
1393
|
parseCallExecutedEvents,
|
|
1325
|
-
parseCallResults
|
|
1394
|
+
parseCallResults,
|
|
1395
|
+
parseEther2 as parseEther,
|
|
1396
|
+
parseUnits,
|
|
1397
|
+
privateKeyToAccount3 as privateKeyToAccount,
|
|
1398
|
+
webSocket3 as webSocket,
|
|
1399
|
+
zeroAddress
|
|
1326
1400
|
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@megaflow-labs/sdk",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.2",
|
|
4
4
|
"description": "Batch transaction SDK for MegaETH — compose, simulate and execute multiple on-chain operations in a single atomic transaction.",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"module": "dist/index.mjs",
|