-
-
Save usametov/27801077860a178d99e1690b45bdf9fc to your computer and use it in GitHub Desktop.
This is a sample cardano wallet connect for Nami
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import React, { useState } from 'react'; | |
import { useModel } from 'umi'; | |
import { Avatar, Button, Col, Modal, Row, Statistic } from 'antd'; | |
import Loader from '../../utils/loader'; | |
import type Paginate from '@/interfaces/Paginate'; | |
import type { WalletError } from '@/components/WalletConnect/WalletErrors'; | |
import { useCallback } from 'react'; | |
import { fromHex } from '@/utils/utils'; | |
import { fiatToDiemHumanFriendly } from '@/utils/amount-precision'; | |
import { UserOutlined } from '@ant-design/icons'; | |
// backwards compatibility until all Nami users have updated | |
const isBrowser = () => typeof window !== 'undefined'; | |
if (isBrowser() && window.cardano && window.cardano.enable && !window.cardano.nami) { | |
window.cardano.nami = { | |
enable: async () => { | |
if (await window.cardano.enable()) { | |
return { | |
getBalance: () => window.cardano.getBalance(), | |
signData: (address: string, payload: string) => window.cardano.signData(address, payload), | |
signTx: (tx: string, partialSign: boolean) => window.cardano.signTx(tx, partialSign), | |
submitTx: (tx: string) => window.cardano.submitTx(tx), | |
getUtxos: (amount: any, paginate: Paginate) => window.cardano.getUtxos(amount, paginate), | |
getUsedAddresses: () => window.cardano.getUsedAddresses(), | |
getUnusedAddresses: async () => [], | |
getChangeAddress: () => window.cardano.getChangeAddress(), | |
getRewardAddresses: () => window.cardano.getRewardAddresses(), | |
getNetworkId: () => window.cardano.getNetworkId(), | |
experimental: { | |
on: (eventName: string, callback: any) => { | |
if (eventName == 'accountChange') window.cardano.onAccountChange(callback); | |
else if (eventName == 'networkChange') window.cardano.onNetworkChange(callback); | |
}, | |
off: (eventName: string, callback: any) => window.cardano.off(eventName, callback), | |
getCollateral: () => window.cardano.getCollateral(), | |
}, | |
}; | |
} else { | |
return false; | |
} | |
}, | |
isEnabled: () => window.cardano.isEnabled(), | |
apiVersion: '0.1.0', | |
name: 'Nami', | |
icon: "data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 486.17 499.86'%3E%3Cdefs%3E%3Cstyle%3E.cls-1%7Bfill:%23349ea3;%7D%3C/style%3E%3C/defs%3E%3Cg id='Layer_2' data-name='Layer 2'%3E%3Cg id='Layer_1-2' data-name='Layer 1'%3E%3Cpath id='path16' class='cls-1' d='M73.87,52.15,62.11,40.07A23.93,23.93,0,0,1,41.9,61.87L54,73.09,486.17,476ZM102.4,168.93V409.47a23.76,23.76,0,0,1,32.13-2.14V245.94L395,499.86h44.87Zm303.36-55.58a23.84,23.84,0,0,1-16.64-6.68v162.8L133.46,15.57H84L421.28,345.79V107.6A23.72,23.72,0,0,1,405.76,113.35Z'/%3E%3Cpath id='path18' class='cls-1' d='M38.27,0A38.25,38.25,0,1,0,76.49,38.27v0A38.28,38.28,0,0,0,38.27,0ZM41.9,61.8a22,22,0,0,1-3.63.28A23.94,23.94,0,1,1,62.18,38.13V40A23.94,23.94,0,0,1,41.9,61.8Z'/%3E%3Cpath id='path20' class='cls-1' d='M405.76,51.2a38.24,38.24,0,0,0,0,76.46,37.57,37.57,0,0,0,15.52-3.3A38.22,38.22,0,0,0,405.76,51.2Zm15.52,56.4a23.91,23.91,0,1,1,8.39-18.18A23.91,23.91,0,0,1,421.28,107.6Z'/%3E%3Cpath id='path22' class='cls-1' d='M134.58,390.81A38.25,38.25,0,1,0,157.92,426a38.24,38.24,0,0,0-23.34-35.22Zm-15,59.13A23.91,23.91,0,1,1,143.54,426a23.9,23.9,0,0,1-23.94,23.91Z'/%3E%3C/g%3E%3C/g%3E%3C/svg%3E", | |
_events: {}, | |
}; | |
} | |
const addressToBech32 = async () => { | |
await Loader.load(); | |
const address = (await window.cardano.selectedWallet.getUsedAddresses())[0]; | |
return Loader.Cardano.Address.from_bytes(Buffer.from(address, 'hex')).to_bech32(); | |
}; | |
// const getUtxos = async() => { | |
// return (await window.cardano.selectedWallet.getUtxos()).map((utxo: any) => | |
// Loader.Cardano.TransactionUnspentOutput.from_bytes(fromHex(utxo)), | |
// ); | |
//} | |
const getBalance = async () => { | |
await Loader.load(); | |
const balance = await window.cardano.selectedWallet.getBalance(); | |
const value = Loader.Cardano.Value.from_bytes(fromHex(balance)); | |
const lovelace = parseInt(value.coin().to_str()); | |
return lovelace; | |
// use valueToAsset to add all asset. | |
}; | |
const NoNami = () => { | |
if (window.cardano) return true; | |
Modal.info({ | |
title: 'No compatible wallet detected!', | |
content: ( | |
<div> | |
<p>We currently support Nami Wallet Only!</p> | |
<p> Download and Installed Nami Broswer wallet to get Started</p> | |
</div> | |
), | |
okText: 'Download', | |
onOk: () => window.open('https://namiwallet.io'), | |
}); | |
return false; | |
}; | |
const WrongNetworkToast = async (api: any): Promise<boolean> => { | |
if (0 === (await api.getNetworkId())) return Promise.resolve(true); | |
Modal.info({ | |
title: 'Wrong Cardano Network Detected!!', | |
content: ( | |
<div> | |
<p>Change your Cardano Network!</p> | |
</div> | |
), | |
}); | |
return false; | |
}; | |
const checkStatus = async (api: any) => { | |
return await WrongNetworkToast(api); | |
}; | |
const WalletConnect = () => { | |
const [hasCardano, setHasCardano] = useState(null); | |
const [flag, setFlag] = React.useState(false); | |
const { wallet, connectWallet } = useModel('wallet'); | |
// const [shortAddress, setShortAddress] = useState(''); | |
const [balance, setBalance] = useState(0); | |
React.useEffect(() => { | |
if (wallet.connected && !flag) { | |
return ( | |
window.cardano.selectedWallet.name === 'Nami' && | |
window.cardano.selectedWallet.experimental.on( | |
'accountChange', | |
async () => { | |
const address = await addressToBech32(); | |
connectWallet({ | |
...wallet, | |
connected: true, | |
address: address, | |
}); | |
setFlag(true); | |
}, | |
) | |
); | |
} | |
}, [wallet, connectWallet]); | |
React.useEffect(() => { | |
setHasCardano(window.cardano); | |
}, []); | |
const checkConnection = useCallback(async () => { | |
if (window.cardano) { | |
const session = JSON.parse(localStorage.getItem('session') || '{}'); | |
// check if session is empty | |
if (Object.keys(session).length === 0) return; | |
if (!(await window.cardano[session.walletName].isEnabled())) return; | |
const api = await window.cardano[session.walletName].enable().catch((e: WalletError) => { | |
console.log(e); | |
}); | |
if (api) { | |
if (!(await checkStatus(api))) { | |
return; | |
} | |
if (session.walletName === 'flint') { | |
window.cardano.selectedWallet = { | |
...window.cardano[session.walletName], | |
...api, | |
experimental: { | |
getCollateral: api.getCollateral, | |
}, | |
}; | |
} else { | |
window.cardano.selectedWallet = { | |
...window.cardano[session.walletName], | |
...api, | |
}; | |
} | |
} | |
if (Date.now() - parseInt(session.time) < 6000000) { | |
const connectAddress = await addressToBech32(); | |
const walletBalance = await getBalance(); | |
setBalance(walletBalance); | |
// if (connectAddress.length < 11) { | |
// setShortAddress(connectAddress); | |
// } else { | |
// setShortAddress(`${connectAddress.slice(0, 6)}...${connectAddress.slice(-4)}`); | |
// } | |
connectWallet({ | |
...wallet, | |
connected: api ? true : false, | |
address: connectAddress, | |
}); | |
} | |
} | |
}, []); | |
React.useEffect(() => { | |
checkConnection(); | |
}, [checkConnection]); | |
return wallet.connected ? ( | |
<Row gutter={6}> | |
{/* <Meta | |
avatar={<Avatar src={window.cardano.selectedWallet.icon} style={{ height: '18px' }} />} | |
/> */} | |
<Col span={2}> | |
{/* <Meta | |
avatar={<Avatar src={window.cardano.selectedWallet.icon} />} | |
/> */} | |
<Avatar shape="square" size="small" src={window.cardano.selectedWallet.icon} /> | |
</Col> | |
<Col span={4}> | |
<Avatar size="small" icon={<UserOutlined />} /> | |
</Col> | |
<Col span={18}> | |
<Statistic value={fiatToDiemHumanFriendly(balance)} precision={2} suffix="₳" /> | |
</Col> | |
</Row> | |
) : ( | |
<Button | |
onClick={async () => { | |
return hasCardano | |
? // 1. enable wallet to connect | |
window.cardano && | |
Object.keys(window.cardano) | |
.filter((walletName) => walletName == 'nami' || walletName == 'ccvault') | |
.map(async (walletName) => { | |
const api = await window.cardano[walletName].enable().catch((e: WalletError) => { | |
console.log(e); | |
}); | |
if (api) { | |
if (!(await checkStatus(api))) { | |
return; | |
} | |
window.cardano.selectedWallet = { | |
...window.cardano[walletName], | |
...api, | |
}; | |
localStorage.setItem( | |
'session', | |
JSON.stringify({ | |
time: Date.now().toString(), | |
walletName, | |
}), | |
); | |
// set global wallet state | |
const address = await addressToBech32(); | |
// setShortAddress(`${address.slice(0, 6)}...${address.slice(-4)}`); | |
connectWallet({ | |
...wallet, | |
connected: true, | |
address: address, | |
}); | |
} | |
}) | |
: // end of wallet enabled | |
NoNami(); | |
}} | |
type="primary" | |
size="large" | |
> | |
Connect your wallet | |
</Button> | |
); | |
}; | |
export default WalletConnect; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment