Skip to content

Commit

Permalink
Merge pull request #55 from ChainSafe/lykhoyda/transfer-balance
Browse files Browse the repository at this point in the history
Lykhoyda/transfer balance
  • Loading branch information
Lykhoyda authored Jan 8, 2025
2 parents e569ff1 + 4b9f3fa commit 9ec987d
Show file tree
Hide file tree
Showing 44 changed files with 963 additions and 151 deletions.
2 changes: 2 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,8 @@ byte-unit = { version = "5.1.4", features = ["byte"] }

[patch.crates-io]

[workspace.lints.rust]
unexpected_cfgs = { level = "warn", check-cfg = ['cfg(wasm_bindgen)', 'cfg(wasm_bindgen_unstable_test_coverage)'] }

#[patch.'https://github.com/chainsafe/librustzcash']
#zcash_address = { path = "../librustzcash/components/zcash_address" }
Expand Down
3 changes: 3 additions & 0 deletions crates/webz-common/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -14,3 +14,6 @@ zcash_address.workspace = true
thiserror.workspace = true
wasm-bindgen.workspace = true
js-sys.workspace = true

[lints]
workspace = true
3 changes: 3 additions & 0 deletions crates/webz-keys/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -25,3 +25,6 @@ bip0039.workspace = true

# fixes "failed to resolve: use of undeclared crate or module `imp`" error
getrandom = { version = "0.2", features = ["js"] }

[lints]
workspace = true
3 changes: 3 additions & 0 deletions crates/webz-requests/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -25,3 +25,6 @@ serde-wasm-bindgen.workspace = true

# fixes "failed to resolve: use of undeclared crate or module `imp`" error
getrandom = { version = "0.2", features = ["js"] }

[lints]
workspace = true
5 changes: 4 additions & 1 deletion crates/webz-wallet/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -86,4 +86,7 @@ wasm_sync = "0.1.2"
http = { version = "1.1.0", default-features = false }
serde.workspace = true
postcard = { version = "1.0.10", features = ["alloc"] }
serde-wasm-bindgen.workspace = true
serde-wasm-bindgen.workspace = true

