Update code to make linter happy
This commit is contained in:
@@ -1,4 +1,6 @@
|
||||
const DevHelper = (props) => (
|
||||
import React from "react";
|
||||
|
||||
const DevHelper = (_props) => (
|
||||
<div className="dev-helper">
|
||||
<h3>Dev Helper</h3>
|
||||
<h4>Pages</h4>
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
import React from "react";
|
||||
|
||||
import StackableContainer from "../layout/StackableContainer";
|
||||
import Button from "../inputs/Button";
|
||||
|
||||
export default ({ transactionHash }) => (
|
||||
const CompletedTransaction = ({ transactionHash }) => (
|
||||
<StackableContainer lessPadding lessMargin>
|
||||
<StackableContainer lessPadding lessMargin lessRadius>
|
||||
<div className="confirmation">
|
||||
@@ -27,3 +29,5 @@ export default ({ transactionHash }) => (
|
||||
`}</style>
|
||||
</StackableContainer>
|
||||
);
|
||||
|
||||
export default CompletedTransaction;
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import React from "react";
|
||||
import copy from "copy-to-clipboard";
|
||||
|
||||
export default (props) => (
|
||||
const CopyAndPaste = (props) => (
|
||||
<div className="icon" onClick={() => copy(props.copyText)}>
|
||||
<svg viewBox="0 0 100 100" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M13 32H41C53.1503 32 63 41.8497 63 54V94H13V32Z" />
|
||||
@@ -29,3 +30,5 @@ export default (props) => (
|
||||
`}</style>
|
||||
</div>
|
||||
);
|
||||
|
||||
export default CopyAndPaste;
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
import React from "react";
|
||||
|
||||
import { abbreviateLongString } from "../../lib/displayHelpers";
|
||||
import CopyAndPaste from "./CopyAndPaste";
|
||||
|
||||
export default ({ hash, abbreviate }) => (
|
||||
const HashView = ({ hash, abbreviate }) => (
|
||||
<div className="hash-view">
|
||||
<div>{abbreviate ? abbreviateLongString(hash) : hash}</div>
|
||||
<CopyAndPaste copyText={hash} />
|
||||
@@ -12,3 +14,5 @@ export default ({ hash, abbreviate }) => (
|
||||
`}</style>
|
||||
</div>
|
||||
);
|
||||
|
||||
export default HashView;
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
import React from "react";
|
||||
|
||||
import { printableCoin } from "../../lib/displayHelpers";
|
||||
import StackableContainer from "../layout/StackableContainer";
|
||||
|
||||
|
||||
const MultisigHoldings = (props) => {
|
||||
return (
|
||||
<StackableContainer lessPadding fullHeight>
|
||||
@@ -17,4 +18,5 @@ const MultisigHoldings = (props) => {
|
||||
</StackableContainer>
|
||||
);
|
||||
};
|
||||
|
||||
export default MultisigHoldings;
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
import React from "react";
|
||||
|
||||
import StackableContainer from "../layout/StackableContainer";
|
||||
import { abbreviateLongString } from "../../lib/displayHelpers";
|
||||
|
||||
@@ -18,12 +20,12 @@ const dummyMembers = [
|
||||
address: "cosmos1t5u0jfg3ljsjrh2m9e47d4ny2hea7eehxrzdgd",
|
||||
},
|
||||
];
|
||||
const MultisigMembers = (props) => (
|
||||
const MultisigMembers = (_props) => (
|
||||
<StackableContainer lessPadding>
|
||||
<h2>Members</h2>
|
||||
<ul className="meta-data">
|
||||
{dummyMembers.map((member) => (
|
||||
<li>
|
||||
<li key={member.address}>
|
||||
<div className="nickname">
|
||||
<label>Nickname:</label>
|
||||
<div className="info">{member.nickname}</div>
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
import React from "react";
|
||||
|
||||
import StackableContainer from "../layout/StackableContainer";
|
||||
|
||||
const ThresholdInfo = ({ signatures, account }) => (
|
||||
@@ -39,4 +41,5 @@ const ThresholdInfo = ({ signatures, account }) => (
|
||||
`}</style>
|
||||
</StackableContainer>
|
||||
);
|
||||
|
||||
export default ThresholdInfo;
|
||||
|
||||
@@ -1,8 +1,10 @@
|
||||
import React from "react";
|
||||
|
||||
import HashView from "./HashView";
|
||||
import StackableContainer from "../layout/StackableContainer";
|
||||
import { printableCoins } from "../../lib/displayHelpers";
|
||||
|
||||
export default (props) => (
|
||||
const TransactionInfo = (props) => (
|
||||
<StackableContainer lessPadding lessMargin>
|
||||
<ul className="meta-data">
|
||||
{props.tx.msgs && (
|
||||
@@ -68,3 +70,5 @@ export default (props) => (
|
||||
`}</style>
|
||||
</StackableContainer>
|
||||
);
|
||||
|
||||
export default TransactionInfo;
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
import axios from "axios";
|
||||
import React from "react";
|
||||
|
||||
import StackableContainer from "../layout/StackableContainer";
|
||||
@@ -51,7 +50,7 @@ class TransactionList extends React.Component {
|
||||
<StackableContainer lessPadding>
|
||||
<h2>Past Transactions</h2>
|
||||
<ul>
|
||||
{dummyTXs.map((tx, i) => (
|
||||
{dummyTXs.map((tx) => (
|
||||
<li key={tx.txHash} className="tx">
|
||||
<TransactionInfo tx={tx} abbreviate />
|
||||
</li>
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
import axios from "axios";
|
||||
import React from "react";
|
||||
import { withRouter } from "next/router";
|
||||
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
import axios from "axios";
|
||||
import React from "react";
|
||||
import { withRouter } from "next/router";
|
||||
|
||||
@@ -18,17 +17,17 @@ class FindMultisigForm extends React.Component {
|
||||
};
|
||||
}
|
||||
|
||||
handleChange = (e) => {
|
||||
handleChange(e) {
|
||||
this.setState({
|
||||
[e.target.name]: e.target.value,
|
||||
});
|
||||
};
|
||||
}
|
||||
|
||||
handleSearch = async () => {
|
||||
async handleSearch() {
|
||||
this.setState({ processing: true });
|
||||
|
||||
this.props.router.push(`/multi/${this.state.address}`);
|
||||
};
|
||||
}
|
||||
|
||||
render() {
|
||||
return (
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
import axios from "axios";
|
||||
import React from "react";
|
||||
import { withRouter } from "next/router";
|
||||
import { StargateClient } from "@cosmjs/stargate";
|
||||
@@ -10,7 +9,7 @@ import StackableContainer from "../layout/StackableContainer";
|
||||
import ThresholdInput from "../inputs/ThresholdInput";
|
||||
import { exampleAddress, examplePubkey } from "../../lib/displayHelpers";
|
||||
|
||||
let emptyPubKeyGroup = () => {
|
||||
const emptyPubKeyGroup = () => {
|
||||
return { address: "", compressedPubkey: "", keyError: "", isPubkey: false };
|
||||
};
|
||||
|
||||
@@ -25,25 +24,25 @@ class MultiSigForm extends React.Component {
|
||||
};
|
||||
}
|
||||
|
||||
handleChangeThreshold = (e) => {
|
||||
handleChangeThreshold(e) {
|
||||
const threshold =
|
||||
e.target.value <= this.state.pubkeys.length
|
||||
? e.target.value
|
||||
: this.state.pubkeys.length;
|
||||
this.setState({ threshold });
|
||||
};
|
||||
}
|
||||
|
||||
handleKeyGroupChange = (index, e) => {
|
||||
handleKeyGroupChange(index, e) {
|
||||
const { pubkeys } = this.state;
|
||||
pubkeys[index][e.target.name] = e.target.value;
|
||||
this.setState({ pubkeys });
|
||||
};
|
||||
}
|
||||
|
||||
handleAddKey = () => {
|
||||
handleAddKey() {
|
||||
this.setState({ pubkeys: this.state.pubkeys.concat(emptyPubKeyGroup()) });
|
||||
};
|
||||
}
|
||||
|
||||
handleRemove = (index) => {
|
||||
handleRemove(index) {
|
||||
this.setState((prevState) => {
|
||||
const pubkeys = Array.from(prevState.pubkeys);
|
||||
pubkeys.splice(index, 1);
|
||||
@@ -55,9 +54,9 @@ class MultiSigForm extends React.Component {
|
||||
|
||||
return { pubkeys, threshold };
|
||||
});
|
||||
};
|
||||
}
|
||||
|
||||
getPubkeyFromNode = async (address) => {
|
||||
async getPubkeyFromNode(address) {
|
||||
const nodeAddress = process.env.NEXT_PUBLIC_NODE_ADDRESS;
|
||||
const client = await StargateClient.connect(nodeAddress);
|
||||
const accountOnChain = await client.getAccount(address);
|
||||
@@ -68,9 +67,9 @@ class MultiSigForm extends React.Component {
|
||||
);
|
||||
}
|
||||
return accountOnChain.pubkey.value;
|
||||
};
|
||||
}
|
||||
|
||||
handleKeyBlur = async (index, e) => {
|
||||
async handleKeyBlur(index, e) {
|
||||
try {
|
||||
const { pubkeys } = this.state;
|
||||
let pubkey;
|
||||
@@ -83,7 +82,7 @@ class MultiSigForm extends React.Component {
|
||||
}
|
||||
} else {
|
||||
// use address to fetch pubkey
|
||||
let address = e.target.value;
|
||||
const address = e.target.value;
|
||||
if (address.length > 0) {
|
||||
pubkey = await this.getPubkeyFromNode(address);
|
||||
}
|
||||
@@ -98,9 +97,9 @@ class MultiSigForm extends React.Component {
|
||||
pubkeys[index].keyError = error.message;
|
||||
this.setState({ pubkeys });
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
handleCreate = async () => {
|
||||
async handleCreate() {
|
||||
this.setState({ processing: true });
|
||||
const compressedPubkeys = this.state.pubkeys.map(
|
||||
(item) => item.compressedPubkey
|
||||
@@ -115,13 +114,13 @@ class MultiSigForm extends React.Component {
|
||||
} catch (error) {
|
||||
console.log("Failed to creat multisig: ", error);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
togglePubkey = (index) => {
|
||||
togglePubkey(index) {
|
||||
const { pubkeys } = this.state;
|
||||
pubkeys[index].isPubkey = !pubkeys[index].isPubkey;
|
||||
this.setState({ pubkeys });
|
||||
};
|
||||
}
|
||||
|
||||
render() {
|
||||
return (
|
||||
|
||||
@@ -24,21 +24,26 @@ class TransactionForm extends React.Component {
|
||||
};
|
||||
}
|
||||
|
||||
handleChange = (e) => {
|
||||
handleChange(e) {
|
||||
this.setState({
|
||||
[e.target.name]: e.target.value,
|
||||
});
|
||||
};
|
||||
}
|
||||
|
||||
createTransaction = (toAddress, amount, gas) => {
|
||||
const amountInAtomics = Decimal.fromUserInput(amount, Number(process.env.NEXT_PUBLIC_DISPLAY_DENOM_EXPONENT)).atomics;
|
||||
createTransaction(toAddress, amount, gas) {
|
||||
const amountInAtomics = Decimal.fromUserInput(
|
||||
amount,
|
||||
Number(process.env.NEXT_PUBLIC_DISPLAY_DENOM_EXPONENT)
|
||||
).atomics;
|
||||
const msgSend = {
|
||||
fromAddress: this.props.address,
|
||||
toAddress: toAddress,
|
||||
amount: [{
|
||||
amount: amountInAtomics,
|
||||
denom: process.env.NEXT_PUBLIC_DENOM
|
||||
}],
|
||||
amount: [
|
||||
{
|
||||
amount: amountInAtomics,
|
||||
denom: process.env.NEXT_PUBLIC_DENOM,
|
||||
},
|
||||
],
|
||||
};
|
||||
const msg = {
|
||||
typeUrl: "/cosmos.bank.v1beta1.MsgSend",
|
||||
@@ -53,12 +58,14 @@ class TransactionForm extends React.Component {
|
||||
fee: fee,
|
||||
memo: this.state.memo,
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
handleCreate = async () => {
|
||||
async handleCreate() {
|
||||
const addressError = checkAddress(this.state.toAddress);
|
||||
if (addressError) {
|
||||
this.setState({ addressError: `Invalid address for network ${process.env.NEXT_PUBLIC_CHAIN_ID}: ${addressError}` });
|
||||
this.setState({
|
||||
addressError: `Invalid address for network ${process.env.NEXT_PUBLIC_CHAIN_ID}: ${addressError}`,
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -75,7 +82,7 @@ class TransactionForm extends React.Component {
|
||||
this.props.router.push(
|
||||
`${this.props.address}/transaction/${transactionID}`
|
||||
);
|
||||
};
|
||||
}
|
||||
|
||||
render() {
|
||||
return (
|
||||
|
||||
@@ -1,8 +1,7 @@
|
||||
import React from "react";
|
||||
import axios from "axios";
|
||||
import { toBase64 } from "@cosmjs/encoding";
|
||||
import React from "react";
|
||||
import { SigningStargateClient } from "@cosmjs/stargate";
|
||||
import { registry } from "@cosmjs/proto-signing";
|
||||
|
||||
import Button from "../inputs/Button";
|
||||
import HashView from "../dataViews/HashView";
|
||||
@@ -25,14 +24,14 @@ export default class TransactionSigning extends React.Component {
|
||||
this.connectWallet();
|
||||
}
|
||||
|
||||
componentDidUpdate(prevProps, prevState) {
|
||||
componentDidUpdate(prevProps) {
|
||||
if (!prevProps.transaction && this.props.transaction) {
|
||||
this.setState({ transaction: this.props.transaction });
|
||||
console.log(JSON.parse(this.props.transaction.signatures));
|
||||
}
|
||||
}
|
||||
|
||||
handleBroadcast = async () => {
|
||||
async handleBroadcast() {
|
||||
this.setState({ processing: true });
|
||||
const res = await axios.get(
|
||||
`/api/transaction/${this.state.transaction.uuid}/broadcast`
|
||||
@@ -42,13 +41,13 @@ export default class TransactionSigning extends React.Component {
|
||||
transaction: res.data,
|
||||
processing: false,
|
||||
});
|
||||
};
|
||||
}
|
||||
|
||||
clickFileUpload = () => {
|
||||
clickFileUpload() {
|
||||
this.fileInput.current.click();
|
||||
};
|
||||
}
|
||||
|
||||
connectWallet = async () => {
|
||||
async connectWallet() {
|
||||
try {
|
||||
await window.keplr.enable(process.env.NEXT_PUBLIC_CHAIN_ID);
|
||||
const walletAccount = await window.keplr.getKey(
|
||||
@@ -61,9 +60,9 @@ export default class TransactionSigning extends React.Component {
|
||||
} catch (e) {
|
||||
console.log("enable err: ", e);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
signTransaction = async () => {
|
||||
async signTransaction() {
|
||||
try {
|
||||
window.keplr.defaultOptions = {
|
||||
sign: {
|
||||
@@ -75,7 +74,6 @@ export default class TransactionSigning extends React.Component {
|
||||
const offlineSigner = window.getOfflineSignerOnlyAmino(
|
||||
process.env.NEXT_PUBLIC_CHAIN_ID
|
||||
);
|
||||
const accounts = await offlineSigner.getAccounts();
|
||||
const signingClient = await SigningStargateClient.offline(offlineSigner);
|
||||
const signerData = {
|
||||
accountNumber: this.props.tx.accountNumber,
|
||||
@@ -104,7 +102,7 @@ export default class TransactionSigning extends React.Component {
|
||||
signature: bases64EncodedSignature,
|
||||
address: this.state.walletAccount.bech32Address,
|
||||
};
|
||||
const res = await axios.post(
|
||||
const _res = await axios.post(
|
||||
`/api/transaction/${this.props.transactionID}/signature`,
|
||||
signature
|
||||
);
|
||||
@@ -114,7 +112,7 @@ export default class TransactionSigning extends React.Component {
|
||||
} catch (error) {
|
||||
console.log("Error creating signature:", error);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
render() {
|
||||
return (
|
||||
|
||||
+1
-1
@@ -1,10 +1,10 @@
|
||||
import React from "react";
|
||||
import NextHead from "next/head";
|
||||
import { string } from "prop-types";
|
||||
|
||||
const defaultDescription =
|
||||
"*:;;;:*:;;;:**:;;;:*:;;;:*COSMOS MULTISIGN*:;;;:*:;;;:**:;;;:*:;;;:*";
|
||||
const defaultOGURL = "";
|
||||
const defaultOGImage = "";
|
||||
|
||||
const Head = (props) => (
|
||||
<NextHead>
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
import React from "react";
|
||||
|
||||
const Button = (props) => (
|
||||
<>
|
||||
{props.href ? (
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
import React from "react";
|
||||
|
||||
const Input = (props) => (
|
||||
<div className="text-input">
|
||||
<label>{props.label || ""}</label>
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
export default (props) => (
|
||||
import React from "react";
|
||||
|
||||
const ThresholdInput = (props) => (
|
||||
<>
|
||||
<p>Signatures required to send a transaction</p>
|
||||
<div className="threshold-group">
|
||||
@@ -51,3 +53,4 @@ export default (props) => (
|
||||
`}</style>
|
||||
</>
|
||||
);
|
||||
export default ThresholdInput;
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
import React from "react";
|
||||
|
||||
import Head from "../head";
|
||||
import StackableContainer from "./StackableContainer";
|
||||
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
import React from "react";
|
||||
|
||||
const StackableContainer = (props) => (
|
||||
<div className={`container ${props.base ? "base" : ""}`}>
|
||||
{props.children}
|
||||
|
||||
+23
-14
@@ -47,37 +47,39 @@ const printableCoin = (coin) => {
|
||||
const ticker = coin.denom.slice(1).toUpperCase();
|
||||
return value + thinSpace + ticker;
|
||||
}
|
||||
|
||||
|
||||
// Fallback to plain coin display
|
||||
return coin.amount + thinSpace + coin.denom;
|
||||
}
|
||||
};
|
||||
|
||||
const printableCoins = (coins) => {
|
||||
if (coins.length !== 1) {
|
||||
throw new Error("Implementation only supports exactly one coin entry.")
|
||||
throw new Error("Implementation only supports exactly one coin entry.");
|
||||
}
|
||||
return printableCoin(coins[0]);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Generates an example address for the configured blockchain.
|
||||
*
|
||||
*
|
||||
* `index` can be set to a small integer in order to get different addresses. Defaults to 0.
|
||||
*/
|
||||
const exampleAddress = (index) => {
|
||||
const usedIndex = index || 0;
|
||||
let data = Bech32.decode("cosmos1vqpjljwsynsn58dugz0w8ut7kun7t8ls2qkmsq").data;
|
||||
let data = Bech32.decode(
|
||||
"cosmos1vqpjljwsynsn58dugz0w8ut7kun7t8ls2qkmsq"
|
||||
).data;
|
||||
for (let i = 0; i < usedIndex; ++i) {
|
||||
data = sha512(data).slice(0, data.length); // hash one time and trim to original length
|
||||
}
|
||||
return Bech32.encode(process.env.NEXT_PUBLIC_ADDRESS_PREFIX, data);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Generates an example pubkey (secp256k1, compressed).
|
||||
*
|
||||
*
|
||||
* `index` can be set to a small integer in order to get different addresses. Defaults to 0.
|
||||
*
|
||||
*
|
||||
* Note: the keys are not necessarily valid (as in points on the chain) and should only be used
|
||||
* as dummy data.
|
||||
*/
|
||||
@@ -89,11 +91,11 @@ const examplePubkey = (index) => {
|
||||
data[0] = index % 2 ? 0x02 : 0x03; // pubkeys have to start with 0x02 or 0x03
|
||||
}
|
||||
return toBase64(data);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Returns an error message for invalid addresses.
|
||||
*
|
||||
*
|
||||
* Returns null of there is no error.
|
||||
*/
|
||||
const checkAddress = (input) => {
|
||||
@@ -102,7 +104,7 @@ const checkAddress = (input) => {
|
||||
let data;
|
||||
let prefix;
|
||||
try {
|
||||
({ data, prefix } = Bech32.decode(input));
|
||||
({ data, prefix } = Bech32.decode(input));
|
||||
} catch (error) {
|
||||
return error.toString();
|
||||
}
|
||||
@@ -116,6 +118,13 @@ const checkAddress = (input) => {
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
};
|
||||
|
||||
export { abbreviateLongString, printableCoin, printableCoins, exampleAddress, examplePubkey, checkAddress };
|
||||
export {
|
||||
abbreviateLongString,
|
||||
printableCoin,
|
||||
printableCoins,
|
||||
exampleAddress,
|
||||
examplePubkey,
|
||||
checkAddress,
|
||||
};
|
||||
|
||||
+19
-21
@@ -1,6 +1,5 @@
|
||||
import axios from "axios";
|
||||
import { createMultisigThresholdPubkey, pubkeyToAddress } from "@cosmjs/amino";
|
||||
import { StargateClient } from "@cosmjs/stargate";
|
||||
|
||||
import { getMultisig } from "./graphqlHelpers";
|
||||
|
||||
@@ -16,27 +15,26 @@ const createMultisigFromCompressedSecp256k1Pubkeys = async (
|
||||
compressedPubkeys,
|
||||
threshold
|
||||
) => {
|
||||
try {
|
||||
let pubkeys = compressedPubkeys.map((compressedPubkey) => {
|
||||
return {
|
||||
type: "tendermint/PubKeySecp256k1",
|
||||
value: compressedPubkey,
|
||||
};
|
||||
});
|
||||
const multisigPubkey = createMultisigThresholdPubkey(pubkeys, threshold);
|
||||
const multisigAddress = pubkeyToAddress(multisigPubkey, process.env.NEXT_PUBLIC_ADDRESS_PREFIX);
|
||||
|
||||
// save multisig to fauna
|
||||
const multisig = {
|
||||
address: multisigAddress,
|
||||
pubkeyJSON: JSON.stringify(multisigPubkey),
|
||||
const pubkeys = compressedPubkeys.map((compressedPubkey) => {
|
||||
return {
|
||||
type: "tendermint/PubKeySecp256k1",
|
||||
value: compressedPubkey,
|
||||
};
|
||||
const res = await axios.post("/api/multisig", multisig);
|
||||
console.log(res.data);
|
||||
return res.data.address;
|
||||
} catch (error) {
|
||||
throw error;
|
||||
}
|
||||
});
|
||||
const multisigPubkey = createMultisigThresholdPubkey(pubkeys, threshold);
|
||||
const multisigAddress = pubkeyToAddress(
|
||||
multisigPubkey,
|
||||
process.env.NEXT_PUBLIC_ADDRESS_PREFIX
|
||||
);
|
||||
|
||||
// save multisig to fauna
|
||||
const multisig = {
|
||||
address: multisigAddress,
|
||||
pubkeyJSON: JSON.stringify(multisigPubkey),
|
||||
};
|
||||
const res = await axios.post("/api/multisig", multisig);
|
||||
console.log(res.data);
|
||||
return res.data.address;
|
||||
};
|
||||
|
||||
/**
|
||||
|
||||
+18
-20
@@ -1,24 +1,22 @@
|
||||
import { createMultisig } from "../../../lib/graphqlHelpers";
|
||||
|
||||
export default async function (req, res) {
|
||||
return new Promise(async (resolve) => {
|
||||
switch (req.method) {
|
||||
case "POST":
|
||||
try {
|
||||
const data = req.body;
|
||||
console.log("Function `createMultisig` invoked", data);
|
||||
const saveRes = await createMultisig(data);
|
||||
console.log("success", saveRes.data);
|
||||
res.status(200).send(saveRes.data.data.createMultisig);
|
||||
return resolve();
|
||||
} catch (err) {
|
||||
console.log(err);
|
||||
res.status(400).send(err.message);
|
||||
return resolve();
|
||||
}
|
||||
}
|
||||
// no route matched
|
||||
res.status(405).end();
|
||||
return resolve();
|
||||
});
|
||||
switch (req.method) {
|
||||
case "POST":
|
||||
try {
|
||||
const data = req.body;
|
||||
console.log("Function `createMultisig` invoked", data);
|
||||
const saveRes = await createMultisig(data);
|
||||
console.log("success", saveRes.data);
|
||||
res.status(200).send(saveRes.data.data.createMultisig);
|
||||
return;
|
||||
} catch (err) {
|
||||
console.log(err);
|
||||
res.status(400).send(err.message);
|
||||
return;
|
||||
}
|
||||
}
|
||||
// no route matched
|
||||
res.status(405).end();
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -1,25 +1,23 @@
|
||||
import { updateTxHash } from "../../../../lib/graphqlHelpers";
|
||||
|
||||
export default async function (req, res) {
|
||||
return new Promise(async (resolve) => {
|
||||
switch (req.method) {
|
||||
case "POST":
|
||||
try {
|
||||
const { transactionID } = req.query;
|
||||
const { txHash } = req.body;
|
||||
console.log("Function `updateTransaction` invoked", txHash);
|
||||
const saveRes = await updateTxHash(transactionID, txHash);
|
||||
console.log("success", saveRes.data);
|
||||
res.status(200).send(saveRes.data.data.updateTransaction);
|
||||
return resolve();
|
||||
} catch (err) {
|
||||
console.log(err);
|
||||
res.status(400).send(err.message);
|
||||
return resolve();
|
||||
}
|
||||
}
|
||||
// no route matched
|
||||
res.status(405).end();
|
||||
return resolve();
|
||||
});
|
||||
switch (req.method) {
|
||||
case "POST":
|
||||
try {
|
||||
const { transactionID } = req.query;
|
||||
const { txHash } = req.body;
|
||||
console.log("Function `updateTransaction` invoked", txHash);
|
||||
const saveRes = await updateTxHash(transactionID, txHash);
|
||||
console.log("success", saveRes.data);
|
||||
res.status(200).send(saveRes.data.data.updateTransaction);
|
||||
return;
|
||||
} catch (err) {
|
||||
console.log(err);
|
||||
res.status(400).send(err.message);
|
||||
return;
|
||||
}
|
||||
}
|
||||
// no route matched
|
||||
res.status(405).end();
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -1,25 +1,23 @@
|
||||
import { createSignature } from "../../../../lib/graphqlHelpers";
|
||||
|
||||
export default async function (req, res) {
|
||||
return new Promise(async (resolve) => {
|
||||
switch (req.method) {
|
||||
case "POST":
|
||||
try {
|
||||
const { transactionID } = req.query;
|
||||
const data = req.body;
|
||||
console.log("Function `createSignature` invoked", data);
|
||||
const saveRes = await createSignature(data, transactionID);
|
||||
console.log("success", saveRes.data);
|
||||
res.status(200).send(saveRes.data.data.createSignature);
|
||||
return resolve();
|
||||
} catch (err) {
|
||||
console.log(err);
|
||||
res.status(400).send(err.message);
|
||||
return resolve();
|
||||
}
|
||||
}
|
||||
// no route matched
|
||||
res.status(405).end();
|
||||
return resolve();
|
||||
});
|
||||
switch (req.method) {
|
||||
case "POST":
|
||||
try {
|
||||
const { transactionID } = req.query;
|
||||
const data = req.body;
|
||||
console.log("Function `createSignature` invoked", data);
|
||||
const saveRes = await createSignature(data, transactionID);
|
||||
console.log("success", saveRes.data);
|
||||
res.status(200).send(saveRes.data.data.createSignature);
|
||||
return;
|
||||
} catch (err) {
|
||||
console.log(err);
|
||||
res.status(400).send(err.message);
|
||||
return;
|
||||
}
|
||||
}
|
||||
// no route matched
|
||||
res.status(405).end();
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -1,26 +1,24 @@
|
||||
import { createTransaction } from "../../../lib/graphqlHelpers";
|
||||
|
||||
export default async function (req, res) {
|
||||
return new Promise(async (resolve) => {
|
||||
switch (req.method) {
|
||||
case "POST":
|
||||
try {
|
||||
const data = req.body;
|
||||
console.log("Function `createTransaction` invoked", data);
|
||||
const saveRes = await createTransaction(data.dataJSON);
|
||||
console.log("success", saveRes.data);
|
||||
res
|
||||
.status(200)
|
||||
.send({ transactionID: saveRes.data.data.createTransaction._id });
|
||||
return resolve();
|
||||
} catch (err) {
|
||||
console.log(err);
|
||||
res.status(400).send(err.message);
|
||||
return resolve();
|
||||
}
|
||||
}
|
||||
// no route matched
|
||||
res.status(405).end();
|
||||
return resolve();
|
||||
});
|
||||
switch (req.method) {
|
||||
case "POST":
|
||||
try {
|
||||
const data = req.body;
|
||||
console.log("Function `createTransaction` invoked", data);
|
||||
const saveRes = await createTransaction(data.dataJSON);
|
||||
console.log("success", saveRes.data);
|
||||
res
|
||||
.status(200)
|
||||
.send({ transactionID: saveRes.data.data.createTransaction._id });
|
||||
return;
|
||||
} catch (err) {
|
||||
console.log(err);
|
||||
res.status(400).send(err.message);
|
||||
return;
|
||||
}
|
||||
}
|
||||
// no route matched
|
||||
res.status(405).end();
|
||||
return;
|
||||
}
|
||||
|
||||
+5
-1
@@ -1,8 +1,10 @@
|
||||
import React from "react";
|
||||
|
||||
import MultisigForm from "../components/forms/MultisigForm";
|
||||
import Page from "../components/layout/Page";
|
||||
import StackableContainer from "../components/layout/StackableContainer";
|
||||
|
||||
export default () => (
|
||||
const CreatePage = () => (
|
||||
<Page>
|
||||
<StackableContainer base>
|
||||
<StackableContainer lessPadding>
|
||||
@@ -12,3 +14,5 @@ export default () => (
|
||||
</StackableContainer>
|
||||
</Page>
|
||||
);
|
||||
|
||||
export default CreatePage;
|
||||
|
||||
+6
-2
@@ -1,14 +1,18 @@
|
||||
import React from "react";
|
||||
|
||||
import FindMultisigForm from "../components/forms/FindMultisigForm";
|
||||
import Page from "../components/layout/Page";
|
||||
import StackableContainer from "../components/layout/StackableContainer";
|
||||
|
||||
export default () => (
|
||||
const MultiPage = () => (
|
||||
<Page>
|
||||
<StackableContainer base>
|
||||
<StackableContainer lessPadding>
|
||||
<h1 className="title">Cosmoshub Multisig Manager</h1>
|
||||
</StackableContainer>
|
||||
<FindMultisigForm />
|
||||
<FindMultisigForm />
|
||||
</StackableContainer>
|
||||
</Page>
|
||||
);
|
||||
|
||||
export default MultiPage;
|
||||
|
||||
@@ -6,11 +6,9 @@ import Button from "../../../components/inputs/Button";
|
||||
import { getMultisigAccount } from "../../../lib/multisigHelpers";
|
||||
import HashView from "../../../components/dataViews/HashView";
|
||||
import MultisigHoldings from "../../../components/dataViews/MultisigHoldings";
|
||||
import MultisigMembers from "../../../components/dataViews/MultisigMembers";
|
||||
import Page from "../../../components/layout/Page";
|
||||
import StackableContainer from "../../../components/layout/StackableContainer";
|
||||
import TransactionForm from "../../../components/forms/TransactionForm";
|
||||
import TransactionList from "../../../components/dataViews/TransactionList";
|
||||
|
||||
export async function getServerSideProps(context) {
|
||||
try {
|
||||
|
||||
@@ -1,10 +1,9 @@
|
||||
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 { fromBase64 } from "@cosmjs/encoding";
|
||||
import { createMultisigThresholdPubkey, pubkeyToAddress } from "@cosmjs/amino";
|
||||
import { registry } from "@cosmjs/proto-signing";
|
||||
|
||||
import Button from "../../../../components/inputs/Button";
|
||||
import { findTransactionByID } from "../../../../lib/graphqlHelpers";
|
||||
@@ -67,19 +66,12 @@ const transactionPage = ({
|
||||
const [transactionHash, setTransactionHash] = useState(txHash);
|
||||
const txInfo = (transactionJSON && JSON.parse(transactionJSON)) || null;
|
||||
const addSignature = (signature) => {
|
||||
setCurrentSignatures((currentSignatures) => [
|
||||
...currentSignatures,
|
||||
signature,
|
||||
]);
|
||||
setCurrentSignatures((prevState) => [...prevState, signature]);
|
||||
};
|
||||
const broadcastTx = async () => {
|
||||
try {
|
||||
setIsBroadcasting(true);
|
||||
setBroadcastError("");
|
||||
const signatures = new Map();
|
||||
currentSignatures.forEach((signature) => {
|
||||
signatures.set(signature.address, fromBase64(signature.signature));
|
||||
});
|
||||
|
||||
const bodyBytes = fromBase64(currentSignatures[0].bodyBytes);
|
||||
const signedTx = makeMultisignedTx(
|
||||
@@ -87,14 +79,16 @@ const transactionPage = ({
|
||||
txInfo.sequence,
|
||||
txInfo.fee,
|
||||
bodyBytes,
|
||||
signatures
|
||||
new Map(
|
||||
currentSignatures.map((s) => [s.address, fromBase64(s.signature)])
|
||||
)
|
||||
);
|
||||
const broadcaster = await StargateClient.connect(nodeAddress);
|
||||
const result = await broadcaster.broadcastTx(
|
||||
Uint8Array.from(TxRaw.encode(signedTx).finish())
|
||||
);
|
||||
console.log(result);
|
||||
const res = await axios.post(`/api/transaction/${transactionID}`, {
|
||||
const _res = await axios.post(`/api/transaction/${transactionID}`, {
|
||||
txHash: result.transactionHash,
|
||||
});
|
||||
setTransactionHash(result.transactionHash);
|
||||
@@ -126,7 +120,7 @@ const transactionPage = ({
|
||||
/>
|
||||
)}
|
||||
{currentSignatures.length >=
|
||||
parseInt(accountOnChain.pubkey.value.threshold) &&
|
||||
parseInt(accountOnChain.pubkey.value.threshold, 10) &&
|
||||
!transactionHash && (
|
||||
<>
|
||||
<Button
|
||||
|
||||
Reference in New Issue
Block a user