Skip to content

Cosmos (updating...)

When running a DApp in the Bitget Wallet App or in the Chrome browser with the Chrome Extension installed, you can access the global object window.bitkeep.keplr for subsequent API calls.

Note

  1. Only supports Sei mainnet
  2. All methods only support Sei connections
js
const provider = window.bitkeep.keplr
const provider = window.bitkeep.keplr

Supported Versions:

PlatformVersionDescription
Chrome Extension>=v1.4.8
App(IOS)>=v7.3.7
App(Android)>=v7.3.7

Supported Shains

ChainChain IDDescription
Seipacific-1

cosmosjs sdk

Basic methods

Installation status

js
const isBitKeepInstalled = window.bitkeep && window.bitkeep.keplr;
const isBitKeepInstalled = window.bitkeep && window.bitkeep.keplr;

Provider detection

js
function getProvider() {
  const provider = window.bitkeep && window.bitkeep.keplr;
  if (!provider) {
    window.open('https://web3.bitget.com/en/wallet-download?type=2');
    throw 'Please go to  https://web3.bitget.com/en/wallet-download?type=2 to download!!';
  }
  return provider;
}
function getProvider() {
  const provider = window.bitkeep && window.bitkeep.keplr;
  if (!provider) {
    window.open('https://web3.bitget.com/en/wallet-download?type=2');
    throw 'Please go to  https://web3.bitget.com/en/wallet-download?type=2 to download!!';
  }
  return provider;
}

Connect to the Bitget Wallet

js
enable(chainId: string): Promise<void>
// Only support Sei main network
enable(chainId: string): Promise<void>
// Only support Sei main network

Get address/public key

js
getKey(chainId: string): Promise<{
    // Name of the selected Wallet.
    name: string;
    algo: string;
    pubKey: Uint8Array;
    address: Uint8Array;
    bech32Address: string;
}>


await provider.getKey('pacific-1')
getKey(chainId: string): Promise<{
    // Name of the selected Wallet.
    name: string;
    algo: string;
    pubKey: Uint8Array;
    address: Uint8Array;
    bech32Address: string;
}>


await provider.getKey('pacific-1')

Sign Amino

js
signAmino(chainId: string, signer: string, signDoc: StdSignDoc): Promise<AminoSignResponse>
signAmino(chainId: string, signer: string, signDoc: StdSignDoc): Promise<AminoSignResponse>

Similar to CosmJS OfflineSigner's signAmino, Bitkeep's signAmino requires the chain ID as a required parameter. It signs the Amino-encoded StdSignDoc.

Sign Direct/Protobuf

js
signDirect(chainId:string, signer:string, signDoc: {
    /** SignDoc bodyBytes */
    bodyBytes?: Uint8Array | null;
    /** SignDoc authInfoBytes */
    authInfoBytes?: Uint8Array | null;
    /** SignDoc chainId */
    chainId?: string | null;
    /** SignDoc accountNumber */
    accountNumber?: Long | null;
  }): Promise<DirectSignResponse>
signDirect(chainId:string, signer:string, signDoc: {
    /** SignDoc bodyBytes */
    bodyBytes?: Uint8Array | null;
    /** SignDoc authInfoBytes */
    authInfoBytes?: Uint8Array | null;
    /** SignDoc chainId */
    chainId?: string | null;
    /** SignDoc accountNumber */
    accountNumber?: Long | null;
  }): Promise<DirectSignResponse>

Similar to CosmJS OfflineDirectSigner's signDirect, but bitkeep signDirect requires chain-id as a mandatory parameter. Signs Proto-encoded StdSignDoc.

sendTx

Request Transaction Broadcast

js
sendTx(
    chainId: string,
    tx: Uint8Array,
    mode: BroadcastMode
): Promise<Uint8Array>;
sendTx(
    chainId: string,
    tx: Uint8Array,
    mode: BroadcastMode
): Promise<Uint8Array>;

This function requests Bitget Wallet to delegate the broadcasting of the transaction to Bitget Wallet's LCD endpoint (instead of broadcasting the transaction from the webpage). If the method successfully broadcasts, it returns the transaction hash; otherwise, it throws an error.

signArbitrary

js
signArbitrary(
    chainId: string,
    signer: string,
    data: string | Uint8Array
): Promise<StdSignature>;

verifyArbitrary(
    chainId: string,
    signer: string,
    data: string | Uint8Array,
    signature: StdSignature
): Promise<boolean>;
signArbitrary(
    chainId: string,
    signer: string,
    data: string | Uint8Array
): Promise<StdSignature>;

verifyArbitrary(
    chainId: string,
    signer: string,
    data: string | Uint8Array,
    signature: StdSignature
): Promise<boolean>;

This is an experimental implementation of ADR-36. Use this feature at your own risk.

Its primary use is to prove the ownership of an off-chain account by requesting an ADR-36 signature using the signArbitrary API.

