Extension Wallet
Integration
COSMOS Chains
Vanilla

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
example
<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
example
<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.

example
<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
example
<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
example
<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
example
<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
example
<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
example
<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
example
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.

example
window.removeEventListener('cosmostation_keystorechange', handler);