This repository has been archived by the owner on Nov 5, 2023. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 46
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #253 from web3well/bw-230-send-eth
Send eth
- Loading branch information
Showing
17 changed files
with
522 additions
and
16 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
57 changes: 57 additions & 0 deletions
57
extension/source/Home/Wallet/Wallets/SendDetail/AmountSelector.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,57 @@ | ||
import { ethers } from 'ethers'; | ||
import { FunctionComponent, useMemo } from 'react'; | ||
import Display from '../../../../cells/components/Display'; | ||
|
||
import TextBox from '../../../../cells/components/TextBox'; | ||
import { IReadableCell } from '../../../../cells/ICell'; | ||
import MemoryCell from '../../../../cells/MemoryCell'; | ||
import TransformCell from '../../../../cells/TransformCell'; | ||
import Button from '../../../../components/Button'; | ||
|
||
const AmountSelector: FunctionComponent<{ | ||
selectedAsset: IReadableCell<string | undefined>; | ||
onSend: (amountWei: string) => void; | ||
}> = ({ selectedAsset, onSend }) => { | ||
const amount = useMemo(() => new MemoryCell(''), []); | ||
|
||
const amountValid = useMemo( | ||
() => | ||
new TransformCell( | ||
amount, | ||
($amount) => $amount || '0', | ||
($amount, $newAmount) => | ||
Number.isFinite(Number($newAmount)) ? $newAmount : $amount, | ||
), | ||
[amount], | ||
); | ||
|
||
return ( | ||
<div className="flex flex-col gap-4"> | ||
<div className="text-body">Select Amount</div> | ||
<div className="flex justify-end gap-2"> | ||
<TextBox | ||
value={amountValid} | ||
className="text-right" | ||
style={{ maxWidth: '10rem' }} | ||
/> | ||
<div className="self-center"> | ||
<Display cell={selectedAsset} /> | ||
</div> | ||
</div> | ||
<div className="flex justify-end"> | ||
<Button | ||
className="btn-primary" | ||
onPress={async () => | ||
onSend( | ||
ethers.utils.parseEther(await amountValid.read()).toHexString(), | ||
) | ||
} | ||
> | ||
Send | ||
</Button> | ||
</div> | ||
</div> | ||
); | ||
}; | ||
|
||
export default AmountSelector; |
41 changes: 41 additions & 0 deletions
41
extension/source/Home/Wallet/Wallets/SendDetail/AssetSelector.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
import { ArrowRight } from 'phosphor-react'; | ||
import { FunctionComponent } from 'react'; | ||
import ICell from '../../../../cells/ICell'; | ||
|
||
import useCell from '../../../../cells/useCell'; | ||
import Loading from '../../../../components/Loading'; | ||
import onAction from '../../../../helpers/onAction'; | ||
import { useQuill } from '../../../QuillContext'; | ||
import Balance from '../Balance'; | ||
|
||
const AssetSelector: FunctionComponent<{ | ||
selectedAsset: ICell<string | undefined>; | ||
}> = ({ selectedAsset }) => { | ||
const quill = useQuill(); | ||
const selectedAddress = useCell(quill.cells.selectedAddress); | ||
|
||
return ( | ||
<div className="flex flex-col gap-4"> | ||
<div className="text-body">Select Asset</div> | ||
<div className="grid grid-cols-2 gap-4"> | ||
<div | ||
className={[ | ||
'flex flex-row p-4 gap-4 rounded-lg bg-white border', | ||
'border-grey-400 shadow-md cursor-pointer active:bg-grey-200', | ||
'select-none cursor-pointer', | ||
].join(' ')} | ||
{...onAction(() => selectedAsset.write('ETH'))} | ||
> | ||
<div className="grow">{/* TODO: icon */}Ether</div> | ||
<div> | ||
{selectedAddress && <Balance address={selectedAddress} />} | ||
{!selectedAddress && <Loading />} | ||
</div> | ||
<ArrowRight className="self-center" size={20} /> | ||
</div> | ||
</div> | ||
</div> | ||
); | ||
}; | ||
|
||
export default AssetSelector; |
74 changes: 74 additions & 0 deletions
74
extension/source/Home/Wallet/Wallets/SendDetail/BigSendButton.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,74 @@ | ||
import { CaretLeft, X } from 'phosphor-react'; | ||
import { FunctionComponent } from 'react'; | ||
import { useNavigate } from 'react-router-dom'; | ||
|
||
import useCell from '../../../../cells/useCell'; | ||
import formatCompactAddress from '../../../../helpers/formatCompactAddress'; | ||
import onAction from '../../../../helpers/onAction'; | ||
import type { SendDetailCells } from './SendDetail'; | ||
|
||
const roundFieldClasses = [ | ||
'text-[8pt] bg-blue-100 bg-opacity-40 leading-normal', | ||
'rounded-full px-2 py-1 flex place-items-center gap-2', | ||
].join(' '); | ||
|
||
const BigSendButton: FunctionComponent<{ | ||
cells: SendDetailCells; | ||
}> = ({ cells }) => { | ||
const navigate = useNavigate(); | ||
|
||
const selectedAsset = useCell(cells.selectedAsset); | ||
const recipient = useCell(cells.recipient); | ||
const amountWei = useCell(cells.amountWei); | ||
|
||
const visibility = amountWei === undefined ? '' : 'invisible'; | ||
|
||
return ( | ||
<div className="btn-primary-outer justify-center grow leading-10"> | ||
<div className="flex grow justify-center"> | ||
<div | ||
className={`${visibility} btn-primary-inner flex flex-row gap-2`} | ||
{...onAction(async () => { | ||
if (recipient !== undefined) { | ||
await cells.recipient.write(undefined); | ||
} else if (selectedAsset !== undefined) { | ||
await cells.selectedAsset.write(undefined); | ||
} else { | ||
navigate('/wallets'); | ||
} | ||
})} | ||
> | ||
<CaretLeft className="self-center" size={20} /> | ||
<div>Back</div> | ||
</div> | ||
<div className="flex grow justify-center py-2 gap-2"> | ||
<div>Send</div> | ||
{selectedAsset !== undefined && ( | ||
<div className="flex flex-col justify-center"> | ||
<div className={roundFieldClasses}>{selectedAsset}</div> | ||
</div> | ||
)} | ||
{recipient !== undefined && ( | ||
<> | ||
<div>to</div> | ||
<div className="flex flex-col justify-center"> | ||
<div className={roundFieldClasses}> | ||
{formatCompactAddress(recipient)} | ||
</div> | ||
</div> | ||
</> | ||
)} | ||
</div> | ||
<div | ||
className={`${visibility} btn-primary-inner flex flex-row gap-2`} | ||
{...onAction(() => navigate('/wallets'))} | ||
> | ||
<div>Cancel</div> | ||
<X className="self-center" size={20} /> | ||
</div> | ||
</div> | ||
</div> | ||
); | ||
}; | ||
|
||
export default BigSendButton; |
88 changes: 88 additions & 0 deletions
88
extension/source/Home/Wallet/Wallets/SendDetail/RecipientSelector.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,88 @@ | ||
import { ethers } from 'ethers'; | ||
import { ArrowRight } from 'phosphor-react'; | ||
import { FunctionComponent, useMemo } from 'react'; | ||
import Blockies from 'react-blockies'; | ||
import TextBox from '../../../../cells/components/TextBox'; | ||
|
||
import ICell from '../../../../cells/ICell'; | ||
import MemoryCell from '../../../../cells/MemoryCell'; | ||
import useCell from '../../../../cells/useCell'; | ||
import Loading from '../../../../components/Loading'; | ||
import onAction from '../../../../helpers/onAction'; | ||
import { useQuill } from '../../../QuillContext'; | ||
import Balance from '../Balance'; | ||
|
||
const RecipientSelector: FunctionComponent<{ | ||
recipient: ICell<string | undefined>; | ||
}> = ({ recipient }) => { | ||
const quill = useQuill(); | ||
const selectedAddress = useCell(quill.cells.selectedAddress); | ||
const keyring = useCell(quill.cells.keyring); | ||
|
||
const searchText = useMemo(() => new MemoryCell(''), []); | ||
const searchTextValue = useCell(searchText); | ||
|
||
const searchTextLowercase = (searchTextValue ?? '').toLowerCase(); | ||
|
||
const recipients = (() => { | ||
if (searchTextValue && ethers.utils.isAddress(searchTextValue)) { | ||
return [{ address: searchTextValue, name: 'Custom Recipient' }]; | ||
} | ||
|
||
return (keyring?.wallets ?? []) | ||
.map((wallet, i) => ({ | ||
address: wallet.address, | ||
name: `Wallet ${i}`, | ||
})) | ||
.filter((r) => r.address !== selectedAddress) | ||
.filter( | ||
(r) => | ||
r.address.toLowerCase().includes(searchTextLowercase) || | ||
r.name.toLowerCase().includes(searchTextLowercase), | ||
); | ||
})(); | ||
|
||
return ( | ||
<div className="flex flex-col gap-4"> | ||
<div className="text-body">Select Recipient</div> | ||
<div> | ||
<TextBox value={searchText} placeholder="Search" /> | ||
</div> | ||
{recipients.length === 0 && 'No recipients found'} | ||
<div className="grid grid-cols-2 gap-4"> | ||
{recipients.map((r) => { | ||
if (r === undefined) { | ||
return <div />; | ||
} | ||
|
||
return ( | ||
<div | ||
key={`${r.name}:${r.address}`} | ||
className={[ | ||
'flex flex-row p-4 gap-4 rounded-lg bg-white border', | ||
'border-grey-400 shadow-md cursor-pointer active:bg-grey-200', | ||
'select-none cursor-pointer', | ||
].join(' ')} | ||
{...onAction(() => recipient.write(r.address))} | ||
> | ||
<Blockies | ||
seed={r.address} | ||
className="rounded-md self-center" | ||
size={5} | ||
scale={8} | ||
/> | ||
<div className="grow self-center">{r.name}</div> | ||
<div className="self-center"> | ||
{selectedAddress && <Balance address={r.address} />} | ||
{!selectedAddress && <Loading />} | ||
</div> | ||
<ArrowRight className="self-center" size={20} /> | ||
</div> | ||
); | ||
})} | ||
</div> | ||
</div> | ||
); | ||
}; | ||
|
||
export default RecipientSelector; |
Oops, something went wrong.