Kasperia Wallet API Documentation
Integrate Kasperia Wallet by choosing one access mode first: use the injected provider inside the Kasperia App WebView or desktop extension, or use a deep-link request with callback from an external mobile browser. This guide covers connecting accounts, checking networks, reading balances, signing messages, and sending transactions.
window.kasperia for Kaspa native APIs and window.kasperia.ethereum for EVM APIs. New integrations should avoid mixed casing or fallback global names unless a third-party EVM library requires window.ethereum.Kaspa Native
Use window.kasperia to connect a Kaspa account, read network and balance, switch Kaspa network, and send KAS.
EVM
Use window.kasperia.ethereum as an EIP-1193 compatible provider for EVM accounts, chains, RPC, and transactions.
Mobile App
When the dApp is opened inside the Kasperia app, the provider is injected automatically at document start.
Integration Modes
| Mode | When to use | Provider | User confirmation |
|---|---|---|---|
| Mobile In-App Browser | User opens the dApp inside Kasperia App WebView. | window.kasperia and window.kasperia.ethereum | Connect, switch network, signing, and transaction requests are confirmed in the app. |
| External Mobile Browser | User opens the dApp from Safari, Chrome, Telegram, X, or another external app. | No injected provider until the user opens Kasperia App. | Use a deep link or universal link request payload and receive the result by callback. |
| Browser Extension | User opens the dApp in a desktop browser with the Kasperia extension installed. | window.kasperia and window.kasperia.ethereum | Handled by the extension wallet UI. |
Provider Objects
Kasperia exposes one canonical wallet object for dApps:
window.kasperia
For EVM dApps, use the EVM provider under the same namespace:
window.kasperia.ethereum
| Object | Purpose | Use this in new integrations? |
|---|---|---|
window.kasperia | Kaspa native wallet API and shared request entry. | Yes |
window.kasperia.ethereum | EVM EIP-1193 compatible provider. | Yes |
window.ethereum | Compatibility with existing EVM libraries. | Only when a third-party library requires it. |
Quick Start
Most integrations should follow this order:
- Detect the environment. If
window.kasperiaexists, use the injected provider. If it does not exist on mobile, open Kasperia through the external request flow. - Connect after a user click. Use
requestAccounts()for Kaspa oreth_requestAccountsfor EVM. - Check the current network. Read
getNetwork()oreth_chainId. If the user is on the wrong network, call the switch method and wait for confirmation. - Read state. Read the selected account, balance, and network again after connect or switch.
- Submit user actions. Sign messages or send transactions only after the user confirms the action in your UI.
eth_requestAccounts → eth_chainId → wallet_switchEthereumChain if needed → eth_sendTransaction or personal_sign.Copy-paste EVM integration
const KASPLEX_L2_TESTNET = '0x28c64'; // 167012
const KASPLEX_L2_MAINNET = '0x3173b'; // 202555
const BSC_TESTNET = '0x61'; // 97
const BSC_MAINNET = '0x38'; // 56
function getKasperiaWallet() {
return window.kasperia && window.kasperia.isKasperia ? window.kasperia : null;
}
function getKasperiaEvmProvider() {
const wallet = getKasperiaWallet();
return wallet && wallet.ethereum ? wallet.ethereum : null;
}
async function waitForKasperia(timeout = 3000) {
const wallet = getKasperiaWallet();
if (wallet) return wallet;
return new Promise((resolve, reject) => {
const timer = setTimeout(() => reject(new Error('Kasperia provider not found')), timeout);
window.addEventListener('kasperia#initialized', () => {
clearTimeout(timer);
const injected = getKasperiaWallet();
injected ? resolve(injected) : reject(new Error('Kasperia provider not found'));
}, { once: true });
});
}
async function connectEvm() {
await waitForKasperia();
const provider = getKasperiaEvmProvider();
if (!provider) throw new Error('Kasperia EVM provider is not available');
const accounts = await provider.request({ method: 'eth_requestAccounts' });
return { provider, address: accounts[0] };
}
async function ensureEvmChain(provider, targetChainId) {
const currentChainId = await provider.request({ method: 'eth_chainId' });
if (currentChainId.toLowerCase() === targetChainId.toLowerCase()) return;
await provider.request({
method: 'wallet_switchEthereumChain',
params: [{ chainId: targetChainId }]
});
}
async function connectAndPrepareEvm() {
const { provider, address } = await connectEvm();
await ensureEvmChain(provider, KASPLEX_L2_TESTNET);
const balance = await provider.request({
method: 'eth_getBalance',
params: [address, 'latest']
});
return { provider, address, balance };
}
Copy-paste Kaspa native integration
async function connectKaspa() {
const wallet = await waitForKasperia();
const accounts = await wallet.requestAccounts();
const address = accounts[0];
const network = await wallet.getNetwork();
const balance = await wallet.getBalance();
return { wallet, address, network, balance };
}
async function switchKaspaToTestnet10() {
const wallet = await waitForKasperia();
await wallet.switchNetwork('testnet-10');
return await wallet.getNetwork();
}
Mobile Overview
The Kasperia mobile app supports two mobile access paths:
- In-App Browser: the dApp page runs inside Kasperia WebView. The wallet provider is injected automatically.
- External Browser: the dApp runs outside Kasperia. Use a deep link or universal link request to open Kasperia and get a callback response.
In-App Browser
Use this mode when your dApp is opened inside the Kasperia mobile app. The app injects window.kasperia at document start. Your page should wait for the provider, then use the same APIs as the browser extension integration.
waitForKasperia() after the click, then call the account, network, balance, sign, or transaction method required by your product flow.async function initInKasperiaApp() {
const wallet = await waitForKasperia();
// Kaspa native provider
const kaspaAccounts = await wallet.requestAccounts();
// EVM provider
const evmProvider = wallet.ethereum;
const evmAccounts = evmProvider
? await evmProvider.request({ method: 'eth_requestAccounts' })
: [];
return { wallet, kaspaAccounts, evmProvider, evmAccounts };
}
After connection, always re-read the network before showing balances or enabling transaction buttons.
External Browser
Use this mode when the user opens your dApp in Safari, Chrome, Telegram, X, or another external mobile app. In this environment, the page cannot assume that window.kasperia is injected. Instead, create a wallet request, open Kasperia, and receive the result through your callback URL.
Supported request URLs:
kasperia://wallet/request?payload=<base64url-json>
https://link.kasperia.app/wallet/request?payload=<base64url-json>
kasperia://wallet/request and https://link.kasperia.app/wallet/request.External Request Payload
The payload is a JSON object encoded as base64url without padding. Each request should have a unique id. Your callback handler must decode walletResponse and verify that the response id matches the request id.
const payload = {
id: crypto.randomUUID(),
origin: window.location.origin,
method: 'eth_requestAccounts',
params: {},
callback: `${window.location.origin}/wallet-callback`
};
Encode and open the request:
function base64UrlEncodeJson(json) {
const raw = JSON.stringify(json);
const bytes = new TextEncoder().encode(raw);
let binary = '';
bytes.forEach((b) => binary += String.fromCharCode(b));
return btoa(binary)
.replace(/\+/g, '-')
.replace(/\//g, '_')
.replace(/=+$/g, '');
}
function openKasperiaWalletRequest(payload) {
const encoded = base64UrlEncodeJson(payload);
window.location.href = `kasperia://wallet/request?payload=${encoded}`;
}
Kasperia returns the result by appending walletResponse to your callback URL:
https://your-dapp.com/wallet-callback?walletResponse=<base64url-json>
Decoded success response:
{
id: 'request-id',
success: true,
data: ['0x1234...']
}
Decoded error response:
{
id: 'request-id',
success: false,
error: {
code: 4001,
message: 'User rejected the request'
}
}
https or your app scheme. If origin is provided, the callback host should match the origin host.Mobile Support Matrix
| Action | In-App Browser | External Request | Notes |
|---|---|---|---|
| Connect Kaspa | window.kasperia.requestAccounts() | kasperia_requestAccounts | Shows Connect Wallet confirmation if not authorized. |
| Connect EVM | window.kasperia.ethereum.request({ method: 'eth_requestAccounts' }) | eth_requestAccounts | Returns the current EVM address. |
| Get Kaspa network | window.kasperia.getNetwork() | kasperia_getNetwork | Returns current Kaspa network id. |
| Switch Kaspa network | window.kasperia.switchNetwork('mainnet') | kasperia_switchNetwork | Supports mainnet and testnet-10 aliases depending on app config. |
| Switch EVM chain | wallet_switchEthereumChain | wallet_switchEthereumChain | Shows Switch Network confirmation. |
| Get balance | getBalance / eth_getBalance | Supported | EVM token contract balance is not exposed in the current service. |
| Send KAS | sendKaspa | kasperia_sendKaspa | Amount must be in sompi. |
| Send EVM transaction | eth_sendTransaction | eth_sendTransaction | Shows transaction confirmation. |
| Sign message | personal_sign | personal_sign | Typed data v4 is not supported yet. |
Connect Wallet
Requests access to the current Kaspa account. If the site is not authorized, Kasperia shows a Connect Wallet confirmation.
async function connectKaspaWallet() {
const accounts = await window.kasperia.requestAccounts();
const address = accounts[0];
console.log('Kaspa address:', address);
return address;
}
Returns
['kaspa:...']
// or
['kaspatest:...']
Accounts
After the site is connected, use getAccounts to read the current Kaspa address without opening the connect prompt again.
const accounts = await window.kasperia.getAccounts();
const current = await window.kasperia.request({ method: 'kasperia_currentAccount' });
const publicKey = await window.kasperia.getPublicKey();
Current account response
{
id: 'account-id',
name: 'Account 1',
kaspaAddress: 'kaspa:...',
evmAddress: '0x...',
publicKey: '...',
isCurrent: true
}
Network
Use getNetwork for the current Kaspa network and getNetworks for all available Kaspa and EVM networks.
const currentKaspaNetwork = await window.kasperia.getNetwork();
const allNetworks = await window.kasperia.getNetworks();
Switch Kaspa network:
await window.kasperia.switchNetwork('mainnet');
await window.kasperia.switchNetwork('testnet-10');
You can also use the generic request form:
await window.kasperia.request({
method: 'kasperia_switchNetwork',
params: { type: 'kaspa', network: 'testnet-10' }
});
Balance
Read the current Kaspa account balance. The raw unit is sompi and decimals is 8.
const balance = await window.kasperia.getBalance();
console.log(balance.raw, balance.symbol, balance.decimals);
Response
{
type: 'kaspa',
network: 'mainnet',
address: 'kaspa:...',
symbol: 'KAS',
decimals: 8,
total: '100000000',
available: '100000000',
pending: '0',
raw: '100000000'
}
Send KAS
Use sendKaspa to send KAS. The amount must be passed in sompi.
async function sendKas() {
const to = 'kaspa:qp...';
const sompi = '100000000'; // 1 KAS
const txid = await window.kasperia.sendKaspa(to, sompi, {
payload: ''
});
console.log('Kaspa txid:', txid);
}
Generic request form:
const result = await window.kasperia.request({
method: 'kasperia_sendKaspa',
params: {
to: 'kaspa:qp...',
sompi: '100000000',
payload: ''
}
});
Generic Request
window.kasperia.request is the shared low-level request method. It is useful for methods without a convenience wrapper.
const version = await window.kasperia.getVersion();
const result = await window.kasperia.request({
method: 'kasperia_getNetworks',
params: {}
});
| Method | Description | Params |
|---|---|---|
kasperia_requestAccounts | Connect and return Kaspa account. | {} |
kasperia_accounts | Return connected Kaspa account. | {} |
kasperia_currentAccount | Return current account object. | {} |
kasperia_getPublicKey | Return current account public key. | {} |
kasperia_getBalance | Return Kaspa or EVM balance depending on type. | { type, address } |
kasperia_getNetwork | Return current Kaspa network id. | {} |
kasperia_getNetworks | Return available Kaspa and EVM networks. | {} |
kasperia_switchNetwork | Switch Kaspa or EVM network. | { type, network } or { type, chainId } |
kasperia_sendKaspa | Send KAS. | { to, sompi, payload } |
kasperia_disconnect | Revoke site permission. | {} |
Kaspa Events
window.kasperia.on('networkChanged', (network) => {
console.log('Kaspa network changed:', network);
});
window.kasperia.on('accountsChanged', (accounts) => {
console.log('Kaspa accounts changed:', accounts);
});
Get EVM Provider
Use window.kasperia.ethereum as the recommended EVM provider.
function getEvmProvider() {
if (window.kasperia && window.kasperia.ethereum) {
return window.kasperia.ethereum;
}
return null;
}
The provider supports request, send, sendAsync, enable, events, selectedAddress, chainId, and networkVersion.
Connect EVM Account
async function connectEvmWallet() {
const provider = window.kasperia.ethereum;
const accounts = await provider.request({ method: 'eth_requestAccounts' });
return accounts[0];
}
Read connected EVM accounts without prompting:
const accounts = await window.kasperia.ethereum.request({
method: 'eth_accounts'
});
Get / Switch Chain
Read the current EVM chain id. The result is a hex string.
const chainId = await window.kasperia.ethereum.request({
method: 'eth_chainId'
});
console.log(chainId); // example: '0x28c64' = 167012
Switch EVM chain. Kasperia will show a Switch Network confirmation sheet in the app.
await window.kasperia.ethereum.request({
method: 'wallet_switchEthereumChain',
params: [{ chainId: '0x28c64' }]
});
wallet_addEthereumChain is treated as a switch request to an already configured chain. The current app implementation does not add arbitrary new RPC networks from dApp params.
Get EVM Balance
Use eth_getBalance to read the native EVM balance. The result is a hex quantity.
const address = '0x...';
const balanceHex = await window.kasperia.ethereum.request({
method: 'eth_getBalance',
params: [address, 'latest']
});
You can also use the Kasperia generic request form:
const balance = await window.kasperia.request({
method: 'kasperia_getBalance',
params: {
type: 'evm',
address: '0x...'
}
});
Send EVM Transaction
Use eth_sendTransaction for EVM transfers or contract calls. The app will show a transaction confirmation sheet before submitting the transaction.
async function sendEvmTransaction() {
const provider = window.kasperia.ethereum;
const [from] = await provider.request({ method: 'eth_requestAccounts' });
const txHash = await provider.request({
method: 'eth_sendTransaction',
params: [{
from,
to: '0x0000000000000000000000000000000000000000',
value: '0x0',
data: '0x'
}]
});
console.log('EVM tx hash:', txHash);
}
from address must match the current Kasperia EVM account. If it does not match, the request will fail with invalid params.For native transfers without custom gas or data, you may use the generic request form:
const result = await window.kasperia.request({
method: 'kasperia_sendTransaction',
params: {
type: 'evm',
to: '0x...',
amount: '0.01'
}
});
Sign Message
The current mobile implementation supports personal_sign.
const provider = window.kasperia.ethereum;
const [address] = await provider.request({ method: 'eth_requestAccounts' });
const signature = await provider.request({
method: 'personal_sign',
params: ['Hello Kasperia', address]
});
Generic request form:
const signed = await window.kasperia.request({
method: 'kasperia_signMessage',
params: {
message: 'Hello Kasperia',
address: '0x...'
}
});
Read-only RPC
The mobile app proxies common read-only EVM RPC calls through the current selected EVM network RPC URL.
const blockNumber = await window.kasperia.ethereum.request({
method: 'eth_blockNumber'
});
EVM Events
const provider = window.kasperia.ethereum;
provider.on('accountsChanged', (accounts) => {
console.log('EVM accounts changed:', accounts);
});
provider.on('chainChanged', (chainId) => {
console.log('EVM chain changed:', chainId);
});
provider.on('connect', ({ chainId }) => {
console.log('Connected:', chainId);
});
provider.on('disconnect', (error) => {
console.log('Disconnected:', error);
});
QR Scan Link Overview
Kasperia can scan a QR code, parse its text content, and open the matching app page with pre-filled parameters. QR scan links are intended to guide the user to the correct screen; they do not silently send funds. The user still reviews and confirms the action inside the app.
krc20://transfer?... , a Kasperia app route such as kasperia://bridge, an EVM transfer URL, or a normal https:// dApp URL.Open Send KAS and pre-fill the recipient, amount, and optional payload.
Open a Kasperia app page such as Bridge, KRC20 token list, or Ecosystem Fund.
Open KRC20 transfer, mint, or token detail flows.
Open an EVM native-token or contract-token transfer page. chainId is required.
Open a dApp URL inside the Kasperia WebView.
General QR Link Format
Use URL query parameters for optional values. Always URL-encode user-generated text, especially payloads, spaces, symbols, and non-English characters.
| Parameter | Used by | Description | Example |
|---|---|---|---|
to / address | KAS, Bridge, KRC20, EVM | Recipient address. For Kaspa and KRC20, the address prefix must match the current Kaspa network. | to=kaspatest:... |
amount | KAS, Bridge, KRC20, EVM | Optional amount used to pre-fill the target page. Use a human-readable decimal value unless your own UI clearly tells users otherwise. | amount=5 |
payload | KAS | Optional Kaspa transaction payload. Encode it with encodeURIComponent. | payload=hello |
tick | KRC20 | KRC20 ticker symbol. Required for KRC20 transfer and mint. | tick=JEMES |
chainId | EVM | Required EVM chain id. The app must already have a matching network config. | chainId=56 |
token | EVM | Optional ERC20 contract address. If omitted, the app opens the native-token transfer flow. | token=0x... |
targetAmount | Ecosystem Fund | Optional target amount for the Ecosystem Fund page. | targetAmount=100 |
? after the route and & between parameters. Raw Kaspa address links may also use the compact form shown below, but query-style links are easier for developers to generate and debug.KAS Transfer QR
A Kaspa QR can contain only a recipient address, or it can include amount and payload. Scanning the QR opens the Send KAS page with the parsed values pre-filled.
kaspatest:qr24daqennp22ang7flqyzn47wrhn90vgvgnem92tk78ga3teewcgyngg85ey
kaspatest:qr24daqennp22ang7flqyzn47wrhn90vgvgnem92tk78ga3teewcgyngg85ey&amount=5
kaspatest:qr24daqennp22ang7flqyzn47wrhn90vgvgnem92tk78ga3teewcgyngg85ey&amount=5&payload=haha
Alternative query-style format:
kaspa://transfer?to=kaspatest:qr24daqennp22ang7flqyzn47wrhn90vgvgnem92tk78ga3teewcgyngg85ey&amount=5&payload=haha
Generate a KAS transfer QR string:
function buildKasTransferQr({ to, amount, payload }) {
const params = new URLSearchParams();
params.set('to', to);
if (amount !== undefined && amount !== '') params.set('amount', String(amount));
if (payload) params.set('payload', payload);
return `kaspa://transfer?${params.toString()}`;
}
const qrText = buildKasTransferQr({
to: 'kaspatest:qr24daqennp22ang7flqyzn47wrhn90vgvgnem92tk78ga3teewcgyngg85ey',
amount: 5,
payload: 'haha'
});
Kasperia App Pages
Use the kasperia:// scheme to open supported Kasperia app pages. This is useful for QR codes printed on websites, campaigns, bridge pages, or offline materials.
| QR content | Supported parameters | Result in app |
|---|---|---|
kasperia://bridge | to, address, amount | Open the Bridge page. If recipient or amount is provided, the page receives them as initial values. |
kasperia://bridge?to=kaspatest:...&amount=5 | to, amount | Open Bridge with recipient and amount pre-filled. |
kasperia://krc20_tokens | None | Open the KRC20 token list page. |
kasperia://eco_system_fund?to=kaspatest:...&amount=5&targetAmount=100 | to / address, amount, targetAmount | Open the Ecosystem Fund page with receive address and amounts. |
kasperia://bridge?to=kaspatest:qr24daqennp22ang7flqyzn47wrhn90vgvgnem92tk78ga3teewcgyngg85ey&amount=5
KRC20 Transfer / Mint QR
Use the krc20:// scheme for KRC20 token actions. The app checks the current Kaspa network, looks up the current account token data, and opens the matching KRC20 page.
| Action | QR content | Required parameters | Result in app |
|---|---|---|---|
| Transfer | krc20://transfer?tick=JEMES&to=kaspatest:...&amount=5 | tick, optional to, optional amount | Open KRC20 Send page for the ticker. |
| Mint | krc20://mint?tick=JEMES&to=kaspatest:...&amount=5 | tick, optional to, optional amount | Open KRC20 Mint page. If to is missing, the current account Kaspa address is used. |
| Token detail | krc20://token?tick=JEMES | tick | Open the KRC20 token detail page if the current account has token data. |
Examples:
krc20://transfer?tick=JEMES&to=kaspatest:qr24daqennp22ang7flqyzn47wrhn90vgvgnem92tk78ga3teewcgyngg85ey&amount=5
krc20://mint?tick=JEMES&to=kaspatest:qr24daqennp22ang7flqyzn47wrhn90vgvgnem92tk78ga3teewcgyngg85ey&amount=5
krc20://token?tick=JEMES
function buildKrc20TransferQr({ tick, to, amount }) {
const params = new URLSearchParams();
params.set('tick', tick);
if (to) params.set('to', to);
if (amount !== undefined && amount !== '') params.set('amount', String(amount));
return `krc20://transfer?${params.toString()}`;
}
EVM Transfer QR
Use the ethereum://transfer scheme to open the EVM Send page. chainId is required. If token is omitted, Kasperia opens the native-token transfer flow for that chain. If token is provided, Kasperia treats it as a contract token address and opens the token transfer flow.
ethereum://transfer?chainId=56&to=0xEe461548B7CA5b4A1C9E4c078054BD047b8786c1&amount=1.5
ethereum://transfer?chainId=56&token=0x1234567890abcdef1234567890abcdef12345678&to=0xEe461548B7CA5b4A1C9E4c078054BD047b8786c1&amount=100
chainId. If the chain id is missing or not configured, the app will show an error instead of opening the send page.function buildEvmTransferQr({ chainId, to, amount, token }) {
const params = new URLSearchParams();
params.set('chainId', String(chainId));
params.set('to', to);
if (amount !== undefined && amount !== '') params.set('amount', String(amount));
if (token) params.set('token', token);
return `ethereum://transfer?${params.toString()}`;
}
Open dApp URL QR
If the scanned QR content is a normal web URL, Kasperia opens it inside the app WebView. The dApp can then use window.kasperia and window.kasperia.ethereum after provider injection.
https://kas.fun/
https://kasbridge-tn10evm-m.kaspafoundation.org/
Recommended dApp behavior after being opened from a QR:
async function initAfterQrOpen() {
const wallet = await ensureKasperiaReady();
const accounts = await wallet.requestAccounts();
const network = await wallet.getNetwork();
return { accounts, network };
}
QR Builder Examples
Developers can generate QR codes with any QR library as long as the encoded content is the exact plain-text link.
import QRCode from 'qrcode';
const qrText = 'krc20://transfer?tick=JEMES&to=kaspatest:qr24daqennp22ang7flqyzn47wrhn90vgvgnem92tk78ga3teewcgyngg85ey&amount=5';
const dataUrl = await QRCode.toDataURL(qrText);
document.querySelector('#qr').src = dataUrl;
Plain JavaScript helper for building links safely:
const KAS_TEST_ADDRESS = 'kaspatest:qr24daqennp22ang7flqyzn47wrhn90vgvgnem92tk78ga3teewcgyngg85ey';
const examples = {
kasWithoutAmount: KAS_TEST_ADDRESS,
kasWithAmount: `${KAS_TEST_ADDRESS}&amount=5`,
kasWithPayload: `${KAS_TEST_ADDRESS}&amount=5&payload=${encodeURIComponent('haha afasdfsdafasdf')}`,
bridge: `kasperia://bridge?to=${encodeURIComponent(KAS_TEST_ADDRESS)}&amount=5`,
krc20Transfer: `krc20://transfer?tick=JEMES&to=${encodeURIComponent(KAS_TEST_ADDRESS)}&amount=5`,
krc20Mint: `krc20://mint?tick=JEMES&to=${encodeURIComponent(KAS_TEST_ADDRESS)}&amount=5`,
evmTransfer: 'ethereum://transfer?chainId=56&to=0xEe461548B7CA5b4A1C9E4c078054BD047b8786c1&amount=1.5',
dapp: 'https://kas.fun/'
};
Validation Notes
- Scanning a payment QR opens a pre-filled app page; the user must still confirm the transfer or mint operation.
- For Kaspa and KRC20 links, the recipient address prefix must match the current Kaspa network. A
kaspatest:address should be used on testnet, and akaspa:address should be used on mainnet. - For KRC20 actions,
tickis required. If the token cannot be found for the current account, the app shows an error. - For EVM transfer links,
chainIdis required and must exist in the app network config. - Use
encodeURIComponentorURLSearchParamsfor payloads and addresses when generating QR links from JavaScript. - Avoid putting private keys, seed phrases, passwords, or long sensitive data inside QR codes.
- Unsupported or unknown protocols should be treated as invalid QR content by the dApp or campaign page.
Network Reference
Use window.kasperia.getNetworks() to get the exact networks configured in the current app build. A network item may include the following fields:
{
type: 'evm',
id: '167012',
name: 'Kasplex L2 Testnet',
isCurrent: true,
chainId: 167012,
rpcUrl: 'https://...',
explorerUrl: 'https://...',
symbol: 'KAS',
decimals: 18
}
getNetworks() and then switching to a chain that exists in the returned list.Error Codes
| Code | Meaning | Common reason |
|---|---|---|
4001 | User rejected | User tapped Cancel, Reject, or closed the request. |
4100 | Unauthorized | The site is not connected to Kasperia Wallet. |
4200 | Unsupported method | The method is not exposed by the current app service. |
4900 | Disconnected | The wallet provider was disconnected. |
-32602 | Invalid params | Missing address, invalid chain id, invalid transaction params, or mismatched from address. |
-32603 | Internal error | Wallet bridge, RPC, or transaction service failed. |
try {
await window.kasperia.ethereum.request({
method: 'wallet_switchEthereumChain',
params: [{ chainId: '0x28c64' }]
});
} catch (error) {
if (error.code === 4001) {
console.log('User rejected the request');
} else {
console.error(error.code, error.message, error.data);
}
}
Best Practices
- Use
window.kasperiaas the single canonical namespace in your dApp. - Use
window.kasperia.ethereumfor EVM requests instead of mixing multiple provider names. - Always call connect, switch network, signing, and transaction APIs from a user click or similar direct action.
- Disable your button while a wallet request is pending to avoid duplicate confirmation sheets.
- After switching EVM chains, re-read
eth_chainIdand update your UI from thechainChangedevent. - Pass EVM transaction
value,gas,gasPrice, andnonceas hex quantities. - Pass Kaspa transfer amounts in sompi, not decimal KAS.
- For external callback flows, generate a unique
idfor every request and verify the response id.
Unsupported Methods
| Method | Status | Recommendation |
|---|---|---|
kasperia_submitCommitReveal | Not supported in mobile WebView yet. | Do not expose KNS/KRC commit-reveal flows through the mobile dApp API until app service support is added. |
kasperia_signTransaction | Not exposed by current wallet services. | Use send transaction flows that show confirmation and submit through the app. |
eth_signTypedData_v4 | Not supported yet. | Use personal_sign only if your use case allows it. |
| ERC20 balance by contract | Not exposed by current mobile service. | Use read-only RPC calls or your own RPC/indexer for token balances. |
KASPERIA