Compare commits
21 Commits
feature/ch
...
feat/long-
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
3a1159cffc | ||
|
|
3136de1bd1 | ||
|
|
67ffd3f1b4 | ||
|
|
8508cb69c4 | ||
|
|
89217d2633 | ||
|
|
ba1b64391c | ||
|
|
098d919a77 | ||
|
|
b2af37ab4b | ||
|
|
dcb7e94e86 | ||
|
|
67848b3d8d | ||
|
|
31a86263a1 | ||
|
|
4d0025afc1 | ||
|
|
f85bd2398d | ||
|
|
a2a6596cc5 | ||
|
|
37208ce97e | ||
|
|
bf4042926d | ||
|
|
3ccc1c16ac | ||
|
|
135f0c91a1 | ||
|
|
8f5786e242 | ||
|
|
810eb4ca27 | ||
|
|
e6574f9f12 |
@@ -512,6 +512,7 @@ const ImportAccountDialog = () => {
|
||||
<Input
|
||||
name="secret"
|
||||
type="password"
|
||||
autoComplete="new-password"
|
||||
value={value}
|
||||
onChange={(e) => setValue(e.target.value)}
|
||||
/>
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
import { useCallback, useEffect } from "react";
|
||||
import { useEffect } from "react";
|
||||
import ReconnectingWebSocket, { CloseEvent } from "reconnecting-websocket";
|
||||
import { proxy, ref, useSnapshot } from "valtio";
|
||||
import { subscribeKey } from "valtio/utils";
|
||||
import { Select } from ".";
|
||||
import state, { ILog, transactionsState } from "../state";
|
||||
import { extractJSON } from "../utils/json";
|
||||
@@ -15,7 +17,7 @@ export interface IStreamState {
|
||||
status: "idle" | "opened" | "closed";
|
||||
statusChangeTimestamp?: number;
|
||||
logs: ILog[];
|
||||
socket?: WebSocket;
|
||||
socket?: ReconnectingWebSocket;
|
||||
}
|
||||
|
||||
export const streamState = proxy<IStreamState>({
|
||||
@@ -24,12 +26,85 @@ export const streamState = proxy<IStreamState>({
|
||||
logs: [] as ILog[],
|
||||
});
|
||||
|
||||
const onOpen = (account: ISelect | null) => {
|
||||
if (!account) {
|
||||
return;
|
||||
}
|
||||
// streamState.logs = [];
|
||||
streamState.status = "opened";
|
||||
streamState.statusChangeTimestamp = Date.now();
|
||||
|
||||
pushLog(`Debug stream opened for account ${account?.value}`, {
|
||||
type: "success",
|
||||
});
|
||||
};
|
||||
const onError = () => {
|
||||
pushLog("Something went wrong! Check your connection and try again.", {
|
||||
type: "error",
|
||||
});
|
||||
};
|
||||
const onClose = (e: CloseEvent) => {
|
||||
// 999 = closed websocket connection by switching account
|
||||
if (e.code !== 4999) {
|
||||
pushLog(`Connection was closed. [code: ${e.code}]`, {
|
||||
type: "error",
|
||||
});
|
||||
}
|
||||
streamState.status = "closed";
|
||||
streamState.statusChangeTimestamp = Date.now();
|
||||
};
|
||||
const onMessage = (event: any) => {
|
||||
// Ping returns just account address, if we get that
|
||||
// response we don't need to log anything
|
||||
if (event.data !== streamState.selectedAccount?.value) {
|
||||
pushLog(event.data);
|
||||
}
|
||||
};
|
||||
|
||||
let interval: NodeJS.Timer | null = null;
|
||||
|
||||
const addListeners = (account: ISelect | null) => {
|
||||
if (account?.value && streamState.socket?.url.endsWith(account?.value)) {
|
||||
return;
|
||||
}
|
||||
streamState.logs = [];
|
||||
if (account?.value) {
|
||||
if (interval) {
|
||||
clearInterval(interval);
|
||||
}
|
||||
if (streamState.socket) {
|
||||
streamState.socket?.removeEventListener("open", () => onOpen(account));
|
||||
streamState.socket?.removeEventListener("close", onClose);
|
||||
streamState.socket?.removeEventListener("error", onError);
|
||||
streamState.socket?.removeEventListener("message", onMessage);
|
||||
}
|
||||
|
||||
streamState.socket = ref(
|
||||
new ReconnectingWebSocket(
|
||||
`wss://${process.env.NEXT_PUBLIC_DEBUG_STREAM_URL}/${account?.value}`
|
||||
)
|
||||
);
|
||||
if (streamState.socket) {
|
||||
interval = setInterval(() => {
|
||||
streamState.socket?.send("");
|
||||
}, 10000);
|
||||
}
|
||||
|
||||
streamState.socket.addEventListener("open", () => onOpen(account));
|
||||
streamState.socket.addEventListener("close", onClose);
|
||||
streamState.socket.addEventListener("error", onError);
|
||||
streamState.socket.addEventListener("message", onMessage);
|
||||
}
|
||||
};
|
||||
|
||||
subscribeKey(streamState, "selectedAccount", addListeners);
|
||||
|
||||
const DebugStream = () => {
|
||||
const { selectedAccount, logs, socket } = useSnapshot(streamState);
|
||||
const { selectedAccount, logs } = useSnapshot(streamState);
|
||||
const { activeHeader: activeTxTab } = useSnapshot(transactionsState);
|
||||
const { accounts } = useSnapshot(state);
|
||||
|
||||
const accountOptions = accounts.map(acc => ({
|
||||
const accountOptions = accounts.map((acc) => ({
|
||||
label: acc.name,
|
||||
value: acc.address,
|
||||
}));
|
||||
@@ -42,117 +117,21 @@ const DebugStream = () => {
|
||||
options={accountOptions}
|
||||
hideSelectedOptions
|
||||
value={selectedAccount}
|
||||
onChange={acc => (streamState.selectedAccount = acc as any)}
|
||||
onChange={(acc) => {
|
||||
streamState.socket?.close(
|
||||
4999,
|
||||
"Old connection closed because user switched account"
|
||||
);
|
||||
streamState.selectedAccount = acc as any;
|
||||
}}
|
||||
css={{ width: "100%" }}
|
||||
/>
|
||||
</>
|
||||
);
|
||||
|
||||
useEffect(() => {
|
||||
const account = selectedAccount?.value;
|
||||
if (account && (!socket || !socket.url.endsWith(account))) {
|
||||
socket?.close();
|
||||
streamState.socket = ref(
|
||||
new WebSocket(
|
||||
`wss://${process.env.NEXT_PUBLIC_DEBUG_STREAM_URL}/${account}`
|
||||
)
|
||||
);
|
||||
} else if (!account && socket) {
|
||||
socket.close();
|
||||
streamState.socket = undefined;
|
||||
}
|
||||
}, [selectedAccount?.value, socket]);
|
||||
|
||||
const onMount = useCallback(async () => {
|
||||
// deliberately using `proxy` values and not the `useSnapshot` ones to have no dep list
|
||||
const acc = streamState.selectedAccount;
|
||||
const status = streamState.status;
|
||||
|
||||
if (status === "opened" && acc) {
|
||||
// fetch the missing ones
|
||||
try {
|
||||
const url = `https://${process.env.NEXT_PUBLIC_DEBUG_STREAM_URL}/recent/${acc?.value}`;
|
||||
|
||||
// TODO Remove after api sets cors properly
|
||||
const res = await fetch("/api/proxy", {
|
||||
method: "POST",
|
||||
body: JSON.stringify({ url }),
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
},
|
||||
});
|
||||
|
||||
if (!res.ok) return;
|
||||
|
||||
const body = await res.json();
|
||||
|
||||
if (!body?.logs) return;
|
||||
|
||||
const start = streamState.statusChangeTimestamp || 0;
|
||||
streamState.logs = [];
|
||||
pushLog(`Debug stream opened for account ${acc.value}`, {
|
||||
type: "success",
|
||||
});
|
||||
|
||||
const logs = Object.entries(body.logs).filter(([tm]) => +tm >= start);
|
||||
|
||||
logs.forEach(([tm, log]) => pushLog(log));
|
||||
} catch (error) {
|
||||
console.error(error);
|
||||
}
|
||||
}
|
||||
}, []);
|
||||
|
||||
useEffect(() => {
|
||||
onMount();
|
||||
}, [onMount]);
|
||||
|
||||
useEffect(() => {
|
||||
const account = selectedAccount?.value;
|
||||
const socket = streamState.socket;
|
||||
if (!socket) return;
|
||||
|
||||
const onOpen = () => {
|
||||
streamState.logs = [];
|
||||
streamState.status = "opened";
|
||||
streamState.statusChangeTimestamp = Date.now();
|
||||
pushLog(`Debug stream opened for account ${account}`, {
|
||||
type: "success",
|
||||
});
|
||||
};
|
||||
const onError = () => {
|
||||
pushLog("Something went wrong! Check your connection and try again.", {
|
||||
type: "error",
|
||||
});
|
||||
};
|
||||
const onClose = (e: CloseEvent) => {
|
||||
pushLog(`Connection was closed. [code: ${e.code}]`, {
|
||||
type: "error",
|
||||
});
|
||||
streamState.selectedAccount = null;
|
||||
streamState.status = "closed";
|
||||
streamState.statusChangeTimestamp = Date.now();
|
||||
};
|
||||
const onMessage = (event: any) => {
|
||||
pushLog(event.data);
|
||||
};
|
||||
|
||||
socket.addEventListener("open", onOpen);
|
||||
socket.addEventListener("close", onClose);
|
||||
socket.addEventListener("error", onError);
|
||||
socket.addEventListener("message", onMessage);
|
||||
|
||||
return () => {
|
||||
socket.removeEventListener("open", onOpen);
|
||||
socket.removeEventListener("close", onClose);
|
||||
socket.removeEventListener("message", onMessage);
|
||||
socket.removeEventListener("error", onError);
|
||||
};
|
||||
}, [selectedAccount?.value, socket]);
|
||||
|
||||
useEffect(() => {
|
||||
const account = transactionsState.transactions.find(
|
||||
tx => tx.header === activeTxTab
|
||||
(tx) => tx.header === activeTxTab
|
||||
)?.state.selectedAccount;
|
||||
|
||||
if (account && account.value !== streamState.selectedAccount?.value)
|
||||
|
||||
@@ -34,7 +34,9 @@ const DeployEditor = () => {
|
||||
|
||||
const [showContent, setShowContent] = useState(false);
|
||||
|
||||
const activeFile = snap.files[snap.active];
|
||||
const activeFile = snap.files[snap.active]?.compiledContent
|
||||
? snap.files[snap.active]
|
||||
: snap.files.filter((file) => file.compiledContent)[0];
|
||||
const compiledSize = activeFile?.compiledContent?.byteLength || 0;
|
||||
const color =
|
||||
compiledSize > FILESIZE_BREAKPOINTS[1]
|
||||
@@ -60,12 +62,21 @@ const DeployEditor = () => {
|
||||
{activeFile?.lastCompiled && (
|
||||
<ReactTimeAgo date={activeFile.lastCompiled} locale="en-US" />
|
||||
)}
|
||||
|
||||
{activeFile.compiledContent?.byteLength && (
|
||||
<Text css={{ ml: "$2", color }}>
|
||||
({filesize(activeFile.compiledContent.byteLength)})
|
||||
</Text>
|
||||
)}
|
||||
</Flex>
|
||||
{activeFile.compiledContent?.byteLength &&
|
||||
activeFile.compiledContent?.byteLength >= 64000 && (
|
||||
<Flex css={{ flexDirection: "column", py: "$3", pb: "$1" }}>
|
||||
<Text css={{ ml: "$2", color: "$error" }}>
|
||||
File size is larger than 64kB, cannot set hook!
|
||||
</Text>
|
||||
</Flex>
|
||||
)}
|
||||
<Button variant="link" onClick={() => setShowContent(true)}>
|
||||
View as WAT-file
|
||||
</Button>
|
||||
@@ -119,8 +130,8 @@ const DeployEditor = () => {
|
||||
className="hooks-editor"
|
||||
defaultLanguage={"wat"}
|
||||
language={"wat"}
|
||||
path={`file://tmp/c/${snap.files?.[snap.active]?.name}.wat`}
|
||||
value={snap.files?.[snap.active]?.compiledWatContent || ""}
|
||||
path={`file://tmp/c/${activeFile?.name}.wat`}
|
||||
value={activeFile?.compiledWatContent || ""}
|
||||
beforeMount={(monaco) => {
|
||||
monaco.languages.register({ id: "wat" });
|
||||
monaco.languages.setLanguageConfiguration("wat", wat.config);
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import React, { useState, useEffect, useCallback } from "react";
|
||||
import React, { useState, useEffect, useCallback, useRef } from "react";
|
||||
import {
|
||||
Plus,
|
||||
Share,
|
||||
@@ -101,7 +101,7 @@ const EditorNavigation = ({ showWat }: { showWat?: boolean }) => {
|
||||
if (!filename) {
|
||||
return { error: "You need to add filename" };
|
||||
}
|
||||
if (snap.files.find(file => file.name === filename)) {
|
||||
if (snap.files.find((file) => file.name === filename)) {
|
||||
return { error: "Filename already exists." };
|
||||
}
|
||||
|
||||
@@ -132,22 +132,55 @@ const EditorNavigation = ({ showWat }: { showWat?: boolean }) => {
|
||||
createNewFile(filename);
|
||||
setFilename("");
|
||||
}, [filename, setIsNewfileDialogOpen, setFilename, validateFilename]);
|
||||
|
||||
const scrollRef = useRef<HTMLDivElement>(null);
|
||||
const containerRef = useRef<HTMLDivElement>(null);
|
||||
const files = snap.files;
|
||||
return (
|
||||
<Flex css={{ flexShrink: 0, gap: "$0" }}>
|
||||
<Flex
|
||||
id="kissa"
|
||||
ref={scrollRef}
|
||||
css={{
|
||||
overflowX: "scroll",
|
||||
overflowY: "hidden",
|
||||
py: "$3",
|
||||
pb: "$0",
|
||||
flex: 1,
|
||||
"&::-webkit-scrollbar": {
|
||||
height: 0,
|
||||
background: "transparent",
|
||||
height: "0.3em",
|
||||
background: "rgba(0,0,0,.0)",
|
||||
},
|
||||
"&::-webkit-scrollbar-gutter": "stable",
|
||||
"&::-webkit-scrollbar-thumb": {
|
||||
backgroundColor: "rgba(0,0,0,.2)",
|
||||
outline: "0px",
|
||||
borderRadius: "9999px",
|
||||
},
|
||||
scrollbarColor: "rgba(0,0,0,.2) rgba(0,0,0,0)",
|
||||
scrollbarGutter: "stable",
|
||||
scrollbarWidth: "thin",
|
||||
".dark &": {
|
||||
"&::-webkit-scrollbar": {
|
||||
background: "rgba(0,0,0,.0)",
|
||||
},
|
||||
"&::-webkit-scrollbar-gutter": "stable",
|
||||
"&::-webkit-scrollbar-thumb": {
|
||||
backgroundColor: "rgba(255,255,255,.2)",
|
||||
outline: "0px",
|
||||
borderRadius: "9999px",
|
||||
},
|
||||
scrollbarColor: "rgba(255,255,255,.2) rgba(0,0,0,0)",
|
||||
scrollbarGutter: "stable",
|
||||
scrollbarWidth: "thin",
|
||||
},
|
||||
}}
|
||||
onWheelCapture={(e) => {
|
||||
if (scrollRef.current) {
|
||||
scrollRef.current.scrollLeft += e.deltaY;
|
||||
}
|
||||
}}
|
||||
>
|
||||
<Container css={{ flex: 1 }}>
|
||||
<Container css={{ flex: 1 }} ref={containerRef}>
|
||||
<Stack
|
||||
css={{
|
||||
gap: "$3",
|
||||
@@ -233,8 +266,8 @@ const EditorNavigation = ({ showWat }: { showWat?: boolean }) => {
|
||||
<Label>Filename</Label>
|
||||
<Input
|
||||
value={filename}
|
||||
onChange={e => setFilename(e.target.value)}
|
||||
onKeyPress={e => {
|
||||
onChange={(e) => setFilename(e.target.value)}
|
||||
onKeyPress={(e) => {
|
||||
if (e.key === "Enter") {
|
||||
handleConfirm();
|
||||
}
|
||||
@@ -509,8 +542,8 @@ const EditorNavigation = ({ showWat }: { showWat?: boolean }) => {
|
||||
type="number"
|
||||
min="1"
|
||||
value={editorSettings.tabSize}
|
||||
onChange={e =>
|
||||
setEditorSettings(curr => ({
|
||||
onChange={(e) =>
|
||||
setEditorSettings((curr) => ({
|
||||
...curr,
|
||||
tabSize: Number(e.target.value),
|
||||
}))
|
||||
|
||||
@@ -164,21 +164,15 @@ const HooksEditor = () => {
|
||||
onConnection: (connection) => {
|
||||
// create and start the language client
|
||||
const languageClient = createLanguageClient(connection);
|
||||
languageClient.start();
|
||||
// connection.onDispose((d) => {
|
||||
// console.log("disposed: ", d);
|
||||
// });
|
||||
// connection.onError((ee) => {
|
||||
// console.log(ee =)
|
||||
// })
|
||||
// connection.onClose(() => {
|
||||
// try {
|
||||
// // disposable.stop();
|
||||
// disposable.dispose();
|
||||
// } catch (err) {
|
||||
// console.log("err", err);
|
||||
// }
|
||||
// });
|
||||
const disposable = languageClient.start();
|
||||
|
||||
connection.onClose(() => {
|
||||
try {
|
||||
disposable.dispose();
|
||||
} catch (err) {
|
||||
console.log("err", err);
|
||||
}
|
||||
});
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
@@ -30,12 +30,6 @@ import PanelBox from "./PanelBox";
|
||||
import { templateFileIds } from "../state/constants";
|
||||
import { styled } from "../stitches.config";
|
||||
|
||||
import Starter from "../components/icons/Starter";
|
||||
import Firewall from "../components/icons/Firewall";
|
||||
import Notary from "../components/icons/Notary";
|
||||
import Carbon from "../components/icons/Carbon";
|
||||
import Peggy from "../components/icons/Peggy";
|
||||
|
||||
const ImageWrapper = styled(Flex, {
|
||||
position: "relative",
|
||||
mt: "$2",
|
||||
@@ -301,66 +295,18 @@ const Navigation = () => {
|
||||
},
|
||||
}}
|
||||
>
|
||||
<PanelBox
|
||||
as="a"
|
||||
href={`/develop/${templateFileIds.starter}`}
|
||||
>
|
||||
<ImageWrapper>
|
||||
<Starter />
|
||||
</ImageWrapper>
|
||||
<Heading>Starter</Heading>
|
||||
{Object.values(templateFileIds).map((template) => (
|
||||
<PanelBox
|
||||
key={template.id}
|
||||
as="a"
|
||||
href={`/develop/${template.id}`}
|
||||
>
|
||||
<ImageWrapper>{template.icon()}</ImageWrapper>
|
||||
<Heading>{template.name}</Heading>
|
||||
|
||||
<Text>
|
||||
Just a basic starter with essential imports, just
|
||||
accepts any transaction coming through
|
||||
</Text>
|
||||
</PanelBox>
|
||||
|
||||
<PanelBox
|
||||
as="a"
|
||||
href={`/develop/${templateFileIds.firewall}`}
|
||||
css={{ alignItems: "flex-start" }}
|
||||
>
|
||||
<ImageWrapper>
|
||||
<Firewall />
|
||||
</ImageWrapper>
|
||||
<Heading>Firewall</Heading>
|
||||
<Text>
|
||||
This Hook essentially checks a blacklist of accounts
|
||||
</Text>
|
||||
</PanelBox>
|
||||
<PanelBox
|
||||
as="a"
|
||||
href={`/develop/${templateFileIds.notary}`}
|
||||
>
|
||||
<ImageWrapper>
|
||||
<Notary />
|
||||
</ImageWrapper>
|
||||
<Heading>Notary</Heading>
|
||||
<Text>
|
||||
Collecting signatures for multi-sign transactions
|
||||
</Text>
|
||||
</PanelBox>
|
||||
<PanelBox
|
||||
as="a"
|
||||
href={`/develop/${templateFileIds.carbon}`}
|
||||
>
|
||||
<ImageWrapper>
|
||||
<Carbon />
|
||||
</ImageWrapper>
|
||||
<Heading>Carbon</Heading>
|
||||
<Text>Send a percentage of sum to an address</Text>
|
||||
</PanelBox>
|
||||
<PanelBox
|
||||
as="a"
|
||||
href={`/develop/${templateFileIds.peggy}`}
|
||||
>
|
||||
<ImageWrapper>
|
||||
<Peggy />
|
||||
</ImageWrapper>
|
||||
<Heading>Peggy</Heading>
|
||||
<Text>An oracle based stable coin hook</Text>
|
||||
</PanelBox>
|
||||
<Text>{template.description}</Text>
|
||||
</PanelBox>
|
||||
))}
|
||||
</Flex>
|
||||
</Flex>
|
||||
<DialogClose asChild>
|
||||
@@ -394,6 +340,8 @@ const Navigation = () => {
|
||||
height: 0,
|
||||
background: "transparent",
|
||||
},
|
||||
scrollbarColor: "transparent",
|
||||
scrollbarWidth: "none",
|
||||
}}
|
||||
>
|
||||
<Stack
|
||||
|
||||
@@ -140,6 +140,16 @@ export const SetHookDialog: React.FC<{ accountAddress: string }> = React.memo(
|
||||
return null;
|
||||
}
|
||||
|
||||
const tooLargeFile = () => {
|
||||
const activeFile = snap.files[snap.active].compiledContent
|
||||
? snap.files[snap.active]
|
||||
: snap.files.filter((file) => file.compiledContent)[0];
|
||||
return Boolean(
|
||||
activeFile?.compiledContent?.byteLength &&
|
||||
activeFile?.compiledContent?.byteLength >= 64000
|
||||
);
|
||||
};
|
||||
|
||||
const onSubmit: SubmitHandler<SetHookData> = async (data) => {
|
||||
const currAccount = state.accounts.find(
|
||||
(acc) => acc.address === account.address
|
||||
@@ -164,7 +174,8 @@ export const SetHookDialog: React.FC<{ accountAddress: string }> = React.memo(
|
||||
variant={"secondary"}
|
||||
disabled={
|
||||
account.isLoading ||
|
||||
!snap.files.filter((file) => file.compiledWatContent).length
|
||||
!snap.files.filter((file) => file.compiledWatContent).length ||
|
||||
tooLargeFile()
|
||||
}
|
||||
>
|
||||
Set Hook
|
||||
|
||||
@@ -38,22 +38,22 @@ export const TxUI: FC<UIProps> = ({
|
||||
txFields,
|
||||
} = txState;
|
||||
|
||||
const transactionsOptions = transactionsData.map(tx => ({
|
||||
const transactionsOptions = transactionsData.map((tx) => ({
|
||||
value: tx.TransactionType,
|
||||
label: tx.TransactionType,
|
||||
}));
|
||||
|
||||
const accountOptions: SelectOption[] = accounts.map(acc => ({
|
||||
const accountOptions: SelectOption[] = accounts.map((acc) => ({
|
||||
label: acc.name,
|
||||
value: acc.address,
|
||||
}));
|
||||
|
||||
const destAccountOptions: SelectOption[] = accounts
|
||||
.map(acc => ({
|
||||
.map((acc) => ({
|
||||
label: acc.name,
|
||||
value: acc.address,
|
||||
}))
|
||||
.filter(acc => acc.value !== selectedAccount?.value);
|
||||
.filter((acc) => acc.value !== selectedAccount?.value);
|
||||
|
||||
const [feeLoading, setFeeLoading] = useState(false);
|
||||
|
||||
@@ -108,15 +108,15 @@ export const TxUI: FC<UIProps> = ({
|
||||
const specialFields = ["TransactionType", "Account", "Destination"];
|
||||
|
||||
const otherFields = Object.keys(txFields).filter(
|
||||
k => !specialFields.includes(k)
|
||||
(k) => !specialFields.includes(k)
|
||||
) as [keyof TxFields];
|
||||
|
||||
const switchToJson = () =>
|
||||
setState({ editorSavedValue: null, viewType: "json" });
|
||||
|
||||
|
||||
useEffect(() => {
|
||||
const defaultOption = transactionsOptions.find(
|
||||
tt => tt.value === "Payment"
|
||||
(tt) => tt.value === "Payment"
|
||||
);
|
||||
if (defaultOption) {
|
||||
handleChangeTxType(defaultOption);
|
||||
@@ -204,7 +204,7 @@ export const TxUI: FC<UIProps> = ({
|
||||
/>
|
||||
</Flex>
|
||||
)}
|
||||
{otherFields.map(field => {
|
||||
{otherFields.map((field) => {
|
||||
let _value = txFields[field];
|
||||
|
||||
let value: string | undefined;
|
||||
@@ -253,13 +253,39 @@ export const TxUI: FC<UIProps> = ({
|
||||
/>
|
||||
) : (
|
||||
<Input
|
||||
type={isFee ? "number" : "text"}
|
||||
value={value}
|
||||
onChange={e => {
|
||||
handleSetField(field, e.target.value);
|
||||
onChange={(e) => {
|
||||
if (isFee) {
|
||||
const val = e.target.value
|
||||
.replaceAll(".", "")
|
||||
.replaceAll(",", "");
|
||||
handleSetField(field, val);
|
||||
} else {
|
||||
handleSetField(field, e.target.value);
|
||||
}
|
||||
}}
|
||||
onKeyPress={
|
||||
isFee
|
||||
? (e) => {
|
||||
if (e.key === "." || e.key === ",") {
|
||||
e.preventDefault();
|
||||
}
|
||||
}
|
||||
: undefined
|
||||
}
|
||||
css={{
|
||||
width: "70%",
|
||||
flex: "inherit",
|
||||
"-moz-appearance": "textfield",
|
||||
"&::-webkit-outer-spin-button": {
|
||||
"-webkit-appearance": "none",
|
||||
margin: 0,
|
||||
},
|
||||
"&::-webkit-inner-spin-button ": {
|
||||
"-webkit-appearance": "none",
|
||||
margin: 0,
|
||||
},
|
||||
}}
|
||||
/>
|
||||
)}
|
||||
@@ -268,6 +294,8 @@ export const TxUI: FC<UIProps> = ({
|
||||
size="xs"
|
||||
variant="primary"
|
||||
outline
|
||||
disabled={txState.txIsDisabled}
|
||||
isDisabled={txState.txIsDisabled}
|
||||
isLoading={feeLoading}
|
||||
css={{
|
||||
position: "absolute",
|
||||
|
||||
@@ -32,14 +32,20 @@ const Test = () => {
|
||||
if (!showComponent) {
|
||||
return null;
|
||||
}
|
||||
const hasScripts =
|
||||
snap.files.filter((f) => f.name.endsWith(".js")).length > 0;
|
||||
const hasScripts = Boolean(
|
||||
snap.files.filter((f) => f.name.toLowerCase()?.endsWith(".js")).length
|
||||
);
|
||||
|
||||
return (
|
||||
<Container css={{ px: 0 }}>
|
||||
<Split
|
||||
direction="vertical"
|
||||
sizes={
|
||||
getSplit("testVertical") || (hasScripts ? [50, 20, 30] : [50, 50])
|
||||
hasScripts && getSplit("testVertical")?.length === 2
|
||||
? [50, 20, 30]
|
||||
: hasScripts
|
||||
? [50, 20, 50]
|
||||
: [50, 50]
|
||||
}
|
||||
gutterSize={4}
|
||||
gutterAlign="center"
|
||||
@@ -95,7 +101,7 @@ const Test = () => {
|
||||
</Box>
|
||||
</Split>
|
||||
</Flex>
|
||||
{hasScripts && (
|
||||
{hasScripts ? (
|
||||
<Flex
|
||||
as="div"
|
||||
css={{
|
||||
@@ -110,7 +116,7 @@ const Test = () => {
|
||||
clearLog={() => (state.scriptLogs = [])}
|
||||
/>
|
||||
</Flex>
|
||||
)}
|
||||
) : null}
|
||||
<Flex>
|
||||
<Split
|
||||
direction="horizontal"
|
||||
|
||||
@@ -39,7 +39,7 @@ export const compileCode = async (activeId: number) => {
|
||||
files: [
|
||||
{
|
||||
type: "c",
|
||||
options: state.compileOptions.optimizationLevel || '-O0',
|
||||
options: state.compileOptions.optimizationLevel || '-O2',
|
||||
name: state.files[activeId].name,
|
||||
src: state.files[activeId].content,
|
||||
},
|
||||
|
||||
@@ -54,15 +54,15 @@ export const prepareDeployHookTx = async (
|
||||
account: IAccount & { name?: string },
|
||||
data: SetHookData
|
||||
) => {
|
||||
if (
|
||||
!state.files ||
|
||||
state.files.length === 0 ||
|
||||
!state.files?.[state.active]?.compiledContent
|
||||
) {
|
||||
const activeFile = state.files[state.active]?.compiledContent
|
||||
? state.files[state.active]
|
||||
: state.files.filter((file) => file.compiledContent)[0];
|
||||
|
||||
if (!state.files || state.files.length === 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!state.files?.[state.active]?.compiledContent) {
|
||||
if (!activeFile?.compiledContent) {
|
||||
return;
|
||||
}
|
||||
if (!state.client) {
|
||||
@@ -99,7 +99,7 @@ export const prepareDeployHookTx = async (
|
||||
{
|
||||
Hook: {
|
||||
CreateCode: arrayBufferToHex(
|
||||
state.files?.[state.active]?.compiledContent
|
||||
activeFile?.compiledContent
|
||||
).toUpperCase(),
|
||||
HookOn: calculateHookOn(hookOnValues),
|
||||
HookNamespace,
|
||||
|
||||
@@ -19,7 +19,7 @@ export const fetchFiles = (gistId: string) => {
|
||||
octokit
|
||||
.request("GET /gists/{gist_id}", { gist_id: gistId })
|
||||
.then(async res => {
|
||||
if (!Object.values(templateFileIds).includes(gistId)) {
|
||||
if (!Object.values(templateFileIds).map(v => v.id).includes(gistId)) {
|
||||
return res
|
||||
}
|
||||
// in case of templates, fetch header file(s) and append to res
|
||||
|
||||
@@ -1,20 +1,41 @@
|
||||
// export const templateFileIds = {
|
||||
// 'starter': '1d14e51e2e02dc0a508cb0733767a914', // TODO currently same as accept
|
||||
// 'firewall': 'bcd6d0c0fcbe52545ddb802481ff9d26',
|
||||
// 'notary': 'a789c75f591eeab7932fd702ed8cf9ea',
|
||||
// 'carbon': '43925143fa19735d8c6505c34d3a6a47',
|
||||
// 'peggy': 'ceaf352e2a65741341033ab7ef05c448',
|
||||
// 'headers': '9b448e8a55fab11ef5d1274cb59f9cf3'
|
||||
// }
|
||||
import Carbon from "../../components/icons/Carbon";
|
||||
import Firewall from "../../components/icons/Firewall";
|
||||
import Notary from "../../components/icons/Notary";
|
||||
import Peggy from "../../components/icons/Peggy";
|
||||
import Starter from "../../components/icons/Starter";
|
||||
|
||||
export const templateFileIds = {
|
||||
'starter': '1f7d2963d9e342ea092286115274f3e3',
|
||||
'firewall': '70edec690f0de4dd315fad1f4f996d8c',
|
||||
'notary': '3d5677768fe8a54c4f6317e185d9ba66',
|
||||
'carbon': 'a9fbcaf1b816b198c7fc0f62962bebf2',
|
||||
'doubler': '56b86174aeb70b2b48eee962bad3e355',
|
||||
'peggy': 'd21298a37e1550b781682014762a567b',
|
||||
'headers': '55f639bce59a49c58c45e663776b5138'
|
||||
'starter': {
|
||||
id: '9106f1fe60482d90475bfe8f1315affe',
|
||||
name: 'Starter',
|
||||
description: 'Just a basic starter with essential imports, just accepts any transaction coming through',
|
||||
icon: Starter
|
||||
|
||||
},
|
||||
'firewall': {
|
||||
id: '741816f53eddac862ef1ba400e1b9b84',
|
||||
name: 'Firewall',
|
||||
description: 'This Hook essentially checks a blacklist of accounts',
|
||||
icon: Firewall
|
||||
},
|
||||
'notary': {
|
||||
id: '0dfe12adb0aa75cff24c3c19497fb95a',
|
||||
name: 'Notary',
|
||||
description: 'Collecting signatures for multi-sign transactions',
|
||||
icon: Notary
|
||||
},
|
||||
'carbon': {
|
||||
id: '5941c19dce3e147948f564e224553c02',
|
||||
name: 'Carbon',
|
||||
description: 'Send a percentage of sum to an address',
|
||||
icon: Carbon
|
||||
},
|
||||
'peggy': {
|
||||
id: '52e61c02e777c44c913808981a4ca61f',
|
||||
name: 'Peggy',
|
||||
description: 'An oracle based stable coin hook',
|
||||
icon: Peggy
|
||||
},
|
||||
}
|
||||
|
||||
export const apiHeaderFiles = ['hookapi.h', 'sfcodes.h', 'hookmacro.h']
|
||||
export const apiHeaderFiles = ['hookapi.h', 'sfcodes.h', 'macro.h', 'extern.h', 'error.h'];
|
||||
|
||||
@@ -114,7 +114,7 @@ let initialState: IState = {
|
||||
mainModalShowed: false,
|
||||
accounts: [],
|
||||
compileOptions: {
|
||||
optimizationLevel: '-O0',
|
||||
optimizationLevel: '-O2',
|
||||
strip: true
|
||||
}
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user