If the request requires ADR-36's 0 API signature document from Bitget Wallet instead of using the signArbitrary API, it will act as signArbitrary.

  • Only supports signing documents in Amino format. (In the case of protobuf, ADR-36 requirements are not fully specified for implementation)
  • The sign document message should be a single message type "sign/MsgSignData".
  • The sign document "sign/MsgSignData" message should have "signer" and "data" as its values. "data" should be base64 encoded.
  • The sign document chain_id should be an empty string ("").
  • The sign document memo should be an empty string ("").
  • The sign document account_number should be "0".
  • The sign document sequence should be "0".
  • The sign document fee should be ({gas: "0", amount: []}).

Using verifyArbitrary, you can verify the result of an ADR-36 standard request made by the signArbitrary API or the signAmino API.

verifyArbitrary is only for simple use cases. verifyArbitrary returns the verification result of the signed document for the currently selected account. If the account is not the currently selected account, it throws an error.

It is recommended to use the verifyADR36Amino function in your implementation rather than the verifyArbitrary API.

Change Key Store Event

js
keplr_keystorechange
keplr_keystorechange

When a user switches their key store/account on the webpage after receiving information on the key store/account, the keys known to the webpage may not match the selected key in Bitget Wallet, which could cause interaction issues.

To prevent this, Bitget Wallet emits a keplr_keystorechange event to the webpage window when the key store/account changes. You can request new keys/accounts based on this event listener.

js
window.addEventListener("keplr_keystorechange", () => {
    console.log("Key store in BitKeep is changed. You may need to refetch the account info.")
})
window.addEventListener("keplr_keystorechange", () => {
    console.log("Key store in BitKeep is changed. You may need to refetch the account info.")
})

keplr_keystorechange is a unified method in the keplr wallet standard that can simultaneously listen for corresponding changes in both keplr and Bitget wallets. Developers can distinguish the event source using the following code:

js
var currentWalllet = ''; //DApp should connect with just one wallet at same time.
try{
    await provider.enable(chainId);
    currentWalllet = 'bitget'; //rewrite when switch the wallet.
    console.log('bitget connect:', {chainId, result});
}catch(error){
    //connect error
}

/* 
address changed, 
chainId changed
*/
window.addEventListener("keplr_keystorechange", (event) => {
    if(currentWalllet == 'bitget'){
        console.log("bitget keplr_keystorechange:", event);
    }else{
        console.log("other keplr_keystorechange:", event);
    }
});
var currentWalllet = ''; //DApp should connect with just one wallet at same time.
try{
    await provider.enable(chainId);
    currentWalllet = 'bitget'; //rewrite when switch the wallet.
    console.log('bitget connect:', {chainId, result});
}catch(error){
    //connect error
}

/* 
address changed, 
chainId changed
*/
window.addEventListener("keplr_keystorechange", (event) => {
    if(currentWalllet == 'bitget'){
        console.log("bitget keplr_keystorechange:", event);
    }else{
        console.log("other keplr_keystorechange:", event);
    }
});

Using with CosmosJS

Connecting with Cosmosjs

@cosmjs/launchpad@cosmjs/stargate

You can connect Bitget Wallet to CosmJS using OfflineSigner.

js
// Enabling before using the bitkeep.keplr is recommended.
// This method will ask the user whether or not to allow access if they haven't visited this website.
// Also, it will request user to unlock the wallet if the wallet is locked.
await window.bitkeep.keplr.enable(chainId);

const offlineSigner = window.bitkeep.getOfflineSigner(chainId);

// You can get the address/public keys by `getAccounts` method.
// It can return the array of address/public key.
// But, currently, BitKeep extension manages only one address/public key pair.
// XXX: This line is needed to set the sender address for SigningCosmosClient.
const accounts = await offlineSigner.getAccounts();

// Initialize the api with the offline signer that is injected by BitKeep extension.
const cosmJS = new SigningCosmosClient(
    "https://sei-rpc.polkachu.com",
    accounts[0].address,
    offlineSigner,
);
// Enabling before using the bitkeep.keplr is recommended.
// This method will ask the user whether or not to allow access if they haven't visited this website.
// Also, it will request user to unlock the wallet if the wallet is locked.
await window.bitkeep.keplr.enable(chainId);

const offlineSigner = window.bitkeep.getOfflineSigner(chainId);

// You can get the address/public keys by `getAccounts` method.
// It can return the array of address/public key.
// But, currently, BitKeep extension manages only one address/public key pair.
// XXX: This line is needed to set the sender address for SigningCosmosClient.
const accounts = await offlineSigner.getAccounts();

// Initialize the api with the offline signer that is injected by BitKeep extension.
const cosmJS = new SigningCosmosClient(
    "https://sei-rpc.polkachu.com",
    accounts[0].address,
    offlineSigner,
);
  • To get an OfflineSigner, you can use bitkeep.keplr.getOfflineSigner(chainId) or window.bitkeep.getOfflineSigner(chainId). (window.bitkeep.getOfflineSigner is an alias that runs bitkeep.keplr.getOfflineSigner and returns its value)
  • If the BitKeep extension is locked, the window.bitkeep.keplr.enable(chainId) method will prompt the user to unlock their extension. If the user has not granted permission to connect their extension to the website, it will first request to connect the website.
  • If the user cancels the unlock or denies the connection permission, an error will be thrown.
  • If the extension is already unlocked and the website has connection permission, nothing will happen.

