Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Stephen/fix custom keplr #941

Draft
wants to merge 2 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
114 changes: 63 additions & 51 deletions src/components/chainlist.jsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,13 @@
import { useState, useEffect, useMemo } from 'react'
import { mainnet as mainnetEvmMetadata, testnet as testnetEvmMetadata } from "../../src/data/evm_chains.json"
import { mainnet as mainnetCosmosMetadata, testnet as testnetCosmosMetadata } from "../../src/data/cosmos_chains.json"
import AddKeplr from "./keplr"
import { useState, useEffect, useMemo } from "react";
import {
mainnet as mainnetEvmMetadata,
testnet as testnetEvmMetadata,
} from "../../src/data/evm_chains.json";
import {
mainnet as mainnetCosmosMetadata,
testnet as testnetCosmosMetadata,
} from "../../src/data/cosmos_chains.json";
import AddKeplr from "./keplr/add-keplr";

function ChainListRow({ chainId, name, identifier, environment }) {
return (
Expand All @@ -13,85 +19,93 @@ function ChainListRow({ chainId, name, identifier, environment }) {
<AddKeplr environment={environment} chain={chainId} />
</td>
</tr>
)
);
}


const createChainIndex = (chains) => {
const index = new Map();
for (const chain of chains) {
if (index.has(chain.chain_id)) {
console.error(`duplicate chain ${chain.chain_id}. Removing to be safe`)
index.delete(chain.chain_id)
console.error(`duplicate chain ${chain.chain_id}. Removing to be safe`);
index.delete(chain.chain_id);
}
index.set(chain.network_id, chain)
index.set(chain.network_id, chain);
}
return index
}
return index;
};

export default ({ environment }) => {
const chainIndex = useMemo(() => {
switch (environment) {
case `mainnet`:
return createChainIndex([...mainnetEvmMetadata, ...mainnetCosmosMetadata])
return createChainIndex([
...mainnetEvmMetadata,
...mainnetCosmosMetadata,
]);
case `testnet`:
return createChainIndex([...testnetEvmMetadata, ...testnetCosmosMetadata])
return createChainIndex([
...testnetEvmMetadata,
...testnetCosmosMetadata,
]);
default:
console.error(`invalid environment ${environment}`)
return null
console.error(`invalid environment ${environment}`);
return null;
}
}, [environment]);

const [fetching, setFetching] = useState(false)
const [response, setResponse] = useState(null)
const [error, setError] = useState(null)
const [fetching, setFetching] = useState(false);
const [response, setResponse] = useState(null);
const [error, setError] = useState(null);

useEffect(() => {
if (!response) request();
}, [response])
}, [response]);

const request = async () => {
setFetching(true);

setFetching(true)

const endpoint_url = environment === `testnet`
? `https://lcd-axelar-testnet.imperator.co/axelar/nexus/v1beta1/chains?status=1`
: `https://lcd-axelar.imperator.co/axelar/nexus/v1beta1/chains?status=1`;
const endpoint_url =
environment === `testnet`
? `https://lcd-axelar-testnet.imperator.co/axelar/nexus/v1beta1/chains?status=1`
: `https://lcd-axelar.imperator.co/axelar/nexus/v1beta1/chains?status=1`;

fetch(endpoint_url)
.then(data => data.json())
.then(chains => setResponse(chains))
.catch(error => setError(true))
.finally(() => setFetching(false))
}
.then((data) => data.json())
.then((chains) => setResponse(chains))
.catch((error) => setError(true))
.finally(() => setFetching(false));
};

const tableRowData = useMemo(() => {
if (!response) return null
if (!response) return null;
return response.chains.map((chainIdentifier, idx) => {
const chainData = chainIndex.get(chainIdentifier)
const chainData = chainIndex.get(chainIdentifier);
if (!chainData) {
console.error(`chain ${chainIdentifier} not found in chain index`)
return null
console.error(`chain ${chainIdentifier} not found in chain index`);
return null;
}

return <ChainListRow
key={idx}
chainId={chainData.chain_id}
name={chainData.name}
identifier={chainIdentifier}
environment={environment} />
return (
<ChainListRow
key={idx}
chainId={chainData.chain_id}
name={chainData.name}
identifier={chainIdentifier}
environment={environment}
/>
);
});
}, [response, environment])
}, [response, environment]);

