diff --git a/components/forms/TransactionSigning.tsx b/components/forms/TransactionSigning.tsx index f1b0c2d..cffdfbc 100644 --- a/components/forms/TransactionSigning.tsx +++ b/components/forms/TransactionSigning.tsx @@ -1,4 +1,4 @@ -import { makeCosmoshubPath } from "@cosmjs/amino"; +import { MultisigThresholdPubkey, makeCosmoshubPath } from "@cosmjs/amino"; import { toBase64 } from "@cosmjs/encoding"; import { LedgerSigner } from "@cosmjs/ledger-amino"; import { SigningStargateClient } from "@cosmjs/stargate"; @@ -12,6 +12,8 @@ import HashView from "../dataViews/HashView"; import Button from "../inputs/Button"; import StackableContainer from "../layout/StackableContainer"; +type SigningStatus = "not_signed" | "not_a_member" | "signed"; + interface LoadingStates { readonly signing?: boolean; readonly keplr?: boolean; @@ -21,15 +23,18 @@ interface LoadingStates { interface Props { signatures: DbSignature[]; tx: DbTransaction; + pubkey: MultisigThresholdPubkey; transactionID: string; addSignature: (signature: DbSignature) => void; } const TransactionSigning = (props: Props) => { + const memberPubkeys = props.pubkey.value.pubkeys.map(({ value }) => value); + const { state } = useAppContext(); const [walletAccount, setWalletAccount] = useState(); const [sigError, setSigError] = useState(""); - const [hasSigned, setHasSigned] = useState(false); + const [signing, setSigning] = useState("not_signed"); const [walletType, setWalletType] = useState<"Keplr" | "Ledger">(); const [ledgerSigner, setLedgerSigner] = useState({}); const [loading, setLoading] = useState({}); @@ -44,12 +49,23 @@ const TransactionSigning = (props: Props) => { sign: { preferNoSetFee: true, preferNoSetMemo: true, disableBalanceCheck: true }, }; const tempWalletAccount = await window.keplr.getKey(state.chain.chainId); - console.log(tempWalletAccount); - const tempHasSigned = props.signatures.some( - (sig) => sig.address === tempWalletAccount.bech32Address, - ); setWalletAccount(tempWalletAccount); - setHasSigned(tempHasSigned); + + const pubkey = toBase64(tempWalletAccount.pubKey); + const isMember = memberPubkeys.includes(pubkey); + const hasSigned = isMember + ? props.signatures.some((sig) => sig.address === tempWalletAccount.bech32Address) + : false; + if (!isMember) { + setSigning("not_a_member"); + } else { + if (hasSigned) { + setSigning("signed"); + } else { + setSigning("not_signed"); + } + } + setWalletType("Keplr"); } catch (e) { console.log("enable keplr err: ", e); @@ -71,20 +87,29 @@ const TransactionSigning = (props: Props) => { hdPaths: [makeCosmoshubPath(0)], prefix: state.chain.addressPrefix, }); - console.log(offlineSigner); const accounts = await offlineSigner.getAccounts(); - console.log(accounts); const tempWalletAccount: WalletAccount = { bech32Address: accounts[0].address, - pubkey: accounts[0].pubkey, + pubKey: accounts[0].pubkey, algo: accounts[0].algo, }; - - const tempHasSigned = props.signatures.some( - (sig) => sig.address === tempWalletAccount.bech32Address, - ); setWalletAccount(tempWalletAccount); - setHasSigned(tempHasSigned); + + const pubkey = toBase64(tempWalletAccount.pubKey); + const isMember = memberPubkeys.includes(pubkey); + const hasSigned = isMember + ? props.signatures.some((sig) => sig.address === tempWalletAccount.bech32Address) + : false; + if (!isMember) { + setSigning("not_a_member"); + } else { + if (hasSigned) { + setSigning("signed"); + } else { + setSigning("not_signed"); + } + } + setLedgerSigner(offlineSigner); setWalletType("Ledger"); } catch (e) { @@ -142,7 +167,7 @@ const TransactionSigning = (props: Props) => { signature, ); props.addSignature(signature); - setHasSigned(true); + setSigning("signed"); } } catch (e) { console.log("signing err: ", e); @@ -153,7 +178,7 @@ const TransactionSigning = (props: Props) => { return ( - {hasSigned ? ( + {signing === "signed" ? (
@@ -162,7 +187,15 @@ const TransactionSigning = (props: Props) => {

You've signed this transaction.

- ) : ( + ) : null} + {signing === "not_a_member" ? ( + +
+

You don't belong to this multisig.

+
+
+ ) : null} + {signing === "not_signed" ? ( <>

Sign this transaction

@@ -190,7 +223,7 @@ const TransactionSigning = (props: Props) => { )} - )} + ) : null} {sigError && (
@@ -241,6 +274,10 @@ const TransactionSigning = (props: Props) => { height: 0.8em; margin-right: 0.5em; } + .multisig-error p { + color: red; + font-size: 16px; + } `} ); diff --git a/pages/multi/[address]/transaction/[transactionID].tsx b/pages/multi/[address]/transaction/[transactionID].tsx index d67c41e..dac3082 100644 --- a/pages/multi/[address]/transaction/[transactionID].tsx +++ b/pages/multi/[address]/transaction/[transactionID].tsx @@ -168,10 +168,11 @@ const TransactionPage = ({ {broadcastError &&
{broadcastError}
} )} - {!transactionHash && ( + {!transactionHash && !!pubkey && ( diff --git a/types/index.ts b/types/index.ts index f6e78f1..16c5879 100644 --- a/types/index.ts +++ b/types/index.ts @@ -39,7 +39,7 @@ export interface DbAccount { export interface WalletAccount { address?: Uint8Array; - pubkey: Uint8Array; + pubKey: Uint8Array; algo: string; bech32Address: string; isNanoLedger?: boolean;