mtpay-wallet-kit
v0.1.7
Published
MTPAY wallet connection and payment kit for BSC apps, with React components and Vue3-friendly SDK APIs.
Readme
MTPAY Wallet Kit
MTPAY Wallet Kit is a wallet connection and payment SDK for BNB Smart Chain apps. It includes React UI components and framework-neutral APIs that can be used from Vue3 or other frontends.
Install
npm install mtpay-wallet-kitDefault styles are injected automatically when the package is imported. Host apps do not need to write wallet modal styles.
WalletModal renders through a React portal to document.body by default, so the full-screen backdrop is not affected by host page headers, fixed navigation bars, transformed parents, or container overflow. If a special app needs inline rendering, pass disablePortal.
React Usage
import { useMemo, useState } from 'react';
import { WalletManager, WalletModal, walletKitConfig } from 'mtpay-wallet-kit';
export function CheckoutWallet() {
const manager = useMemo(() => new WalletManager(walletKitConfig.chain), []);
const [wallet, setWallet] = useState();
const [open, setOpen] = useState(false);
return (
<>
<button className="your-connect-button" onClick={() => setOpen(true)}>
{wallet?.address || 'Connect wallet'}
</button>
<WalletModal
open={open}
manager={manager}
onClose={() => setOpen(false)}
onConnected={setWallet}
onError={(error) => showToast(error.message)}
onStatusChange={(status) => console.log(status)}
/>
</>
);
}The button is yours. WalletButton is only an optional prebuilt button.
Custom Wallet UI
Host apps should normally keep their own buttons and product UI. The SDK only needs an event to open the modal, or a selected wallet object when you build a fully custom list.
<button className="your-connect-button" onClick={() => setOpen(true)}>
{wallet ? shortAddress(wallet.address) : 'Connect wallet'}
</button>
<WalletModal
open={open}
manager={manager}
onClose={() => setOpen(false)}
onConnected={setWallet}
variant="compact" // default | compact | minimal
size="md" // sm | md | lg
placement="bottom" // center | bottom
labels={{
title: 'Connect Wallet',
installed: 'INSTALLED',
app: 'APP',
footerBrand: 'MTPAY'
}}
theme={{
accentColor: '#63e6be',
background: 'rgba(14, 18, 27, 0.96)',
borderColor: 'rgba(198, 211, 235, 0.18)'
}}
className="my-wallet-modal"
backdropClassName="my-wallet-backdrop"
portalContainer={document.body}
disablePortal={false}
/>WalletButton is available only when you want a prebuilt button. It is not required for wallet connection.
The bundled CSS uses fixed px sizing, text-size-adjust: 100%, truncation, responsive grid rows, and 100dvh max heights to reduce layout distortion on mobile browsers and when users enlarge system text. You can override final details with className, style, backdropClassName, stable SDK classes like .mtpay-wallet-modal-backdrop / .mtpay-wallet-modal, or CSS variables.
The default backdrop is a plain black overlay with a light 4px blur, and the wallet modal ships without an outer drop shadow for a cleaner integration inside product pages.
Wallet status labels are detected at runtime. MetaMask is matched strictly to avoid false INSTALLED labels from other EIP-1193 wallets that expose MetaMask compatibility flags.
Vue3 Usage
<script setup lang="ts">
import { ref } from 'vue';
import { WalletManager, detectWallets, walletKitConfig } from 'mtpay-wallet-kit';
const manager = new WalletManager(walletKitConfig.chain);
const wallet = ref();
const wallets = ref([]);
async function openWallets() {
wallets.value = await detectWallets();
}
async function connect(selectedWallet) {
wallet.value = await manager.connect(selectedWallet);
}
</script>
<template>
<button @click="openWallets">
{{ wallet?.address || 'Connect Wallet' }}
</button>
<button v-for="item in wallets" :key="item.id" @click="connect(item)">
{{ item.name }}
</button>
</template>Payment Usage
import { PaymentService, walletKitConfig } from 'mtpay-wallet-kit';
const service = new PaymentService(walletKitConfig);
async function payWithYourButton() {
try {
const result = await service.payMtAndConfirm(wallet, '100', '0xReceiverAddress');
showSuccess(result.hash, result.status);
} catch (error) {
showError(error instanceof Error ? error.message : String(error));
}
}Successful payment JSON includes ok, chainId, receiver, wallet, token, invoiceAmountUsdt, tokenAmount, price, hash, blockNumber, status, and confirmedAt.
Your own button, toast, order status, and page layout stay in the host app. The SDK returns the payment result or throws a normalized error that can be shown to the user.
Payment Modal
Use PaymentModal when the payment flow should open like the wallet selector, with a black backdrop, 4px blur, centered placement, and a React portal to document.body.
import { PaymentModal } from 'mtpay-wallet-kit';
<PaymentModal
open={payOpen}
wallet={wallet}
initialAmountUsdt="100"
initialReceiver="0xReceiverAddress"
onConnect={() => setWalletOpen(true)}
onClose={() => setPayOpen(false)}
onSubmitted={(record) => {
console.log('submitted', record.hash);
}}
onSuccess={(payment) => {
console.log('confirmed', payment.hash, payment.status);
}}
onError={(error) => {
console.error(error.message);
}}
onStatusChange={(status) => {
console.log(status);
}}
/>onSuccess and onPaid both receive the confirmed PaymentJson result, including ok, chainId, receiver, wallet, token, invoiceAmountUsdt, tokenAmount, price, hash, blockNumber, status, and confirmedAt. onSubmitted fires immediately after the transaction is broadcast. PaymentSheet remains available for inline checkout panels, while PaymentModal is the ready-to-use modal wrapper.
All UI is optional: use WalletManager and PaymentService directly when your product needs fully custom buttons, toasts, dialogs, or order flows.
Environment
Configure BSC RPC and token addresses in the host app:
VITE_BSC_CHAIN_ID=56
VITE_BSC_RPC_URLS=https://rpc.supermt-quick.com,https://bsc-dataseed.binance.org
VITE_MT_TOKEN_ADDRESS=0x...
VITE_USDT_TOKEN_ADDRESS=0x...
VITE_PRICE_PROXY_URL=https://mtpay.ai/api/mt-price
VITE_MT_USDT_PRICE=1VITE_PRICE_PROXY_URL is optional. If it is not set, the SDK uses the default MTPAY quote endpoint, https://mtpay.ai/api/mt-price, backed by ave.ai on the MTPAY server. You can override it with your own backend quote endpoint. Keep ave.ai or other price provider API keys on your backend. Do not expose private API keys through frontend VITE_ variables.
Local Development
npm install
npm run dev
npm run build
npm pack --dry-runLicense
MIT
