Skip to main content

dApp Integration

Altitude Wallet exposes a window.postMessage API that lets any web application request wallet connections and token transfers. No SDK installation or external dependency is required — the bridge is injected automatically by the browser extension's content script.

How It Works

Altitude Wallet injects a content script into every page at document_start. This script listens for window.postMessage calls from your dApp and forwards them to the extension's background service worker, which handles vault access, signing, and transaction broadcasting.

Your dApp                Content Script              Background Worker
│ │ │
│ window.postMessage() │ │
│ ──────────────────────> │ │
│ │ sendMessage() │
│ │ ──────────────────────> │
│ │ │
│ │ Open popup
│ │ for user approval
│ │ │
│ │ <────────────────────── │
│ <───────────────────── │ │
│ window.postMessage() │ │
│ (response) │ │

All communication is asynchronous and Promise-based. Every request includes a unique id so your dApp can match responses to requests.

Connect Wallet

Request a connection to the user's wallet. If the wallet is locked, Altitude Wallet opens a popup prompting the user to enter their password. Once unlocked, the selected account address is returned.

Request

const id = crypto.randomUUID();

window.postMessage(
{
type: 'ALTITUDE_WALLET_CONNECT',
id,
},
'*'
);

Response

The extension responds with a message of type ALTITUDE_WALLET_CONNECT_RESPONSE:

window.addEventListener('message', (event) => {
if (event.source !== window) return;

const { type, id: responseId, result, error } = event.data;

if (type === 'ALTITUDE_WALLET_CONNECT_RESPONSE' && responseId === id) {
if (error) {
console.error('Connection rejected:', error);
return;
}

console.log('Connected address:', result.address);
}
});

Result

FieldTypeDescription
addressstringThe user's selected account address

Errors

Error messageCause
Wallet not set up. Please create a wallet first.No wallet exists in the extension
No account selected.No wallet or account is currently selected
Selected account not found.Account data is corrupted or missing

Send Tokens

Request a token transfer. Altitude Wallet opens a confirmation popup where the user reviews the token, amount, recipient, and gas fee before approving or rejecting the transaction.

Request

const id = crypto.randomUUID();

window.postMessage(
{
type: 'ALTITUDE_WALLET_SEND_TO',
id,
data: {
token: {
chainId: 1,
address: '0x0000000000000000000000000000000000000000',
name: 'Ether',
symbol: 'ETH',
decimals: 18,
logoURI: 'https://assets.coingecko.com/coins/images/279/small/ethereum.png',
nativeToken: true,
},
amount: {
value: 0.001,
fiat: 2,
},
recipientAddress: '0x742d35Cc6634C0532925a3b844Bc454e4438f44e',
},
},
'*'
);

Response

window.addEventListener('message', (event) => {
if (event.source !== window) return;

const { type, id: responseId, result, error } = event.data;

if (type === 'ALTITUDE_WALLET_SEND_TO_RESPONSE' && responseId === id) {
if (error) {
console.error('Transaction failed:', error);
return;
}

console.log('Transaction hash:', result.txHash);
}
});

Result

FieldTypeDescription
txHashstringThe on-chain transaction hash

Errors

Error messageCause
Missing sendTo dataThe data field was omitted from the request
Wallet not set up. Please create a wallet first.No wallet exists in the extension
SendTo request timeoutUser did not respond within 10 minutes

Data Types

Token

The token object describes the asset being sent.

FieldTypeRequiredDescription
chainIdnumberYesEVM chain ID (e.g. 1 for Ethereum, 8453 for Base)
addressstringYesToken contract address. Use the zero address for native tokens
namestringYesHuman-readable token name
symbolstringYesToken ticker symbol (e.g. ETH, USDC)
decimalsnumberYesToken decimals (18 for most ERC-20 tokens)
logoURIstringYesURL to the token icon
nativeTokenbooleanNoSet to true for the chain's native gas token

Amount

FieldTypeRequiredDescription
valuenumberYesAmount in human-readable units (e.g. 0.001)
fiatnumberNoUSD-equivalent value for display purposes

Recipient

FieldTypeRequiredDescription
recipientAddressstringYesValid EVM address (0x...)

Complete Example

A minimal integration that connects to the wallet and sends a transaction:

<!DOCTYPE html>
<html>
<head>
<title>dApp Example</title>
</head>
<body>
<button id="connect">Connect Wallet</button>
<button id="send" disabled>Send 0.001 ETH</button>
<script>
function sendRequest(type, data) {
const id = crypto.randomUUID();

return new Promise((resolve, reject) => {
const handler = (event) => {
if (event.source !== window) return;

const msg = event.data;
if (msg.id !== id) return;

if (msg.type === `${type}_RESPONSE`) {
window.removeEventListener('message', handler);

if (msg.error) {
reject(new Error(msg.error));
} else {
resolve(msg.result);
}
}
};

window.addEventListener('message', handler);

window.postMessage({ type, id, data }, '*');
});
}

document.getElementById('connect').addEventListener('click', async () => {
try {
const { address } = await sendRequest('ALTITUDE_WALLET_CONNECT');
console.log('Connected:', address);
document.getElementById('send').disabled = false;
} catch (err) {
console.error(err);
}
});

document.getElementById('send').addEventListener('click', async () => {
try {
const { txHash } = await sendRequest('ALTITUDE_WALLET_SEND_TO', {
token: {
chainId: 1,
address: '0x0000000000000000000000000000000000000000',
name: 'Ether',
symbol: 'ETH',
decimals: 18,
logoURI: 'https://assets.coingecko.com/coins/images/279/small/ethereum.png',
nativeToken: true,
},
amount: { value: 0.001, fiat: 2 },
recipientAddress: '0x742d35Cc6634C0532925a3b844Bc454e4438f44e',
});
console.log('Tx hash:', txHash);
} catch (err) {
console.error(err);
}
});
</script>
</body>
</html>

TypeScript Definitions

For projects using TypeScript, copy these types into your codebase:

interface DappSendToToken {
chainId: number;
address: string;
name: string;
symbol: string;
decimals: number;
logoURI: string;
nativeToken?: boolean;
}

interface DappSendToRequestData {
token: DappSendToToken;
amount: { value: number; fiat?: number };
recipientAddress: string;
}

interface ConnectResult {
address: string;
}

interface SendToResult {
txHash: string;
}

interface WindowMessage {
type: string;
id: string;
data?: DappSendToRequestData;
result?: unknown;
error?: string;
}

Message Reference

RequestResponsePurpose
ALTITUDE_WALLET_CONNECTALTITUDE_WALLET_CONNECT_RESPONSEConnect wallet, get address
ALTITUDE_WALLET_SEND_TOALTITUDE_WALLET_SEND_TO_RESPONSESend token transfer for approval

All messages share the same shape:

{
type: string, // One of the request/response types above
id: string, // UUID for request-response matching
data?: object, // Request payload (sendTo only)
result?: object, // Response payload (on success)
error?: string, // Error message (on failure)
}

Security Notes

  • User confirmation required — Both connect and sendTo open a visible popup. The user must explicitly approve before any data is returned or any transaction is signed
  • No silent signing — There is no way to sign a transaction without a user actively confirming it in the popup
  • Timeout — A sendTo request expires after 10 minutes if the user does not respond
  • Extension must be installed — The content script is injected by the browser extension. Without it, window.postMessage calls are simply ignored