Compare commits

..

14 Commits

Author SHA1 Message Date
JaniAnttonen
810d3b2524 Add a todo 2022-02-25 16:34:09 +02:00
JaniAnttonen
a3393ded1e Fix build 2022-02-25 15:22:09 +02:00
JaniAnttonen
17ede265b1 Remove debug logging 2022-02-25 14:39:06 +02:00
JaniAnttonen
629070edad Save split state 2022-02-25 13:50:56 +02:00
Vaclav Barta
cc83924c27 Merge pull request #98 from eqlabs/bugfix/typos
fix for #97
2022-02-15 08:49:38 +01:00
Vaclav Barta
e3e964f72a fix for #97 2022-02-11 13:54:52 +01:00
Joni Juup
bdb2c0cf8f Merge pull request #93 from eqlabs/bugfix/monaco-popups
Fix monaco popup issues
2022-02-09 15:10:28 +02:00
muzamil
3e8dbc9793 Merge pull request #91 from eqlabs/fixes
Clearing some issues
2022-02-09 18:32:47 +05:30
muzam
d735cd3833 Merge branch 'main' into fixes 2022-02-09 18:31:35 +05:30
muzam
1a3f5d144c change accept template to starter 2022-02-09 14:26:19 +05:30
muzam
ce81c11c29 Update hooks installed info in card 2022-02-08 19:56:30 +05:30
muzam
3a98b95e3d fix firewall template link 2022-02-08 18:59:40 +05:30
muzam
8bc36655e2 disallow illegal characters in filename 2022-02-08 15:26:22 +05:30
muzam
b6ab536a60 Clear log on compile 2022-02-08 15:08:38 +05:30
11 changed files with 91 additions and 86 deletions

View File

