@alien-id/miniapps-solana-provider
v1.3.5
Published
Solana wallet provider for Alien miniapps. Implements the [Wallet Standard](https://github.com/wallet-standard/wallet-standard) so the Alien Wallet is auto-discovered by `@solana/wallet-adapter` — no manual adapter config needed.
Downloads
456
Keywords
Readme
@alien-id/miniapps-solana-provider
Solana wallet provider for Alien miniapps. Implements the Wallet Standard so the Alien Wallet is auto-discovered by @solana/wallet-adapter — no manual adapter config needed.
Runs inside the Alien app WebView only. The provider communicates with the host app's native wallet through the miniapp bridge (
window.__miniAppsBridge__).
Install
bun add @alien-id/miniapps-solana-providerIf you use @solana/wallet-adapter-react (most common setup), you also need:
bun add @solana/wallet-adapter-react @solana/wallet-adapter-react-ui @solana/web3.jsQuick Start
1. Register the wallet
Call initAlienWallet() once at your app's entry point, before rendering any wallet UI. This registers Alien Wallet with the wallet-standard registry so adapters can discover it.
// src/main.tsx
import { initAlienWallet } from '@alien-id/miniapps-solana-provider';
initAlienWallet();2. Set up providers (React)
Use the standard Solana wallet adapter providers. Pass an empty array to wallets — Alien Wallet is discovered automatically via wallet-standard.
// src/App.tsx
import { ConnectionProvider, WalletProvider } from '@solana/wallet-adapter-react';
import { WalletModalProvider } from '@solana/wallet-adapter-react-ui';
const RPC_URL = 'https://api.mainnet-beta.solana.com';
function App() {
return (
<ConnectionProvider endpoint={RPC_URL}>
<WalletProvider wallets={[]} autoConnect>
<WalletModalProvider>
<YourApp />
</WalletModalProvider>
</WalletProvider>
</ConnectionProvider>
);
}3. Use the wallet
Use useWallet() as you normally would with any Solana wallet adapter:
import { useWallet } from '@solana/wallet-adapter-react';
import { useConnection } from '@solana/wallet-adapter-react';
import { Transaction, SystemProgram, PublicKey, LAMPORTS_PER_SOL } from '@solana/web3.js';
function SendSol() {
const { publicKey, sendTransaction, signMessage } = useWallet();
const { connection } = useConnection();
async function handleSend() {
if (!publicKey) return;
const tx = new Transaction().add(
SystemProgram.transfer({
fromPubkey: publicKey,
toPubkey: new PublicKey('RECIPIENT_ADDRESS'),
lamports: 0.01 * LAMPORTS_PER_SOL,
}),
);
const signature = await sendTransaction(tx, connection);
console.log('Sent:', signature);
}
async function handleSignMessage() {
if (!signMessage) return;
const message = new TextEncoder().encode('Hello from Alien!');
const signature = await signMessage(message);
console.log('Signed:', signature);
}
return (
<div>
<p>Connected: {publicKey?.toBase58()}</p>
<button onClick={handleSend}>Send 0.01 SOL</button>
<button onClick={handleSignMessage}>Sign Message</button>
</div>
);
}Supported Features
| Feature | Description |
|---|---|
| standard:connect | Connect to the wallet, returns the public key |
| standard:disconnect | Disconnect from the wallet |
| standard:events | Listen for account changes |
| solana:signTransaction | Sign a transaction without broadcasting |
| solana:signAndSendTransaction | Sign and broadcast a transaction |
| solana:signMessage | Sign an arbitrary message (Ed25519) |
Supported chains: solana:mainnet, solana:devnet, solana:testnet
Supported transaction versions: legacy, 0 (versioned transactions)
Without React
You can use AlienSolanaWallet directly if you're not using React:
import { AlienSolanaWallet } from '@alien-id/miniapps-solana-provider';
const wallet = new AlienSolanaWallet();
// Connect
const { accounts } = await wallet.features['standard:connect'].connect();
const account = accounts[0];
console.log('Address:', account.address);
// Sign and send a transaction
const { signature } = (
await wallet.features['solana:signAndSendTransaction'].signAndSendTransaction({
account,
transaction: serializedTxBytes, // Uint8Array
chain: 'solana:mainnet',
})
)[0];Error Handling
All wallet operations throw AlienWalletError on failure. The code property indicates what went wrong:
import { AlienWalletError } from '@alien-id/miniapps-solana-provider';
import { WALLET_ERROR } from '@alien-id/miniapps-contract';
try {
await sendTransaction(tx, connection);
} catch (err) {
if (err instanceof AlienWalletError) {
switch (err.code) {
case WALLET_ERROR.USER_REJECTED: // 5000
// User rejected the request in the Alien app
break;
case WALLET_ERROR.INVALID_PARAMS: // -32602
// Malformed input (e.g. invalid transaction)
break;
case WALLET_ERROR.INTERNAL_ERROR: // -32603
// Host-side internal/send failure
break;
case WALLET_ERROR.REQUEST_EXPIRED: // 8000
// Host app did not respond in time
break;
}
}
}How It Works
sequenceDiagram
participant Miniapp as Miniapp (WebView)
participant Bridge as Bridge Layer
participant Host as Alien App (Native)
Miniapp->>Bridge: wallet.features['standard:connect'].connect()
Bridge->>Host: wallet.solana:connect (via postMessage)
Host-->>Bridge: wallet.solana:connect.response { publicKey }
Bridge-->>Miniapp: { accounts: [{ address, publicKey }] }
Miniapp->>Bridge: wallet.features['solana:signAndSendTransaction'].signAndSendTransaction(...)
Bridge->>Host: wallet.solana:sign.send { transaction (base64) }
Host->>Host: Sign with user's key, broadcast to Solana
Host-->>Bridge: wallet.solana:sign.send.response { signature }
Bridge-->>Miniapp: { signature: Uint8Array }The provider encodes all data (transactions, messages) as base64 for the bridge, and decodes responses back to Uint8Array for the wallet-standard interface. Public keys and transaction signatures use base58 encoding in bridge messages.
Contract Version
The wallet methods require contract version 1.0.0 or higher. Use useIsMethodSupported from @alien-id/miniapps-react to check compatibility before using wallet features:
import { useIsMethodSupported } from '@alien-id/miniapps-react';
function WalletFeature() {
const { supported, minVersion } = useIsMethodSupported('wallet.solana:connect');
if (!supported) {
return <p>Please update Alien App to v{minVersion} or later.</p>;
}
return <WalletUI />;
}If the bridge is unavailable, initAlienWallet() returns without
registering. If the contract version is too old, it logs a warning and
does not register.
API Reference
initAlienWallet()
Registers the Alien Wallet with the wallet-standard registry. Call once at app startup. Safe to call multiple times (no-op after first call).
AlienSolanaWallet
The wallet class implementing the Wallet interface from @wallet-standard/base. You only need this for non-React usage or advanced scenarios.
AlienSolanaAccount
Implements WalletAccount. Created internally on connect. Properties:
address— base58 public key stringpublicKey—Uint8Array(32 bytes)chains—['solana:mainnet', 'solana:devnet', 'solana:testnet']features—['solana:signTransaction', 'solana:signAndSendTransaction', 'solana:signMessage']
AlienWalletError
Error class thrown by wallet operations. Properties:
code—WalletSolanaErrorCode(5000 | -32602 | -32603 | 8000)message— Human-readable error description
