deleteMsg()}>
✕
-
MsgInstantiateContract
+
MsgInstantiateContract2
Date: Mon, 10 Jul 2023 19:11:16 +0200
Subject: [PATCH 11/44] Fix remove error
---
.../forms/CreateTxForm/MsgForm/MsgInstantiateContract2Form.tsx | 1 +
.../forms/CreateTxForm/MsgForm/MsgInstantiateContractForm.tsx | 1 +
2 files changed, 2 insertions(+)
diff --git a/components/forms/CreateTxForm/MsgForm/MsgInstantiateContract2Form.tsx b/components/forms/CreateTxForm/MsgForm/MsgInstantiateContract2Form.tsx
index bcc66ab..ed6474f 100644
--- a/components/forms/CreateTxForm/MsgForm/MsgInstantiateContract2Form.tsx
+++ b/components/forms/CreateTxForm/MsgForm/MsgInstantiateContract2Form.tsx
@@ -57,6 +57,7 @@ const MsgInstantiateContract2Form = ({
useEffect(() => {
assert(state.chain.denom, "denom missing");
+ setCodeIdError("");
setAdminAddressError("");
setMsgContentError("");
setCustomDenomError("");
diff --git a/components/forms/CreateTxForm/MsgForm/MsgInstantiateContractForm.tsx b/components/forms/CreateTxForm/MsgForm/MsgInstantiateContractForm.tsx
index a40abbe..cc1ff7f 100644
--- a/components/forms/CreateTxForm/MsgForm/MsgInstantiateContractForm.tsx
+++ b/components/forms/CreateTxForm/MsgForm/MsgInstantiateContractForm.tsx
@@ -55,6 +55,7 @@ const MsgInstantiateContractForm = ({
useEffect(() => {
assert(state.chain.denom, "denom missing");
+ setCodeIdError("");
setAdminAddressError("");
setMsgContentError("");
setCustomDenomError("");
From 7ebb8f3389ada1c3f09d7a87311f703f4a158403 Mon Sep 17 00:00:00 2001
From: abefernan <44572727+abefernan@users.noreply.github.com>
Date: Mon, 10 Jul 2023 19:18:02 +0200
Subject: [PATCH 12/44] Add migrate types
---
lib/txMsgHelpers.ts | 2 ++
types/txMsg.ts | 3 +++
2 files changed, 5 insertions(+)
diff --git a/lib/txMsgHelpers.ts b/lib/txMsgHelpers.ts
index 9e2f0b9..f5cb6b8 100644
--- a/lib/txMsgHelpers.ts
+++ b/lib/txMsgHelpers.ts
@@ -26,6 +26,8 @@ const gasOfMsg = (msgType: MsgTypeUrl): number => {
return 150_000;
case MsgTypeUrls.Instantiate2:
return 150_000;
+ case MsgTypeUrls.Migrate:
+ return 150_000;
default:
throw new Error("Unknown msg type");
}
diff --git a/types/txMsg.ts b/types/txMsg.ts
index 0c6db2c..6a1ccb2 100644
--- a/types/txMsg.ts
+++ b/types/txMsg.ts
@@ -13,6 +13,7 @@ import {
MsgExecuteContract,
MsgInstantiateContract,
MsgInstantiateContract2,
+ MsgMigrateContract,
} from "cosmjs-types/cosmwasm/wasm/v1/tx";
import { MsgTransfer } from "cosmjs-types/ibc/applications/transfer/v1/tx";
@@ -28,6 +29,7 @@ export const MsgTypeUrls = {
Execute: "/cosmwasm.wasm.v1.MsgExecuteContract",
Instantiate: "/cosmwasm.wasm.v1.MsgInstantiateContract",
Instantiate2: "/cosmwasm.wasm.v1.MsgInstantiateContract2",
+ Migrate: "/cosmwasm.wasm.v1.MsgMigrateContract",
} as const;
export type MsgTypeUrl = (typeof MsgTypeUrls)[keyof typeof MsgTypeUrls];
@@ -44,4 +46,5 @@ export const MsgCodecs = {
[MsgTypeUrls.Execute]: MsgExecuteContract,
[MsgTypeUrls.Instantiate]: MsgInstantiateContract,
[MsgTypeUrls.Instantiate2]: MsgInstantiateContract2,
+ [MsgTypeUrls.Migrate]: MsgMigrateContract,
};
From 3d4f9dea893d4e7e04cb70bc64f5cbb25a3f52ae Mon Sep 17 00:00:00 2001
From: abefernan <44572727+abefernan@users.noreply.github.com>
Date: Mon, 10 Jul 2023 19:18:13 +0200
Subject: [PATCH 13/44] Add migrate details
---
.../TxMsgMigrateContractDetails.tsx | 56 +++++++++++++++++++
.../dataViews/TransactionInfo/index.tsx | 3 +
2 files changed, 59 insertions(+)
create mode 100644 components/dataViews/TransactionInfo/TxMsgMigrateContractDetails.tsx
diff --git a/components/dataViews/TransactionInfo/TxMsgMigrateContractDetails.tsx b/components/dataViews/TransactionInfo/TxMsgMigrateContractDetails.tsx
new file mode 100644
index 0000000..8e095a1
--- /dev/null
+++ b/components/dataViews/TransactionInfo/TxMsgMigrateContractDetails.tsx
@@ -0,0 +1,56 @@
+import { fromUtf8 } from "@cosmjs/encoding";
+import { MsgMigrateContract } from "cosmjs-types/cosmwasm/wasm/v1/tx";
+import HashView from "../HashView";
+
+interface TxMsgMigrateContractDetailsProps {
+ readonly msgValue: MsgMigrateContract;
+}
+
+const TxMsgMigrateContractDetails = ({ msgValue }: TxMsgMigrateContractDetailsProps) => (
+ <>
+
+ MsgMigrateContract
+
+
+
+
+
+
+
+
+
+ {msgValue.codeId.toString()}
+
+
+
+ {fromUtf8(msgValue.msg)}
+
+
+ >
+);
+
+export default TxMsgMigrateContractDetails;
diff --git a/components/dataViews/TransactionInfo/index.tsx b/components/dataViews/TransactionInfo/index.tsx
index 0b11c6c..c6f5c12 100644
--- a/components/dataViews/TransactionInfo/index.tsx
+++ b/components/dataViews/TransactionInfo/index.tsx
@@ -10,6 +10,7 @@ import TxMsgDelegateDetails from "./TxMsgDelegateDetails";
import TxMsgExecuteContractDetails from "./TxMsgExecuteContractDetails";
import TxMsgInstantiateContract2Details from "./TxMsgInstantiateContract2Details";
import TxMsgInstantiateContractDetails from "./TxMsgInstantiateContractDetails";
+import TxMsgMigrateContractDetails from "./TxMsgMigrateContractDetails";
import TxMsgRedelegateDetails from "./TxMsgRedelegateDetails";
import TxMsgSendDetails from "./TxMsgSendDetails";
import TxMsgSetWithdrawAddressDetails from "./TxMsgSetWithdrawAddressDetails";
@@ -40,6 +41,8 @@ const TxMsgDetails = ({ typeUrl, value: msgValue }: EncodeObject) => {
return
;
case MsgTypeUrls.Instantiate2:
return
;
+ case MsgTypeUrls.Migrate:
+ return
;
default:
return null;
}
From fad870cc471890da25194a42f55ddf9ca0b3572c Mon Sep 17 00:00:00 2001
From: abefernan <44572727+abefernan@users.noreply.github.com>
Date: Mon, 10 Jul 2023 19:18:49 +0200
Subject: [PATCH 14/44] Add migrate form
---
.../MsgForm/MsgMigrateContractForm.tsx | 152 ++++++++++++++++++
.../forms/CreateTxForm/MsgForm/index.tsx | 3 +
components/forms/CreateTxForm/index.tsx | 1 +
3 files changed, 156 insertions(+)
create mode 100644 components/forms/CreateTxForm/MsgForm/MsgMigrateContractForm.tsx
diff --git a/components/forms/CreateTxForm/MsgForm/MsgMigrateContractForm.tsx b/components/forms/CreateTxForm/MsgForm/MsgMigrateContractForm.tsx
new file mode 100644
index 0000000..71dc473
--- /dev/null
+++ b/components/forms/CreateTxForm/MsgForm/MsgMigrateContractForm.tsx
@@ -0,0 +1,152 @@
+import { MsgMigrateContractEncodeObject } from "@cosmjs/cosmwasm-stargate";
+import { toUtf8 } from "@cosmjs/encoding";
+import { assert } from "@cosmjs/utils";
+import { useEffect, useState } from "react";
+import { MsgGetter } from "..";
+import { useAppContext } from "../../../../context/AppContext";
+import { checkAddress, exampleAddress } from "../../../../lib/displayHelpers";
+import { MsgCodecs, MsgTypeUrls } from "../../../../types/txMsg";
+import Input from "../../../inputs/Input";
+import StackableContainer from "../../../layout/StackableContainer";
+
+interface MsgMigrateContractFormProps {
+ readonly fromAddress: string;
+ readonly setMsgGetter: (msgGetter: MsgGetter) => void;
+ readonly deleteMsg: () => void;
+}
+
+const MsgMigrateContractForm = ({
+ fromAddress,
+ setMsgGetter,
+ deleteMsg,
+}: MsgMigrateContractFormProps) => {
+ const { state } = useAppContext();
+ assert(state.chain.addressPrefix, "addressPrefix missing");
+
+ const [codeId, setCodeId] = useState("");
+ const [contractAddress, setContractAddress] = useState("");
+ const [msgContent, setMsgContent] = useState("{}");
+
+ const [codeIdError, setCodeIdError] = useState("");
+ const [contractAddressError, setContractAddressError] = useState("");
+ const [msgContentError, setMsgContentError] = useState("");
+
+ useEffect(() => {
+ assert(state.chain.denom, "denom missing");
+
+ setCodeIdError("");
+ setContractAddressError("");
+ setMsgContentError("");
+
+ const isMsgValid = (): boolean => {
+ assert(state.chain.addressPrefix, "addressPrefix missing");
+
+ if (!codeId || !Number.isSafeInteger(Number(codeId)) || Number(codeId) <= 0) {
+ setCodeIdError("Code ID must be a positive integer");
+ return false;
+ }
+
+ const addressErrorMsg = checkAddress(contractAddress, state.chain.addressPrefix);
+ if (addressErrorMsg) {
+ setContractAddressError(
+ `Invalid address for network ${state.chain.chainId}: ${addressErrorMsg}`,
+ );
+ return false;
+ }
+
+ try {
+ JSON.parse(msgContent);
+ } catch {
+ setMsgContentError("Msg must be valid JSON");
+ return false;
+ }
+
+ return true;
+ };
+
+ const msgValue = MsgCodecs[MsgTypeUrls.Migrate].fromPartial({
+ sender: fromAddress,
+ contract: contractAddress,
+ codeId,
+ msg: toUtf8(msgContent),
+ });
+
+ const msg: MsgMigrateContractEncodeObject = { typeUrl: MsgTypeUrls.Migrate, value: msgValue };
+
+ setMsgGetter({ isMsgValid, msg });
+ }, [
+ codeId,
+ contractAddress,
+ fromAddress,
+ msgContent,
+ setMsgGetter,
+ state.chain.addressPrefix,
+ state.chain.chainId,
+ state.chain.denom,
+ ]);
+
+ return (
+
+
+ MsgMigrateContract
+
+ setCodeId(target.value)}
+ error={codeIdError}
+ />
+
+
+ setContractAddress(target.value)}
+ error={contractAddressError}
+ placeholder={`E.g. ${exampleAddress(0, state.chain.addressPrefix)}`}
+ />
+
+
+ setMsgContent(target.value)}
+ error={msgContentError}
+ placeholder={"Enter msg JSON"}
+ />
+
+
+
+ );
+};
+
+export default MsgMigrateContractForm;
diff --git a/components/forms/CreateTxForm/MsgForm/index.tsx b/components/forms/CreateTxForm/MsgForm/index.tsx
index c47864c..21f048f 100644
--- a/components/forms/CreateTxForm/MsgForm/index.tsx
+++ b/components/forms/CreateTxForm/MsgForm/index.tsx
@@ -6,6 +6,7 @@ import MsgDelegateForm from "./MsgDelegateForm";
import MsgExecuteContractForm from "./MsgExecuteContractForm";
import MsgInstantiateContract2Form from "./MsgInstantiateContract2Form";
import MsgInstantiateContractForm from "./MsgInstantiateContractForm";
+import MsgMigrateContractForm from "./MsgMigrateContractForm";
import MsgRedelegateForm from "./MsgRedelegateForm";
import MsgSendForm from "./MsgSendForm";
import MsgSetWithdrawAddressForm from "./MsgSetWithdrawAddressForm";
@@ -43,6 +44,8 @@ const MsgForm = ({ msgType, senderAddress, ...restProps }: MsgFormProps) => {
return
;
case MsgTypeUrls.Instantiate2:
return
;
+ case MsgTypeUrls.Migrate:
+ return
;
default:
return null;
}
diff --git a/components/forms/CreateTxForm/index.tsx b/components/forms/CreateTxForm/index.tsx
index 9385e9c..df7624a 100644
--- a/components/forms/CreateTxForm/index.tsx
+++ b/components/forms/CreateTxForm/index.tsx
@@ -188,6 +188,7 @@ const CreateTxForm = ({ router, senderAddress, accountOnChain }: CreateTxFormPro
label="Add MsgInstantiateContract2"
onClick={() => addMsgType(MsgTypeUrls.Instantiate2)}
/>
+
diff --git a/components/forms/CreateTxForm/MsgForm/MsgInstantiateContract2Form.tsx b/components/forms/CreateTxForm/MsgForm/MsgInstantiateContract2Form.tsx
index ed6474f..46584fa 100644
--- a/components/forms/CreateTxForm/MsgForm/MsgInstantiateContract2Form.tsx
+++ b/components/forms/CreateTxForm/MsgForm/MsgInstantiateContract2Form.tsx
@@ -1,12 +1,11 @@
import { MsgInstantiateContract2EncodeObject } from "@cosmjs/cosmwasm-stargate";
import { toUtf8 } from "@cosmjs/encoding";
import { Decimal } from "@cosmjs/math";
-import { assert } from "@cosmjs/utils";
import { useEffect, useState } from "react";
import { MsgGetter } from "..";
-import { useAppContext } from "../../../../context/AppContext";
+import { useChains } from "../../../../context/ChainsContext";
+import { ChainInfo } from "../../../../context/ChainsContext/types";
import { checkAddress, exampleAddress } from "../../../../lib/displayHelpers";
-import { ChainInfo } from "../../../../types";
import { MsgCodecs, MsgTypeUrls } from "../../../../types/txMsg";
import Input from "../../../inputs/Input";
import Select from "../../../inputs/Select";
@@ -33,10 +32,9 @@ const MsgInstantiateContract2Form = ({
setMsgGetter,
deleteMsg,
}: MsgInstantiateContract2FormProps) => {
- const { state } = useAppContext();
- assert(state.chain.addressPrefix, "addressPrefix missing");
+ const { chain } = useChains();
- const denomOptions = getDenomOptions(state.chain.assets);
+ const denomOptions = getDenomOptions(chain.assets);
const [codeId, setCodeId] = useState("");
const [label, setLabel] = useState("");
@@ -55,8 +53,6 @@ const MsgInstantiateContract2Form = ({
const [amountError, setAmountError] = useState("");
useEffect(() => {
- assert(state.chain.denom, "denom missing");
-
setCodeIdError("");
setAdminAddressError("");
setMsgContentError("");
@@ -64,18 +60,14 @@ const MsgInstantiateContract2Form = ({
setAmountError("");
const isMsgValid = (): boolean => {
- assert(state.chain.addressPrefix, "addressPrefix missing");
-
if (!codeId || !Number.isSafeInteger(Number(codeId)) || Number(codeId) <= 0) {
setCodeIdError("Code ID must be a positive integer");
return false;
}
- const addressErrorMsg = checkAddress(adminAddress, state.chain.addressPrefix);
+ const addressErrorMsg = checkAddress(adminAddress, chain.addressPrefix);
if (adminAddress && addressErrorMsg) {
- setAdminAddressError(
- `Invalid address for network ${state.chain.chainId}: ${addressErrorMsg}`,
- );
+ setAdminAddressError(`Invalid address for network ${chain.chainId}: ${addressErrorMsg}`);
return false;
}
@@ -113,7 +105,7 @@ const MsgInstantiateContract2Form = ({
return Decimal.fromUserInput(amount, 0).atomics;
}
- const foundAsset = state.chain.assets?.find((asset) => asset.symbol === denom);
+ const foundAsset = chain.assets?.find((asset) => asset.symbol === denom);
const exponent =
foundAsset?.denom_units.find((unit) => unit.denom === foundAsset.symbol.toLowerCase())
?.exponent ?? 0;
@@ -144,6 +136,10 @@ const MsgInstantiateContract2Form = ({
}, [
adminAddress,
amount,
+ chain.addressPrefix,
+ chain.assets,
+ chain.chainId,
+ chain.denom,
codeId,
customDenom,
fixMsg,
@@ -153,10 +149,6 @@ const MsgInstantiateContract2Form = ({
salt,
selectedDenom.value,
setMsgGetter,
- state.chain.addressPrefix,
- state.chain.assets,
- state.chain.chainId,
- state.chain.denom,
]);
return (
@@ -189,7 +181,7 @@ const MsgInstantiateContract2Form = ({
value={adminAddress}
onChange={({ target }) => setAdminAddress(target.value)}
error={adminAddressError}
- placeholder={`E.g. ${exampleAddress(0, state.chain.addressPrefix)}`}
+ placeholder={`E.g. ${exampleAddress(0, chain.addressPrefix)}`}
/>
diff --git a/components/forms/CreateTxForm/MsgForm/MsgInstantiateContractForm.tsx b/components/forms/CreateTxForm/MsgForm/MsgInstantiateContractForm.tsx
index cc1ff7f..3e5b668 100644
--- a/components/forms/CreateTxForm/MsgForm/MsgInstantiateContractForm.tsx
+++ b/components/forms/CreateTxForm/MsgForm/MsgInstantiateContractForm.tsx
@@ -1,12 +1,11 @@
import { MsgInstantiateContractEncodeObject } from "@cosmjs/cosmwasm-stargate";
import { toUtf8 } from "@cosmjs/encoding";
import { Decimal } from "@cosmjs/math";
-import { assert } from "@cosmjs/utils";
import { useEffect, useState } from "react";
import { MsgGetter } from "..";
-import { useAppContext } from "../../../../context/AppContext";
+import { useChains } from "../../../../context/ChainsContext";
+import { ChainInfo } from "../../../../context/ChainsContext/types";
import { checkAddress, exampleAddress } from "../../../../lib/displayHelpers";
-import { ChainInfo } from "../../../../types";
import { MsgCodecs, MsgTypeUrls } from "../../../../types/txMsg";
import Input from "../../../inputs/Input";
import Select from "../../../inputs/Select";
@@ -33,10 +32,9 @@ const MsgInstantiateContractForm = ({
setMsgGetter,
deleteMsg,
}: MsgInstantiateContractFormProps) => {
- const { state } = useAppContext();
- assert(state.chain.addressPrefix, "addressPrefix missing");
+ const { chain } = useChains();
- const denomOptions = getDenomOptions(state.chain.assets);
+ const denomOptions = getDenomOptions(chain.assets);
const [codeId, setCodeId] = useState("");
const [label, setLabel] = useState("");
@@ -53,8 +51,6 @@ const MsgInstantiateContractForm = ({
const [amountError, setAmountError] = useState("");
useEffect(() => {
- assert(state.chain.denom, "denom missing");
-
setCodeIdError("");
setAdminAddressError("");
setMsgContentError("");
@@ -62,18 +58,14 @@ const MsgInstantiateContractForm = ({
setAmountError("");
const isMsgValid = (): boolean => {
- assert(state.chain.addressPrefix, "addressPrefix missing");
-
if (!codeId || !Number.isSafeInteger(Number(codeId)) || Number(codeId) <= 0) {
setCodeIdError("Code ID must be a positive integer");
return false;
}
- const addressErrorMsg = checkAddress(adminAddress, state.chain.addressPrefix);
+ const addressErrorMsg = checkAddress(adminAddress, chain.addressPrefix);
if (adminAddress && addressErrorMsg) {
- setAdminAddressError(
- `Invalid address for network ${state.chain.chainId}: ${addressErrorMsg}`,
- );
+ setAdminAddressError(`Invalid address for network ${chain.chainId}: ${addressErrorMsg}`);
return false;
}
@@ -111,7 +103,7 @@ const MsgInstantiateContractForm = ({
return Decimal.fromUserInput(amount, 0).atomics;
}
- const foundAsset = state.chain.assets?.find((asset) => asset.symbol === denom);
+ const foundAsset = chain.assets?.find((asset) => asset.symbol === denom);
const exponent =
foundAsset?.denom_units.find((unit) => unit.denom === foundAsset.symbol.toLowerCase())
?.exponent ?? 0;
@@ -140,6 +132,9 @@ const MsgInstantiateContractForm = ({
}, [
adminAddress,
amount,
+ chain.addressPrefix,
+ chain.assets,
+ chain.chainId,
codeId,
customDenom,
fromAddress,
@@ -147,10 +142,6 @@ const MsgInstantiateContractForm = ({
msgContent,
selectedDenom.value,
setMsgGetter,
- state.chain.addressPrefix,
- state.chain.assets,
- state.chain.chainId,
- state.chain.denom,
]);
return (
@@ -183,7 +174,7 @@ const MsgInstantiateContractForm = ({
value={adminAddress}
onChange={({ target }) => setAdminAddress(target.value)}
error={adminAddressError}
- placeholder={`E.g. ${exampleAddress(0, state.chain.addressPrefix)}`}
+ placeholder={`E.g. ${exampleAddress(0, chain.addressPrefix)}`}
/>
diff --git a/components/forms/CreateTxForm/MsgForm/MsgMigrateContractForm.tsx b/components/forms/CreateTxForm/MsgForm/MsgMigrateContractForm.tsx
index 71dc473..8d42e3f 100644
--- a/components/forms/CreateTxForm/MsgForm/MsgMigrateContractForm.tsx
+++ b/components/forms/CreateTxForm/MsgForm/MsgMigrateContractForm.tsx
@@ -1,9 +1,8 @@
import { MsgMigrateContractEncodeObject } from "@cosmjs/cosmwasm-stargate";
import { toUtf8 } from "@cosmjs/encoding";
-import { assert } from "@cosmjs/utils";
import { useEffect, useState } from "react";
import { MsgGetter } from "..";
-import { useAppContext } from "../../../../context/AppContext";
+import { useChains } from "../../../../context/ChainsContext";
import { checkAddress, exampleAddress } from "../../../../lib/displayHelpers";
import { MsgCodecs, MsgTypeUrls } from "../../../../types/txMsg";
import Input from "../../../inputs/Input";
@@ -20,8 +19,7 @@ const MsgMigrateContractForm = ({
setMsgGetter,
deleteMsg,
}: MsgMigrateContractFormProps) => {
- const { state } = useAppContext();
- assert(state.chain.addressPrefix, "addressPrefix missing");
+ const { chain } = useChains();
const [codeId, setCodeId] = useState("");
const [contractAddress, setContractAddress] = useState("");
@@ -32,25 +30,19 @@ const MsgMigrateContractForm = ({
const [msgContentError, setMsgContentError] = useState("");
useEffect(() => {
- assert(state.chain.denom, "denom missing");
-
setCodeIdError("");
setContractAddressError("");
setMsgContentError("");
const isMsgValid = (): boolean => {
- assert(state.chain.addressPrefix, "addressPrefix missing");
-
if (!codeId || !Number.isSafeInteger(Number(codeId)) || Number(codeId) <= 0) {
setCodeIdError("Code ID must be a positive integer");
return false;
}
- const addressErrorMsg = checkAddress(contractAddress, state.chain.addressPrefix);
+ const addressErrorMsg = checkAddress(contractAddress, chain.addressPrefix);
if (addressErrorMsg) {
- setContractAddressError(
- `Invalid address for network ${state.chain.chainId}: ${addressErrorMsg}`,
- );
+ setContractAddressError(`Invalid address for network ${chain.chainId}: ${addressErrorMsg}`);
return false;
}
@@ -80,9 +72,9 @@ const MsgMigrateContractForm = ({
fromAddress,
msgContent,
setMsgGetter,
- state.chain.addressPrefix,
- state.chain.chainId,
- state.chain.denom,
+ chain.addressPrefix,
+ chain.chainId,
+ chain.denom,
]);
return (
@@ -107,7 +99,7 @@ const MsgMigrateContractForm = ({
value={contractAddress}
onChange={({ target }) => setContractAddress(target.value)}
error={contractAddressError}
- placeholder={`E.g. ${exampleAddress(0, state.chain.addressPrefix)}`}
+ placeholder={`E.g. ${exampleAddress(0, chain.addressPrefix)}`}
/>
From 726bde774c377f285cd210ec8f741e9b57dcaba9 Mon Sep 17 00:00:00 2001
From: abefernan <44572727+abefernan@users.noreply.github.com>
Date: Thu, 13 Jul 2023 18:22:31 +0200
Subject: [PATCH 16/44] Add jsoneditor dep
---
package-lock.json | 13 ++++++++++++-
package.json | 3 ++-
2 files changed, 14 insertions(+), 2 deletions(-)
diff --git a/package-lock.json b/package-lock.json
index 7dac6e3..850f6e6 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -24,7 +24,8 @@
"next": "^13.3.0",
"react": "^18.2.0",
"react-dom": "^18.2.0",
- "react-select": "^5.7.2"
+ "react-select": "^5.7.2",
+ "vanilla-jsoneditor": "^0.17.8"
},
"devDependencies": {
"@testing-library/jest-dom": "^5.16.5",
@@ -8719,6 +8720,11 @@
"node": ">=10.12.0"
}
},
+ "node_modules/vanilla-jsoneditor": {
+ "version": "0.17.8",
+ "resolved": "https://registry.npmjs.org/vanilla-jsoneditor/-/vanilla-jsoneditor-0.17.8.tgz",
+ "integrity": "sha512-DP9GP/IBQjYOnC820CYoFuXs3vgrL+zdGGp1X83qFirSkRWPeP+6zB/14a0LYhvomQNNezes5Gwel89MKc4Qbg=="
+ },
"node_modules/w3c-xmlserializer": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/w3c-xmlserializer/-/w3c-xmlserializer-4.0.0.tgz",
@@ -15537,6 +15543,11 @@
"convert-source-map": "^1.6.0"
}
},
+ "vanilla-jsoneditor": {
+ "version": "0.17.8",
+ "resolved": "https://registry.npmjs.org/vanilla-jsoneditor/-/vanilla-jsoneditor-0.17.8.tgz",
+ "integrity": "sha512-DP9GP/IBQjYOnC820CYoFuXs3vgrL+zdGGp1X83qFirSkRWPeP+6zB/14a0LYhvomQNNezes5Gwel89MKc4Qbg=="
+ },
"w3c-xmlserializer": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/w3c-xmlserializer/-/w3c-xmlserializer-4.0.0.tgz",
diff --git a/package.json b/package.json
index d134d52..bb14c36 100644
--- a/package.json
+++ b/package.json
@@ -28,7 +28,8 @@
"next": "^13.3.0",
"react": "^18.2.0",
"react-dom": "^18.2.0",
- "react-select": "^5.7.2"
+ "react-select": "^5.7.2",
+ "vanilla-jsoneditor": "^0.17.8"
},
"devDependencies": {
"@testing-library/jest-dom": "^5.16.5",
From a8acfa4fb167ce3ef3ed2546d1ecbdedd7b3654a Mon Sep 17 00:00:00 2001
From: abefernan <44572727+abefernan@users.noreply.github.com>
Date: Thu, 13 Jul 2023 18:22:39 +0200
Subject: [PATCH 17/44] Add JsonEditor component
---
components/inputs/JsonEditor.tsx | 65 ++++++++++++++++++++++++++++++++
1 file changed, 65 insertions(+)
create mode 100644 components/inputs/JsonEditor.tsx
diff --git a/components/inputs/JsonEditor.tsx b/components/inputs/JsonEditor.tsx
new file mode 100644
index 0000000..a171671
--- /dev/null
+++ b/components/inputs/JsonEditor.tsx
@@ -0,0 +1,65 @@
+import { CSSProperties, useEffect, useRef } from "react";
+import { JSONEditorPropsOptional, JSONEditor as VanillaJsonEditor } from "vanilla-jsoneditor";
+
+const editorStyle: { [key: string]: string } & CSSProperties = {
+ "--jse-a-color": "white",
+ "--jse-delimiter-color": "white",
+ "--jse-key-color": "white",
+ "--jse-text-color": "white",
+ "--jse-value-color": "white",
+ "--jse-value-color-boolean": "white",
+ "--jse-value-color-null": "white",
+ "--jse-value-color-number": "white",
+ "--jse-value-color-string": "white",
+ "--jse-value-color-url": "white",
+ "--jse-background-color": "transparent",
+ "--jse-panel-background": "transparent",
+ "--jse-selection-background-color": "rgba(255, 255, 255, 0.5)",
+ "--jse-main-border": "2px solid rgba(255, 255, 255, 0.5)",
+ "--jse-panel-border": "2px solid rgba(255, 255, 255, 0.5)",
+};
+
+interface JsonEditorProps extends JSONEditorPropsOptional {
+ readonly label?: string;
+}
+
+export default function JsonEditor({ label, ...editorProps }: JsonEditorProps) {
+ const refContainer = useRef
(null);
+ const refEditor = useRef(null);
+
+ useEffect(() => {
+ if (!refContainer.current) return;
+
+ refEditor.current = new VanillaJsonEditor({ target: refContainer.current, props: {} });
+
+ return () => {
+ if (refEditor.current) {
+ refEditor.current.destroy();
+ refEditor.current = null;
+ }
+ };
+ }, []);
+
+ useEffect(() => {
+ if (refEditor.current) {
+ refEditor.current.updateProps({ mode: "text", mainMenuBar: false, ...editorProps });
+ }
+ }, [editorProps]);
+
+ return (
+
+ {label ? : null}
+
+
+ );
+}
From 089383a401eff280e1d9905f778337d781f6a181 Mon Sep 17 00:00:00 2001
From: abefernan <44572727+abefernan@users.noreply.github.com>
Date: Thu, 13 Jul 2023 18:23:02 +0200
Subject: [PATCH 18/44] Use JsonEditor in MsgExecuteContractForm
---
.../MsgForm/MsgExecuteContractForm.tsx | 25 +++++++------------
1 file changed, 9 insertions(+), 16 deletions(-)
diff --git a/components/forms/CreateTxForm/MsgForm/MsgExecuteContractForm.tsx b/components/forms/CreateTxForm/MsgForm/MsgExecuteContractForm.tsx
index 3f136eb..6c6e59c 100644
--- a/components/forms/CreateTxForm/MsgForm/MsgExecuteContractForm.tsx
+++ b/components/forms/CreateTxForm/MsgForm/MsgExecuteContractForm.tsx
@@ -1,6 +1,7 @@
import { MsgExecuteContractEncodeObject } from "@cosmjs/cosmwasm-stargate";
import { toUtf8 } from "@cosmjs/encoding";
import { Decimal } from "@cosmjs/math";
+import dynamic from "next/dynamic";
import { useEffect, useState } from "react";
import { MsgGetter } from "..";
import { useChains } from "../../../../context/ChainsContext";
@@ -11,6 +12,8 @@ import Input from "../../../inputs/Input";
import Select from "../../../inputs/Select";
import StackableContainer from "../../../layout/StackableContainer";
+const JsonEditor = dynamic(() => import("../../../inputs/JsonEditor"), { ssr: false });
+
const customDenomOption = { label: "Custom (enter denom below)", value: "custom" } as const;
const getDenomOptions = (assets: ChainInfo["assets"]) => {
@@ -43,13 +46,11 @@ const MsgExecuteContractForm = ({
const [amount, setAmount] = useState("0");
const [contractAddressError, setContractAddressError] = useState("");
- const [msgContentError, setMsgContentError] = useState("");
const [customDenomError, setCustomDenomError] = useState("");
const [amountError, setAmountError] = useState("");
useEffect(() => {
setContractAddressError("");
- setMsgContentError("");
setCustomDenomError("");
setAmountError("");
@@ -60,13 +61,6 @@ const MsgExecuteContractForm = ({
return false;
}
- try {
- JSON.parse(msgContent);
- } catch {
- setMsgContentError("Msg must be valid JSON");
- return false;
- }
-
if (selectedDenom.value === customDenomOption.value && !customDenom) {
setCustomDenomError("Custom denom must be set because of selection above");
return false;
@@ -145,13 +139,12 @@ const MsgExecuteContractForm = ({
/>
- setMsgContent(target.value)}
- error={msgContentError}
- placeholder={"Enter msg JSON"}
+
+ setMsgContent("text" in newMsgContent ? newMsgContent.text ?? "{}" : "{}")
+ }
/>
From edc1c61b8d6ce56ca605ced6b85d4dd7f0bc9d49 Mon Sep 17 00:00:00 2001
From: abefernan <44572727+abefernan@users.noreply.github.com>
Date: Thu, 13 Jul 2023 18:23:16 +0200
Subject: [PATCH 19/44] Use JsonEditor in MsgInstantiateContractForm
---
.../MsgForm/MsgInstantiateContractForm.tsx | 27 +++++++------------
1 file changed, 10 insertions(+), 17 deletions(-)
diff --git a/components/forms/CreateTxForm/MsgForm/MsgInstantiateContractForm.tsx b/components/forms/CreateTxForm/MsgForm/MsgInstantiateContractForm.tsx
index 3e5b668..5cb44ab 100644
--- a/components/forms/CreateTxForm/MsgForm/MsgInstantiateContractForm.tsx
+++ b/components/forms/CreateTxForm/MsgForm/MsgInstantiateContractForm.tsx
@@ -1,6 +1,7 @@
import { MsgInstantiateContractEncodeObject } from "@cosmjs/cosmwasm-stargate";
import { toUtf8 } from "@cosmjs/encoding";
import { Decimal } from "@cosmjs/math";
+import dynamic from "next/dynamic";
import { useEffect, useState } from "react";
import { MsgGetter } from "..";
import { useChains } from "../../../../context/ChainsContext";
@@ -11,6 +12,8 @@ import Input from "../../../inputs/Input";
import Select from "../../../inputs/Select";
import StackableContainer from "../../../layout/StackableContainer";
+const JsonEditor = dynamic(() => import("../../../inputs/JsonEditor"), { ssr: false });
+
const customDenomOption = { label: "Custom (enter denom below)", value: "custom" } as const;
const getDenomOptions = (assets: ChainInfo["assets"]) => {
@@ -46,14 +49,12 @@ const MsgInstantiateContractForm = ({
const [codeIdError, setCodeIdError] = useState("");
const [adminAddressError, setAdminAddressError] = useState("");
- const [msgContentError, setMsgContentError] = useState("");
const [customDenomError, setCustomDenomError] = useState("");
const [amountError, setAmountError] = useState("");
useEffect(() => {
setCodeIdError("");
setAdminAddressError("");
- setMsgContentError("");
setCustomDenomError("");
setAmountError("");
@@ -69,13 +70,6 @@ const MsgInstantiateContractForm = ({
return false;
}
- try {
- JSON.parse(msgContent);
- } catch {
- setMsgContentError("Msg must be valid JSON");
- return false;
- }
-
if (selectedDenom.value === customDenomOption.value && !customDenom) {
setCustomDenomError("Custom denom must be set because of selection above");
return false;
@@ -116,7 +110,7 @@ const MsgInstantiateContractForm = ({
const msgValue = MsgCodecs[MsgTypeUrls.Instantiate].fromPartial({
sender: fromAddress,
- codeId,
+ codeId: codeId || 1,
label,
admin: adminAddress,
msg: toUtf8(msgContent),
@@ -178,13 +172,12 @@ const MsgInstantiateContractForm = ({
/>
- setMsgContent(target.value)}
- error={msgContentError}
- placeholder={"Enter msg JSON"}
+
+ setMsgContent("text" in newMsgContent ? newMsgContent.text ?? "{}" : "{}")
+ }
/>
From 11858574804477fe116e0e14cd255bb0e413e4a2 Mon Sep 17 00:00:00 2001
From: abefernan <44572727+abefernan@users.noreply.github.com>
Date: Thu, 13 Jul 2023 18:23:26 +0200
Subject: [PATCH 20/44] Use JsonEditor in MsgInstantiateContract2Form
---
.../MsgForm/MsgInstantiateContract2Form.tsx | 27 +++++++------------
1 file changed, 10 insertions(+), 17 deletions(-)
diff --git a/components/forms/CreateTxForm/MsgForm/MsgInstantiateContract2Form.tsx b/components/forms/CreateTxForm/MsgForm/MsgInstantiateContract2Form.tsx
index 46584fa..05fea76 100644
--- a/components/forms/CreateTxForm/MsgForm/MsgInstantiateContract2Form.tsx
+++ b/components/forms/CreateTxForm/MsgForm/MsgInstantiateContract2Form.tsx
@@ -1,6 +1,7 @@
import { MsgInstantiateContract2EncodeObject } from "@cosmjs/cosmwasm-stargate";
import { toUtf8 } from "@cosmjs/encoding";
import { Decimal } from "@cosmjs/math";
+import dynamic from "next/dynamic";
import { useEffect, useState } from "react";
import { MsgGetter } from "..";
import { useChains } from "../../../../context/ChainsContext";
@@ -11,6 +12,8 @@ import Input from "../../../inputs/Input";
import Select from "../../../inputs/Select";
import StackableContainer from "../../../layout/StackableContainer";
+const JsonEditor = dynamic(() => import("../../../inputs/JsonEditor"), { ssr: false });
+
const customDenomOption = { label: "Custom (enter denom below)", value: "custom" } as const;
const getDenomOptions = (assets: ChainInfo["assets"]) => {
@@ -48,14 +51,12 @@ const MsgInstantiateContract2Form = ({
const [codeIdError, setCodeIdError] = useState("");
const [adminAddressError, setAdminAddressError] = useState("");
- const [msgContentError, setMsgContentError] = useState("");
const [customDenomError, setCustomDenomError] = useState("");
const [amountError, setAmountError] = useState("");
useEffect(() => {
setCodeIdError("");
setAdminAddressError("");
- setMsgContentError("");
setCustomDenomError("");
setAmountError("");
@@ -71,13 +72,6 @@ const MsgInstantiateContract2Form = ({
return false;
}
- try {
- JSON.parse(msgContent);
- } catch {
- setMsgContentError("Msg must be valid JSON");
- return false;
- }
-
if (selectedDenom.value === customDenomOption.value && !customDenom) {
setCustomDenomError("Custom denom must be set because of selection above");
return false;
@@ -118,7 +112,7 @@ const MsgInstantiateContract2Form = ({
const msgValue = MsgCodecs[MsgTypeUrls.Instantiate2].fromPartial({
sender: fromAddress,
- codeId,
+ codeId: codeId || 1,
label,
admin: adminAddress,
fixMsg,
@@ -203,13 +197,12 @@ const MsgInstantiateContract2Form = ({
/>
- setMsgContent(target.value)}
- error={msgContentError}
- placeholder={"Enter msg JSON"}
+
+ setMsgContent("text" in newMsgContent ? newMsgContent.text ?? "{}" : "{}")
+ }
/>
From fd60bd5e421d076a858dd8d02bf66e5135fd0a90 Mon Sep 17 00:00:00 2001
From: abefernan <44572727+abefernan@users.noreply.github.com>
Date: Thu, 13 Jul 2023 18:45:03 +0200
Subject: [PATCH 21/44] Remove unneded dep from useEffect
---
.../forms/CreateTxForm/MsgForm/MsgInstantiateContract2Form.tsx | 1 -
1 file changed, 1 deletion(-)
diff --git a/components/forms/CreateTxForm/MsgForm/MsgInstantiateContract2Form.tsx b/components/forms/CreateTxForm/MsgForm/MsgInstantiateContract2Form.tsx
index 05fea76..b95d28e 100644
--- a/components/forms/CreateTxForm/MsgForm/MsgInstantiateContract2Form.tsx
+++ b/components/forms/CreateTxForm/MsgForm/MsgInstantiateContract2Form.tsx
@@ -133,7 +133,6 @@ const MsgInstantiateContract2Form = ({
chain.addressPrefix,
chain.assets,
chain.chainId,
- chain.denom,
codeId,
customDenom,
fixMsg,
From 5cc4d506e9445a48fba4003346bac96da6c28ebe Mon Sep 17 00:00:00 2001
From: abefernan <44572727+abefernan@users.noreply.github.com>
Date: Thu, 13 Jul 2023 18:45:20 +0200
Subject: [PATCH 22/44] Use JsonEditor in MsgMigrateContractForm
---
.../MsgForm/MsgMigrateContractForm.tsx | 32 +++++++------------
1 file changed, 12 insertions(+), 20 deletions(-)
diff --git a/components/forms/CreateTxForm/MsgForm/MsgMigrateContractForm.tsx b/components/forms/CreateTxForm/MsgForm/MsgMigrateContractForm.tsx
index 8d42e3f..09f6dc6 100644
--- a/components/forms/CreateTxForm/MsgForm/MsgMigrateContractForm.tsx
+++ b/components/forms/CreateTxForm/MsgForm/MsgMigrateContractForm.tsx
@@ -1,5 +1,6 @@
import { MsgMigrateContractEncodeObject } from "@cosmjs/cosmwasm-stargate";
import { toUtf8 } from "@cosmjs/encoding";
+import dynamic from "next/dynamic";
import { useEffect, useState } from "react";
import { MsgGetter } from "..";
import { useChains } from "../../../../context/ChainsContext";
@@ -8,6 +9,8 @@ import { MsgCodecs, MsgTypeUrls } from "../../../../types/txMsg";
import Input from "../../../inputs/Input";
import StackableContainer from "../../../layout/StackableContainer";
+const JsonEditor = dynamic(() => import("../../../inputs/JsonEditor"), { ssr: false });
+
interface MsgMigrateContractFormProps {
readonly fromAddress: string;
readonly setMsgGetter: (msgGetter: MsgGetter) => void;
@@ -27,12 +30,10 @@ const MsgMigrateContractForm = ({
const [codeIdError, setCodeIdError] = useState("");
const [contractAddressError, setContractAddressError] = useState("");
- const [msgContentError, setMsgContentError] = useState("");
useEffect(() => {
setCodeIdError("");
setContractAddressError("");
- setMsgContentError("");
const isMsgValid = (): boolean => {
if (!codeId || !Number.isSafeInteger(Number(codeId)) || Number(codeId) <= 0) {
@@ -46,20 +47,13 @@ const MsgMigrateContractForm = ({
return false;
}
- try {
- JSON.parse(msgContent);
- } catch {
- setMsgContentError("Msg must be valid JSON");
- return false;
- }
-
return true;
};
const msgValue = MsgCodecs[MsgTypeUrls.Migrate].fromPartial({
sender: fromAddress,
contract: contractAddress,
- codeId,
+ codeId: codeId || 1,
msg: toUtf8(msgContent),
});
@@ -67,14 +61,13 @@ const MsgMigrateContractForm = ({
setMsgGetter({ isMsgValid, msg });
}, [
+ chain.addressPrefix,
+ chain.chainId,
codeId,
contractAddress,
fromAddress,
msgContent,
setMsgGetter,
- chain.addressPrefix,
- chain.chainId,
- chain.denom,
]);
return (
@@ -103,13 +96,12 @@ const MsgMigrateContractForm = ({
/>
- setMsgContent(target.value)}
- error={msgContentError}
- placeholder={"Enter msg JSON"}
+
+ setMsgContent("text" in newMsgContent ? newMsgContent.text ?? "{}" : "{}")
+ }
/>
>
);
diff --git a/components/dataViews/TransactionInfo/TxMsgInstantiateContract2Details.tsx b/components/dataViews/TransactionInfo/TxMsgInstantiateContract2Details.tsx
index 00cefe9..c390a8d 100644
--- a/components/dataViews/TransactionInfo/TxMsgInstantiateContract2Details.tsx
+++ b/components/dataViews/TransactionInfo/TxMsgInstantiateContract2Details.tsx
@@ -1,6 +1,8 @@
-import { fromUtf8 } from "@cosmjs/encoding";
+import { fromUtf8, toHex } from "@cosmjs/encoding";
import { MsgInstantiateContract2 } from "cosmjs-types/cosmwasm/wasm/v1/tx";
import dynamic from "next/dynamic";
+import { useState } from "react";
+import { JSONValue } from "vanilla-jsoneditor";
import { useChains } from "../../../context/ChainsContext";
import { printableCoins } from "../../../lib/displayHelpers";
import HashView from "../HashView";
@@ -13,6 +15,20 @@ interface TxMsgInstantiateContract2DetailsProps {
const TxMsgInstantiateContract2Details = ({ msgValue }: TxMsgInstantiateContract2DetailsProps) => {
const { chain } = useChains();
+ const [parseError, setParseError] = useState("");
+
+ const json: JSONValue = (() => {
+ if (parseError) {
+ return {};
+ }
+
+ try {
+ return JSON.parse(fromUtf8(msgValue.msg));
+ } catch (e) {
+ setParseError(e instanceof Error ? e.message : "Failed to decode UTF-8 msg");
+ return {};
+ }
+ })();
return (
<>
@@ -45,9 +61,15 @@ const TxMsgInstantiateContract2Details = ({ msgValue }: TxMsgInstantiateContract
{printableCoins(msgValue.funds, chain)}
-
-
-
+ {parseError ? (
+
+ {parseError}
+
+ ) : (
+
+
+
+ )}
>
);
diff --git a/components/dataViews/TransactionInfo/TxMsgInstantiateContractDetails.tsx b/components/dataViews/TransactionInfo/TxMsgInstantiateContractDetails.tsx
index c50db10..fe6513a 100644
--- a/components/dataViews/TransactionInfo/TxMsgInstantiateContractDetails.tsx
+++ b/components/dataViews/TransactionInfo/TxMsgInstantiateContractDetails.tsx
@@ -1,6 +1,8 @@
import { fromUtf8 } from "@cosmjs/encoding";
import { MsgInstantiateContract } from "cosmjs-types/cosmwasm/wasm/v1/tx";
import dynamic from "next/dynamic";
+import { useState } from "react";
+import { JSONValue } from "vanilla-jsoneditor";
import { useChains } from "../../../context/ChainsContext";
import { printableCoins } from "../../../lib/displayHelpers";
import HashView from "../HashView";
@@ -13,6 +15,20 @@ interface TxMsgInstantiateContractDetailsProps {
const TxMsgInstantiateContractDetails = ({ msgValue }: TxMsgInstantiateContractDetailsProps) => {
const { chain } = useChains();
+ const [parseError, setParseError] = useState("");
+
+ const json: JSONValue = (() => {
+ if (parseError) {
+ return {};
+ }
+
+ try {
+ return JSON.parse(fromUtf8(msgValue.msg));
+ } catch (e) {
+ setParseError(e instanceof Error ? e.message : "Failed to decode UTF-8 msg");
+ return {};
+ }
+ })();
return (
<>
@@ -41,9 +57,15 @@ const TxMsgInstantiateContractDetails = ({ msgValue }: TxMsgInstantiateContractD
{printableCoins(msgValue.funds, chain)}
-
-
-
+ {parseError ? (
+
+ {parseError}
+
+ ) : (
+
+
+
+ )}
>
);
diff --git a/components/dataViews/TransactionInfo/TxMsgMigrateContractDetails.tsx b/components/dataViews/TransactionInfo/TxMsgMigrateContractDetails.tsx
index 09be796..086222e 100644
--- a/components/dataViews/TransactionInfo/TxMsgMigrateContractDetails.tsx
+++ b/components/dataViews/TransactionInfo/TxMsgMigrateContractDetails.tsx
@@ -1,6 +1,8 @@
import { fromUtf8 } from "@cosmjs/encoding";
import { MsgMigrateContract } from "cosmjs-types/cosmwasm/wasm/v1/tx";
import dynamic from "next/dynamic";
+import { useState } from "react";
+import { JSONValue } from "vanilla-jsoneditor";
import HashView from "../HashView";
const JsonEditor = dynamic(() => import("../../inputs/JsonEditor"), { ssr: false });
@@ -9,50 +11,79 @@ interface TxMsgMigrateContractDetailsProps {
readonly msgValue: MsgMigrateContract;
}
-const TxMsgMigrateContractDetails = ({ msgValue }: TxMsgMigrateContractDetailsProps) => (
- <>
-
- MsgMigrateContract
-
-
-
-
-
-
-
-
-
- {msgValue.codeId.toString()}
-
-
-
-
-
- >
-);
+const TxMsgMigrateContractDetails = ({ msgValue }: TxMsgMigrateContractDetailsProps) => {
+ const [parseError, setParseError] = useState("");
+
+ const json: JSONValue = (() => {
+ if (parseError) {
+ return {};
+ }
+
+ try {
+ return JSON.parse(fromUtf8(msgValue.msg));
+ } catch (e) {
+ setParseError(e instanceof Error ? e.message : "Failed to decode UTF-8 msg");
+ return {};
+ }
+ })();
+
+ return (
+ <>
+
+ MsgMigrateContract
+
+
+
+
+
+
+
+
+
+ {msgValue.codeId.toString()}
+
+ {parseError ? (
+
+ {parseError}
+
+ ) : (
+
+
+
+ )}
+
+ >
+ );
+};
export default TxMsgMigrateContractDetails;
From f62fa054755a9e354244f78448152bc8d05f5d08 Mon Sep 17 00:00:00 2001
From: abefernan <44572727+abefernan@users.noreply.github.com>
Date: Wed, 26 Jul 2023 17:44:45 +0200
Subject: [PATCH 41/44] Return undefined msgContentUtf8Array
---
.../forms/CreateTxForm/MsgForm/MsgExecuteContractForm.tsx | 2 +-
.../forms/CreateTxForm/MsgForm/MsgInstantiateContractForm.tsx | 2 +-
.../forms/CreateTxForm/MsgForm/MsgMigrateContractForm.tsx | 2 +-
3 files changed, 3 insertions(+), 3 deletions(-)
diff --git a/components/forms/CreateTxForm/MsgForm/MsgExecuteContractForm.tsx b/components/forms/CreateTxForm/MsgForm/MsgExecuteContractForm.tsx
index 93d7fad..3340c5c 100644
--- a/components/forms/CreateTxForm/MsgForm/MsgExecuteContractForm.tsx
+++ b/components/forms/CreateTxForm/MsgForm/MsgExecuteContractForm.tsx
@@ -95,7 +95,7 @@ const MsgExecuteContractForm = ({
// The JsonEditor does not escape \n or remove whitespaces, so we need to parse + stringify
return toUtf8(JSON.stringify(JSON.parse(msgContent)));
} catch {
- return Uint8Array.from([]);
+ return undefined;
}
})();
diff --git a/components/forms/CreateTxForm/MsgForm/MsgInstantiateContractForm.tsx b/components/forms/CreateTxForm/MsgForm/MsgInstantiateContractForm.tsx
index 07bac73..8039b8a 100644
--- a/components/forms/CreateTxForm/MsgForm/MsgInstantiateContractForm.tsx
+++ b/components/forms/CreateTxForm/MsgForm/MsgInstantiateContractForm.tsx
@@ -111,7 +111,7 @@ const MsgInstantiateContractForm = ({
// The JsonEditor does not escape \n or remove whitespaces, so we need to parse + stringify
return toUtf8(JSON.stringify(JSON.parse(msgContent)));
} catch {
- return Uint8Array.from([]);
+ return undefined;
}
})();
diff --git a/components/forms/CreateTxForm/MsgForm/MsgMigrateContractForm.tsx b/components/forms/CreateTxForm/MsgForm/MsgMigrateContractForm.tsx
index d89f48b..59c1880 100644
--- a/components/forms/CreateTxForm/MsgForm/MsgMigrateContractForm.tsx
+++ b/components/forms/CreateTxForm/MsgForm/MsgMigrateContractForm.tsx
@@ -55,7 +55,7 @@ const MsgMigrateContractForm = ({
// The JsonEditor does not escape \n or remove whitespaces, so we need to parse + stringify
return toUtf8(JSON.stringify(JSON.parse(msgContent)));
} catch {
- return Uint8Array.from([]);
+ return undefined;
}
})();
From d6c1686dd734e65c5beaf640150c9fbcf72d2582 Mon Sep 17 00:00:00 2001
From: abefernan <44572727+abefernan@users.noreply.github.com>
Date: Wed, 26 Jul 2023 17:45:38 +0200
Subject: [PATCH 42/44] Remove fix msg. Use hex salt
---
.../MsgForm/MsgInstantiateContract2Form.tsx | 41 +++++++++++--------
1 file changed, 24 insertions(+), 17 deletions(-)
diff --git a/components/forms/CreateTxForm/MsgForm/MsgInstantiateContract2Form.tsx b/components/forms/CreateTxForm/MsgForm/MsgInstantiateContract2Form.tsx
index d3ebba6..56951e8 100644
--- a/components/forms/CreateTxForm/MsgForm/MsgInstantiateContract2Form.tsx
+++ b/components/forms/CreateTxForm/MsgForm/MsgInstantiateContract2Form.tsx
@@ -1,5 +1,5 @@
import { MsgInstantiateContract2EncodeObject } from "@cosmjs/cosmwasm-stargate";
-import { toUtf8 } from "@cosmjs/encoding";
+import { fromHex, toUtf8 } from "@cosmjs/encoding";
import dynamic from "next/dynamic";
import { useEffect, useState } from "react";
import { MsgGetter } from "..";
@@ -42,7 +42,6 @@ const MsgInstantiateContract2Form = ({
const [codeId, setCodeId] = useState("");
const [label, setLabel] = useState("");
const [adminAddress, setAdminAddress] = useState("");
- const [fixMsg, setFixMsg] = useState(false);
const [salt, setSalt] = useState("");
const [msgContent, setMsgContent] = useState("{}");
const [selectedDenom, setSelectedDenom] = useState(denomOptions[0]);
@@ -52,6 +51,7 @@ const MsgInstantiateContract2Form = ({
const [codeIdError, setCodeIdError] = useState("");
const [labelError, setLabelError] = useState("");
const [adminAddressError, setAdminAddressError] = useState("");
+ const [saltError, setSaltError] = useState("");
const [customDenomError, setCustomDenomError] = useState("");
const [amountError, setAmountError] = useState("");
@@ -59,6 +59,7 @@ const MsgInstantiateContract2Form = ({
setCodeIdError("");
setLabelError("");
setAdminAddressError("");
+ setSaltError("");
setCustomDenomError("");
setAmountError("");
@@ -79,6 +80,13 @@ const MsgInstantiateContract2Form = ({
return false;
}
+ try {
+ fromHex(salt);
+ } catch (e) {
+ setSaltError(e instanceof Error ? e.message : "Salt needs to be an hexadecimal string");
+ return false;
+ }
+
if (selectedDenom.value === customDenomOption.value && !customDenom) {
setCustomDenomError("Custom denom must be set because of selection above");
return false;
@@ -108,12 +116,20 @@ const MsgInstantiateContract2Form = ({
}
})();
+ const hexSalt = (() => {
+ try {
+ return fromHex(salt);
+ } catch {
+ return undefined;
+ }
+ })();
+
const msgContentUtf8Array = (() => {
try {
// The JsonEditor does not escape \n or remove whitespaces, so we need to parse + stringify
return toUtf8(JSON.stringify(JSON.parse(msgContent)));
} catch {
- return Uint8Array.from([]);
+ return undefined;
}
})();
@@ -122,8 +138,8 @@ const MsgInstantiateContract2Form = ({
codeId: codeId || 0,
label,
admin: adminAddress,
- fixMsg,
- salt: toUtf8(salt),
+ fixMsg: false,
+ salt: hexSalt,
msg: msgContentUtf8Array,
funds: [microCoin],
});
@@ -142,7 +158,6 @@ const MsgInstantiateContract2Form = ({
chain.chainId,
codeId,
customDenom,
- fixMsg,
fromAddress,
label,
msgContent,
@@ -187,20 +202,12 @@ const MsgInstantiateContract2Form = ({
From d49baa25fabf7ed26cb78011e68fab96a1e3de2f Mon Sep 17 00:00:00 2001
From: abefernan <44572727+abefernan@users.noreply.github.com>
Date: Wed, 26 Jul 2023 17:50:02 +0200
Subject: [PATCH 43/44] Check empty salt
---
.../CreateTxForm/MsgForm/MsgInstantiateContract2Form.tsx | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/components/forms/CreateTxForm/MsgForm/MsgInstantiateContract2Form.tsx b/components/forms/CreateTxForm/MsgForm/MsgInstantiateContract2Form.tsx
index 56951e8..900dc58 100644
--- a/components/forms/CreateTxForm/MsgForm/MsgInstantiateContract2Form.tsx
+++ b/components/forms/CreateTxForm/MsgForm/MsgInstantiateContract2Form.tsx
@@ -81,6 +81,10 @@ const MsgInstantiateContract2Form = ({
}
try {
+ if (!salt) {
+ throw new Error("Salt is required");
+ }
+
fromHex(salt);
} catch (e) {
setSaltError(e instanceof Error ? e.message : "Salt needs to be an hexadecimal string");
From 62be9d6b5a0eac931da4144fea4b64eada39f855 Mon Sep 17 00:00:00 2001
From: abefernan <44572727+abefernan@users.noreply.github.com>
Date: Thu, 27 Jul 2023 09:39:08 +0200
Subject: [PATCH 44/44] Avoid sending form with JSON errors
---
.../MsgForm/MsgExecuteContractForm.tsx | 14 ++++++++++----
.../MsgForm/MsgInstantiateContract2Form.tsx | 14 ++++++++++----
.../MsgForm/MsgInstantiateContractForm.tsx | 14 ++++++++++----
.../MsgForm/MsgMigrateContractForm.tsx | 14 ++++++++++----
4 files changed, 40 insertions(+), 16 deletions(-)
diff --git a/components/forms/CreateTxForm/MsgForm/MsgExecuteContractForm.tsx b/components/forms/CreateTxForm/MsgForm/MsgExecuteContractForm.tsx
index 3340c5c..a335b98 100644
--- a/components/forms/CreateTxForm/MsgForm/MsgExecuteContractForm.tsx
+++ b/components/forms/CreateTxForm/MsgForm/MsgExecuteContractForm.tsx
@@ -1,7 +1,7 @@
import { MsgExecuteContractEncodeObject } from "@cosmjs/cosmwasm-stargate";
import { toUtf8 } from "@cosmjs/encoding";
import dynamic from "next/dynamic";
-import { useEffect, useState } from "react";
+import { useEffect, useRef, useState } from "react";
import { MsgGetter } from "..";
import { useChains } from "../../../../context/ChainsContext";
import { ChainInfo } from "../../../../context/ChainsContext/types";
@@ -45,6 +45,7 @@ const MsgExecuteContractForm = ({
const [customDenom, setCustomDenom] = useState("");
const [amount, setAmount] = useState("0");
+ const jsonError = useRef(false);
const [contractAddressError, setContractAddressError] = useState("");
const [customDenomError, setCustomDenomError] = useState("");
const [amountError, setAmountError] = useState("");
@@ -55,6 +56,10 @@ const MsgExecuteContractForm = ({
setAmountError("");
const isMsgValid = (): boolean => {
+ if (jsonError.current) {
+ return false;
+ }
+
const addressErrorMsg = checkAddress(contractAddress, chain.addressPrefix);
if (addressErrorMsg) {
setContractAddressError(`Invalid address for network ${chain.chainId}: ${addressErrorMsg}`);
@@ -142,9 +147,10 @@ const MsgExecuteContractForm = ({
- setMsgContent("text" in newMsgContent ? newMsgContent.text ?? "{}" : "{}")
- }
+ onChange={(newMsgContent, _, { contentErrors }) => {
+ setMsgContent("text" in newMsgContent ? newMsgContent.text ?? "{}" : "{}");
+ jsonError.current = !!contentErrors;
+ }}
/>
diff --git a/components/forms/CreateTxForm/MsgForm/MsgInstantiateContract2Form.tsx b/components/forms/CreateTxForm/MsgForm/MsgInstantiateContract2Form.tsx
index 900dc58..64b8a16 100644
--- a/components/forms/CreateTxForm/MsgForm/MsgInstantiateContract2Form.tsx
+++ b/components/forms/CreateTxForm/MsgForm/MsgInstantiateContract2Form.tsx
@@ -1,7 +1,7 @@
import { MsgInstantiateContract2EncodeObject } from "@cosmjs/cosmwasm-stargate";
import { fromHex, toUtf8 } from "@cosmjs/encoding";
import dynamic from "next/dynamic";
-import { useEffect, useState } from "react";
+import { useEffect, useRef, useState } from "react";
import { MsgGetter } from "..";
import { useChains } from "../../../../context/ChainsContext";
import { ChainInfo } from "../../../../context/ChainsContext/types";
@@ -48,6 +48,7 @@ const MsgInstantiateContract2Form = ({
const [customDenom, setCustomDenom] = useState("");
const [amount, setAmount] = useState("0");
+ const jsonError = useRef(false);
const [codeIdError, setCodeIdError] = useState("");
const [labelError, setLabelError] = useState("");
const [adminAddressError, setAdminAddressError] = useState("");
@@ -64,6 +65,10 @@ const MsgInstantiateContract2Form = ({
setAmountError("");
const isMsgValid = (): boolean => {
+ if (jsonError.current) {
+ return false;
+ }
+
if (!codeId || !Number.isSafeInteger(Number(codeId)) || Number(codeId) <= 0) {
setCodeIdError("Code ID must be a positive integer");
return false;
@@ -218,9 +223,10 @@ const MsgInstantiateContract2Form = ({
- setMsgContent("text" in newMsgContent ? newMsgContent.text ?? "{}" : "{}")
- }
+ onChange={(newMsgContent, _, { contentErrors }) => {
+ setMsgContent("text" in newMsgContent ? newMsgContent.text ?? "{}" : "{}");
+ jsonError.current = !!contentErrors;
+ }}
/>
diff --git a/components/forms/CreateTxForm/MsgForm/MsgInstantiateContractForm.tsx b/components/forms/CreateTxForm/MsgForm/MsgInstantiateContractForm.tsx
index 8039b8a..77d1f18 100644
--- a/components/forms/CreateTxForm/MsgForm/MsgInstantiateContractForm.tsx
+++ b/components/forms/CreateTxForm/MsgForm/MsgInstantiateContractForm.tsx
@@ -1,7 +1,7 @@
import { MsgInstantiateContractEncodeObject } from "@cosmjs/cosmwasm-stargate";
import { toUtf8 } from "@cosmjs/encoding";
import dynamic from "next/dynamic";
-import { useEffect, useState } from "react";
+import { useEffect, useRef, useState } from "react";
import { MsgGetter } from "..";
import { useChains } from "../../../../context/ChainsContext";
import { ChainInfo } from "../../../../context/ChainsContext/types";
@@ -47,6 +47,7 @@ const MsgInstantiateContractForm = ({
const [customDenom, setCustomDenom] = useState("");
const [amount, setAmount] = useState("0");
+ const jsonError = useRef(false);
const [codeIdError, setCodeIdError] = useState("");
const [labelError, setLabelError] = useState("");
const [adminAddressError, setAdminAddressError] = useState("");
@@ -61,6 +62,10 @@ const MsgInstantiateContractForm = ({
setAmountError("");
const isMsgValid = (): boolean => {
+ if (jsonError.current) {
+ return false;
+ }
+
if (!codeId || !Number.isSafeInteger(Number(codeId)) || Number(codeId) <= 0) {
setCodeIdError("Code ID must be a positive integer");
return false;
@@ -183,9 +188,10 @@ const MsgInstantiateContractForm = ({
- setMsgContent("text" in newMsgContent ? newMsgContent.text ?? "{}" : "{}")
- }
+ onChange={(newMsgContent, _, { contentErrors }) => {
+ setMsgContent("text" in newMsgContent ? newMsgContent.text ?? "{}" : "{}");
+ jsonError.current = !!contentErrors;
+ }}
/>
diff --git a/components/forms/CreateTxForm/MsgForm/MsgMigrateContractForm.tsx b/components/forms/CreateTxForm/MsgForm/MsgMigrateContractForm.tsx
index 59c1880..c1f4dae 100644
--- a/components/forms/CreateTxForm/MsgForm/MsgMigrateContractForm.tsx
+++ b/components/forms/CreateTxForm/MsgForm/MsgMigrateContractForm.tsx
@@ -1,7 +1,7 @@
import { MsgMigrateContractEncodeObject } from "@cosmjs/cosmwasm-stargate";
import { toUtf8 } from "@cosmjs/encoding";
import dynamic from "next/dynamic";
-import { useEffect, useState } from "react";
+import { useEffect, useRef, useState } from "react";
import { MsgGetter } from "..";
import { useChains } from "../../../../context/ChainsContext";
import { checkAddress, exampleAddress } from "../../../../lib/displayHelpers";
@@ -28,6 +28,7 @@ const MsgMigrateContractForm = ({
const [codeId, setCodeId] = useState("");
const [msgContent, setMsgContent] = useState("{}");
+ const jsonError = useRef(false);
const [contractAddressError, setContractAddressError] = useState("");
const [codeIdError, setCodeIdError] = useState("");
@@ -36,6 +37,10 @@ const MsgMigrateContractForm = ({
setContractAddressError("");
const isMsgValid = (): boolean => {
+ if (jsonError.current) {
+ return false;
+ }
+
const addressErrorMsg = checkAddress(contractAddress, chain.addressPrefix);
if (addressErrorMsg) {
setContractAddressError(`Invalid address for network ${chain.chainId}: ${addressErrorMsg}`);
@@ -108,9 +113,10 @@ const MsgMigrateContractForm = ({
- setMsgContent("text" in newMsgContent ? newMsgContent.text ?? "{}" : "{}")
- }
+ onChange={(newMsgContent, _, { contentErrors }) => {
+ setMsgContent("text" in newMsgContent ? newMsgContent.text ?? "{}" : "{}");
+ jsonError.current = !!contentErrors;
+ }}
/>