Plugin API Guide
GMBOX's plugin system allows developers to extend the wallet's functionality while maintaining security and user experience standards. This guide covers everything you need to build powerful plugins for the GMBOX ecosystem.
Overview
Plugin Architecture
GMBOX plugins are built using a secure, sandboxed architecture that provides:
- Isolated Execution: Plugins run in separate contexts for security
- Controlled API Access: Limited, permission-based access to wallet functionality
- React-Based UI: Modern component-based user interfaces
- TypeScript Support: Full type safety and excellent developer experience
Plugin Types
UI Plugins
- Dashboard widgets and custom views
- New pages and navigation items
- Modal dialogs and overlays
- Custom settings panels
Background Plugins
- Transaction monitoring and analysis
- Automated trading strategies
- Data synchronization services
- Notification systems
Integration Plugins
- External service connections
- API integrations
- Protocol-specific tools
- Custom blockchain support
Getting Started
Prerequisites
- Node.js 18+ and npm/yarn
- TypeScript knowledge
- React experience
- Basic understanding of blockchain concepts
Development Environment Setup
# Install the GMBOX Plugin CLI
npm install -g @walletname/plugin-cli
# Create a new plugin project
npx create-walletname-plugin my-awesome-plugin
# Navigate to the project directory
cd my-awesome-plugin
# Install dependencies
npm install
# Start development server
npm run dev
Project Structure
my-awesome-plugin/
├── src/
│ ├── components/ # React components
│ ├── hooks/ # Custom React hooks
│ ├── types/ # TypeScript type definitions
│ ├── utils/ # Utility functions
│ └── index.tsx # Plugin entry point
├── manifest.json # Plugin configuration
├── package.json # Dependencies and scripts
└── README.md # Plugin documentation
Plugin Manifest
The manifest.json
file defines your plugin's metadata and permissions:
{
"name": "my-awesome-plugin",
"version": "1.0.0",
"displayName": "My Awesome Plugin",
"description": "A plugin that does awesome things",
"author": "Your Name",
"homepage": "https://github.com/username/my-awesome-plugin",
"main": "src/index.tsx",
"permissions": [
"wallet:read",
"transactions:read",
"network:external"
],
"supportedChains": ["ethereum", "polygon", "bsc"],
"category": "trading",
"tags": ["defi", "analytics", "portfolio"]
}
Permission System
Core Permissions
wallet:read
- Read wallet addresses and balanceswallet:write
- Request transaction signaturestransactions:read
- Access transaction historytransactions:write
- Submit new transactionsnetwork:external
- Make external HTTP requestsstorage:local
- Store data locallynotifications:show
- Display notifications
Advanced Permissions
contracts:deploy
- Deploy smart contractskeys:derive
- Derive new addressesbackup:create
- Create wallet backupssettings:modify
- Modify wallet settings
Core API Reference
Wallet API
import { walletAPI } from '@walletname/plugin-api';
// Get wallet information
const wallets = await walletAPI.getWallets();
const activeWallet = await walletAPI.getActiveWallet();
// Get balances
const balances = await walletAPI.getBalances('ethereum');
const tokenBalance = await walletAPI.getTokenBalance(
'ethereum',
'0x742d35Cc6634C0532925a3b8D6Bd4796C7CB6c5c', // token address
'0x...' // wallet address
);
// Get addresses
const addresses = await walletAPI.getAddresses('ethereum');
const newAddress = await walletAPI.generateAddress('ethereum');
Transaction API
import { transactionAPI } from '@walletname/plugin-api';
// Get transaction history
const transactions = await transactionAPI.getTransactions({
chain: 'ethereum',
address: '0x...',
limit: 50
});
// Send a transaction
const txRequest = {
to: '0x742d35Cc6634C0532925a3b8D6Bd4796C7CB6c5c',
value: '1000000000000000000', // 1 ETH in wei
gasLimit: '21000',
gasPrice: '20000000000' // 20 gwei
};
const txHash = await transactionAPI.sendTransaction('ethereum', txRequest);
// Sign a message
const signature = await transactionAPI.signMessage('Hello World!');
Network API
import { networkAPI } from '@walletname/plugin-api';
// Get network information
const networks = await networkAPI.getSupportedNetworks();
const currentNetwork = await networkAPI.getCurrentNetwork();
// Switch networks
await networkAPI.switchNetwork('polygon');
// Make external requests (requires network:external permission)
const response = await networkAPI.httpRequest({
url: 'https://api.coingecko.com/api/v3/simple/price',
method: 'GET',
params: {
ids: 'ethereum',
vs_currencies: 'usd'
}
});
Storage API
import { storageAPI } from '@walletname/plugin-api';
// Store data locally
await storageAPI.set('user-preferences', {
theme: 'dark',
notifications: true
});
// Retrieve data
const preferences = await storageAPI.get('user-preferences');
// Remove data
await storageAPI.remove('old-data');
// Clear all plugin data
await storageAPI.clear();
UI API
import { uiAPI } from '@walletname/plugin-api';
// Show notifications
uiAPI.showNotification({
title: 'Transaction Complete',
message: 'Your swap was successful!',
type: 'success'
});
// Show modal dialogs
const result = await uiAPI.showModal({
title: 'Confirm Action',
content: 'Are you sure you want to proceed?',
buttons: ['Cancel', 'Confirm']
});
// Register menu items
uiAPI.registerMenuItem({
id: 'my-plugin-menu',
label: 'My Plugin',
icon: 'plugin-icon',
onClick: () => {
// Handle menu click
}
});
React Components and Hooks
Built-in Components
GMBOX provides a set of pre-built components for consistent UI:
import {
Button,
Card,
Input,
Modal,
Toast,
Spinner,
TokenIcon,
AddressDisplay,
BalanceDisplay
} from '@walletname/plugin-ui';
function MyComponent() {
return (
<Card>
<TokenIcon symbol="ETH" size="large" />
<AddressDisplay
address="0x742d35Cc6634C0532925a3b8D6Bd4796C7CB6c5c"
copyable
short
/>
<BalanceDisplay
balance="1.5"
symbol="ETH"
fiatValue="2400.50"
currency="USD"
/>
<Button variant="primary" onClick={() => {}}>
Execute Action
</Button>
</Card>
);
}
Custom Hooks
import {
useWallet,
useTransactions,
useBalance,
useNetwork,
useStorage
} from '@walletname/plugin-hooks';
function MyPluginComponent() {
const { activeWallet, switchWallet } = useWallet();
const { balance, loading, error } = useBalance('ethereum');
const { transactions } = useTransactions({ chain: 'ethereum' });
const { network, switchNetwork } = useNetwork();
const [settings, setSettings] = useStorage('plugin-settings', {});
// Your component logic here
}
Advanced Features
Smart Contract Interaction
import { contractAPI } from '@walletname/plugin-api';
// Deploy a contract
const deployedContract = await contractAPI.deployContract({
chain: 'ethereum',
bytecode: '0x608060405234801561001057600080fd5b50...',
abi: [...],
constructorArgs: ['Hello', 'World']
});
// Interact with existing contracts
const contract = contractAPI.getContract({
address: '0x742d35Cc6634C0532925a3b8D6Bd4796C7CB6c5c',
abi: [...],
chain: 'ethereum'
});
// Call read-only functions
const result = await contract.call('balanceOf', ['0x...']);
// Send transactions
const txHash = await contract.send('transfer', [
'0x...', // recipient
'1000000000000000000' // amount
]);
Event Handling
import { eventAPI } from '@walletname/plugin-api';
// Listen for new transactions
eventAPI.on('transaction:new', (transaction) => {
console.log('New transaction:', transaction);
});
// Listen for balance changes
eventAPI.on('balance:changed', ({ chain, address, balance }) => {
console.log(`Balance changed for ${address} on ${chain}: ${balance}`);
});
// Listen for network changes
eventAPI.on('network:changed', (network) => {
console.log('Network changed to:', network);
});
// Custom event handling
eventAPI.emit('my-plugin:custom-event', { data: 'example' });
Background Processing
import { backgroundAPI } from '@walletname/plugin-api';
// Register background tasks
backgroundAPI.registerTask('price-monitor', {
interval: 60000, // 1 minute
handler: async () => {
// Fetch and process price data
const prices = await fetchPrices();
await storageAPI.set('latest-prices', prices);
}
});
// One-time background operations
backgroundAPI.scheduleTask('data-sync', {
delay: 5000, // 5 seconds
handler: async () => {
await syncUserData();
}
});
Testing and Debugging
Local Development
# Start the development server
npm run dev
# Run tests
npm test
# Build for production
npm run build
# Validate plugin
npm run validate
Testing Framework
import { createPluginTestEnvironment } from '@walletname/plugin-testing';
describe('My Plugin', () => {
let testEnv;
beforeEach(async () => {
testEnv = await createPluginTestEnvironment();
});
it('should handle wallet connection', async () => {
const wallet = await testEnv.connectWallet({
address: '0x742d35Cc6634C0532925a3b8D6Bd4796C7CB6c5c',
balance: '1000000000000000000'
});
expect(wallet.address).toBe('0x742d35Cc6634C0532925a3b8D6Bd4796C7CB6c5c');
});
});
Publishing and Distribution
Plugin Marketplace
-
Prepare for Submission
npm run build npm run validate npm run package
-
Submit to Marketplace
- Upload your plugin package
- Provide detailed description and screenshots
- Submit for security review
-
Review Process
- Automated security scanning
- Manual code review
- User experience evaluation
- Final approval and publication
Direct Distribution
# Generate distributable package
npm run package
# The output will be a .wplugin file
# Users can install via: GMBOX > Settings > Plugins > Install from File
Best Practices
Security
- Minimize Permissions: Only request permissions you actually need
- Validate Input: Always validate user input and external data
- Secure Storage: Encrypt sensitive data before storing
- Error Handling: Implement proper error handling and recovery
Performance
- Efficient Updates: Use React best practices for performance
- Background Processing: Offload heavy operations to background tasks
- Caching: Cache frequently accessed data
- Memory Management: Clean up resources and event listeners
User Experience
- Responsive Design: Support different screen sizes
- Accessibility: Follow accessibility guidelines
- Clear Feedback: Provide clear status indicators and error messages
- Documentation: Include clear usage instructions
Example Plugins
Simple Balance Monitor
import React, { useEffect, useState } from 'react';
import { useBalance, useWallet } from '@walletname/plugin-hooks';
import { Card, BalanceDisplay } from '@walletname/plugin-ui';
export default function BalanceMonitor() {
const { activeWallet } = useWallet();
const { balance } = useBalance('ethereum');
const [threshold, setThreshold] = useState(1.0);
useEffect(() => {
if (balance && parseFloat(balance) < threshold) {
// Show low balance notification
uiAPI.showNotification({
title: 'Low Balance Warning',
message: `Your ETH balance is below ${threshold} ETH`,
type: 'warning'
});
}
}, [balance, threshold]);
return (
<Card title="Balance Monitor">
<BalanceDisplay balance={balance} symbol="ETH" />
<input
type="number"
value={threshold}
onChange={(e) => setThreshold(parseFloat(e.target.value))}
placeholder="Warning threshold"
/>
</Card>
);
}
Support and Resources
- Documentation: docs.walletname.com/plugins
- API Reference: api.walletname.com
- SDK Repository: github.com/walletname/plugin-sdk
- Developer Discord: discord.gg/walletname-dev
- Example Plugins: github.com/walletname/example-plugins
Ready to build your first plugin? Start with our plugin template and join our developer community for support and collaboration.