Cosmos Kit
Cosmology's components (opens in a new tab) work with Nym. They cover:
- Wallets such as Keplr, Cosmostation, and others from your React application
- The Ledger hardware wallet (opens in a new tab) from your browser
- Any wallet that supports Wallet Connect v2.0 (opens in a new tab)
Environment Setup
Create a new project with Vite:
npm create vite@latestChoose React, then Typescript. Navigate to your application directory and run:
cd < YOUR_APP >
npm i
npm run devInstallation
Install the required package:
npm install @cosmos-kit/react @cosmos-kit/keplr @cosmos-kit/ledger chain-registryYou need to polyfill some nodejs modules in order to use keplr and ledger wallets by modifying your vite.config.js file:
npm install @esbuild-plugins/node-globals-polyfill// vite.config.js
import { defineConfig } from 'vite'
import react from '@vitejs/plugin-react'
import { NodeGlobalsPolyfillPlugin } from '@esbuild-plugins/node-globals-polyfill'
export default defineConfig({
plugins: [react()],
optimizeDeps: {
esbuildOptions: {
define: {
global: 'globalThis'
},
plugins: [
NodeGlobalsPolyfillPlugin({
buffer: true
})
]
}
}
})Your components have to be wrapped into a ChainProvider (opens in a new tab),
in order to use the useChain('nyx') hook. The nyx chain is provided in the 'chain-registry' NPM package by default.
Now, go to the src folder and open your App.tsx file to replace all the code with the following, which will allow you to connect and disconnect a Ledger or Keplr wallet to Nyx:
import "./App.css";
import React from 'react';
import { ChainProvider, useChain } from '@cosmos-kit/react';
import { assets, chains } from 'chain-registry';
import { wallets as ledger } from '@cosmos-kit/ledger';
import { wallets as keplr } from '@cosmos-kit/keplr';
import { AminoMsg, makeSignDoc } from '@cosmjs/amino';
import { MsgSend } from 'cosmjs-types/cosmos/bank/v1beta1/tx';
export const getDoc = (address: string) => {
const chainId = 'nyx';
const msg: AminoMsg = {
type: '/cosmos.bank.v1beta1.MsgSend',
value: MsgSend.fromPartial({
fromAddress: address,
toAddress: 'n1nn8tghp94n8utsgyg3kfttlxm0exgjrsqkuwu9',
amount: [{ amount: '1000', denom: 'unym' }],
}),
};
const fee = {
amount: [{ amount: '2000', denom: 'ucosm' }],
gas: '180000', // 180k
};
const memo = 'Use your power wisely';
const accountNumber = 15;
const sequence = 16;
const doc = makeSignDoc([msg], fee, chainId, memo, accountNumber, sequence);
return doc
};
function MyComponent() {
const {wallet, address, connect, disconnect, getOfflineSignerAmino } =
useChain('nyx');
React.useEffect(() => {
connect();
disconnect();
}, []);
const sign = async () => {
if (!address) return
const doc = getDoc(address);
return getOfflineSignerAmino().signAmino(address, doc);
};
return (
<div>
<div>
{wallet &&
<div>
<div>Connected to {wallet?.prettyName} </div>
<div>Address: <code>{address}</code></div>
</div>}
</div>
{wallet ? (
<div>
<button onClick={() => disconnect()}>Disconnect wallet</button>
</div>
) : (
<div>
<button onClick={() => connect()}>Connect wallet</button>
</div>
)}
</div>
);
}
export default function App() {
const assetsFixedUp = React.useMemo(() => {
const nyx = assets.find((a) => a.chain_name === 'nyx');
if (nyx) {
const nyxCoin = nyx.assets.find((a) => a.name === 'nyx');
if (nyxCoin) {
nyxCoin.coingecko_id = 'nyx';
}
nyx.assets = nyx.assets.reverse();
}
return assets;
}, [assets]);
return (
<ChainProvider
chains={[chains.find((c) => c.chain_id === 'nyx')!]}
assetLists={assetsFixedUp}
wallets={[...ledger, ...keplr]}
signerOptions={{
preferredSignType: () => 'amino',
}}
>
<MyComponent/>
</ChainProvider>
)
}