Skip to content

Commit

Permalink
Merge pull request #3 from btclayer2/feat/init
Browse files Browse the repository at this point in the history
Feat/init
  • Loading branch information
xl2412 authored Jan 4, 2025
2 parents c75de7e + a662827 commit 4007c5f
Show file tree
Hide file tree
Showing 16 changed files with 1,693 additions and 9 deletions.
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,8 @@ frontend/dist
.idea/**/gradle.xml
.idea/**/libraries

.idea

# Gradle and Maven with auto-import
# When using Gradle or Maven with auto-import, you should exclude module files,
# since they will be recreated, and may cause churn. Uncomment if using
Expand Down
7 changes: 6 additions & 1 deletion frontend/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,9 @@
"@radix-ui/react-progress": "^1.1.1",
"@radix-ui/react-slot": "^1.1.1",
"@radix-ui/react-toast": "^1.2.4",
"@radix-ui/react-tabs": "^1.1.1",
"@chakra-ui/react": "latest",
"@emotion/react": "^11.13.3",
"buffer": "^6.0.3",
"class-variance-authority": "^0.7.1",
"clsx": "^2.1.1",
Expand All @@ -26,7 +29,9 @@
"react-dom": "^18.2.0",
"react-router-dom": "^7.1.1",
"tailwind-merge": "^2.6.0",
"tailwindcss-animate": "^1.0.7"
"tailwindcss-animate": "^1.0.7",
"zustand": "^4.4.7",
"axios": "^1.6.2"
},
"devDependencies": {
"@types/node": "^22.10.2",
Expand Down
2 changes: 1 addition & 1 deletion frontend/package.json.md5
Original file line number Diff line number Diff line change
@@ -1 +1 @@
ea7209d897ed9c2afa228dddb3f94876
33e2512928c379407bb7705b483d477b
1,312 changes: 1,312 additions & 0 deletions frontend/pnpm-lock.yaml

Large diffs are not rendered by default.

19 changes: 13 additions & 6 deletions frontend/src/App.tsx
Original file line number Diff line number Diff line change
@@ -1,15 +1,22 @@
import { Routes, Route } from "react-router-dom";
import Main from "./pages/Main/Main";
import LndState from "./pages/LndState/LndState";
import Create from "./pages/Create/Create";
import './App.css';
import React from 'react';
import { ChakraProvider, defaultSystem } from "@chakra-ui/react"


function App() {
return (
<Routes>
<Route path="/" element={< Main />} />
<Route path="/lndState" element={<LndState />} />
</Routes>
)
return (
<ChakraProvider value={defaultSystem}>
<Routes>
<Route path="/" element={< Main />} />
<Route path="/lndState" element={<LndState />} />
<Route path="/create" element={<Create/>} />
</Routes>
</ChakraProvider>
)
}

export default App
33 changes: 33 additions & 0 deletions frontend/src/components/ui/field.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
import { Field as ChakraField } from "@chakra-ui/react"
import * as React from "react"

export interface FieldProps extends Omit<ChakraField.RootProps, "label"> {
label?: React.ReactNode
helperText?: React.ReactNode
errorText?: React.ReactNode
optionalText?: React.ReactNode
}

export const Field = React.forwardRef<HTMLDivElement, FieldProps>(
function Field(props, ref) {
const { label, children, helperText, errorText, optionalText, ...rest } =
props
return (
<ChakraField.Root ref={ref} {...rest}>
{label && (
<ChakraField.Label>
{label}
<ChakraField.RequiredIndicator fallback={optionalText} />
</ChakraField.Label>
)}
{children}
{helperText && (
<ChakraField.HelperText>{helperText}</ChakraField.HelperText>
)}
{errorText && (
<ChakraField.ErrorText>{errorText}</ChakraField.ErrorText>
)}
</ChakraField.Root>
)
},
)
12 changes: 12 additions & 0 deletions frontend/src/components/ui/provider.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
"use client"

import { ChakraProvider, defaultSystem } from "@chakra-ui/react"


export function Provider() {
return (
<ChakraProvider value={defaultSystem}>
{/*<ColorModeProvider {...props} />*/}
</ChakraProvider>
)
}
22 changes: 22 additions & 0 deletions frontend/src/pages/Create/Create.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import { useNavigate } from 'react-router-dom';
import { useToast } from '@/hooks/use-toast';
import Pwd from '@/pages/Create/Pwd';
import Tab from '@/pages/Create/Tab';
import { useCreateStore } from '@/store/create';

function Create() {
const navigate = useNavigate();
const { toast } = useToast()
const {status} = useCreateStore()


return (
<div className='dark flex flex-col items-center justify-center h-screen mx-w-full'>
<div style={{width:'fit-content', maxHeight:'500px', padding:'24px', border:'1px solid white', borderRadius:'8px', display:'flex', flexDirection:'column', alignItems: 'center', justifyItems:'center'}}>
{status === 'pwd' ? <Pwd/> : <Tab/>}
</div>
</div>
)
}

export default Create
69 changes: 69 additions & 0 deletions frontend/src/pages/Create/Import.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
import { Button, Input, Stack, Textarea } from "@chakra-ui/react";
import { Field } from "@/components/ui/field";
import { useState } from "react";
import { useCreateStore } from '@/store/create';
import { toast } from '@/hooks/use-toast';

function Import() {
// 定义状态存储两个文本框的值
const [mnemonic, setMnemonic] = useState("");
const [passphrase, setPassphrase] = useState("");
const [error, setError] = useState(""); // 错误提示信息

const { initWallet, pwd } = useCreateStore()
// 验证方法:检查是否为24个单词
const validateMnemonic = (mnemonic: string) => {
const words = mnemonic.trim().split(/\s+/); // 通过空格分割单词
return words.length === 24;
};

// 表单提交逻辑
const onSubmit = (event: React.FormEvent) => {
debugger
event.preventDefault(); // 阻止默认表单提交行为
// 检查第一个文本框内容
if (!validateMnemonic(mnemonic)) {
setError("The mnemonic must consist of exactly 24 words.");
toast({
variant: "default",
title: "The mnemonic must consist of exactly 24 words.",
})
return;
}

// 清除错误信息
setError("");

// 检查通过,输出成功
console.log("Mnemonic:", mnemonic);
console.log("Passphrase:", passphrase || "No passphrase provided.");
initWallet(pwd, mnemonic, passphrase, '')
};

return (
<div className="dark flex flex-col items-center justify-center mx-w-full">
<form onSubmit={onSubmit} className="flex flex-col justify-center items-center">
<Stack gap="4" align="flex-start" width="500px">
<Field label="Your Own Mnemonic" errorText={error}>
<Textarea
placeholder="Please enter the 24-word mnemonic, separated by spaces."
value={mnemonic}
onChange={(e) => setMnemonic(e.target.value)}
style={{height:'200px'}}
/>
</Field>
<Field label="Input your cipher seed passphrase">
<Input
placeholder="If not, no input is required."
value={passphrase}
onChange={(e) => setPassphrase(e.target.value)}
/>
</Field>
</Stack>
<Button type="submit" onClick={onSubmit}>Submit</Button>
</form>
</div>
);
}

export default Import;
68 changes: 68 additions & 0 deletions frontend/src/pages/Create/New.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
import { useNavigate } from 'react-router-dom';
import { useToast } from '@/hooks/use-toast';
import { useState } from 'react';
import { useCreateStore } from '@/store/create';
import { Box, Button, Input, Stack, Textarea } from '@chakra-ui/react';
import { Field } from '@/components/ui/field';

function New() {

const [confirmPassphrase, setConfirmPassphrase] = useState("");
const [newStatus, setNewStatus] = useState<'phrase' | 'word'>('phrase')
const { initWallet, pwd, createPassphrase, setCreatePassphrase, genSeed, createMnemonic, showCreateMnemonic } = useCreateStore()
const navigate = useNavigate();

const onSubmit = async (event: React.FormEvent) => {
event.preventDefault(); // 阻止默认表单提交行为
if (confirmPassphrase === createPassphrase) {
console.log('下一步')
await genSeed(createPassphrase)
setNewStatus('word')

}
};

const finishCreate = async() => {
await initWallet(pwd, createMnemonic, createPassphrase ? createPassphrase : 'aezeed', '')
navigate('/lndState')
};

return (
<div className="dark flex flex-col items-center justify-center mx-w-full">
{newStatus === 'phrase' && <form onSubmit={onSubmit} className="flex flex-col justify-center items-center">
<div style={{textAlign:'center', padding:'12px 0 24px 0'}}> Set cipher seed passphrase(optional)</div>
<Stack gap="4" align="flex-start" width="500px">

<Field label="Input your cipher seed passphrase">
<Input
placeholder="If not, no input is required."
value={createPassphrase}
onChange={(e) => setCreatePassphrase(e.target.value)}
/>
</Field>
<Field label="Confirm your cipher seed passphrase">
<Input
placeholder="If not, no input is required."
value={confirmPassphrase}
onChange={(e) => setConfirmPassphrase(e.target.value)}
/>
</Field>
</Stack>
<Button type="submit" onClick={onSubmit}>Submit</Button>
</form>}
{newStatus === 'word' && <div style={{width:'400px', padding:'12px', display:'flex', flexDirection:'column', alignItems: 'center', justifyItems:'center'}}>
<div style={{fontSize:'18px',fontWeight: '600', margin:'8px 0'}}>New mnemonic</div>
<div style={{maxWidth:'280px'}}>{showCreateMnemonic}</div>
<div style={{maxWidth:'280px',marginTop:'24px', fontSize:'12px'}}>
1 Please take a moment to write down this mnemonic phrase on a piece of paper.
</div>
<div style={{maxWidth:'280px', fontSize:'12px'}}>
2 It's your backup and you can use it to recover the wallet.
</div>
<Button type="submit" onClick={finishCreate}>Confirm</Button>
</div>}
</div>
);
}

export default New
59 changes: 59 additions & 0 deletions frontend/src/pages/Create/Pwd.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
import { useNavigate } from 'react-router-dom';
import { Toaster } from "@/components/ui/toaster"
import { useToast } from '@/hooks/use-toast';
import { Label } from '@/components/ui/label';
import { useState } from 'react';
import { Input } from '@/components/ui/input';
import { Button } from '@/components/ui/button';
import { useCreateStore } from '@/store/create';
import { Stack } from '@chakra-ui/react';
import { Field } from '@/components/ui/field';

function Pwd() {

const {pwd, setPwd, setStatus} = useCreateStore()
const [confirmPwd, setConfirmPwd] = useState('');
const [error, setError] = useState('')
const navigate = useNavigate();
const { toast } = useToast()

const onSubmit = (event: React.FormEvent) => {
event.preventDefault(); // 阻止默认表单提交行为
console.log(pwd, confirmPwd)
if(pwd.length < 8) {
setError('The password must be at least eight digits!')
} else if(pwd === confirmPwd) {
setStatus('create')
}else{
setError('Check whether the entered password is consistent')
}
}
return (
<>
<Toaster />
<form className="flex flex-col items-center justify-center" onSubmit={onSubmit}>
<div style={{textAlign:'center', padding:'12px 0 24px 0'}}>Create a password for your wallet</div>
<Stack gap="4" align="flex-start" width="500px">

<Field label="Input wallet Password:" helperText="The password must be at least eight digits!" errorText={error}>
<Input
placeholder="is required."
value={pwd}
onChange={(e) => setPwd(e.target.value)}
/>
</Field>
<Field label="Confirm wallet Password:" errorText={error}>
<Input
placeholder="is required."
value={confirmPwd}
onChange={(e) => setConfirmPwd(e.target.value)}
/>
</Field>
</Stack>
<Button type="submit" className="m-4">Confirm</Button>
</form>
</>
)
}

export default Pwd
23 changes: 23 additions & 0 deletions frontend/src/pages/Create/Tab.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import React from 'react';
import Import from '@/pages/Create/Import';
import New from '@/pages/Create/New';
import { Tabs } from "@chakra-ui/react"
function Tab() {
return (
<Tabs.Root defaultValue="import" variant="plain">
<Tabs.List bg="bg.muted" rounded="l3" p="1">
<Tabs.Trigger value="import" className="px-6">
Our Own Mnemonic
</Tabs.Trigger>
<Tabs.Trigger value="new" className="px-6">
New Wallet
</Tabs.Trigger>
<Tabs.Indicator rounded="l2" />
</Tabs.List>
<Tabs.Content value="import"><Import/></Tabs.Content>
<Tabs.Content value="new"><New/></Tabs.Content>
</Tabs.Root>
)
}

export default Tab
2 changes: 1 addition & 1 deletion frontend/src/pages/LndState/LndState.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,7 @@ function LndState() {
case WalletState.WalletState_NON_EXISTING:
//TODO need create wallet
InitState()
console.log('need init')
navigate('/create')
break
case WalletState.WalletState_LOCKED:
setIsWalletUnlocked(false)
Expand Down
3 changes: 3 additions & 0 deletions frontend/src/pages/Main/Main.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ protocol.simple-taproot-chans=true`);
title: "Lnd Error",
description: "Node is not ready to run",
})
navigate('/create');
return;
}
try {
Expand All @@ -61,6 +62,7 @@ protocol.simple-taproot-chans=true`);
title: "Lnd Error",
description: String(error),
})
navigate('/create');
}
}

Expand All @@ -74,6 +76,7 @@ protocol.simple-taproot-chans=true`);
title: "Lnd Config Error",
description: String(error),
})
navigate('/create');
setIsReady(false)
}
}
Expand Down
Loading

0 comments on commit 4007c5f

Please sign in to comment.