if (fetching)
return <div className="mx-1 mt-5 space-y-4">
Fetching active chains...
</div>
return <div className="mx-1 mt-5 space-y-4">Fetching active chains...</div>;

if (error)
return <div className="mx-1 mt-5 space-y-4">
Error loading chains. Please refresh this page.
</div>
return (
<div className="mx-1 mt-5 space-y-4">
Error loading chains. Please refresh this page.
</div>
);

return (
<div className="mx-1 mt-5 space-y-1">
Expand All @@ -104,10 +118,8 @@ export default ({ environment }) => {
<th>Add Chain</th>
</tr>
</thead>
<tbody>
{tableRowData}
</tbody>
<tbody>{tableRowData}</tbody>
</table>
</div>
)
}
);
};
67 changes: 67 additions & 0 deletions src/components/keplr/add-custom-keplr.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
export default ({
providedSettings = null,
title = "Add Custom Chain Config",
}) => {
let settings;
const addNetwork = async () => {
if (!providedSettings) {
let field = document.getElementById("keplr_wallet_json_configuration");
console.log("field", field);

// re-layout the field
try {
const ugly = field.value;
document.getElementById("keplr_wallet_json_configuration").value =
JSON.stringify(JSON.parse(ugly), undefined, 4);
} catch (error) {
if (error instanceof SyntaxError) {
alert(
"There was a syntax error. Please correct it and try again: " +
error.message
);
} else {
throw error;
}
}

try {
settings = JSON.parse(field.value);
} catch (error) {
if (error instanceof SyntaxError) {
alert(
"There was a syntax error. Please correct it and try again: " +
error.message
);
} else {
alert(error.message);
}
}
} else {
settings = providedSettings;
}
console.log("settings were determined to be", settings);

try {
await window.keplr.enable(settings.chainId);
alert(settings.chainId + " already added");
} catch (e) {
console.log(
"Unable to connect to wallet natively, so trying experimental chain"
);
try {
await window.keplr.experimentalSuggestChain(settings);
await window.keplr.enable(settings.chainId);
} catch (e2) {
alert("Invalid Keplr JSON configuration. " + e2.message);
console.log("and yet there is a problem in trying to do that too", e2);
}
}
};

return (
<button onClick={() => addNetwork()} className="flex keplr-button">
{title}
<img src="/images/wallets/keplr.png" alt="" width={16} height={16} />
</button>
);
};
File renamed without changes.
42 changes: 23 additions & 19 deletions src/components/textarea.jsx
Original file line number Diff line number Diff line change
@@ -1,24 +1,28 @@
import { useState } from "react";
const placeholder = '{"rpc":"https://axelartest-rpc.quickapi.com:443","rest":"https://axelartest-lcd.quickapi.com:443","chainId":"axelar-testnet-lisbon-3","chainName":"Axelar Testnet","stakeCurrency":{"coinDenom":"AXL","coinMinimalDenom":"uaxl","coinDecimals":6},"bech32Config":{"bech32PrefixAccAddr":"axelar","bech32PrefixAccPub":"axelarpub","bech32PrefixValAddr":"axelarvaloper","bech32PrefixValPub":"axelarvaloperpub","bech32PrefixConsAddr":"axelarvalcons","bech32PrefixConsPub":"axelarvalconspub"},"bip44":{"coinType":118},"currencies":[{"coinDenom":"AXL","coinMinimalDenom":"uaxl","coinDecimals":6}],"feeCurrencies":[{"coinDenom":"AXL","coinMinimalDenom":"uaxl","coinDecimals":6}],"gasPriceStep":{"low":0.05,"average":0.125,"high":0.2},"features":["stargate","no-legacy-stdTx","ibc-transfer"]}'
const placeholder =
'{"rpc":"https://axelartest-rpc.quickapi.com:443","rest":"https://axelartest-lcd.quickapi.com:443","chainId":"axelar-testnet-lisbon-3","chainName":"Axelar Testnet","stakeCurrency":{"coinDenom":"AXL","coinMinimalDenom":"uaxl","coinDecimals":6},"bech32Config":{"bech32PrefixAccAddr":"axelar","bech32PrefixAccPub":"axelarpub","bech32PrefixValAddr":"axelarvaloper","bech32PrefixValPub":"axelarvaloperpub","bech32PrefixConsAddr":"axelarvalcons","bech32PrefixConsPub":"axelarvalconspub"},"bip44":{"coinType":118},"currencies":[{"coinDenom":"AXL","coinMinimalDenom":"uaxl","coinDecimals":6}],"feeCurrencies":[{"coinDenom":"AXL","coinMinimalDenom":"uaxl","coinDecimals":6}],"gasPriceStep":{"low":0.05,"average":0.125,"high":0.2},"features":["stargate","no-legacy-stdTx","ibc-transfer"]}';

