-
Notifications
You must be signed in to change notification settings - Fork 226
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
0cfddd2
commit 259345e
Showing
7 changed files
with
1,425 additions
and
91 deletions.
There are no files selected for viewing
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
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
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,122 @@ | ||
/* eslint-disable import/no-extraneous-dependencies */ | ||
/* eslint-disable react/display-name */ | ||
import React, { useEffect, useState } from 'react'; | ||
import clsx from 'clsx'; | ||
import { makeStyles } from '@mui/styles'; | ||
import LoadingButton from '@mui/lab/LoadingButton'; | ||
import List from '@mui/material/List'; | ||
import ListItem from '@mui/material/ListItem'; | ||
import ListItemText from '@mui/material/ListItemText'; | ||
import DialogTitle from '@mui/material/DialogTitle'; | ||
import Dialog from '@mui/material/Dialog'; | ||
import { NETWORK_CONFIGS, suggestChain } from '../util/SuggestChain'; | ||
|
||
const useStyles = makeStyles(_ => ({ | ||
hidden: { | ||
display: 'none', | ||
}, | ||
connector: { | ||
display: 'flex', | ||
flexDirection: 'row', | ||
alignItems: 'center', | ||
height: '100%', | ||
}, | ||
centeredText: { | ||
textAlign: 'center', | ||
}, | ||
dialog: { | ||
minWidth: 240, | ||
}, | ||
})); | ||
|
||
const ChainConnector = () => { | ||
const classes = useStyles(); | ||
const [dialogOpened, setDialogOpened] = useState(false); | ||
const [networkConfig, setNetworkConfig] = useState(null); | ||
const [connectionInProgress, setConnectionInProgress] = useState(false); | ||
|
||
const handleClose = () => { | ||
setDialogOpened(false); | ||
}; | ||
|
||
const selectNetworkConfig = nc => { | ||
setNetworkConfig(nc); | ||
setDialogOpened(false); | ||
}; | ||
|
||
useEffect(() => { | ||
if (!networkConfig) { | ||
return () => {}; | ||
} | ||
|
||
let networkChanged = false; | ||
setConnectionInProgress(true); | ||
|
||
const connect = async () => { | ||
if (!window.getOfflineSigner || !window.keplr) { | ||
setNetworkConfig(null); | ||
alert('Please install the Keplr extension'); | ||
} else if (window.keplr.experimentalSuggestChain) { | ||
try { | ||
const cosmJS = await suggestChain(networkConfig[0]); | ||
if (!networkChanged) { | ||
setConnectionInProgress(false); | ||
window.cosmJS = cosmJS; | ||
} | ||
} catch { | ||
if (!networkChanged) { | ||
setConnectionInProgress(false); | ||
setNetworkConfig(null); | ||
} | ||
} | ||
} else { | ||
setNetworkConfig(null); | ||
alert('Please use the most recent version of the Keplr extension'); | ||
} | ||
}; | ||
connect(); | ||
|
||
return () => { | ||
networkChanged = true; | ||
}; | ||
}, [networkConfig]); | ||
|
||
return ( | ||
<> | ||
<div className={clsx('Connector', classes.connector)}> | ||
<LoadingButton | ||
loading={connectionInProgress} | ||
color="primary" | ||
variant="outlined" | ||
onClick={() => setDialogOpened(true)} | ||
> | ||
{networkConfig ? 'Connected' : 'Connect Wallet'} | ||
</LoadingButton> | ||
</div> | ||
<Dialog onClose={handleClose} open={dialogOpened}> | ||
<div className={classes.dialog}> | ||
<DialogTitle className={classes.centeredText}> | ||
Select Network | ||
</DialogTitle> | ||
<List sx={{ pt: 0 }}> | ||
{NETWORK_CONFIGS.map(nc => ( | ||
<ListItem | ||
button | ||
selected={nc === networkConfig} | ||
onClick={() => selectNetworkConfig(nc)} | ||
key={nc[0]} | ||
> | ||
<ListItemText | ||
className={classes.centeredText} | ||
primary={nc[1]} | ||
/> | ||
</ListItem> | ||
))} | ||
</List> | ||
</div> | ||
</Dialog> | ||
</> | ||
); | ||
}; | ||
|
||
export default ChainConnector; |
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
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
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,78 @@ | ||
import { SigningCosmosClient } from '@cosmjs/launchpad'; | ||
|
||
export const AGORIC_COIN_TYPE = 564; | ||
export const COSMOS_COIN_TYPE = 118; | ||
export const NETWORK_CONFIGS = [ | ||
['https://main.agoric.net/network-config', 'Agoric Mainnet'], | ||
['https://testnet.agoric.net/network-config', 'Agoric Testnet'], | ||
['https://devnet.agoric.net/network-config', 'Agoric Devnet'], | ||
['https://stage.agoric.net/network-config', 'Agoric Stage'], | ||
]; | ||
|
||
export async function suggestChain(networkConfig, caption = undefined) { | ||
const coinType = Number( | ||
new URL(networkConfig).searchParams.get('coinType') || AGORIC_COIN_TYPE, | ||
); | ||
const res = await fetch(networkConfig); | ||
if (!res.ok) { | ||
throw Error(`Cannot fetch network: ${res.status}`); | ||
} | ||
const { chainName: chainId, rpcAddrs } = await res.json(); | ||
const hostname = new URL(networkConfig).hostname; | ||
const network = hostname.split('.')[0]; | ||
let rpc; | ||
let api; | ||
if (network !== hostname) { | ||
rpc = `https://${network}.rpc.agoric.net`; | ||
api = `https://${network}.api.agoric.net`; | ||
} else { | ||
rpc = `http://${rpcAddrs[Math.floor(Math.random() * rpcAddrs.length)]}`; | ||
api = rpc.replace(/(:\d+)?$/, ':1317'); | ||
} | ||
const stakeCurrency = { | ||
coinDenom: 'BLD', | ||
coinMinimalDenom: 'ubld', | ||
coinDecimals: 6, | ||
coinGeckoId: undefined, | ||
}; | ||
const stableCurrency = { | ||
coinDenom: 'RUN', | ||
coinMinimalDenom: 'urun', | ||
coinDecimals: 6, | ||
coinGeckoId: undefined, | ||
}; | ||
const chainInfo = { | ||
rpc, | ||
rest: api, | ||
chainId, | ||
chainName: caption || `Agoric ${network}`, | ||
stakeCurrency, | ||
walletUrlForStaking: `https://${network}.staking.agoric.app`, | ||
bip44: { | ||
coinType, | ||
}, | ||
bech32Config: { | ||
bech32PrefixAccAddr: 'agoric', | ||
bech32PrefixAccPub: 'agoricpub', | ||
bech32PrefixValAddr: 'agoricvaloper', | ||
bech32PrefixValPub: 'agoricvaloperpub', | ||
bech32PrefixConsAddr: 'agoricvalcons', | ||
bech32PrefixConsPub: 'agoricvalconspub', | ||
}, | ||
currencies: [stakeCurrency, stableCurrency], | ||
feeCurrencies: [stableCurrency], | ||
features: ['stargate', 'ibc-transfer'], | ||
}; | ||
await window.keplr.experimentalSuggestChain(chainInfo); | ||
await window.keplr.enable(chainId); | ||
|
||
const offlineSigner = window.getOfflineSigner(chainId); | ||
const accounts = await offlineSigner.getAccounts(); | ||
const cosmJS = new SigningCosmosClient( | ||
'https://node-cosmoshub-3.keplr.app/rest', // TODO: Provide correct rest API | ||
accounts[0].address, | ||
offlineSigner, | ||
); | ||
|
||
return cosmJS; | ||
} |
Oops, something went wrong.