How to Integrate New Wallets into CosmosKit
Quickly Add Extension Wallets
-
Copy files in Leap Extension (opens in a new tab) to your package;
-
Replace
Leapwith your wallet name (with first letter capitalized) globally; -
Replace
leapwith your wallet name (with first letter in lowercase) globally; -
Edit file
client.ts,registry.ts,types.tsandutils.ts. Replace what is different from Leap with the new wallet specified methods/properties. -
Construct the MainWallet (class in
main-wallet.ts) instance and put it intoChainProviderwalletsproperty.
Quickly Add Mobile Wallets
For wallets support Wallet Connect v2.0 (opens in a new tab)
-
Copy files in Keplr Mobile (opens in a new tab) to your package;
-
Replace
Keplrwith your wallet name (with first letter capitalized) globally; -
Replace
keplrwith your wallet name (with first letter in lowercase) globally; -
Edit file
client.ts,registry.tsandtypes.ts. Replace what is different from Keplr with the new wallet specified methods/properties. Forclient.ts, the main replacement would happen ingetAppUrland themethodparameter ofsendCustomRequest -
Construct the MainWallet (class in
main-wallet.ts) instance and put it intoChainProviderwalletsproperty.
Add New Wallets from Scratch
1️⃣ Prepare basic information for wallet
Required properties
| Key | Type | Description |
|---|---|---|
| name | WalletName = string | identifier |
| prettyName | string | display name |
| mode | WalletMode = 'extension' | 'wallet-connect' | wallet client type |
| mobileDisabled* | boolean | display on mobile or not |
| walletconnect | { name: string; projectId: string; encoding?: BufferEncoding } | only required when you are integrating mobile wallets based on walletconnect (opens in a new tab). If encoding is undefined, by default using hex to encode bytes |
* Usually true when mode is wallet-connect, false when mode is extension.
Optional properties
| Key | Type | Description |
|---|---|---|
| rejectMessage | string | { source: string; target?: string } | rejectMessage or rejectMessage.source is error message string thrown by wallet app/extension when user rejects, while rejectMessage.target is message returned by hooks. If not provided, target would be 'Request Rejected!' |
| connectEventNamesOnWindow | string[] | window event names to fire auto-connect |
| connectEventNamesOnClient | string[] | wallet client event names to fire auto-connect (make sure on and off methods are defined in WalletClient) |
| downloads | DownloadInfo[] (opens in a new tab) | wallet app/extension download information |
| logo | string | { major: string, minor: string } | wallet logo url, display on default modal. For MetaMask Snaps, use logo: { major: METAMASK_LOGO, minor: WALLET_LOGO } |
| extends | 'MetaMask' | indicate it's a MetaMask Snap |
Examples
2️⃣ Implement WalletClient
MainWallet is a class organizing all ChainWallets. It should extend MainWalletBase class, in which protected _chainWallets property stores all ChainWallets.
Required methods
| Key | Type | Description |
|---|---|---|
| getSimpleAccount | (chainId: string) => Promise<SimpleAccount> | return account with address but without pubkey and algo |
Optional methods
| Key | Type | Description |
|---|---|---|
| getAccount | (chainId: string) => Promise<WalletAccount>* | return account with address, pubkey and algo |
| getOfflineSigner | (chainId: string, preferredSignType?: SignType) => Promise<OfflineSigner> | prioritize returning preferredSignType (by default amino) corresponding signer if it is available, otherwise return siger that is provided. |
| enable | (chainIds: string | string[]) => Promise<void> | give permission for the webpage to access wallet |
| addChain | (chainInfo: ChainRecord) => Promise<void> | add new Cosmos-SDK based blockchains that isn't natively integrated to wallet app/extension |
| on | (type: string, listener: EventListenerOrEventListenerObject) => void | add event listener |
| off | (type: string, listener: EventListenerOrEventListenerObject) => void | remove event listener |
Examples
3️⃣ Extend ChainWalletBase
Create a ChainWallet class that extends ChainWalletBase. ChainWallet provides wallet information for a particular chain, e.g. address, offlineSigner, etc.
ChainWalletBase has implemented a bunch of methods such as wallet connection, sign, broadcast, etc. [learn more]. Therefore, normally you don't need to do any extra work inside ChainWallet. But feel free to overwrite these methods or add new methods/properties if customization is needed to meet new demand.
Examples
4️⃣ Extend MainWalletBase
Create a MainWallet class that extends MainWalletBase. MainWallet organizes all ChainWallets, which are stored in protected member _chainWallets.
Note: Class
ChainWalletcreated in Step 3 is required inMainWalletBaseconstruction.
Required methods
| Key | Type |
|---|---|
| initClient | () => void | Promise<void>* |
* WalletClient is the one implemented in Step 2.
Also, feel free to overwrite methods in MainWalletBase or add new methods/properties if necessary.
Examples
5️⃣ Get MainWallet instance
You can construct your MainWallet Instance according to your MainWallet construct method now. Usually the walletInfo object prepared in Step 1 is imported here as a construction argument.
Examples
Last but not least, append this instance to the wallets property of ChainProvider.
6️⃣ Don't Forget To Update Docs
Add Mardown File just like other wallets here (opens in a new tab).