@@ -36,13 +36,11 @@ const AccountDialog = ({
}) => {
const snap = useSnapshot(state);
const [showSecret, setShowSecret] = useState(false);
const activeAccount = snap.accounts.find(
(account) => account.address === activeAccountAddress
);
const activeAccount = snap.accounts.find(account => account.address === activeAccountAddress);
return (
<Dialog
open={Boolean(activeAccountAddress)}
onOpenChange={(open) => {
onOpenChange={open => {
setShowSecret(false);
!open && setActiveAccountAddress(null);
}}
@@ -137,7 +135,7 @@ const AccountDialog = ({
}}
ghost
size="xs"
onClick={() => setShowSecret((curr) => !curr)}
onClick={() => setShowSecret(curr => !curr)}
>
{showSecret ? "Hide" : "Show"}
</Button>
@@ -201,15 +199,7 @@ const AccountDialog = ({
fontFamily: "$monospace",
}}
>
{activeAccount && activeAccount?.hooks?.length > 0
? activeAccount?.hooks
.map((i) => {
return `${i?.substring(0, 6)}...${i?.substring(
i.length - 4
)}`;
})
.join(", ")
: ""}
{activeAccount && activeAccount.hooks.length}
</Text>
</Flex>
</Flex>
@@ -231,15 +221,13 @@ interface AccountProps {
showHookStats?: boolean;
}
const Accounts: FC<AccountProps> = (props) => {
const Accounts: FC<AccountProps> = props => {
const snap = useSnapshot(state);
const [activeAccountAddress, setActiveAccountAddress] = useState<
string | null
>(null);
const [activeAccountAddress, setActiveAccountAddress] = useState<string | null>(null);
useEffect(() => {
const fetchAccInfo = async () => {
if (snap.clientStatus === "online") {
const requests = snap.accounts.map((acc) =>
const requests = snap.accounts.map(acc =>
snap.client?.send({
id: acc.address,
command: "account_info",
@@ -251,15 +239,13 @@ const Accounts: FC<AccountProps> = (props) => {
const address = res?.account_data?.Account as string;
const balance = res?.account_data?.Balance as string;
const sequence = res?.account_data?.Sequence as number;
const accountToUpdate = state.accounts.find(
(acc) => acc.address === address
);
const accountToUpdate = state.accounts.find(acc => acc.address === address);
if (accountToUpdate) {
accountToUpdate.xrp = balance;
accountToUpdate.sequence = sequence;
}
});
const objectRequests = snap.accounts.map((acc) => {
const objectRequests = snap.accounts.map(acc => {
return snap.client?.send({
id: `${acc.address}-hooks`,
command: "account_objects",
@@ -269,9 +255,7 @@ const Accounts: FC<AccountProps> = (props) => {
const objectResponses = await Promise.all(objectRequests);
objectResponses.forEach((res: any) => {
const address = res?.account as string;
const accountToUpdate = state.accounts.find(
(acc) => acc.address === address
);
const accountToUpdate = state.accounts.find(acc => acc.address === address);
if (accountToUpdate) {
accountToUpdate.hooks = res.account_objects
.filter((ac: any) => ac?.LedgerEntryType === "Hook")
@@ -353,7 +337,7 @@ const Accounts: FC<AccountProps> = (props) => {
overflowY: "auto",
}}
>
{snap.accounts.map((account) => (
{snap.accounts.map(account => (
<Flex
column
key={account.address + account.name}
@@ -406,11 +390,10 @@ const Accounts: FC<AccountProps> = (props) => {
isLoading={account.isLoading}
disabled={
account.isLoading ||
!snap.files.filter((file) => file.compiledWatContent)
.length
!snap.files.filter(file => file.compiledWatContent).length
}
variant="secondary"
onClick={(e) => {
onClick={e => {
e.stopPropagation();
deployHook(account);
}}
@@ -421,7 +404,7 @@ const Accounts: FC<AccountProps> = (props) => {
</Flex>
{props.showHookStats && (
<Text muted small css={{ mt: "$2" }}>
X hooks installed
{account.hooks.length} hook{account.hooks.length === 1 ? "" : "s"} installed
</Text>
)}
</Flex>
@@ -453,7 +436,7 @@ const ImportAccountDialog = () => {
name="secret"
type="password"
value={value}
onChange={(e) => setValue(e.target.value)}
onChange={e => setValue(e.target.value)}
/>
</DialogDescription>

View File

@@ -90,9 +90,16 @@ const EditorNavigation = ({ showWat }: { showWat?: boolean }) => {
const validateFilename = useCallback(
(filename: string): { error: string | null } => {
if (snap.files.find((file) => file.name === filename)) {
// check if filename already exists
if (snap.files.find(file => file.name === filename)) {
return { error: "Filename already exists." };
}
// check for illegal characters
const ILLEGAL_REGEX = /[/]/gi;
if (filename.match(ILLEGAL_REGEX)) {
return { error: "Filename contains illegal characters" };
}
// More checks in future
return { error: null };
},

View File

@@ -173,7 +173,7 @@ const HooksEditor = () => {
fontFamily: "$monospace",
}}
>
Click the link above to create a your file
Click the link above to create your file
</Text>
</Box>
</Box>

View File

@@ -279,28 +279,18 @@ const Navigation = () => {
>
<Heading>Starter</Heading>
<Text>
Just an empty starter with essential imports
Just a basic starter with essential imports
</Text>
</PanelBox>
<PanelBox
as="a"
href={`/develop/${templateFileIds.starter}`}
href={`/develop/${templateFileIds.firewall}`}
>
<Heading>Firewall</Heading>
<Text>
This Hook essentially checks a blacklist of accounts
</Text>
</PanelBox>
<PanelBox
as="a"
href={`/develop/${templateFileIds.accept}`}
>
<Heading>Accept</Heading>
<Text>
This hook just accepts any transaction coming through
it
</Text>
</PanelBox>
<PanelBox
as="a"
href={`/develop/${templateFileIds.notary}`}
@@ -322,7 +312,7 @@ const Navigation = () => {
href={`/develop/${templateFileIds.peggy}`}
>
<Heading>Peggy</Heading>
<Text>An oracle based stabe coin hook</Text>
<Text>An oracle based stable coin hook</Text>
</PanelBox>
</Flex>
</Flex>

View File

@@ -1,8 +1,9 @@
import React from "react";
import dynamic from "next/dynamic";
import React from "react";
import Split from "react-split";
import { useSnapshot } from "valtio";
import state from "../../state";
import Split from "react-split";
import { getSplit, saveSplit } from "../../state/actions/persistSplits";
const DeployEditor = dynamic(() => import("../../components/DeployEditor"), {
ssr: false,
@@ -17,21 +18,22 @@ const LogBox = dynamic(() => import("../../components/LogBox"), {
});
const Deploy = () => {
const snap = useSnapshot(state);
const { deployLogs } = useSnapshot(state);
return (
<Split
direction="vertical"
gutterSize={4}
gutterAlign="center"
sizes={[40, 60]}
sizes={getSplit("deployVertical") || [40, 60]}
style={{ height: "calc(100vh - 60px)" }}
onDragEnd={(e) => saveSplit("deployVertical", e)}
>
<main style={{ display: "flex", flex: 1, position: "relative" }}>
<DeployEditor />
</main>
<Split
direction="horizontal"
sizes={[50, 50]}
sizes={getSplit("deployHorizontal") || [50, 50]}
minSize={[320, 160]}
gutterSize={4}
gutterAlign="center"
@@ -41,6 +43,7 @@ const Deploy = () => {
width: "100%",
height: "100%",
}}
onDragEnd={(e) => saveSplit("deployHorizontal", e)}
>
<div style={{ alignItems: "stretch", display: "flex" }}>
<Accounts />
@@ -48,7 +51,7 @@ const Deploy = () => {
<div>
<LogBox
title="Deploy Log"
logs={snap.deployLogs}
logs={deployLogs}
clearLog={() => (state.deployLogs = [])}
/>
</div>

View File

@@ -1,14 +1,15 @@
import dynamic from "next/dynamic";
import { useSnapshot } from "valtio";
import Hotkeys from "react-hot-keys";
import { Play } from "phosphor-react";
import Split from "react-split";
import type { NextPage } from "next";
import { compileCode } from "../../state/actions";
import state from "../../state";
import Button from "../../components/Button";
import dynamic from "next/dynamic";
import { Play } from "phosphor-react";
import Hotkeys from "react-hot-keys";
import Split from "react-split";
import { useSnapshot } from "valtio";
import Box from "../../components/Box";
import Button from "../../components/Button";
import state from "../../state";
import { compileCode } from "../../state/actions";
import { getSplit, saveSplit } from "../../state/actions/persistSplits";
const HooksEditor = dynamic(() => import("../../components/HooksEditor"), {
ssr: false,
@@ -24,11 +25,12 @@ const Home: NextPage = () => {
return (
<Split
direction="vertical"
sizes={[70, 30]}
sizes={getSplit("developVertical") || [70, 30]}
minSize={[100, 100]}
gutterAlign="center"
gutterSize={4}
style={{ height: "calc(100vh - 60px)" }}
onDragEnd={(e) => saveSplit("developVertical", e)}
>
<main style={{ display: "flex", flex: 1, position: "relative" }}>
<HooksEditor />

View File

@@ -1,22 +1,17 @@
import {
Container,
Flex,
Box,
Tabs,
Tab,
Input,
Select,
Text,
Button,
} from "../../components";
import { Play } from "phosphor-react";
import dynamic from "next/dynamic";
import { useSnapshot } from "valtio";
import { Play } from "phosphor-react";
import { FC, useCallback, useEffect, useState } from "react";
import Split from "react-split";
import { useSnapshot } from "valtio";
import {
Box, Button, Container,
Flex, Input,
Select, Tab, Tabs, Text
} from "../../components";
import transactionsData from "../../content/transactions.json";
import state from "../../state";
import { sendTransaction } from "../../state/actions";
import { useCallback, useEffect, useState, FC } from "react";
import transactionsData from "../../content/transactions.json";
import { getSplit, saveSplit } from "../../state/actions/persistSplits";
const DebugStream = dynamic(() => import("../../components/DebugStream"), {
ssr: false,
@@ -349,16 +344,17 @@ const Transaction: FC<Props> = ({ header, ...props }) => {
};
const Test = () => {
const snap = useSnapshot(state);
const { transactionLogs } = useSnapshot(state);
const [tabHeaders, setTabHeaders] = useState<string[]>(["test1.json"]);
return (
<Container css={{ px: 0 }}>
<Split
direction="vertical"
sizes={[50, 50]}
sizes={getSplit("testVertical") || [50, 50]}
gutterSize={4}
gutterAlign="center"
style={{ height: "calc(100vh - 60px)" }}
onDragEnd={(e) => saveSplit("testVertical", e)}
>
<Flex
row
@@ -370,7 +366,7 @@ const Test = () => {
>
<Split
direction="horizontal"
sizes={[50, 50]}
sizes={getSplit("testHorizontal") || [50, 50]}
minSize={[180, 320]}
gutterSize={4}
gutterAlign="center"
@@ -380,6 +376,7 @@ const Test = () => {
width: "100%",
height: "100%",
}}
onDragEnd={(e) => saveSplit("testHorizontal", e)}
>
<Box css={{ width: "55%", px: "$2" }}>
<Tabs
@@ -428,7 +425,7 @@ const Test = () => {
>
<LogBox
title="Development Log"
logs={snap.transactionLogs}
logs={transactionLogs}
clearLog={() => (state.transactionLogs = [])}
/>
</Box>

View File

@@ -25,6 +25,7 @@ export const compileCode = async (activeId: number) => {
}
// Set loading state to true
state.compiling = true;
state.logs = []
try {
const res = await fetch(process.env.NEXT_PUBLIC_COMPILE_API_ENDPOINT, {
method: "POST",

View File

@@ -0,0 +1,15 @@
import { snapshot } from "valtio"
import state from ".."
export type SplitSize = number[]
export const saveSplit = (splitId: string, event: SplitSize) => {
state.splits[splitId] = event
}
export const getSplit = (splitId: string): SplitSize | null => {
const { splits } = snapshot(state)
const split = splits[splitId]
return split ? split : null
}

View File

@@ -1,6 +1,5 @@
export const templateFileIds = {
'starter': '1d14e51e2e02dc0a508cb0733767a914', // TODO currently same as accept
'accept': '1d14e51e2e02dc0a508cb0733767a914',
'firewall': 'bcd6d0c0fcbe52545ddb802481ff9d26',
'notary': 'a789c75f591eeab7932fd702ed8cf9ea',
'carbon': '43925143fa19735d8c6505c34d3a6a47',

View File

@@ -1,7 +1,8 @@
import { proxy, ref, subscribe } from "valtio";
import { devtools } from 'valtio/utils'
import type monaco from "monaco-editor";
import { proxy, ref, subscribe } from "valtio";
import { devtools } from 'valtio/utils';
import { XrplClient } from "xrpl-client";
import { SplitSize } from "./actions/persistSplits";
export interface IFile {
name: string;
@@ -55,6 +56,9 @@ export interface IState {
editorSettings: {
tabSize: number;
};
splits: {
[id: string]: SplitSize
};
client: XrplClient | null;
clientStatus: "offline" | "online";
mainModalOpen: boolean;
@@ -83,6 +87,7 @@ let initialState: IState = {
editorSettings: {
tabSize: 2,
},
splits: {},
client: null,
clientStatus: "offline" as "offline",
mainModalOpen: false,
@@ -91,6 +96,9 @@ let initialState: IState = {
let localStorageAccounts: string | null = null;
let initialAccounts: IAccount[] = [];
// TODO: What exactly should we store in localStorage? editorSettings, splits, accounts?
// Check if there's a persited accounts in localStorage
if (typeof window !== "undefined") {
try {
@@ -139,4 +147,4 @@ if (typeof window !== "undefined") {
}
});
}
export default state
export default state