Vanilla
This approach allows you to interact with the Cosmostation Extension without installing any additional packages or SDKs. All functionality is exposed through the globally injected window.cosmostation object, making it suitable for simple integrations, quick prototypes, or environments where minimizing dependencies is important.
Because it relies solely on the browser extension, this method works immediately after the user installs Cosmostation and refreshes the page, with no build-time configuration required.
This section demonstrates how to interact with the Cosmostation Extension using the Vanilla JavaScript API (no SDK, no additional packages required).
All examples rely on the injected global object:
window.cosmostation;If the extension is not installed, requests will fail and should be handled gracefully in your application.
Supported Chains
This request returns a list of Cosmos-based chain IDs currently supported by the Cosmostation Extension.
You can use this information to:
- dynamically enable / disable chains in your dApp UI
- verify whether a requested chain is supported before requesting an account
- guide users to add a custom chain if needed
<button
onClick={async () => {
try {
if (!window.cosmostation) {
throw new Error('Cosmostation extension not installed');
}
const account = await window.cosmostation.cosmos.request({
method: 'cos_supportedChainIds',
});
} catch (e) {
console.log(e.message);
}
}}
>
Request Supported Chains
</button>Request Account
Get account information for a specific chain.
This call:
- prompts the user to connect (if not already connected)
- returns the selected account address and public key
- scopes the account to the specified
chainName
<button
onClick={async () => {
try {
if (!window.cosmostation) {
throw new Error('Cosmostation extension not installed');
}
const account = await window.cosmostation.cosmos.request({
method: 'cos_requestAccount',
params: { chainName: 'cosmoshub-4' },
});
} catch (e) {
console.log(e.message);
}
}}
>
Request Account
</button>Sign
This section covers different signing methods supported by the Cosmostation Extension for Cosmos SDK–based chains.
Each signing method serves a different purpose depending on transaction format and compatibility requirements.
SignAmino
Signing with Amino JSON, the legacy signing format.
<button
onClick={async () => {
try {
if (!window.cosmostation) {
throw new Error('Cosmostation extension not installed');
}
const doc = {
//...
};
const response = await window.cosmostation.cosmos.request({
method: 'cos_signAmino',
params: { chainName: 'cosmoshub-4', doc },
});
console.log(response.signature);
} catch (e) {
console.log(e.message);
}
}}
>
Sign Amino
</button>SignDirect
Signing using Protobuf-based Direct SignDoc.
This is the recommended approach for modern Cosmos SDK chains.
Use this method when:
- constructing transactions with protobuf messages
- working with
SIGN_MODE_DIRECT
<button
onClick={async () => {
try {
if (!window.cosmostation) {
throw new Error('Cosmostation extension not installed');
}
const doc = {
// ...
};
const response = await window.cosmostation.cosmos.request({
method: 'cos_signDirect',
params: {
chainName: 'cosmoshub-4',
doc,
},
});
console.log(response.signatures);
} catch (e) {
console.log(e.message);
}
}}
>
Sign Direct
</button>SignMessage
Sign arbitrary bytes (off-chain message signing).
Typical use cases:
- authentication / login flows
- ownership verification
- off-chain signatures without broadcasting a transaction
<button
onClick={async () => {
try {
if (!window.cosmostation) {
throw new Error('Cosmostation extension not installed');
}
const account = await window.cosmostation.cosmos.request({
method: 'cos_requestAccount',
params: { chainName: 'cosmoshub-4' },
});
const response = await window.cosmostation.cosmos.request({
method: 'cos_signMessage',
params: {
chainName: 'cosmoshub-4',
message: 'Test (Sign Message)',
signer: account.address,
},
});
console.log(response.signature);
} catch (e) {
console.log(e.message);
}
}}
>
Sign Message
</button>VerifyMessage
Verify a previously signed message.
This allows your dApp to:
- confirm that a signature was produced by a given address
- validate authentication challenges
- ensure message integrity
<button
onClick={async () => {
try {
if (!window.cosmostation) {
throw new Error('Cosmostation extension not installed');
}
const message = 'Test (Sign Message)';
const account = await window.cosmostation.cosmos.request({
method: 'cos_requestAccount',
params: { chainName: 'cosmoshub-4' },
});
const signResponse = await window.cosmostation.cosmos.request({
method: 'cos_signMessage',
params: {
chainName: 'cosmoshub-4',
message,
signer: account.address,
},
});
const verifyResponse = await window.cosmostation.cosmos.request({
method: 'cos_verifyMessage',
params: {
chainName: 'cosmoshub-4',
message,
signer: account.address,
publicKey: signResponse.pub_key.value,
signature: signResponse.signature,
},
});
console.log(verifyResponse ? 'verified' : 'not verified');
} catch (e) {
console.log(e.message);
}
}}
>
Sign & Verify Message
</button>AddCW20Token
Request the extension to track a CW20 token.
After approval:
- the token appears in the wallet UI
- balances are fetched automatically
- users can transfer the token via the extension
<button
onClick={async () => {
try {
if (!window.cosmostation) {
throw new Error('Cosmostation extension not installed');
}
await window.cosmostation.cosmos.request({
method: 'cos_addTokensCW20',
params: {
chainName: 'juno-1',
tokens: [
{
contractAddress: 'juno1r4pzw8f9z0sypct5l9j906d47z998ulwvhvqe5xdwgy8wf84583sxwh0pa',
},
],
},
});
console.log('added');
} catch (e) {
console.log(e.message);
}
}}
>
Add CW20 Tokens
</button>AddCustomChain
Add a chain (mainnet or testnet) that is not preloaded in the extension.
Use this when:
- working with private networks
- supporting early testnets
- integrating newly launched Cosmos chains
<button
onClick={async () => {
try {
if (!window.cosmostation) {
throw new Error('Cosmostation extension not installed');
}
const response = await window.cosmostation.cosmos.request({
method: 'cos_addChain',
params: {
chainId: 'custom-chain-1',
chainName: 'custom-chain',
addressPrefix: 'custom',
baseDenom: 'ucustom',
displayDenom: 'CUSTOM',
restURL: 'https://rpc.custom-chain.com',
decimals: 6, // optional
coinType: '118', // optional
},
});
console.log(response.tx_response.txhash);
} catch (e) {
console.log(e.message);
}
}}
>
Add a custom chain
</button>Event
Cosmostation emits browser events when the wallet state changes.
addEventListener
Listen for keystore changes such as:
- account switch
window.addEventListener('cosmostation_keystorechange', () => {
console.log('Key store in Cosmostation is changed. You may need to refetch the account info.');
});removeEventListener
Always clean up listeners when they are no longer needed.
window.removeEventListener('cosmostation_keystorechange', handler);