Back to home
@megaflow-labs/sdk

API Reference

TypeScript-native, viem-compatible, zero-config. Built for MegaETH.

v0.1.1
GitHub

Introduction

The problem: Every DeFi action on a standard EVM chain requires a separate transaction — approve, swap, stake, bridge. Each one is a separate wallet signature, a separate block confirmation, and a separate point of failure. If one step fails, the ones before it don't roll back. You're left with a stuck allowance, a half-executed position, or a drained account.

MegaFlow solves this by bundling any number of on-chain calls into a single atomic transaction through the on-chain MegaRouter contract. If any one call in the batch reverts, the entire transaction reverts — no partial state, no leaked approvals, no half-executed swaps.

Built for MegaETH's real-time layer: MegaFlow useseth_sendRawTransactionSync(EIP-7966), which means the RPC node holds the connection open until the transaction is confirmed on-chain — typically under 10ms. Your executeSync() call returns a mined receipt, not a pending hash.

Atomic
All-or-nothing — one revert rolls back the whole batch
< 10ms
EIP-7966 sync receipts via MegaETH real-time layer
Zero-config
fromPrivateKey() wires everything — no viem setup

Quick Start

Single import, zero boilerplate. As of v0.1.1,fromPrivateKey() handles viem account creation, WalletClient wiring, and chain config internally. The snippet below reads the current on-chain allowance, then batches a safe approval and swap into one atomic call.

Why safeApprove? USDT and some other tokens revert if you call approve() when the current allowance is non-zero. safeApprove() reads the current value and resets it to 0 first if needed — all inside the same atomic batch.

quickstart.ts
import { MegaFlowClient, MEGAETH_TOKENS, parseUnits } from '@megaflow-labs/sdk';

// One-liner setup — no viem/accounts needed
const client = MegaFlowClient.fromPrivateKey('0xYOUR_KEY');

const allowance = await client.getAllowance(MEGAETH_TOKENS.USDC, client.address!, DEX);

const { receipt } = await client
  .batch()
  .safeApprove(MEGAETH_TOKENS.USDC, DEX, parseUnits('100', 6), allowance)
  .swapExactTokensForTokens({ ... })
  .executeSync();   // ← instant receipt

Installation

npmnpm install @megaflow-labs/sdk
pnpmpnpm add @megaflow-labs/sdk
yarnyarn add @megaflow-labs/sdk

Peer dependency: viem ^2.0 (already bundled via re-exports — separate install optional)

MegaFlowClient

The primary entry point. Manages chain config, wallet connection, and builder access.

MegaFlowClient.fromPrivateKey(key)v0.1.1

Creates a fully connected client from a hex private key. No viem import needed.

MegaFlowClient
MegaFlowClient.fromMnemonic(mnemonic)v0.1.1

Creates a connected client from a BIP-39 mnemonic phrase.

MegaFlowClient
new MegaFlowClient(config?)

Zero-config constructor. Uses MegaETH Mainnet and the deployed MegaRouter by default.

MegaFlowClient
.connectWithAccount(account)

Connects a viem Account and creates a WalletClient internally.

this
.connect(walletClient)

Connects an existing viem WalletClient directly.

this
.addressgetter

Returns the connected account address.

Address | undefined
.getTokenBalance(token, address)

Returns the ERC-20 balance for a given address.

Promise<bigint>
.getAllowance(token, owner, spender)

Returns the current ERC-20 allowance.

Promise<bigint>
.getRouterInfo()

Returns the MegaRouter flat fee and fee collector address.

Promise<RouterInfo>
.batch()

Returns a fresh MegaFlowBuilder bound to this client's config.

MegaFlowBuilder

MegaFlowBuilder

Chainable builder returned by .batch(). Every method returns this for fluent chaining.

ERC-20
.approve(token, spender, amount)

Standard ERC-20 approve.

this
.safeApprove(token, spender, amount, current)

USDT-safe: resets allowance to 0 first if current differs, then sets amount.

this
.transfer(token, to, amount)

ERC-20 token transfer.

this
.transferFrom(token, from, to, amount)

ERC-20 transferFrom.

this
.multiTransfer(token, [{to, amount}])

Batches multiple transfers of the same token.

this
DEX & Swaps
.swapExactTokensForTokens(params)

Uniswap V2-compatible token→token swap.

this
.swapExactETHForTokens(params)

ETH→token swap.

this
.swapExactTokensForETH(params)

token→ETH swap.

this
.approveAndSwap(params)

Shorthand: .approve() + .swapExactTokensForTokens() combined.

this
.kyberSwap(params, sender)

Fetches best route from KyberSwap aggregator and adds the swap call.

Promise<this>
WETH & NFTs
.wrapETH(weth, amount)

Deposits ETH into the WETH contract.

this
.unwrapWETH(weth, amount)

Withdraws WETH back to ETH.

this
.transferNFT(nft, from, to, tokenId)

ERC-721 safeTransferFrom.

this
.approveNFT(nft, to, tokenId)

ERC-721 single token approve.

this
.setApprovalForAll(nft, operator, approved)

ERC-721 operator approval.

this
Execution
.simulate()

Dry-run the batch. Returns success, gasEstimate, per-call results, revertReason.

