Integrate the Alpaca Wallet browser extension into your dApp. Let users connect their wallet, sign transactions, and interact with the Keeta blockchain — all through a simple JavaScript API.
The Alpaca Wallet extension injects window.alpaca into approved domains only. To integrate, contact us so we can whitelist your domain in the extension manifest.
Once approved, the extension's content script runs on your site and exposes the full provider API. No SDK to install — just check for window.alpaca and start calling methods.
Your users need the Alpaca Wallet extension installed. If window.alpaca is undefined, prompt them to install it.
Three steps to integrate.
Contact us to whitelist your domain in the extension manifest
Check for window.alpaca and call connect() to get the user's address
Use the API to sign transactions, query balances, and listen for events
The extension injects its provider synchronously at document_start. Check for it after your page loads.
if (window.alpaca) {
// Extension is installed and your domain is whitelisted
const { address, connected } = await window.alpaca.connect();
} else {
// Prompt user to install the Alpaca Wallet extension
} Every method returns a Promise. All token amounts are raw BigInt strings — apply the token's decimal places before displaying to the user.
Connect to the wallet and get the active account address. The wallet must be unlocked — if locked, the user will be prompted to unlock it.
const { address, connected } = await window.alpaca.connect(); Response
{
address: "keeta_abc123...", // Active wallet address
connected: true // Always true on success
} Disconnect the wallet. Locks the session and clears the active connection. Triggers the disconnect event.
await window.alpaca.disconnect(); Response
{ disconnected: true } Lightweight check — returns the current connection state without triggering a connect flow. Use this to restore UI state on page load.
const { connected, address } = await window.alpaca.isConnected();
if (connected) {
// Restore connected UI, address is available
} Response
{
connected: true,
address: "keeta_abc123..." // null if not connected
} Returns the network the wallet is currently configured for. Always pass this network value through your service calls — never assume mainnet.
const { network } = await window.alpaca.getNetwork();
// network: "main" or "test" Response
{ network: "main" } Query on-chain balances. Pass a token address for a single token, or omit it to get all balances. Returns raw BigInt strings — apply the token's decimal places before displaying.
Single token
const result = await window.alpaca.getBalance("keeta_anqdi..."); Response
{
address: "keeta_abc123...", // Wallet address
network: "main",
tokenAddress: "keeta_anqdi...", // Queried token
balance: "1500000000000000000" // Raw BigInt string
} All balances
const result = await window.alpaca.getBalance(); Response
{
address: "keeta_abc123...",
network: "main",
balances: [
{ tokenAddress: "keeta_anqdi...", balance: "1500000000000000000" },
{ tokenAddress: "keeta_ao55q...", balance: "50000000000000000000" }
]
} Sign an arbitrary UTF-8 message with the active account's private key. Useful for proof-of-ownership, login challenges, or off-chain attestations. The private key never leaves the extension.
const { signature, address } = await window.alpaca.signMessage("Login to MyDapp"); Response
{
signature: "a1b2c3d4...", // Hex-encoded detached signature
address: "keeta_abc123..." // Signer address
} Sign a transaction block without broadcasting it. Your backend is responsible for submitting the signed block to the network. Supports three transaction types.
const signedBase64 = await window.alpaca.signTransaction({
type: "SWAP",
params: {
network: "main",
poolAddress: "keeta_pool...", // Pool account address
tokenIn: "keeta_token1...", // Token being sent
tokenOut: "keeta_token2...", // Token being received
amountIn: "1000000000000000000", // Raw amount in
minAmountOut: "950000000000000000", // Slippage-protected minimum
estimatedFees: "50000000000000000", // Network fee amount
feeToken: "keeta_kta..." // Fee token address (usually KTA)
}
});
// Returns: "base64-encoded-signed-block" Response
"eyJhbGciOi..." // Base64-encoded signed block — submit to your backend const signedBase64 = await window.alpaca.signTransaction({
type: "SEND",
params: {
network: "main",
to: "keeta_recipient...",
token: "keeta_token...",
amount: "5000000000000000000"
}
});
// Returns: "base64-encoded-signed-block" const { base64, hash } = await window.alpaca.signTransaction({
type: "FUND",
params: {
network: "main",
to: "keeta_recipient...",
token: "keeta_token...",
amount: "100000000000000000",
previous: "abc123..." // Optional: chain to a prior block hash
}
}); Response
{
base64: "eyJhbGciOi...", // Signed block (not broadcast)
hash: "def456..." // Block hash (use as 'previous' for chaining)
} Sign and broadcast in one step. The extension builds the block, signs it, and publishes it directly to the Keeta network. Use this for simple sends where your backend doesn't need to orchestrate the publish.
const { txHash } = await window.alpaca.sendTransaction({
type: "SEND",
params: {
network: "main",
to: "keeta_recipient...",
token: "keeta_token...",
amount: "5000000000000000000"
}
});
// txHash: "abc123..." — transaction hash on Keeta Response
{ txHash: "abc123..." } signTransaction vs sendTransaction — Use signTransaction when your backend needs to submit the block (e.g. swap trades routed through your API). Use sendTransaction for direct sends where no backend coordination is needed.
Subscribe to events so your dApp can update instantly when the user switches accounts, changes network, or disconnects.
// Subscribe to events
window.alpaca.on("accountChanged", (data) => {
// data.address — new active address
updateUI(data.address);
});
window.alpaca.on("networkChanged", (data) => {
// data.network — "main" or "test"
switchNetwork(data.network);
});
window.alpaca.on("disconnect", () => {
// Wallet locked or disconnected — clear UI state
resetWalletState();
});
// Unsubscribe when done
window.alpaca.off("accountChanged", handler); Fires when the user switches to a different account in the extension popup.
data: { address }
Fires when the user toggles between mainnet and testnet in settings.
data: { network }
Fires when the wallet is locked (auto-lock after 15 min) or the user disconnects.
data: { }
Keeta has two networks. The same wallet address works on both. Use testnet for development — get free test tokens from the Keeta faucet.
| Mainnet | Testnet | |
|---|---|---|
| Network value | "main" | "test" |
| KTA decimals | 18 | 9 |
| KTA address | keeta_anqdilpaz... | keeta_anyiff4v3... |
| Faucet | N/A | faucet.test.keeta.com |
Every method rejects with a standard JavaScript Error if something goes wrong. Wrap calls in try/catch.
try {
const result = await window.alpaca.connect();
} catch (err) {
// err.message will be one of the strings below
console.error(err.message);
} | Error Message | Cause |
|---|---|
| "Wallet is locked. Open the Alpaca extension and unlock it." | Session expired or wallet manually locked |
| "Wallet is locked. Open the extension and enter your password." | Signing requested while wallet is locked |
| "Network connection failed." | Cannot reach Keeta network node |
| "Missing address parameters." | Required fields missing from SWAP params |
| "Message is required for signing" | Empty or missing message passed to signMessage |
Contact us to whitelist your domain and start building on the Alpaca Wallet extension API.
Or email us directly at contact@alpacadex.com