KanariPay
KanariPay is a multi-network payment gateway and lightweight wallet toolkit that helps businesses accept and manage cryptocurrency payments. It’s derived from the open-source pay_evm project and supports a range of EVM-compatible networks plus optional Move-based network support (Sui). KanariPay focuses on simple integration, secure key handling, and flexible network configuration.
Key features
- Multi-network support: Ethereum, Polygon, BNB Smart Chain, Avalanche, Fantom and more (mainnet & testnets).
- Optional Sui (Move) support for Move-based networks.
- Create or import wallets (12-word mnemonic) and securely store private keys.
- Send transactions and display balances for selected networks.
- Add, edit and test custom RPC networks (custom RPC URL, chain ID, currency symbol, explorer).
- Clean, responsive UI and developer-friendly APIs for integration.
Getting started
Prerequisites
- Node (for web integrations) or Flutter/Dart if using the original app components
- Access to desired blockchain RPC endpoints (public or self-hosted)
Note: The upstream project is a Flutter application. For a web or server-side KanariPay integration, adapt the wallet/key management and RPC usage to your stack while following the same security principles.
Installation (example: clone upstream app)
-
Clone the upstream project for reference and assets:
git clone https://github.com/jamesatomc/pay_evm.git (opens in a new tab)
-
If you plan to run the original Flutter app locally:
- Install Flutter and Dart (Flutter 3.9+ recommended)
- Run: flutter pub get
- Run on device/emulator: flutter run
For web or server integrations, implement the same RPC calls used by KanariPay (get balance, build/send transactions) in your chosen language.
Quick integration guide
Below is a condensed guide for integrating KanariPay-style payments into a web backend or serverless function.
- Configure a network
- Provide RPC URL, Chain ID, currency symbol, and optional explorer URL.
- Create or import a wallet
- Generate a 12-word mnemonic and derive keys, or import an existing mnemonic.
- Securely store private keys (see Security section).
- Get balance
- Query the RPC for native token balance and token balances using standard JSON-RPC calls or token indexers.
- Build and send transactions
- Build a raw transaction object with recipient, value, gas limit and gas price (or EIP-1559 fields).
- Sign with the wallet private key and broadcast via the RPC sendRawTransaction method.
Example (pseudo-code):
// Pseudo-code: send native token
const tx = await buildTx({ to: recipient, value: amount, chainId });
const signed = signTx(tx, privateKey);
const txHash = await rpc.sendRawTransaction(signed);Network management
- Add Custom Networks: allow merchants to add private or testnet RPCs. Require a test connection or quick health check before enabling.
- Color-code or mark testnets in the UI to avoid accidental mainnet charges.
Security notes
- Private keys must be stored encrypted at rest (KMS, HSM, or platform-provided secure storage). The upstream app uses Flutter Secure Storage for mobile apps.
- Never store plaintext private keys in logs or public storage.
- For production payment flows, consider a custody provider or KMS to limit exposure.
UX / Operational notes
- Require merchant confirmation steps for high-value payouts.
- Provide reconciliation endpoints (webhooks or push notifications) for successful transactions.
- Encourage use of testnets for integration and QA before switching to mainnet.
Further reading and upstream resources
- Upstream project (reference implementation): https://github.com/jamesatomc/pay_evm (opens in a new tab)
- Flutter docs: https://docs.flutter.dev (opens in a new tab)
If you want, I can:
- Expand this page with code examples in TypeScript (Node.js) that call common JSON-RPC endpoints for balance and sendRawTransaction.
- Add a simple backend example under
services/that demonstrates building and broadcasting a transaction. - Create a step-by-step integration tutorial with sample UI components.
Tell me which of those you'd like next and I'll implement it.