Skip to main content

MOI Wallet

MOI Wallet is the official self-custodial wallet for the MOI Protocol. It is available as a mobile app (iOS and Android) and a browser extension (Chrome). Keys and seed phrases are generated and encrypted on the user's device and never leave it.

Download & Install

PlatformLink
iOS (iPhone & iPad)App Store
Android (Phone & Tablet)Google Play
Chrome Browser ExtensionChrome Web Store

Full documentation for the wallet is available at docs.wallet.moi.technology.


Mobile App

The mobile wallet supports iOS 16+ and Android 8.0+. Key capabilities:

  • Create a new wallet or import from a seed phrase
  • Biometric unlock (Face ID, Touch ID, fingerprint) — handled entirely by the device
  • Multi-account and sub-account management
  • Send and receive MOI assets with a full review flow
  • WalletConnect v2 — connect to any MOI dApp by scanning a QR code
  • Switch between Mainnet and Testnet
  • Real-time push notifications for transactions and session requests

Browser Extension

The Chrome extension injects a window.moi transport into every page. The recommended way to interact with it is through the BrowserProvider class from js-moi-sdk, which wraps the injected transport and exposes a typed API for requesting accounts, sending interactions, and listening to wallet events.

Installation

npm install js-moi-sdk

Detecting the Wallet

import { BrowserProvider } from "js-moi-sdk";

if (globalThis?.moi?.__isMOIWallet === true) {
const provider = new BrowserProvider(globalThis.moi);
}

Requesting Account Access

requestPermissions prompts the user to grant your dApp access to their accounts. Once approved, getWalletAccounts returns the list of addresses — the first element is the currently active account.

import { BrowserProvider } from "js-moi-sdk";

const provider = new BrowserProvider(globalThis.moi);

// Prompt the user to approve account access
await provider.requestPermissions("wallet.Accounts", {});

// Retrieve the list of account addresses
const accounts = await provider.getWalletAccounts();
// returns Hex[] — first element is the active account

Sending an Interaction

import { BrowserProvider } from "js-moi-sdk";

const provider = new BrowserProvider(globalThis.moi);

const response = await provider.sendInteraction({
type: 3,
fuel_price: 1,
fuel_limit: 200,
});

// Wait for the interaction to be confirmed
const receipt = await response.wait();
console.log(response.hash);

The wallet surfaces a full review screen to the user before signing. sendInteraction rejects with an error if the user cancels.

Listening for Account and Network Changes

import { BrowserProvider } from "js-moi-sdk";

const provider = new BrowserProvider(globalThis.moi);

provider.on("accountChange", (identifier) => {
// user switched to a different account
console.log("active account:", identifier);
});

provider.on("networkChange", (network) => {
// user switched network or RPC endpoint
console.log("network:", network.name, network.jsonRpcHost);
});

Reading the Active Network

import { BrowserProvider } from "js-moi-sdk";

const provider = new BrowserProvider(globalThis.moi);

const network = await provider.getNetwork();
// { id, name, jsonRpcHost, blockExplorer? }
console.log(network?.name);

BrowserProvider API Reference

MethodDescription
requestPermissions(key, permission)Prompts the user to grant access (e.g. "wallet.Accounts")
getPermissions()Returns the dApp's currently granted permissions
revokePermissions(key, permission)Revokes a previously granted permission
getWalletAccounts()Returns all account addresses; first element is the active account
getWalletAccount(id?)Returns a single WalletParticipant by identifier, or the master account
sendInteraction(interaction)Submits an interaction for user review and signing
getNetwork()Returns the active NetworkConfiguration
getWalletVersion()Returns the installed wallet version string
on(event, listener)Subscribes to "accountChange" or "networkChange" events

For the full API reference, see the Developer Reference in the wallet docs.


Security Model

  • Keys and seed phrases are generated locally and protected with AES-256-GCM encryption and scrypt key derivation
  • Biometric data is handled entirely by the OS (Secure Enclave / Android Keystore) — the wallet never sees it
  • The extension codebase is open-source on GitHub
  • Non-custodial architecture — Sarva Labs has no access to user funds or keys

Resources