laconic-wallet/development.md
nabarun 361b79b696 Refactor wallet connect instance to use state variables (#8)
Part of [laconicd testnet validator enrollment](https://www.notion.so/laconicd-testnet-validator-enrollment-6fc1d3cafcc64fef8c5ed3affa27c675)
- Refactor `web3wallet` variable into a state variable

Co-authored-by: Shreerang Kale <shreerangkale@gmail.com>
Co-authored-by: Adw8 <adwaitgharpure@gmail.com>
Reviewed-on: cerc-io/laconic-wallet#8
2024-07-29 12:13:15 +00:00

5.2 KiB

Development

WalletConnect details

  • Docs - https://docs.walletconnect.com/api/sign/overview

  • Doc for terminologies - https://docs.walletconnect.com/advanced/glossary

  • Function for creating web3 wallet

    export let core: ICore;
    
    export async function createWeb3Wallet() {
      const core = new Core({
        projectId: Config.WALLET_CONNECT_PROJECT_ID,
      });
    
      web3wallet = await Web3Wallet.init({
        core,
        metadata: {
          name: 'Laconic Wallet',
          description: 'Laconic Wallet',
          url: 'https://wallet.laconic.com/',
          icons: ['https://avatars.githubusercontent.com/u/92608123'],
        },
      });
    
      return web3wallet;
    }
    
  • Hook used for intializing web3 wallet

    export default function useInitialization(setWeb3wallet) {
      const [initialized, setInitialized] = useState(false);
    
      const onInitialize = useCallback(async () => {
        try {
          const web3walletInstance = await createWeb3Wallet();
          setWeb3wallet(web3walletInstance);
    
          setInitialized(true);
        } catch (err: unknown) {
          console.error('Error for initializing', err);
        }
      }, [setWeb3wallet]);
    
      useEffect(() => {
        if (!initialized) {
          onInitialize();
        }
      }, [initialized, onInitialize]);
    
      return initialized;
    }
    
  • Once user clicks on pair, this function is triggered

    export async function web3WalletPair(params: { uri: string }) {
      return await web3wallet.core.pairing.pair({ uri: params.uri });
    }
    
  • In a useEffect, we keep on listening to events that are emitted by dapp and do actions based on it

    useEffect(() => {
      web3wallet?.on('session_proposal', onSessionProposal);
      web3wallet?.on('session_request', onSessionRequest);
      web3wallet?.on('session_delete', onSessionDelete);
      return () => {
        web3wallet?.off('session_proposal', onSessionProposal);
        web3wallet?.off('session_request', onSessionRequest);
        web3wallet?.off('session_delete', onSessionDelete);
      }
    })
    
  • Signing messages

    • Cosmos methods info

      • The signDoc format for signAmino and signDirect is different

      • For signDirect, the message is protobuf encoded , hence to sign it , we have to first convert it to uint8Array

        const bodyBytesArray = Uint8Array.from(
          Buffer.from(request.params.signDoc.bodyBytes, 'hex'),
        );
        const authInfoBytesArray = Uint8Array.from(
          Buffer.from(request.params.signDoc.authInfoBytes, 'hex'),
        );
        
      • This will give us correct signature

patch-package

Data structure of keystore

{
  // Accounts data -> hdpath, privateKey, publicKey, address
  "accounts/eip155:1/0":{
    "username": "",
    "password": "m/44'/60'/0'/0/0,0x0654623fe7a0e3d74f518e22818c1cfd58517e80a232df5d6d20a3afd99fd3bb,0x02cced178c903835bb29e337fa227ba0204a3285eb35797b766ed975b478b4beb6,0xe5fA0Dd92659e287e5e3Fa582Ee20fcf74fb1116"
  },
  "accounts/cosmos:cosmoshub-4/0":{
    "username": "",
    "password": "m/44'/118'/0'/0/0,0xbb9ccc3029178a61ba847c22108318ba119220451c99e6358efd7b85d7d49ed5,0x03a8002f56f99126f930ca3ac1963731e3f08df30822031db7c1dd50851bdfcc3c,cosmos1s5a5ls3d6xmks5fc8tst9x7tx2jv8mfjmn0aq8"
  },

  // Networks Data
  "networks":{
    "username":"",
    "password":[
      {
        "networkId":"1",
        "namespace": "eip155",
        "chainId": "1",
        "networkName": "Ethereum",
        "rpcUrl": "https://cloudflare-eth.com/",
        "currencySymbol": "ETH",
        "coinType": "60"
      },
      {
        "networkId":"2",
        "namespace": "cosmos",
        "chainId": "theta-testnet-001",
        "networkName": "Cosmos Hub Testnet",
        "rpcUrl": "https://rpc-t.cosmos.nodestake.top",
        "nativeDenom": "ATOM",
        "addressPrefix": "cosmos",
        "coinType": "118"
      }
    ]
  },

// Stores count of total accounts for specific chain
  "addAccountCounter/eip155:1":{
    "username": "",
    "password": "3"
  },
  "addAccountCounter/cosmos:cosmoshub-4":{
    "username": "",
    "password": "3"
  },

  // Stores ids of accounts for specific chain
  "accountIndices/eip155:1":{
    "username": "",
    "password": "0,1,2"
  },
  "accountIndices/cosmos:cosmoshub-4":{
    "username": "",
    "password": "0,1,2"
  }
}