Promise<SimulationResult>
.execute(options?)

Full flow: simulate → sign → broadcast → waitForReceipt.

Promise<ExecutionResult>
.executeSync(options?)

Uses eth_sendRawTransactionSync (EIP-7966). Instant receipt in one roundtrip.

Promise<SyncResult>
.executeRealtime(options?)

Uses realtime_sendRawTransaction endpoint.

Promise<SyncResult>
Utilities
.add(target, callData, value?)

Raw call — lowest-level escape hatch.

this
.sendETH(to, amount)

Sends native ETH to an address.

this
.getCalls()

Returns a copy of the current call queue.

MegaCall[]
.getTotalValue()

Sum of all ETH values in the batch.

bigint
.summary()

Human-readable description of the batch.

string
.clear()

Resets all queued calls.

this
.isEmpty

True when the call queue has no items.

boolean

Recipes

Copy-paste patterns for the most common on-chain workflows. All examples use the v0.1.1 single-import — no viem config needed.

Approve + Swap (atomic)

The most common DeFi flow — approval and swap bundled in one tx. If the swap reverts, the approval is also rolled back atomically.

approve-and-swap.ts
import { MegaFlowClient, MEGAETH_TOKENS, parseUnits } from '@megaflow-labs/sdk';

const USDC = MEGAETH_TOKENS.USDC;
const WETH = MEGAETH_TOKENS.WETH;
const DEX  = '0xYOUR_DEX_ROUTER';

const client = MegaFlowClient.fromPrivateKey(process.env.PRIVATE_KEY!);

// Read the current allowance before building the batch
const allowance = await client.getAllowance(USDC, client.address!, DEX);
const amount    = parseUnits('100', 6);  // 100 USDC

const { receipt } = await client
  .batch()
  .safeApprove(USDC, DEX, amount, allowance)  // reset+approve atomically
  .swapExactTokensForTokens({
    amountIn: amount, amountOutMin: 0n,
    path: [USDC, WETH], to: client.address!,
    deadline: BigInt(Date.now() + 300_000),
  })
  .executeSync();   // ← single tx, instant receipt <10ms

console.log('Mined:', receipt.transactionHash);
Multi-token transfer (one tx)

Send USDC, WETH, and native ETH to different recipients — all in a single atomic call. All succeed or all revert.

multi-transfer.ts
import { MegaFlowClient, MEGAETH_TOKENS, parseUnits, parseEther } from '@megaflow-labs/sdk';

const client = MegaFlowClient.fromPrivateKey(key);

await client.batch()
  .transfer(MEGAETH_TOKENS.USDC, '0xAlice', parseUnits('50', 6))
  .transfer(MEGAETH_TOKENS.WETH, '0xBob',   parseEther('0.5'))
  .sendETH('0xCarol',                        parseEther('0.1'))
  .executeSync();
Best-rate swap via KyberSwap aggregator

kyberSwap() is async — it fetches the optimal route from the aggregator API and appends the calldata to your batch. Combine with approve() for a zero-slippage atomic bundle.

kyber-swap.ts
import { MegaFlowClient, MEGAETH_TOKENS, parseUnits } from '@megaflow-labs/sdk';

const client = MegaFlowClient.fromPrivateKey(key);
const amount = parseUnits('500', 6);  // 500 USDC

// kyberSwap() fetches the best route from the aggregator API
const builder = await client
  .batch()
  .approve(MEGAETH_TOKENS.USDC, '0xKyberRouter', amount)
  .kyberSwap({
    tokenIn:  MEGAETH_TOKENS.USDC,
    tokenOut: MEGAETH_TOKENS.WETH,
    amountIn: amount,
    slippage: 50,       // 0.5%
  }, client.address!);

await builder.executeSync();
Simulate before executing

Dry-run the full batch first — no gas consumed, no on-chain state change. Inspect per-call results and revert reasons, then execute only if it passes.

simulate-then-execute.ts
import { MegaFlowClient, MEGAETH_TOKENS, parseUnits } from '@megaflow-labs/sdk';

const client  = MegaFlowClient.fromPrivateKey(key);
const builder = client.batch()
  .approve(tokenA, spender, amount)
  .swapExactTokensForTokens({ ...swapParams });

// 1. Dry-run — zero gas, zero state change
const sim = await builder.simulate();

if (!sim.success) {
  console.error('Revert reason:', sim.revertReason);
  console.error('Failed at call index:', sim.failedCallIndex);
  return;
}

// 2. Simulation passed — safe to execute
console.log('Estimated gas:', sim.gasEstimate);
const { receipt } = await builder.executeSync();

Error Codes

EMPTY_BATCH

No calls queued before execution.

WALLET_NOT_CONNECTED

.connect() or .connectWithAccount() not called.

SIMULATION_FAILED

Dry-run reverted — check revertReason and failedCallIndex.

EXECUTION_FAILED

On-chain transaction reverted.

INVALID_TARGET

A call targets the zero address or invalid contract.

USER_REJECTED

User rejected the transaction in their wallet.

INSUFFICIENT_ETH

ETH value sent is less than the sum required by all calls.

KYBERSWAP_ERROR

KyberSwap aggregator API returned an error.

Need help?

Open an issue or start a discussion on GitHub.

Open an issue