[lints]
workspace = true
1 change: 0 additions & 1 deletion crates/webz-wallet/src/wallet.rs
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,6 @@ const BATCH_SIZE: u32 = 10000;
///
/// TODO
///
pub struct Wallet<W, T> {
/// Internal database used to maintain wallet data (e.g. accounts, transactions, cached blocks)
pub(crate) db: Arc<RwLock<W>>,
Expand Down
5 changes: 4 additions & 1 deletion justfile
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,10 @@ example-message-board *features:
alias c := check

check:
cargo check
cargo check

lint:
cargo clippy

alias cw := check-wasm

Expand Down
2 changes: 1 addition & 1 deletion packages/snap/snap.manifest.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
"url": "https://github.com/MetaMask/template-snap-monorepo.git"
},
"source": {
"shasum": "I0Yfshe6Y+9LqO6LuUhPC0gUMpbHmm6yzzVLPI86hps=",
"shasum": "f+uCIgeC4d6/etrDizge6IA/ySlD1CVlBqtl3ZCOpgA=",
"location": {
"npm": {
"filePath": "dist/bundle.js",
Expand Down
14 changes: 12 additions & 2 deletions packages/web-wallet/src/App.tsx
Original file line number Diff line number Diff line change
@@ -1,13 +1,23 @@
import { useInterval } from 'usehooks-ts';
import { useWebZjsActions } from '@hooks/useWebzjsActions.ts';
import Layout from '@components/Layout/Layout.tsx';
import { Outlet } from 'react-router-dom';
import { Outlet, useLocation } from 'react-router-dom';
import { RESCAN_INTERVAL } from './config/constants.ts';
import { useEffect } from 'react';

function App() {
const { triggerRescan } = useWebZjsActions();
const location = useLocation();

useEffect(() => {
// Add custom background to home page
if (location.pathname === '/') {
document.body.classList.add('home-page', 'home-page-bg');
} else {
document.body.classList.remove('home-page', 'home-page-bg');
}
}, [location.pathname]);

// rescan the wallet periodically
useInterval(() => {
triggerRescan();
}, RESCAN_INTERVAL);
Expand Down
Binary file added packages/web-wallet/src/assets/diamond-bg.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
3 changes: 3 additions & 0 deletions packages/web-wallet/src/assets/icons/check.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
3 changes: 3 additions & 0 deletions packages/web-wallet/src/assets/icons/chevron.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
3 changes: 3 additions & 0 deletions packages/web-wallet/src/assets/icons/warning.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
32 changes: 19 additions & 13 deletions packages/web-wallet/src/assets/index.ts
Original file line number Diff line number Diff line change
@@ -1,18 +1,21 @@
import ChainsafeSvg from './chainsafe.svg';
import FormTransferSvg from './form-transfer.svg';
import MetaMaskLogoSvg from './metaMask-logo.svg';
import MetaMaskSnapsLogoSvg from './metamask-snaps-logo.svg';
import ZcashSvg from './zcash.svg';
import ZcashYellowSvg from './zcash-yellow.svg';
import { ReactComponent as ChainsafeSvg } from './chainsafe.svg';
import { ReactComponent as FormTransferSvg } from './form-transfer.svg';
import { ReactComponent as MetaMaskLogoSvg } from './metaMask-logo.svg';
import { ReactComponent as MetaMaskSnapsLogoSvg } from './metamask-snaps-logo.svg';
import { ReactComponent as ZcashSvg } from './zcash.svg';
import { ReactComponent as ZcashYellowSvg } from './zcash-yellow.svg';

// Icons
import ArrowReceiveSvg from './icons/arrow-receive.svg';
import ArrowTransferSvg from './icons/arrow-transfer.svg';
import ClockSvg from './icons/clock.svg';
import ShieldSvg from './icons/shield.svg';
import ShieldDividedSvg from './icons/shield-divided.svg';
import SummarySvg from './icons/summary.svg';
import CoinsSvg from './icons/coins.svg';
import { ReactComponent as ArrowReceiveSvg } from './icons/arrow-receive.svg';
import { ReactComponent as ArrowTransferSvg } from './icons/arrow-transfer.svg';
import { ReactComponent as ClockSvg } from './icons/clock.svg';
import { ReactComponent as ShieldSvg } from './icons/shield.svg';
import { ReactComponent as ShieldDividedSvg } from './icons/shield-divided.svg';
import { ReactComponent as SummarySvg } from './icons/summary.svg';
import { ReactComponent as CoinsSvg } from './icons/coins.svg';
import { ReactComponent as ChevronSVG } from './icons/chevron.svg';
import { ReactComponent as CheckSVG } from './icons/check.svg';
import { ReactComponent as WarningSVG } from './icons/warning.svg';

export {
ChainsafeSvg,
Expand All @@ -28,4 +31,7 @@ export {
ShieldDividedSvg,
SummarySvg,
CoinsSvg,
ChevronSVG,
CheckSVG,
WarningSVG,
};
40 changes: 40 additions & 0 deletions packages/web-wallet/src/components/Button/Button.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
import React from 'react';
type ButtonVariant = 'primary' | 'secondary';

interface ButtonProps {
onClick: () => void;
label: string;
classNames?: string;
variant?: ButtonVariant;
icon?: React.ReactNode;
}

function Button({
onClick,
label,
classNames = '',
variant = 'primary',
icon,
}: ButtonProps) {
const baseClasses =
'min-w-[228px] px-6 py-3 rounded-3xl text-base font-medium leading-normal cursor-pointer transition-all hover:transition-all';

const variantClasses =
variant === 'primary'
? 'bg-[#0e0e0e] text-white border hover:bg-buttonBlackGradientHover'
: 'bg-transparent text-black hover:bg-[#fff7e6] border hover:border-[#ffa940]';

return (
<button
onClick={onClick}
className={`${baseClasses} ${variantClasses} ${classNames}`}
>
<div className="flex items-center justify-center">
{icon && <span className="mr-2 flex items-center">{icon}</span>}
<span>{label}</span>
</div>
</button>
);
}

export default Button;
11 changes: 11 additions & 0 deletions packages/web-wallet/src/components/ErrorMessage/ErrorMessage.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import React from 'react';

interface ErrorMessageProps {
text?: string;
}

function ErrorMessage({ text }: ErrorMessageProps): React.JSX.Element {
return <>{text && <span className="text-sm text-red-500">{text}</span>}</>;
}

export default ErrorMessage;
76 changes: 48 additions & 28 deletions packages/web-wallet/src/components/Header/Header.tsx
Original file line number Diff line number Diff line change
@@ -1,43 +1,63 @@
import React from 'react';
import { Link } from 'react-router-dom';
import { MetaMaskSnapsLogoSvg, ZcashSvg } from '../../assets';
import { Link, useLocation } from 'react-router-dom';
import { MetaMaskLogoSvg, MetaMaskSnapsLogoSvg, ZcashSvg } from '../../assets';
import Button from '@components/Button/Button';

const Header = (): React.JSX.Element => {
const location = useLocation();
const isHomePage = location.pathname === '/';

return (
<header className="font-inter w-full px-16 flex items-center justify-between bg-transparent py-3 max-h-[3.125rem]">
<header className="font-inter h-16 fixed top-0 left-0 w-full px-16 flex flex-grow items-center justify-between bg-transparent py-3 border-b border-neutral-200">
<Link to={'/'}>
<div className="flex items-center">
<div className="h-6 w-6 mr-3">
<ZcashSvg />
<ZcashSvg className="w-[25px] h-[25px]" />
</div>
<div className="h-6 w-full max-w-[200px]">
<MetaMaskSnapsLogoSvg />
{isHomePage ? (
<MetaMaskSnapsLogoSvg />
) : (
<MetaMaskLogoSvg className="w-[25px] h-[25px]" />
)}
</div>
</div>
</Link>
<nav className="flex">
<a
target="_blank"
href="https://chainsafe.github.io/WebZjs/"
className="px-6 relative after:content-['|'] after:absolute after:right-0 after:top-0 after:bottom-0 after:w-px after:bg-[divide-dividerColor] hover:underline"
>
ZCash Docs
</a>
<a
target="_blank"
href="https://docs.metamask.io/snaps/"
className="px-6 hover:underline"
>
Snap Docs
</a>
<a
target="_blank"
href="https://snaps.metamask.io/"
className="hover:underline"
>
Snap Registry
</a>
</nav>
{isHomePage ? (
<nav className="flex">
<a
target="_blank"
href="https://chainsafe.github.io/WebZjs/"
className="px-6 relative after:content-['|'] after:absolute after:right-0 after:top-0 after:bottom-0 after:w-px after:bg-[divide-dividerColor] hover:underline"
>
ZCash Docs
</a>
<a
target="_blank"
href="https://docs.metamask.io/snaps/"
className="px-6 hover:underline"
>
Snap Docs
</a>
<a
target="_blank"
href="https://snaps.metamask.io/"
className="hover:underline"
>
Snap Registry
</a>
</nav>
) : (
<Button
variant={'secondary'}
classNames={'min-w-max '}
onClick={() => {
// TODO: Clarify sign out functionality
console.log('Sign out');
}}
label={'Sign out'}
/>
)}
</header>
);
};
Expand Down
53 changes: 53 additions & 0 deletions packages/web-wallet/src/components/Input/Input.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
import React from 'react';
import ErrorMessage from '@components/ErrorMessage/ErrorMessage';

interface InputProps extends React.InputHTMLAttributes<HTMLInputElement> {
label?: string;
error?: string;
containerClassName?: string;
labelClassName?: string;
inputClassName?: string;
suffix?: string;
id: string;
}

const Input: React.FC<InputProps> = ({
label,
error,
containerClassName = '',
labelClassName = '',
inputClassName = '',
suffix = '',
id,
...props
}) => {
return (
<div className={`flex flex-col gap-1 w-full ${containerClassName}`}>
{label && (
<label
htmlFor={id}
className={`text-black text-base font-normal leading-normal ${labelClassName}`}
>
{label}
</label>
)}
<div className="h-full flex items-center bg-neutral-50 rounded-xl border border-[#afafaf] p-3">
<input
{...props}
id={id}
className={`flex-grow bg-transparent focus:outline-none text-[#0e0e0e] text-base font-semibold font-inter ${inputClassName}`}
aria-describedby={`${id}-suffix`}
/>
<span
id={`${id}-suffix`}
className="ml-2 text-[#a9aaab] text-base font-medium leading-normal"
>
{suffix}
</span>
</div>
<ErrorMessage text={error} />
</div>
);
};

export default Input;
10 changes: 5 additions & 5 deletions packages/web-wallet/src/components/Layout/Layout.tsx
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
import Header from '../Header/Header.tsx';
import { Outlet } from 'react-router-dom';
import React from 'react';
import Header from '../Header/Header.tsx';
import Footer from '../Footer/Footer.tsx';
import { Outlet } from 'react-router-dom';

const Layout = (): React.JSX.Element => {
const Layout = ({ children }: React.PropsWithChildren): React.JSX.Element => {
return (
<div className="container mx-auto flex flex-col min-h-screen">
<Header />
<main className="flex-grow flex justify-center py-3 self-stretch w-full">
<Outlet />
<main className="flex-grow flex justify-center py-3 self-stretch mt-16 w-full">
{children ? children : <Outlet />}
</main>
<Footer />
</div>
Expand Down
Loading

1 comment on commit 9ec987d

@github-actions
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please sign in to comment.