export default ({}) => {
const [value, setValue] = useState(placeholder);

const [value, setValue] = useState(placeholder);

return <>
<label
htmlFor="keplr_wallet_json_configuration"
className="block mb-2 text-sm font-medium text-gray-900 dark:text-gray-400"
>
Keplr Wallet stringified JSON configuration (Axelar testnet placeholder below)
</label>
<textarea
id="keplr_wallet_json_configuration"
rows="4"
value={value}
onChange={e => setValue(e.target.value)}
className="block p-2.5 w-full text-sm text-gray-900 bg-gray-50 rounded-lg border border-gray-300 focus:ring-blue-500 focus:border-blue-500 dark:bg-gray-700 dark:border-gray-600 dark:placeholder-gray-400 dark:text-white dark:focus:ring-blue-500 dark:focus:border-blue-500"
placeholder={placeholder}>
</textarea>
return (
<>
<label
htmlFor="keplr_wallet_json_configuration"
className="block mb-2 text-sm font-medium text-gray-900 dark:text-gray-400"
>
Keplr Wallet stringified JSON configuration (Axelar testnet placeholder
below)
</label>
<textarea
id="keplr_wallet_json_configuration"
rows="8"
value={value}
onChange={(e) => setValue(e.target.value)}
className="block p-2.5 w-full text-sm text-gray-900 bg-gray-50 rounded-lg border border-gray-300 focus:ring-blue-500 focus:border-blue-500 dark:bg-gray-700 dark:border-gray-600 dark:placeholder-gray-400 dark:text-white dark:focus:ring-blue-500 dark:focus:border-blue-500"
style={{ width: "100%" }}
placeholder={placeholder}
></textarea>
</>
};
);
};
51 changes: 5 additions & 46 deletions src/pages/resources/keplr.mdx
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
# Add a custom network to Keplr

import Button from "../../components/keplr/addKeplrWallet";
import AddKeplr from "../../components/keplr";
import AddKeplr from "../../components/keplr/add-keplr";
import AddCustomKeplr from "../../components/keplr/add-custom-keplr";
import Form from "../../components/textarea";


## Don't have the Keplr Browser extension? Add it here:

[Add Keplr Wallet](https://chrome.google.com/webstore/detail/keplr/dmkamcknogkgcdfhhbddcghachkejeap?hl=en")
Expand All @@ -28,49 +30,6 @@ import Form from "../../components/textarea";
| Terra-2 | <AddKeplr client:only environment="testnet" chain="terra" /> | <AddKeplr client:only environment="mainnet" chain="terra" /> |

## Add your custom network

<Form />

<Button buttonTitle="Validate Input & Add to Keplr" onClick={async (data) => {
let field = document.getElementById("keplr_wallet_json_configuration");
let settings = null;

try {
const ugly = field.value;
document.getElementById('keplr_wallet_json_configuration').value = JSON.stringify(JSON.parse(ugly), undefined, 4);
} catch (error) {
if (error instanceof SyntaxError) {
alert("There was a syntax error. Please correct it and try again: " + error.message);
}
else {
throw error;
}
}

try {
settings = JSON.parse(field.value);

try {
await window.keplr.enable(settings.chainId)
alert(settings.chainId + " already added")
} catch (e) {
console.log("Unable to connect to wallet natively, so trying experimental chain")
try {
await window.keplr.experimentalSuggestChain(settings)
await window.keplr.enable(settings.chainId)
} catch (e2) {
alert("Invalid Keplr JSON configuration. " + e2.message);
console.log("and yet there is a problem in trying to do that too", e2)
}
}

} catch (error) {
if (error instanceof SyntaxError) {
alert("There was a syntax error. Please correct it and try again: " + error.message);
}
else {
alert(error.message);
}
}

}}></Button>
<AddCustomKeplr client:only></AddCustomKeplr>
<AddCustomKeplr client:only title="Amplifier Devnet"></AddCustomKeplr>