Skip to content

Commit

Permalink
Merge pull request #4 from umee-network/matt/add-wallet-error-handling
Browse files Browse the repository at this point in the history
Matt/add wallet error handling
  • Loading branch information
dreamcodez authored Feb 24, 2022
2 parents d615b41 + d12f026 commit 299ec88
Show file tree
Hide file tree
Showing 6 changed files with 89 additions and 80 deletions.
19 changes: 7 additions & 12 deletions components/forms/MultisigForm.js
Original file line number Diff line number Diff line change
Expand Up @@ -93,18 +93,13 @@ const MultiSigForm = (props) => {
const handleCreate = async () => {
setProcessing(true);
const compressedPubkeys = pubkeys.map((item) => item.compressedPubkey);
let multisigAddress;
try {
multisigAddress = await createMultisigFromCompressedSecp256k1Pubkeys(
compressedPubkeys,
parseInt(threshold, 10),
state.chain.addressPrefix,
state.chain.chainId,
);
props.router.push(`/multi/${multisigAddress}`);
} catch (error) {
console.log("Failed to creat multisig: ", error);
}
const multisigAddress = await createMultisigFromCompressedSecp256k1Pubkeys(
compressedPubkeys,
parseInt(threshold, 10),
state.chain.addressPrefix,
state.chain.chainId,
);
props.router.push(`/multi/${multisigAddress}`);
};

const togglePubkey = (index) => {
Expand Down
104 changes: 48 additions & 56 deletions components/forms/TransactionSigning.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,69 +16,61 @@ const TransactionSigning = (props) => {

useEffect(() => {
connectWallet();
window.addEventListener("keplr_keystorechange", connectWallet);
}, []);

const connectWallet = async () => {
try {
await window.keplr.enable(state.chain.chainId);
const tempWalletAccount = await window.keplr.getKey(state.chain.chainId);
const tempHasSigned = props.signatures.some(
(sig) => sig.address === tempWalletAccount.bech32Address,
);
setWalletAccount(tempWalletAccount);
setHasSigned(tempHasSigned);
} catch (e) {
console.log("enable err: ", e);
}
await window.keplr.enable(state.chain.chainId);
const tempWalletAccount = await window.keplr.getKey(state.chain.chainId);
const tempHasSigned = props.signatures.some(
(sig) => sig.address === tempWalletAccount.bech32Address,
);
setWalletAccount(tempWalletAccount);
setHasSigned(tempHasSigned);
console.log("wallet connected:", tempWalletAccount);
window.keplr_wallet = tempWalletAccount;
};

const signTransaction = async () => {
try {
window.keplr.defaultOptions = {
sign: {
preferNoSetMemo: true,
preferNoSetFee: true,
disableBalanceCheck: true,
},
};
const offlineSigner = window.getOfflineSignerOnlyAmino(state.chain.chainId);
const signingClient = await SigningStargateClient.offline(offlineSigner);
const signerData = {
accountNumber: props.tx.accountNumber,
sequence: props.tx.sequence,
chainId: state.chain.chainId,
};
const { bodyBytes, signatures } = await signingClient.sign(
walletAccount.bech32Address,
props.tx.msgs,
props.tx.fee,
props.tx.memo,
signerData,
);
// check existing signatures
const bases64EncodedSignature = toBase64(signatures[0]);
const bases64EncodedBodyBytes = toBase64(bodyBytes);
const prevSigMatch = props.signatures.findIndex(
(signature) => signature.signature === bases64EncodedSignature,
);
window.keplr.defaultOptions = {
sign: {
preferNoSetMemo: true,
preferNoSetFee: true,
disableBalanceCheck: true,
},
};
const offlineSigner = window.getOfflineSignerOnlyAmino(state.chain.chainId);
const signingClient = await SigningStargateClient.offline(offlineSigner);
const signerData = {
accountNumber: props.tx.accountNumber,
sequence: props.tx.sequence,
chainId: state.chain.chainId,
};
const { bodyBytes, signatures } = await signingClient.sign(
walletAccount.bech32Address,
props.tx.msgs,
props.tx.fee,
props.tx.memo,
signerData,
);
// check existing signatures
const bases64EncodedSignature = toBase64(signatures[0]);
const bases64EncodedBodyBytes = toBase64(bodyBytes);
const prevSigMatch = props.signatures.findIndex(
(signature) => signature.signature === bases64EncodedSignature,
);

if (prevSigMatch > -1) {
setSigError("This account has already signed.");
} else {
const signature = {
bodyBytes: bases64EncodedBodyBytes,
signature: bases64EncodedSignature,
address: walletAccount.bech32Address,
};
const _res = await axios.post(
`/api/transaction/${props.transactionID}/signature`,
signature,
);
props.addSignature(signature);
setHasSigned(true);
}
} catch (error) {
console.log("Error creating signature:", error);
if (prevSigMatch > -1) {
setSigError("This account has already signed.");
} else {
const signature = {
bodyBytes: bases64EncodedBodyBytes,
signature: bases64EncodedSignature,
address: walletAccount.bech32Address,
};
const _res = await axios.post(`/api/transaction/${props.transactionID}/signature`, signature);
props.addSignature(signature);
setHasSigned(true);
}
};

Expand Down
18 changes: 17 additions & 1 deletion components/messages/MsgVote.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import React, { useState, useEffect } from "react";
import { useAppContext } from "../../context/AppContext";
import Input from "../../components/inputs/Input";
import Select from "../../components/inputs/Select";
import { checkAddress, exampleAddress } from "../../lib/displayHelpers";
import { checkAddress, checkProposalId } from "../../lib/displayHelpers";

// https://docs.cosmos.network/v0.44/core/proto-docs.html#cosmos.gov.v1beta1.VoteOption
const voteOptions = [
Expand All @@ -19,6 +19,7 @@ const MsgVote = (props) => {
const onCheck = props.onCheck || (() => {});
const { state } = useAppContext();
const [voterError, setVoterError] = useState("");
const [proposalIdError, setProposalIdError] = useState("");

// const [amountError, setAmountError] = useState("");

Expand All @@ -41,6 +42,20 @@ const MsgVote = (props) => {
}
}

const toProposalIdError = checkProposalId(v.proposalId);
if (updateInternalErrors) {
if (toProposalIdError) {
const errorMsg = `Invalid proposal_id for network ${state.chain.chainId}: ${toProposalIdError}`;
setProposalIdError(errorMsg);
} else {
setProposalIdError("");
}
}

if (toVoterError || toProposalIdError) {
return false;
}

return true;
}

Expand Down Expand Up @@ -82,6 +97,7 @@ const MsgVote = (props) => {
type="number"
value={props.msg.value.proposalId}
onChange={(e) => checkAndSetProposalId(e.target.value)}
error={proposalIdError}
/>
</div>
<div className="form-item">
Expand Down
16 changes: 16 additions & 0 deletions lib/displayHelpers.js
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,21 @@ const checkAddress = (input, chainAddressPrefix) => {
return null;
};

const checkProposalId = (input) => {
if (!input) return "Empty";
const n = parseInt(input, 10);

if (isNaN(n)) {
return "Expected an integer";
}

if (n < 0) {
return "Expected a non-negative number";
}

return null;
};

/**
* Returns a link to a transaction in an explorer if an explorer is configured
* for transactions. Returns null otherwise.
Expand All @@ -141,5 +156,6 @@ export {
exampleAddress,
examplePubkey,
checkAddress,
checkProposalId,
explorerLinkTx,
};
9 changes: 1 addition & 8 deletions lib/multisigHelpers.js
Original file line number Diff line number Diff line change
Expand Up @@ -51,22 +51,15 @@ const getMultisigAccount = async (address, client) => {
// is new, and has never submitted a transaction its pubkeys will not be
// available from a node. If the multisig was created with this instance
// of this tool its pubkey will be available in the fauna datastore
let accountOnChain = await client.getAccount(address);
const accountOnChain = await client.getAccount(address);
const chainId = await client.getChainId();

if (!accountOnChain || !accountOnChain.pubkey) {
console.log("No pubkey on chain for: ", address);
const res = await axios.get(`/api/chain/${chainId}/multisig/${address}`);

if (res.status !== 200) {
throw new Error("Multisig has no pubkey on node, and was not created using this tool.");
}
const pubkey = JSON.parse(res.data.pubkeyJSON);

if (!accountOnChain) {
accountOnChain = {};
}
accountOnChain.pubkey = pubkey;
}
return accountOnChain;
};
Expand Down
3 changes: 0 additions & 3 deletions pages/multi/[address]/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -23,12 +23,9 @@ function participantAddressesFromMultisig(multisigPubkey, addressPrefix) {
);
}

const msgKinds = ["/cosmos.bank.v1beta1.MsgSend", "/cosmos.staking.v1beta1.MsgDelegate"];

const multipage = (_props) => {
const { state } = useAppContext();
const [showTxForm, setShowTxForm] = useState(false);
const [msgKind, setMsgKind] = useState("/cosmos.bank.v1beta1.MsgSend");
const [holdings, setHoldings] = useState("");
const [accountOnChain, setAccountOnChain] = useState(null);
const [accountError, setAccountError] = useState(null);
Expand Down

1 comment on commit 299ec88

@vercel
Copy link

@vercel vercel bot commented on 299ec88 Feb 24, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please sign in to comment.