Offline Signers Signature Types

  • In CosmJS, there are two types of signers: OfflineSigner and OfflineDirectSigner. OfflineSigner is used to sign SignDoc serialized with Amino in Cosmos SDK Launchpad (Cosmos SDK v0.39.x or lower). OfflineDirectSigner is used to sign Protobuf-encoded SignDoc.
  • Bitget Wallet supports both types of signers. bitkeep.keplr.getOfflineSigner(chainId) or window.bitkeep.getOfflineSigner(chainId) returns a Signer that satisfies both OfflineSigner and OfflineDirectSigner. Therefore, when using CosmJS with this signer, Amino is used for Launchpad chains, and Protobuf is used for Stargate chains.
  • However, if the messages to be sent can be serialized/deserialized using the Amino codec, you can use the Amino signer. Additionally, due to some limitations with Protobuf SignDoc, Amino may be required in certain situations. For example, the Ledger Nano's Cosmos application currently does not support Protobuf format SignDoc. Also, since Protobuf SignDoc is in binary format, msgs not supported by Bitget Wallet itself may not be readable.
  • If you want to force the use of Amino, you can use the following API: bitkeep.keplr.getOfflineSignerOnlyAmino(chainId) or window.bitkeep.getOfflineSignerOnlyAmino(chainId: string). Since this will always return a signer compatible with Amino, any msg requested by CosmJS that is compatible with Amino will request an Amino SignDoc from Bitget Wallet.
  • Additionally, the API bitkeep.keplr.getOfflineSignerAuto(chainId: string): Promise<OfflineSigner | OfflineDirectSigner> or window.bitkeep.getOfflineSignerAuto(chainId: string): Promise<OfflineSigner | OfflineDirectSigner> is also supported. Note that the returned value is asynchronous. If the account is a ledger-based account, this API will automatically return a signer that only supports Amino, and if the account is a mnemonic/private key-based account, it will return a signer compatible with both Amino and Protobuf. Since this API is affected by the type of linked Bitget Wallet account, if you use the keplr_keystorechange event to detect account changes, you must change the signer using the API when this event is triggered.

Using with Stargate

Bitget Wallet's OfflineSigner implements the OfflineDirectSigner interface. Using SigningStargateClient with Bitget Wallet's OfflineSigner, Bitget Wallet will sign transactions in Proto SignDoc format.

js
import { SigningStargateClient } from "@cosmjs/stargate"

const denom = 'usei'
const toAddress = 'sei1jr0269wfm6ldfdtg6u9vl4hdmk8le0r46x6jkx'
const rpcUrl = 'https://xxx'

// Detect BitKeep Keplr
const keplr = window.bitkeep?.keplr
if (!keplr) {
    return alert("You need to install Bitget Wallet")
}
// Get the current state and amount of tokens that we want to transfer

// Create the signing client
const offlineSigner = window.bitkeep?.getOfflineSigner("atlantic-2")
const signingClient = await SigningStargateClient.connectWithSigner(
    rpcUrl,
    offlineSigner,
)
// Get the address and balance of your user
const account = (await offlineSigner.getAccounts())[0]

// Submit the transaction to send tokens to the faucet
const sendResult = await signingClient.sendTokens(
    account.address,
    toAddress,
    [
        {
            denom: denom,
            amount: '1',
        },
    ],
    {
        amount: [{ denom: denom, amount: "5000" }],
        gas: "200000",
    },
    ''
)

if (sendResult.code !== undefined && sendResult.code !== 0) {
    alert("Failed to send tx: " + sendResult.log || sendResult.rawLog);
} else {
    alert("Succeed to send tx:" + sendResult.transactionHash);
}
import { SigningStargateClient } from "@cosmjs/stargate"

const denom = 'usei'
const toAddress = 'sei1jr0269wfm6ldfdtg6u9vl4hdmk8le0r46x6jkx'
const rpcUrl = 'https://xxx'

// Detect BitKeep Keplr
const keplr = window.bitkeep?.keplr
if (!keplr) {
    return alert("You need to install Bitget Wallet")
}
// Get the current state and amount of tokens that we want to transfer

// Create the signing client
const offlineSigner = window.bitkeep?.getOfflineSigner("atlantic-2")
const signingClient = await SigningStargateClient.connectWithSigner(
    rpcUrl,
    offlineSigner,
)
// Get the address and balance of your user
const account = (await offlineSigner.getAccounts())[0]

// Submit the transaction to send tokens to the faucet
const sendResult = await signingClient.sendTokens(
    account.address,
    toAddress,
    [
        {
            denom: denom,
            amount: '1',
        },
    ],
    {
        amount: [{ denom: denom, amount: "5000" }],
        gas: "200000",
    },
    ''
)

if (sendResult.code !== undefined && sendResult.code !== 0) {
    alert("Failed to send tx: " + sendResult.log || sendResult.rawLog);
} else {
    alert("Succeed to send tx:" + sendResult.transactionHash);
}