Extension Wallet Cosmos Integration
Develop Cosmos based chains dApps
Ctrl Wallet integrates Cosmos based chains.
It allows dApps to be developed on Cosmos based chains.
It injects a Keplr Provider in window.xfi.keplr
and if Keplr isn't instantiated, takes Keplr wallet window.keplr
object and allow you to use its basic API via CosmJS.
Use cosmos-kit
Ctrl Wallet is part of cosmos-kit package to help you connect to many different wallets.
Here is an example of how to use cosmos-kit.
How to detect XDEFI’s Keplr provider
As the official Keplr guide mentioned here;
window.onload = async () => {
if (!window.xfi?.keplr) {
alert("Please install XDEFI extension");
} else {
const chainId = "cosmoshub-4";
const keplr = window.xfi.keplr;
// Enabling before using the Keplr is recommended.
// This method will ask the user whether to allow access if they haven't visited this website.
// Also, it will request that the user unlock the wallet if the wallet is locked.
await keplr.enable(chainId);
const offlineSigner = keplr.getOfflineSigner(chainId);
// You can get the address/public keys by `getAccounts` method.
// It can return the array of address/public key.
// But, currently, Keplr 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 gaia api with the offline signer that is injected by Keplr extension.
const cosmJS = new SigningCosmosClient(
"https://lcd-cosmoshub.keplr.app",
accounts[0].address,
offlineSigner,
);
}
};
Differentiate Keplr and XDEFI window.keplr
If you’d like to differentiate Keplr and XDEFI window.keplr
, you can use window.keplr.isXDEFI
to check if it’s XDEFI’s Keplr provider.
if (window.keplr.isXDEFI) {
// this is XDEFI's Keplr provider
} else {
// this is Keplr's Keplr provider
}
Chains supported on XDEFI
As of release v26, XDEFI supports the following chains (chainId).
- Cosmos Hub,
cosmoshub-4
- Osmosis,
osmosis-1
- Axelar,
axelar-dojo-1
- JUNO,
juno-1
- Crescent,
crescent-1
- KAVA,
kava_2222-10
- Stargaze,
stargaze-1
- Akash,
akashnet-2
- Crypto Org,
crypto-org-chain-mainnet-1
- Kujira,
kaiyo-1
- Sei Testnet,
atlantic-2
- Stride,
stride-1
- Mars Protocol,
mars-1
Basic API
Please find the Full Basic API on Keplr website
Using with Typescript
import { Window as KeplrWindow } from "@keplr-wallet/types";
declare global {
interface Window extends KeplrWindow {}
}
The @keplr-wallet/types
package has the type definition related to Keplr. If you’re using TypeScript, run npm install --save-dev @keplr-wallet/types
or yarn add -D @keplr-wallet/types
to install @keplr-wallet/types
. Then, you can add the @keplr-wallet/types
window to a global window object and register the Keplr related types.
Connect using enable
enable(chainIds: string[]): Promise<void>
The window.keplr.enable(chainIds)
method requests the extension to be unlocked if it’s currently locked. If the user hasn’t given permission to the webpage, it will ask the user to give permission for the webpage to access XDEFI.
Get Address / Public Key
getKey(chainId: string): Promise<{
// Name of the selected key store.
name: string;
algo: string;
pubKey: Uint8Array;
address: Uint8Array;
bech32Address: string;
}>
Sign Amino
signAmino(chainId: string, signer: string, signDoc: StdSignDoc): Promise<AminoSignResponse>
Similar to CosmJS OfflineSigner’s signAmino, but Keplr’s signAmino takes the chain-id as a required parameter. Signs Amino-encoded StdSignDoc.
Sign Direct (Protobuf)
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 Keplr’s signDirect takes the chain-id as a required parameter. Signs Proto-encoded StdSignDoc.
Request Transaction Broadcasting
sendTx(
chainId: string,
tx: Uint8Array,
mode: BroadcastMode
): Promise<Uint8Array>;
This function requests Keplr to delegates the broadcasting of the transaction to Keplr’s LCD endpoints (rather than the webpage broadcasting the transaction). This method returns the transaction hash if it succeeds to broadcast, if else the method will throw an error. When Keplr broadcasts the transaction, Keplr will send the notification on the transaction’s progress.
Request Signature for Arbitrary Message
signArbitrary(
chainId: string,
signer: string,
data: string | Uint8Array
): Promise<StdSignature>;
verifyArbitrary(
chainId: string,
signer: string,
data: string | Uint8Array,
signature: StdSignature
): Promise<boolean>;
See Keplr Docs
Limitations
We don’t support yet (13-Jan-2023)
signEthereum
- Secret Network / SecretJS
- Suggest Chain
experimentalSuggestChain
Use with CosmJS
Please find how to use XDEFI’s Keplr Provider using CosmJS on Keplr website
Connect to XDEFI’s Keplr Provider using CosmJS
// Enabling before using the 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.keplr.enable(chainId);
const offlineSigner = window.getOfflineSigner(chainId);
// You can get the address/public keys by `getAccounts` method.
// It can return the array of address/public key.
// But, currently, Keplr 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 gaia api with the offline signer that is injected by Keplr extension.
const cosmJS = new SigningCosmosClient(
"https://lcd-cosmoshub.keplr.app/rest",
accounts[0].address,
offlineSigner,
);
Suggest Chain (Experimental Feature)
Ctrl (fka XDEFI) follows the same suggest-chain
, suggest-chain-info
interface as Keplr's suggest-chain method. This allows frontends to add their chain to the wallet, if the user should accept it.
The dApps can achieve by either making a connection request with the chainID, and if the user doesn't already have it and it is supported by chain-registry, we will ask them to add it.
We follow the same ChainInfo interface set out by Keplr to add a new custom chain, it should have the data as follows:
interface ChainInfo {
readonly rpc: string;
readonly rest: string;
readonly chainId: string;
readonly chainName: string;
/**
* This indicates the type of coin that can be used for stake.
* You can get actual currency information from Currencies.
*/
readonly stakeCurrency: Currency;
readonly walletUrlForStaking?: string;
readonly bip44: {
coinType: number;
};
readonly alternativeBIP44s?: BIP44[];
readonly bech32Config: Bech32Config;
readonly currencies: AppCurrency[];
/**
* This indicates which coin or token can be used for fee to send transaction.
* You can get actual currency information from Currencies.
*/
readonly feeCurrencies: FeeCurrency[];
/**
* Indicate the features supported by this chain. Ex) cosmwasm, secretwasm ...
*/
readonly features?: string[];
}
You can then make a request follows and add the custom chain:
await window.xfi.keplr.experimentalSuggestChain({
chainId: "my-test-chain",
chainName: "my test chain",
bech32Config: {
bech32PrefixAccAddr: "cosmos",
bech32PrefixAccPub: "cosmospub",
bech32PrefixValAddr: "cosmosvaloper",
bech32PrefixValPub: "cosmosvaloperpub",
bech32PrefixConsAddr: "cosmosvalcons",
bech32PrefixConsPub: "cosmosvalconspub",
},
bip44: {
coinType: 118,
},
currencies: [
{
coinDenom: "stake",
coinMinimalDenom: "stake",
coinDecimals: 6,
coinGeckoId: "cosmos",
coinImageUrl:
"https://raw.githubusercontent.com/cosmos/chain-registry/master/cosmoshub/images/atom.png",
feeCurrency: true,
},
],
feeCurrencies: [
{
coinDenom: "stake",
coinMinimalDenom: "stake",
coinDecimals: 6,
coinGeckoId: "cosmos",
coinImageUrl:
"https://raw.githubusercontent.com/cosmos/chain-registry/master/cosmoshub/images/atom.png",
feeCurrency: true,
},
],
rest: "http://127.0.0.1:1317",
rpc: "http://127.0.0.1:9090",
});