@megaeth-labs/wallet-sdk
v0.1.22
Published
MegaETH Wallet SDK for web applications
Readme
MOSS Wallet SDK
Contents
- Install
- Initialize
- Connection Management
- Authentication
- Transfers
- Smart Contract Interactions
- Session Keys & Permissions
- Message Signing
- Wallet Information
- Event Handling
Install
npm install @megaeth-labs/wallet-sdk
A React Hooks version is also availale as @megaeth-labs/wallet-sdk-react
Types for all requests and responses can be found at src/types.ts
Initialize
Sets up the iFrame-based wallet. Resolves when the wallet is ready.
import { mega } from '@megaeth-labs/wallet-sdk';
await mega.initialise({
network: 'mainnet', // or 'testnet'
logging: 'error', // Optional: 'debug' | 'info' | 'warn' | 'error'
debug: false, // Optional: Enable internal verbose debug logging
sponsorUrl: 'https://your-sponsor-url.com', // Optional: Custom sponsor URL - see Sponsoring
sponsorMode: 'app-only', // Optional: 'everything' | 'app-only' | 'explicit'
sponsorToken: 'native', // Optional: 'native' | 'usdm'
});Connection Management
Connect Wallet
Shows the connection UI and resolves when the user connects or cancels.
const { status, address } = await mega.connect();
if (status === 'connected') {
console.log('Wallet connected:', address);
}Check Status
Get the current connection status without prompting the user.
const { status, address } = await mega.status();Disconnect
Disconnect the current wallet session.
const result = await mega.disconnect();
console.log('Disconnected:', result.status);Authentication
Authenticate with SIWE
Shows the built-in Sign-In with Ethereum (SIWE) UI. Returns a JWT that can be verified at https://wallet-api.megaeth.com/v1/partner-auth/verify?origin=YOUR_ORIGIN&jwt=JWT_TOKEN
const auth = await mega.authenticate();
if (auth.status === 'success' && auth.jwt) {
const response = await fetch(
`https://wallet-api.megaeth.com/v1/partner-auth/verify?origin=${window.location.host}&jwt=${auth.jwt}`
);
const { walletAddress } = await response.json();
}Transfers
Native Token Transfer (ETH)
Transfer native tokens from the connected wallet.
import { parseEther } from 'viem';
const result = await mega.transfer({
type: 'native',
to: '0xRecipientAddress',
amount: parseEther('0.1').toString(),
sponsor: false, // Optional: Use sponsored transactions when sponsor mode is explict
});
if (result.status === 'approved') {
console.log('Transaction hash:', result.receipt.hash);
}ERC20 Token Transfer
Transfer ERC20 tokens.
import { parseUnits } from 'viem';
const result = await mega.transfer({
type: 'erc20',
to: '0xRecipientAddress',
amount: parseUnits('100', 18).toString(), // 100 tokens with 18 decimals
contractAddress: '0xTokenContractAddress',
});ERC721 NFT Transfer
Transfer an ERC721 NFT.
const result = await mega.transfer({
type: 'erc721',
to: '0xRecipientAddress',
contractAddress: '0xNFTContractAddress',
tokenId: 1234,
amount: '0',
});ERC1155 Token Transfer
Transfer ERC1155 tokens.
const result = await mega.transfer({
type: 'erc1155',
to: '0xRecipientAddress',
contractAddress: '0xTokenContractAddress',
tokenId: 1,
amount: '5', // Number of tokens to transfer
});Smart Contract Interactions
Call Contract Method
Execute a contract method with user approval.
const result = await mega.callContract({
address: '0xContractAddress',
abi: contractABI,
functionName: 'mint',
args: [parseEther('1')],
value: parseEther('0.1'), // Optional: ETH value to send
sponsor: false, // Optional: Use sponsored transactions when sponsor mode is explict
});
if (result.status === 'approved') {
console.log('Transaction hash:', result.receipt.hash);
}Call Contract Method (Large Payload)
If you are calling a contract method with a large payload (e.g. deploying a contract via a factory), you can override the default max gas spending limit.
const result = await mega.callContract({
address: '0xContractAddress',
abi: contractABI,
functionName: 'deplosy',
args: [],
maxGasAllowance: parseEther('0.0005')
});
if (result.status === 'approved') {
console.log('Transaction hash:', result.receipt.hash);
}Silent Contract Call (Session Keys)
Execute a contract method silently using session key permissions (no user approval required).
const result = await mega.callContract({
address: '0xContractAddress',
abi: contractABI,
functionName: 'claim',
args: [],
silent: true, // Uses session key with pre-approved permissions
});Batch Contract Calls
Execute multiple contract calls in a single transaction.
const result = await mega.callContract([
{
address: '0xContract1',
abi: abi1,
functionName: 'approve',
args: ['0xSpender', parseEther('100')],
},
{
address: '0xContract2',
abi: abi2,
functionName: 'swap',
args: [parseEther('100')],
},
]);Call Contract with Raw Data
Execute a contract call using raw calldata instead of ABI.
const result = await mega.callContract({
address: '0xContractAddress',
data: '0x...' as `0x${string}`,
value: parseEther('0.1'),
});Read from Contract (No Gas)
Read data from a contract without creating a transaction.
const balance = await mega.getFromContract<bigint>({
address: '0xTokenContract',
abi: erc20ABI,
functionName: 'balanceOf',
args: ['0xUserAddress'],
});
console.log('Balance:', balance.toString());Session Keys & Permissions
Grant Permissions
Grant session key permissions for silent transactions. Users approve once, then your app can execute permitted transactions without additional prompts.
import { parseEther } from 'viem';
const result = await mega.grantPermissions({
permissions: {
expiry: 86400, // Expiry in seconds (24 hours)
permissions: {
// Specific contract calls allowed
calls: [
{
to: '0xContractAddress',
signature: 'mint(uint256)', // Function signature
},
{
to: '0xAnotherContract',
signature: 'claim()',
},
],
// Spending limits for tokens
spend: [
{
limit: parseEther('100'), // 100 ETH
period: 'day', // 'minute' | 'hour' | 'day' | 'week' | 'month' | 'year'
token: undefined, // undefined for native ETH
},
{
limit: parseEther('1000'), // 1000 tokens
period: 'week',
token: '0xTokenAddress' as `0x${string}`,
},
],
},
},
externalAddress: '0xYourAppAddress', // Optional: External address for permissions if sending from another wallet (e.g. from your API)
sponsor: false, // Optional: Sponsor the permission grant transaction when sponsor mode is explicit
});
if (result.status === 'approved') {
console.log('Permissions granted');
}Get Current Permissions
Check what permissions are currently active for an address.
const perms = await mega.getPermissions('0xUserAddress'); // Optional: address parameter
if (perms?.permissions) {
console.log('Expiry:', new Date(perms.permissions.expiry * 1000));
console.log('Allowed calls:', perms.permissions.permissions.calls);
console.log('Spending limits:', perms.permissions.permissions.spend);
}Revoke Permissions
Revoke all active session key permissions.
await mega.revokePermissions();
console.log('All permissions revoked');Message Signing
Sign Message
Request the user to sign a message.
const result = await mega.signMessage('Hello, World!');
if (result.status === 'success' && result.signature) {
console.log('Signature:', result.signature);
}Sign Structured Data (EIP-712)
Sign typed structured data.
const domain = {
name: 'MyApp',
version: '1',
chainId: 1,
verifyingContract: '0xContract',
};
const types = {
Person: [
{ name: 'name', type: 'string' },
{ name: 'wallet', type: 'address' },
],
};
const value = {
name: 'Alice',
wallet: '0x...',
};
const result = await mega.signData({
data: { domain, types, value },
});
if (result.status === 'success' && result.signature) {
console.log('Signature:', result.signature);
}Verifying Messages
For SIWE messages, the @megaeth-labss/wallet-server-verify package can be used to verify the signature.
For other messages or for more control, the following code can be used:
import { PersonalMessage } from 'ox';
import { Porto, RelayActions } from 'porto';
import { RelayClient } from 'porto/viem';
import { http, toBytes } from 'viem';
import { megaeth, megaethTestnet } from 'viem/chains';
const message = 'Hello';
const address = '0x...';
const signature = '0x...';
const chainId = 4326;
const porto = Porto.create({
relay: http('https://wallet-relay.megaeth.com'),
chains: [megaeth, megaethTestnet],
});
const client = RelayClient.fromPorto(porto, {
chainId
});
const result = await RelayActions.verifySignature(client, {
address,
digest: PersonalMessage.getSignPayload(toBytes(message)),
signature
});
if(!result.valid) {
throw new Error('Invalid Signature');
}Wallet Information
Get Token Balances
Retrieve the user's token balances.
// Get all tokens
const allBalances = await mega.balances({});
// Get specific tokens
const specificBalances = await mega.balances({
tokens: ['0xTokenAddress1', '0xTokenAddress2'],
});
specificBalances.forEach(token => {
console.log(`${token.symbol}: ${token.displayBalance}`);
console.log(`USD Value: $${token.usdBalance}`);
});Open Wallet UI
Open the wallet interface for the user.
await mega.open();Deposit Funds
Show the deposit UI to help users fund their wallet.
await mega.deposit();Event Handling
Listen to wallet events for real-time updates.
// Listen for status changes
mega.events.on('statusChange', ({ status, address }) => {
console.log('Status changed:', status, address);
});
// Stop listening
const unsubscribe = mega.events.on('statusChange', handler);
unsubscribe(); // Call to remove listener