forked from cerc-io/laconic-wallet
Add details to setup wallet connect in readme (#58)
* Add details to setup wallet connect in readme * Add hyperlinks for wallet connect terms * Handle review changes * Add keystore data structure and troubleshooting steps in readme * Update readme * Add pre-commit lint hook * Resolve linter warnings * Handle review changes * Fix heading level in readme
This commit is contained in:
parent
1172e67f5f
commit
8c0751f84b
1
.husky/pre-commit
Normal file
1
.husky/pre-commit
Normal file
@ -0,0 +1 @@
|
||||
yarn lint
|
32
README.md
32
README.md
@ -1,6 +1,6 @@
|
||||
# laconic-wallet
|
||||
|
||||
### Install
|
||||
## Install
|
||||
|
||||
- Install [Node](https://nodejs.org/en/download/package-manager/)
|
||||
|
||||
@ -87,7 +87,7 @@
|
||||
```
|
||||
cp .env.example .env
|
||||
```
|
||||
|
||||
|
||||
- In [.env](./.env) file add WalletConnect project id. You can generate your own ProjectId at https://cloud.walletconnect.com
|
||||
|
||||
```
|
||||
@ -134,3 +134,31 @@
|
||||
5. Press `a` to run the application on android
|
||||
|
||||
You should see both the apps running on your emulator or physical device.
|
||||
|
||||
## Flow for the app
|
||||
|
||||
- User scans QR Code on dApp from wallet to connect
|
||||
|
||||
- After clicking on pair button, dApp emits an event 'session_proposal'
|
||||
|
||||
- Wallet listens to this event and opens a modal to either accept or reject the proposal
|
||||
|
||||
- Modal shows information about methods, chains and events the dApp is requesting for
|
||||
|
||||
- This information is taken from [namespaces](https://docs.walletconnect.com/advanced/glossary#namespaces) object received from dApp
|
||||
|
||||
- On accepting, wallet sends the [namespaces](https://docs.walletconnect.com/advanced/glossary#namespaces) object with information about the accounts that are present in the wallet in response
|
||||
|
||||
- Once [session](https://docs.walletconnect.com/advanced/glossary#session) is established, it is shown in the active sessions page
|
||||
|
||||
- In this way, wallet can connect to multiple dApps
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
- To clean the buid
|
||||
|
||||
```
|
||||
cd adroid
|
||||
|
||||
./gradlew clean
|
||||
```
|
||||
|
160
development.md
Normal file
160
development.md
Normal file
@ -0,0 +1,160 @@
|
||||
# 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
|
||||
|
||||
```js
|
||||
export let web3wallet: IWeb3Wallet;
|
||||
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'],
|
||||
},
|
||||
});
|
||||
}
|
||||
```
|
||||
|
||||
- Hook used for intializing web3 wallet
|
||||
|
||||
```js
|
||||
export default function useInitialization() {
|
||||
const [initialized, setInitialized] = useState(false);
|
||||
|
||||
const onInitialize = useCallback(async () => {
|
||||
try {
|
||||
await createWeb3Wallet();
|
||||
setInitialized(true);
|
||||
} catch (err: unknown) {
|
||||
console.log('Error for initializing', err);
|
||||
}
|
||||
}, []);
|
||||
|
||||
useEffect(() => {
|
||||
if (!initialized) {
|
||||
onInitialize();
|
||||
}
|
||||
}, [initialized, onInitialize]);
|
||||
|
||||
return initialized;
|
||||
}
|
||||
```
|
||||
|
||||
- Once user clicks on pair, this function is triggered
|
||||
|
||||
```js
|
||||
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
|
||||
|
||||
```js
|
||||
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
|
||||
|
||||
- Reference - https://docs.leapwallet.io/cosmos/for-dapps-connect-to-leap/api-reference
|
||||
|
||||
- For signDirect, the message is protobuf encoded , hence to sign it , we have to first convert it to uint8Array
|
||||
|
||||
```js
|
||||
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
|
||||
|
||||
## Data structure of keystore
|
||||
|
||||
```json
|
||||
{
|
||||
// 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"
|
||||
}
|
||||
}
|
||||
```
|
@ -5,10 +5,11 @@
|
||||
"scripts": {
|
||||
"android": "react-native run-android",
|
||||
"ios": "react-native run-ios",
|
||||
"lint": "eslint .",
|
||||
"lint": "eslint . --max-warnings=0",
|
||||
"start": "react-native start",
|
||||
"test": "jest",
|
||||
"postinstall": "patch-package"
|
||||
"postinstall": "patch-package",
|
||||
"prepare": "husky"
|
||||
},
|
||||
"dependencies": {
|
||||
"@cosmjs/amino": "^0.32.3",
|
||||
@ -66,6 +67,7 @@
|
||||
"babel-jest": "^29.6.3",
|
||||
"babel-plugin-module-resolver": "^5.0.0",
|
||||
"eslint": "^8.19.0",
|
||||
"husky": "^9.0.11",
|
||||
"jest": "^29.6.3",
|
||||
"metro-babel7-plugin-react-transform": "^0.54.1",
|
||||
"prettier": "2.8.8",
|
||||
|
@ -23,13 +23,7 @@ const SelectNetworkType = ({
|
||||
|
||||
return (
|
||||
<View style={styles.networkDropdown}>
|
||||
<Text
|
||||
style={{
|
||||
fontWeight: 'bold',
|
||||
marginVertical: 10,
|
||||
}}>
|
||||
Select Network Type
|
||||
</Text>
|
||||
<Text style={styles.selectNetworkText}>Select Network Type</Text>
|
||||
<List.Accordion
|
||||
title={selectedNetwork}
|
||||
expanded={expanded}
|
||||
|
@ -265,6 +265,10 @@ const styles = StyleSheet.create({
|
||||
sessionsContainer: { paddingLeft: 12, borderBottomWidth: 0.5 },
|
||||
walletConnectUriText: { padding: 10 },
|
||||
walletConnectLogo: { width: 24, height: 15, margin: 0 },
|
||||
selectNetworkText: {
|
||||
fontWeight: 'bold',
|
||||
marginVertical: 10,
|
||||
},
|
||||
});
|
||||
|
||||
export default styles;
|
||||
|
@ -10,7 +10,7 @@ export let web3wallet: IWeb3Wallet | undefined;
|
||||
export let core: ICore;
|
||||
|
||||
export async function createWeb3Wallet() {
|
||||
const core = new Core({
|
||||
core = new Core({
|
||||
projectId: Config.WALLET_CONNECT_PROJECT_ID,
|
||||
});
|
||||
|
||||
|
@ -5494,6 +5494,11 @@ human-signals@^5.0.0:
|
||||
resolved "https://registry.yarnpkg.com/human-signals/-/human-signals-5.0.0.tgz#42665a284f9ae0dade3ba41ebc37eb4b852f3a28"
|
||||
integrity sha512-AXcZb6vzzrFAUE61HnN4mpLqd/cSIwNQjtNWR0euPm6y0iqx3G4gOXaIDdtdDwZmhwe82LA6+zinmW4UBWVePQ==
|
||||
|
||||
husky@^9.0.11:
|
||||
version "9.0.11"
|
||||
resolved "https://registry.yarnpkg.com/husky/-/husky-9.0.11.tgz#fc91df4c756050de41b3e478b2158b87c1e79af9"
|
||||
integrity sha512-AB6lFlbwwyIqMdHYhwPe+kjOC3Oc5P3nThEoW/AaO2BX3vJDjWPFxYLxokUZOo6RNX20He3AaT8sESs9NJcmEw==
|
||||
|
||||
idb-keyval@^6.2.1:
|
||||
version "6.2.1"
|
||||
resolved "https://registry.yarnpkg.com/idb-keyval/-/idb-keyval-6.2.1.tgz#94516d625346d16f56f3b33855da11bfded2db33"
|
||||
|
Loading…
Reference in New Issue
Block a user