diff --git a/lib/multisigHelpers.js b/lib/multisigHelpers.js index d0809a8..ea8de37 100644 --- a/lib/multisigHelpers.js +++ b/lib/multisigHelpers.js @@ -38,7 +38,7 @@ const createMultisigFromCompressedSecp256k1Pubkeys = async ( /** * This gets a multisigs account (pubkey, sequence, account number, etc) from - * a node and/or the faunadb if the multisig was made on this app + * a node and/or the api if the multisig was made on this app * * @param {string} address The multisig address * @param client A connected stargate cosmoshub client @@ -53,12 +53,12 @@ const getMultisigAccount = async (address, client) => { if (!accountOnChain || !accountOnChain.pubkey) { console.log("No pubkey on chain for: ", address); - const res = await getMultisig(address); + const res = await axios.get(`/api/multisig/${address}`); - if (!res.data.data.getMultisig) { + 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.data.getMultisig.pubkeyJSON); + const pubkey = JSON.parse(res.data.pubkeyJSON); if (!accountOnChain) { accountOnChain = {}; diff --git a/pages/api/multisig/[multisigAddress]/index.js b/pages/api/multisig/[multisigAddress]/index.js new file mode 100644 index 0000000..d174bb2 --- /dev/null +++ b/pages/api/multisig/[multisigAddress]/index.js @@ -0,0 +1,26 @@ +import { getMultisig } from "../../../../lib/graphqlHelpers"; + +export default async function (req, res) { + switch (req.method) { + case "GET": + try { + const { multisigAddress } = req.query; + console.log("Function `getMultisig` invoked", multisigAddress); + const getRes = await getMultisig(multisigAddress); + if (!getRes.data.data.getMultisig) { + res.status(404).send("Multisig not found"); + return; + } + console.log("success", getRes.data.data.getMultisig); + res.status(200).send(getRes.data.data.getMultisig); + return; + } catch (err) { + console.log(err); + res.status(400).send(err.message); + return; + } + } + // no route matched + res.status(405).end(); + return; +} diff --git a/pages/multi/[address]/index.js b/pages/multi/[address]/index.js index 2d23aa1..1ac7b79 100644 --- a/pages/multi/[address]/index.js +++ b/pages/multi/[address]/index.js @@ -1,8 +1,9 @@ -import React, { useState } from "react"; +import React, { useState, useEffect } from "react"; import { pubkeyToAddress } from "@cosmjs/amino"; import { StargateClient } from "@cosmjs/stargate"; import { useRouter } from "next/router"; +import { useAppContext } from "../../../context/AppContext"; import Button from "../../../components/inputs/Button"; import { getMultisigAccount } from "../../../lib/multisigHelpers"; import HashView from "../../../components/dataViews/HashView"; @@ -12,23 +13,6 @@ import Page from "../../../components/layout/Page"; import StackableContainer from "../../../components/layout/StackableContainer"; import TransactionForm from "../../../components/forms/TransactionForm"; -export async function getServerSideProps(context) { - try { - const client = await StargateClient.connect(process.env.NEXT_PUBLIC_NODE_ADDRESS); - const multisigAddress = context.params.address; - const holdings = await client.getBalance(multisigAddress, process.env.NEXT_PUBLIC_DENOM); - const accountOnChain = await getMultisigAccount(multisigAddress, client); - return { - props: { accountOnChain, holdings }, - }; - } catch (error) { - console.log(error); - return { - props: { error: error.message }, - }; - } -} - function participantPubkeysFromMultisig(multisigPubkey) { return multisigPubkey.value.pubkeys; } @@ -40,28 +24,51 @@ function participantAddressesFromMultisig(multisigPubkey, addressPrefix) { } const multipage = (props) => { + const { state } = useAppContext(); const [showTxForm, setShowTxForm] = useState(false); + const [holdings, setHoldings] = useState(""); + const [accountOnChain, setAccountOnChain] = useState(null); + const [accountError, setAccountError] = useState(null); const router = useRouter(); - const { address } = router.query; + + useEffect(() => { + if (router.query.address) { + fetchMultisig(router.query.address); + } + }, [router.query.address]); + + const fetchMultisig = async (address) => { + try { + const client = await StargateClient.connect(state.chain.nodeAddress); + const tempHoldings = await client.getBalance(address, state.chain.denom); + const tempAccountOnChain = await getMultisigAccount(address, client); + setHoldings(tempHoldings); + setAccountOnChain(tempAccountOnChain); + } catch (error) { + setAccountError(error.message); + console.log("Account error:", error); + } + }; + return (

- +

{props.accountOnChain?.pubkey && ( )} - {props.error && ( + {accountError && (

@@ -78,7 +85,7 @@ const multipage = (props) => { )} {showTxForm ? ( { setShowTxForm(false); @@ -87,7 +94,7 @@ const multipage = (props) => { ) : (

- +
diff --git a/pages/multi/[address]/transaction/[transactionID].js b/pages/multi/[address]/transaction/[transactionID].js index 72d92df..a387095 100644 --- a/pages/multi/[address]/transaction/[transactionID].js +++ b/pages/multi/[address]/transaction/[transactionID].js @@ -2,9 +2,11 @@ import React from "react"; import axios from "axios"; import { StargateClient, makeMultisignedTx } from "@cosmjs/stargate"; import { TxRaw } from "cosmjs-types/cosmos/tx/v1beta1/tx"; -import { useState } from "react"; +import { useState, useEffect } from "react"; +import { useRouter } from "next/router"; import { fromBase64 } from "@cosmjs/encoding"; +import { useAppContext } from "../../../../context/AppContext"; import Button from "../../../../components/inputs/Button"; import { findTransactionByID } from "../../../../lib/graphqlHelpers"; import { getMultisigAccount } from "../../../../lib/multisigHelpers"; @@ -16,17 +18,12 @@ import TransactionSigning from "../../../../components/forms/TransactionSigning" import CompletedTransaction from "../../../../components/dataViews/CompletedTransaction"; export async function getServerSideProps(context) { - // get multisig account and transaction info - const nodeAddress = process.env.NEXT_PUBLIC_NODE_ADDRESS; - const client = await StargateClient.connect(nodeAddress); - const multisigAddress = context.params.address; + // get transaction info const transactionID = context.params.transactionID; let transactionJSON; let txHash; - let accountOnChain; let signatures; try { - accountOnChain = await getMultisigAccount(multisigAddress, client); console.log("Function `findTransactionByID` invoked", transactionID); const getRes = await findTransactionByID(transactionID); console.log("success", getRes.data); @@ -38,13 +35,10 @@ export async function getServerSideProps(context) { } return { props: { - multisigAddress, transactionJSON, txHash, - accountOnChain, transactionID, signatures, - nodeAddress, }, }; } @@ -54,18 +48,42 @@ const transactionPage = ({ transactionJSON, transactionID, signatures, - accountOnChain, - nodeAddress, txHash, }) => { + const { state } = useAppContext(); const [currentSignatures, setCurrentSignatures] = useState(signatures); const [broadcastError, setBroadcastError] = useState(""); const [isBroadcasting, setIsBroadcasting] = useState(false); const [transactionHash, setTransactionHash] = useState(txHash); + const [_holdings, setHoldings] = useState(""); + const [accountOnChain, setAccountOnChain] = useState(null); + const [accountError, setAccountError] = useState(null); const txInfo = (transactionJSON && JSON.parse(transactionJSON)) || null; + const router = useRouter(); + const addSignature = (signature) => { setCurrentSignatures((prevState) => [...prevState, signature]); }; + + useEffect(() => { + if (router.query.address) { + fetchMultisig(router.query.address); + } + }, [router.query.address]); + + const fetchMultisig = async (address) => { + try { + const client = await StargateClient.connect(state.chain.nodeAddress); + const tempHoldings = await client.getBalance(address, state.chain.denom); + const tempAccountOnChain = await getMultisigAccount(address, client); + setHoldings(tempHoldings); + setAccountOnChain(tempAccountOnChain); + } catch (error) { + setAccountError(error.message); + console.log("Account error:", error); + } + }; + const broadcastTx = async () => { try { setIsBroadcasting(true); @@ -79,7 +97,7 @@ const transactionPage = ({ bodyBytes, new Map(currentSignatures.map((s) => [s.address, fromBase64(s.signature)])), ); - const broadcaster = await StargateClient.connect(nodeAddress); + const broadcaster = await StargateClient.connect(state.chain.nodeAddress); const result = await broadcaster.broadcastTx( Uint8Array.from(TxRaw.encode(signedTx).finish()), ); @@ -100,13 +118,20 @@ const transactionPage = ({

{transactionHash ? "Completed Transaction" : "In Progress Transaction"}

- + {accountError && ( + +
+

Multisig address could not be found.

+
+
+ )} {transactionHash && } - {!transactionHash && ( + {!transactionHash && accountOnChain && ( )} - {currentSignatures.length >= parseInt(accountOnChain.pubkey.value.threshold, 10) && + {accountOnChain && + currentSignatures.length >= parseInt(accountOnChain.pubkey.value.threshold, 10) && !transactionHash && ( <>