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
|
30
README.md
30
README.md
@ -1,6 +1,6 @@
|
|||||||
# laconic-wallet
|
# laconic-wallet
|
||||||
|
|
||||||
### Install
|
## Install
|
||||||
|
|
||||||
- Install [Node](https://nodejs.org/en/download/package-manager/)
|
- Install [Node](https://nodejs.org/en/download/package-manager/)
|
||||||
|
|
||||||
@ -134,3 +134,31 @@
|
|||||||
5. Press `a` to run the application on android
|
5. Press `a` to run the application on android
|
||||||
|
|
||||||
You should see both the apps running on your emulator or physical device.
|
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": {
|
"scripts": {
|
||||||
"android": "react-native run-android",
|
"android": "react-native run-android",
|
||||||
"ios": "react-native run-ios",
|
"ios": "react-native run-ios",
|
||||||
"lint": "eslint .",
|
"lint": "eslint . --max-warnings=0",
|
||||||
"start": "react-native start",
|
"start": "react-native start",
|
||||||
"test": "jest",
|
"test": "jest",
|
||||||
"postinstall": "patch-package"
|
"postinstall": "patch-package",
|
||||||
|
"prepare": "husky"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@cosmjs/amino": "^0.32.3",
|
"@cosmjs/amino": "^0.32.3",
|
||||||
@ -66,6 +67,7 @@
|
|||||||
"babel-jest": "^29.6.3",
|
"babel-jest": "^29.6.3",
|
||||||
"babel-plugin-module-resolver": "^5.0.0",
|
"babel-plugin-module-resolver": "^5.0.0",
|
||||||
"eslint": "^8.19.0",
|
"eslint": "^8.19.0",
|
||||||
|
"husky": "^9.0.11",
|
||||||
"jest": "^29.6.3",
|
"jest": "^29.6.3",
|
||||||
"metro-babel7-plugin-react-transform": "^0.54.1",
|
"metro-babel7-plugin-react-transform": "^0.54.1",
|
||||||
"prettier": "2.8.8",
|
"prettier": "2.8.8",
|
||||||
|
@ -23,13 +23,7 @@ const SelectNetworkType = ({
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<View style={styles.networkDropdown}>
|
<View style={styles.networkDropdown}>
|
||||||
<Text
|
<Text style={styles.selectNetworkText}>Select Network Type</Text>
|
||||||
style={{
|
|
||||||
fontWeight: 'bold',
|
|
||||||
marginVertical: 10,
|
|
||||||
}}>
|
|
||||||
Select Network Type
|
|
||||||
</Text>
|
|
||||||
<List.Accordion
|
<List.Accordion
|
||||||
title={selectedNetwork}
|
title={selectedNetwork}
|
||||||
expanded={expanded}
|
expanded={expanded}
|
||||||
|
@ -265,6 +265,10 @@ const styles = StyleSheet.create({
|
|||||||
sessionsContainer: { paddingLeft: 12, borderBottomWidth: 0.5 },
|
sessionsContainer: { paddingLeft: 12, borderBottomWidth: 0.5 },
|
||||||
walletConnectUriText: { padding: 10 },
|
walletConnectUriText: { padding: 10 },
|
||||||
walletConnectLogo: { width: 24, height: 15, margin: 0 },
|
walletConnectLogo: { width: 24, height: 15, margin: 0 },
|
||||||
|
selectNetworkText: {
|
||||||
|
fontWeight: 'bold',
|
||||||
|
marginVertical: 10,
|
||||||
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
export default styles;
|
export default styles;
|
||||||
|
@ -10,7 +10,7 @@ export let web3wallet: IWeb3Wallet | undefined;
|
|||||||
export let core: ICore;
|
export let core: ICore;
|
||||||
|
|
||||||
export async function createWeb3Wallet() {
|
export async function createWeb3Wallet() {
|
||||||
const core = new Core({
|
core = new Core({
|
||||||
projectId: Config.WALLET_CONNECT_PROJECT_ID,
|
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"
|
resolved "https://registry.yarnpkg.com/human-signals/-/human-signals-5.0.0.tgz#42665a284f9ae0dade3ba41ebc37eb4b852f3a28"
|
||||||
integrity sha512-AXcZb6vzzrFAUE61HnN4mpLqd/cSIwNQjtNWR0euPm6y0iqx3G4gOXaIDdtdDwZmhwe82LA6+zinmW4UBWVePQ==
|
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:
|
idb-keyval@^6.2.1:
|
||||||
version "6.2.1"
|
version "6.2.1"
|
||||||
resolved "https://registry.yarnpkg.com/idb-keyval/-/idb-keyval-6.2.1.tgz#94516d625346d16f56f3b33855da11bfded2db33"
|
resolved "https://registry.yarnpkg.com/idb-keyval/-/idb-keyval-6.2.1.tgz#94516d625346d16f56f3b33855da11bfded2db33"
|
||||||
|
Loading…
Reference in New Issue
Block a user