From 44e95691849cd67a692ef65a6a9fa2b084668519 Mon Sep 17 00:00:00 2001 From: abefernan <44572727+abefernan@users.noreply.github.com> Date: Fri, 14 Apr 2023 17:27:13 +0200 Subject: [PATCH 1/7] Check if multisig --- pages/multi/[address]/index.tsx | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/pages/multi/[address]/index.tsx b/pages/multi/[address]/index.tsx index 6e4484c..b625281 100644 --- a/pages/multi/[address]/index.tsx +++ b/pages/multi/[address]/index.tsx @@ -1,4 +1,4 @@ -import { MultisigThresholdPubkey, SinglePubkey } from "@cosmjs/amino"; +import { MultisigThresholdPubkey, SinglePubkey, isMultisigThresholdPubkey } from "@cosmjs/amino"; import { Account, StargateClient } from "@cosmjs/stargate"; import { assert } from "@cosmjs/utils"; import { Coin } from "cosmjs-types/cosmos/base/v1beta1/coin"; @@ -49,9 +49,10 @@ const Multipage = () => { assert(state.chain.denom, "denom missing"); const tempHoldings = await client.getAllBalances(address); setHoldings(tempHoldings); - const result = await getMultisigAccount(address, client); - setPubkey(result[0]); - setAccountOnChain(result[1]); + const [newPubkey, newAccountOnChain] = await getMultisigAccount(address, client); + assert(isMultisigThresholdPubkey(newPubkey), "pubkey is not multisig"); + setPubkey(newPubkey); + setAccountOnChain(newAccountOnChain); // eslint-disable-next-line @typescript-eslint/no-explicit-any } catch (error: any) { setAccountError(error.message); From a676f96d85b0fe0bad57cff2ed194d6bf9a592d0 Mon Sep 17 00:00:00 2001 From: abefernan <44572727+abefernan@users.noreply.github.com> Date: Tue, 18 Apr 2023 09:30:13 +0200 Subject: [PATCH 2/7] Revert "Check if multisig" This reverts commit 44e95691849cd67a692ef65a6a9fa2b084668519. --- pages/multi/[address]/index.tsx | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/pages/multi/[address]/index.tsx b/pages/multi/[address]/index.tsx index b625281..6e4484c 100644 --- a/pages/multi/[address]/index.tsx +++ b/pages/multi/[address]/index.tsx @@ -1,4 +1,4 @@ -import { MultisigThresholdPubkey, SinglePubkey, isMultisigThresholdPubkey } from "@cosmjs/amino"; +import { MultisigThresholdPubkey, SinglePubkey } from "@cosmjs/amino"; import { Account, StargateClient } from "@cosmjs/stargate"; import { assert } from "@cosmjs/utils"; import { Coin } from "cosmjs-types/cosmos/base/v1beta1/coin"; @@ -49,10 +49,9 @@ const Multipage = () => { assert(state.chain.denom, "denom missing"); const tempHoldings = await client.getAllBalances(address); setHoldings(tempHoldings); - const [newPubkey, newAccountOnChain] = await getMultisigAccount(address, client); - assert(isMultisigThresholdPubkey(newPubkey), "pubkey is not multisig"); - setPubkey(newPubkey); - setAccountOnChain(newAccountOnChain); + const result = await getMultisigAccount(address, client); + setPubkey(result[0]); + setAccountOnChain(result[1]); // eslint-disable-next-line @typescript-eslint/no-explicit-any } catch (error: any) { setAccountError(error.message); From f971bc6989656ac529f23a3dc18b78cb25ffc5be Mon Sep 17 00:00:00 2001 From: abefernan <44572727+abefernan@users.noreply.github.com> Date: Tue, 18 Apr 2023 15:11:58 +0200 Subject: [PATCH 3/7] Check address when getting multisig account --- lib/multisigHelpers.ts | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/lib/multisigHelpers.ts b/lib/multisigHelpers.ts index 3fb5ee0..4edb9a8 100644 --- a/lib/multisigHelpers.ts +++ b/lib/multisigHelpers.ts @@ -1,13 +1,13 @@ -import axios from "axios"; import { createMultisigThresholdPubkey, isMultisigThresholdPubkey, MultisigThresholdPubkey, pubkeyToAddress, } from "@cosmjs/amino"; -import { Account } from "@cosmjs/stargate"; -import { StargateClient } from "@cosmjs/stargate"; +import { Account, StargateClient } from "@cosmjs/stargate"; import { assert } from "@cosmjs/utils"; +import axios from "axios"; +import { checkAddress } from "./displayHelpers"; /** * Turns array of compressed Secp256k1 pubkeys @@ -56,12 +56,18 @@ const createMultisigFromCompressedSecp256k1Pubkeys = async ( */ const getMultisigAccount = async ( address: string, + addressPrefix: string, client: StargateClient, ): Promise<[MultisigThresholdPubkey, Account | null]> => { // we need the multisig pubkeys to create transactions, if the multisig // 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 + const addressError = checkAddress(address, addressPrefix); + if (addressError) { + throw new Error(addressError); + } + const accountOnChain = await client.getAccount(address); const chainId = await client.getChainId(); From 28701d0893ef3a9a2aed1a91bf5ca4a20196815f Mon Sep 17 00:00:00 2001 From: abefernan <44572727+abefernan@users.noreply.github.com> Date: Tue, 18 Apr 2023 15:12:12 +0200 Subject: [PATCH 4/7] Adapt to new getMultisigAccount --- pages/multi/[address]/index.tsx | 5 +++-- pages/multi/[address]/transaction/[transactionID].tsx | 5 +++-- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/pages/multi/[address]/index.tsx b/pages/multi/[address]/index.tsx index 6e4484c..4a7faa6 100644 --- a/pages/multi/[address]/index.tsx +++ b/pages/multi/[address]/index.tsx @@ -49,7 +49,8 @@ const Multipage = () => { assert(state.chain.denom, "denom missing"); const tempHoldings = await client.getAllBalances(address); setHoldings(tempHoldings); - const result = await getMultisigAccount(address, client); + assert(state.chain.addressPrefix, "addressPrefix missing"); + const result = await getMultisigAccount(address, state.chain.addressPrefix, client); setPubkey(result[0]); setAccountOnChain(result[1]); // eslint-disable-next-line @typescript-eslint/no-explicit-any @@ -58,7 +59,7 @@ const Multipage = () => { console.log("Account error:", error); } }, - [state.chain.denom, state.chain.nodeAddress], + [state.chain.addressPrefix, state.chain.denom, state.chain.nodeAddress], ); useEffect(() => { diff --git a/pages/multi/[address]/transaction/[transactionID].tsx b/pages/multi/[address]/transaction/[transactionID].tsx index 3d9cbab..d67c41e 100644 --- a/pages/multi/[address]/transaction/[transactionID].tsx +++ b/pages/multi/[address]/transaction/[transactionID].tsx @@ -87,7 +87,8 @@ const TransactionPage = ({ try { assert(state.chain.nodeAddress, "Node address missing"); const client = await StargateClient.connect(state.chain.nodeAddress); - const result = await getMultisigAccount(address, client); + assert(state.chain.addressPrefix, "addressPrefix missing"); + const result = await getMultisigAccount(address, state.chain.addressPrefix, client); setPubkey(result[0]); setAccountOnChain(result[1]); // eslint-disable-next-line @typescript-eslint/no-explicit-any @@ -96,7 +97,7 @@ const TransactionPage = ({ console.log("Account error:", error); } }, - [state.chain.nodeAddress], + [state.chain.addressPrefix, state.chain.nodeAddress], ); useEffect(() => { From dfceb356183965673a9616bd63f5c600e8d6bb55 Mon Sep 17 00:00:00 2001 From: abefernan <44572727+abefernan@users.noreply.github.com> Date: Tue, 18 Apr 2023 15:12:50 +0200 Subject: [PATCH 5/7] Check multisig before using it. Notify user --- components/forms/FindMultisigForm.tsx | 53 +++++++++++++++++++++------ 1 file changed, 41 insertions(+), 12 deletions(-) diff --git a/components/forms/FindMultisigForm.tsx b/components/forms/FindMultisigForm.tsx index 8dfbf4a..aa10300 100644 --- a/components/forms/FindMultisigForm.tsx +++ b/components/forms/FindMultisigForm.tsx @@ -1,12 +1,13 @@ -import React, { useState } from "react"; -import { withRouter, NextRouter } from "next/router"; - -import { useAppContext } from "../../context/AppContext"; -import Button from "../inputs/Button"; -import StackableContainer from "../layout/StackableContainer"; -import Input from "../inputs/Input"; -import { exampleAddress } from "../../lib/displayHelpers"; +import { StargateClient } from "@cosmjs/stargate"; import { assert } from "@cosmjs/utils"; +import { NextRouter, withRouter } from "next/router"; +import { useEffect, useState } from "react"; +import { useAppContext } from "../../context/AppContext"; +import { exampleAddress } from "../../lib/displayHelpers"; +import { getMultisigAccount } from "../../lib/multisigHelpers"; +import Button from "../inputs/Button"; +import Input from "../inputs/Input"; +import StackableContainer from "../layout/StackableContainer"; interface Props { router: NextRouter; @@ -15,14 +16,36 @@ interface Props { const FindMultisigForm = (props: Props) => { const { state } = useAppContext(); const [address, setAddress] = useState(""); - const [_processing, setProcessing] = useState(false); + const [multisigError, setMultisigError] = useState(""); const handleSearch = () => { - setProcessing(true); - props.router.push(`/multi/${address}`); }; + useEffect(() => { + (async function () { + if (!address) { + setMultisigError(""); + return; + } + + try { + assert(state.chain.nodeAddress, "Node address missing"); + const client = await StargateClient.connect(state.chain.nodeAddress); + assert(state.chain.addressPrefix, "addressPrefix missing"); + await getMultisigAccount(address, state.chain.addressPrefix, client); + setMultisigError(""); + } catch (error) { + if (error instanceof Error) { + setMultisigError(error.message); + } else { + setMultisigError("Multisig error"); + } + console.error("Multisig error:", error); + } + })(); + }, [address, state.chain.addressPrefix, state.chain.nodeAddress]); + assert(state.chain.addressPrefix, "addressPrefix missing"); return ( @@ -40,8 +63,14 @@ const FindMultisigForm = (props: Props) => { label="Multisig Address" name="address" placeholder={`E.g. ${exampleAddress(0, state.chain.addressPrefix)}`} + error={multisigError} + /> +