Skip to content

Commit

Permalink
Merge pull request #39 from DCFoundation/install-bundle-follower
Browse files Browse the repository at this point in the history
feat(installBundle): add :bundles follower to confirm installation
  • Loading branch information
0xpatrickdev authored Feb 20, 2024
2 parents be7920d + 96e07dc commit 538e185
Show file tree
Hide file tree
Showing 5 changed files with 552 additions and 19 deletions.
7 changes: 7 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
"ts:check": "tsc --noEmit"
},
"dependencies": {
"@agoric/casting": "^0.4.3-u13.0",
"@agoric/cosmic-proto": "dev",
"@agoric/eventual-send": "^0.14.1",
"@agoric/notifier": "^0.6.2",
Expand Down Expand Up @@ -71,5 +72,11 @@
"typescript": "^5.0.2",
"vite": "^4.4.5",
"vitest": "^0.34.6"
},
"resolutions": {
"@cosmjs/encoding": "0.31.1",
"@cosmjs/proto-signing": "0.31.1",
"@cosmjs/stargate": "0.31.1",
"@cosmjs/tendermint-rpc": "0.31.1"
}
}
49 changes: 49 additions & 0 deletions src/components/BundleFollowerToastMessage.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
import { toast } from "react-toastify";
import { ClipboardDocumentIcon } from "@heroicons/react/20/solid";
import { XMarkIcon } from "@heroicons/react/20/solid";

export const BundleFollowerToastMessage = ({
endoZipBase64Sha512,
closeToast = () => {},
clipboard,
}: {
endoZipBase64Sha512: string;
closeToast: () => void;
clipboard?: Navigator["clipboard"];
}) => (
<div className="flex items-start pointer-events-auto">
<div className="ml-3 w-0 flex-1 pt-0.5">
<p className="text-sm font-medium text-gray-900">
Bundle Successfully Installed!
</p>
{clipboard && (
<span className="mt-1 text-sm text-gray-500">
<span
className="text-sm text-blue-500 hover:text-blue-700 underline cursor-pointer"
onClick={async () => {
await clipboard.writeText(endoZipBase64Sha512);
toast.info("Copied to clipboard!", {
position: "bottom-center",
autoClose: 3000,
hideProgressBar: true,
});
}}
>
EndoZipBase64Sha512{" "}
<ClipboardDocumentIcon className="inline-block w-4 h-4" />
</span>
</span>
)}
</div>
<div className="ml-4 flex flex-shrink-0">
<button
type="button"
className="inline-flex rounded-md bg-white text-gray-400 hover:text-gray-500 focus:outline-none focus:ring-2 focus:ring-teal-500 focus:ring-offset-2"
onClick={closeToast}
>
<span className="sr-only">Close</span>
<XMarkIcon className="h-5 w-5" aria-hidden="true" />
</button>
</div>
</div>
);
14 changes: 11 additions & 3 deletions src/config/agoric/agoric.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,13 +15,17 @@ import {
} from "../../lib/messageBuilder";
import { isValidBundle } from "../../utils/validate";
import { makeSignAndBroadcast } from "../../lib/signAndBroadcast";
import { useWatchBundle } from "../../hooks/useWatchBundle";

const Agoric = () => {
const { netName } = useNetwork();
const { netName, networkConfig } = useNetwork();
const { walletAddress, stargateClient } = useWallet();
const proposalFormRef = useRef<HTMLFormElement>(null);
const corEvalFormRef = useRef<HTMLFormElement>(null);
const bundleFormRef = useRef<HTMLFormElement>(null);
const watchBundle = useWatchBundle(networkConfig?.rpc, {
clipboard: window.navigator.clipboard,
});

const signAndBroadcast = useMemo(
() => makeSignAndBroadcast(stargateClient, walletAddress, netName),
Expand All @@ -46,8 +50,12 @@ const Agoric = () => {
submitter: walletAddress,
});
try {
await signAndBroadcast(proposalMsg, "bundle");
bundleFormRef.current?.reset();
const txResponse = await signAndBroadcast(proposalMsg, "bundle");
if (txResponse) {
const { endoZipBase64Sha512 } = JSON.parse(vals.bundle);
await watchBundle(endoZipBase64Sha512, txResponse);
bundleFormRef.current?.reset();
}
} catch (e) {
console.error(e);
}
Expand Down
63 changes: 63 additions & 0 deletions src/hooks/useWatchBundle.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
import {
iterateEach,
makeCastingSpec,
makeFollower,
makeLeader,
} from "@agoric/casting";
import { toast } from "react-toastify";
import { BundleFollowerToastMessage } from "../components/BundleFollowerToastMessage";

type IteratorEnvelope = {
value?: {
endoZipBase64Sha512: string;
installed: boolean;
error: unknown;
};
error?: { message: string; stack: string };
};

export const useWatchBundle = (
rpcUrl: string | undefined,
{ clipboard }: { clipboard?: Navigator["clipboard"] },
) => {
const leader = rpcUrl ? makeLeader(rpcUrl) : undefined;

const watchBundle = async (
expectedEndoZipBase64Sha512: string,
{ height }: { height: number },
) => {
if (!leader) throw Error("Unexpected error: leader not found.");
const castingSpec = makeCastingSpec(":bundles");
const follower = makeFollower(castingSpec, leader);
for await (const envelope of iterateEach(follower, { height })) {
const { value, error } = envelope as IteratorEnvelope;
if (!value && error) {
toast.error(`Bundle installation failed.\nSee console for details.`);
console.log(envelope);
throw error;
}
if (value) {
const { endoZipBase64Sha512, installed, error } = value;
if (endoZipBase64Sha512 === expectedEndoZipBase64Sha512) {
if (!installed) {
toast.error(
`Bundle installation failed.\nSee console for details.`,
);
throw error;
} else {
toast.success(({ closeToast }) => (
<BundleFollowerToastMessage
endoZipBase64Sha512={endoZipBase64Sha512}
closeToast={closeToast as () => void}
clipboard={clipboard}
/>
));
return;
}
}
}
}
};

return watchBundle;
};
Loading

0 comments on commit 538e185

Please sign in to comment.