Skip to content
This repository has been archived by the owner on Oct 13, 2023. It is now read-only.

Commit

Permalink
Merge branch 'dev'
Browse files Browse the repository at this point in the history
  • Loading branch information
Vadim committed Aug 31, 2023
2 parents 58e6f15 + af7fdc7 commit 632df26
Show file tree
Hide file tree
Showing 22 changed files with 1,778 additions and 8,469 deletions.
9,503 changes: 1,357 additions & 8,146 deletions package-lock.json

Large diffs are not rendered by default.

6 changes: 3 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,9 @@
"deploy": "firebase deploy --only hosting"
},
"dependencies": {
"@buf/penumbra-zone_penumbra.bufbuild_connect-es": "^0.12.0-20230726203749-d487f27cf321.1",
"@buf/penumbra-zone_penumbra.bufbuild_connect-web": "^0.8.6-20230726203749-d487f27cf321.1",
"@buf/penumbra-zone_penumbra.bufbuild_es": "^1.3.0-20230726203749-d487f27cf321.1",
"@buf/penumbra-zone_penumbra.bufbuild_connect-es": "^0.13.0-20230821182814-ef47afe3dc33.1",
"@buf/penumbra-zone_penumbra.bufbuild_connect-web": "^0.8.6-20230821182814-ef47afe3dc33.1",
"@buf/penumbra-zone_penumbra.bufbuild_es": "^1.3.0-20230821182814-ef47afe3dc33.1",
"@bufbuild/connect-web": "^0.8.6",
"@microlink/react-json-view": "^1.22.2",
"autoprefixer": "10.4.14",
Expand Down
205 changes: 104 additions & 101 deletions src/app/send/page.tsx
Original file line number Diff line number Diff line change
@@ -1,41 +1,43 @@
'use client'

import { TransactionPlannerRequest } from '@buf/penumbra-zone_penumbra.bufbuild_es/penumbra/view/v1alpha1/view_pb'
import { useEffect, useMemo, useState } from 'react'
import { createPromiseClient } from '@bufbuild/connect'
import { ViewProtocolService } from '@buf/penumbra-zone_penumbra.bufbuild_connect-es/penumbra/view/v1alpha1/view_connect'
import { useRouter } from 'next/navigation'
import { bech32m } from 'bech32'
import {
Button,
ChevronLeftIcon,
Input,
SearchSvg,
Select,
Toogle,
} from '@/components'
import { useAuth, useBalance } from '@/context'
import { useTransactionValues } from '@/hooks'
import { createViewServiceClient, routesPath } from '@/lib'
import { Address } from '@buf/penumbra-zone_penumbra.bufbuild_es/penumbra/core/crypto/v1alpha1/crypto_pb'
import {
AddressValidatorsType,
routesPath,
setOnlyNumberInput,
validateAddress,
extensionTransport,
} from '@/lib'
import { Button, ChevronLeftIcon, Input, SearchSvg, Select } from '@/components'
AddressByIndexRequest,
EphemeralAddressRequest,
TransactionPlannerRequest,
} from '@buf/penumbra-zone_penumbra.bufbuild_es/penumbra/view/v1alpha1/view_pb'
import { bech32m } from 'bech32'
import { useRouter } from 'next/navigation'
import { useEffect, useMemo } from 'react'

export default function Send() {
const { balance } = useBalance()
const auth = useAuth()
const { push } = useRouter()

const [reciever, setReciever] = useState<string>('')
const [amount, setAmount] = useState<string>('')
const [memo, setMemo] = useState<string>('')
const [select, setSelect] = useState<string>('')
const [isValidate, setIsValidate] = useState<AddressValidatorsType>(
{} as AddressValidatorsType
)
const {
values,
isValidate,
handleChangeSelect,
handleChangeInput,
handleMax,
clearState,
handleCheck,
} = useTransactionValues()

useEffect(() => {
if (!auth.walletAddress) {
setAmount('')
setReciever('')
setSelect('')
setIsValidate({} as AddressValidatorsType)
}
if (!auth.walletAddress) clearState()
}, [auth.walletAddress])

const options = useMemo(() => {
Expand All @@ -62,80 +64,78 @@ export default function Send() {
})
}, [balance])

const handleChangeSearch = (event: React.ChangeEvent<HTMLInputElement>) => {
setReciever(event.target.value)
const validators = validateAddress(event.target.value)
setIsValidate(state => ({
...state,
...validators,
}))
if (!event.target.value) setIsValidate({} as AddressValidatorsType)
}
const handleBack = () => push(routesPath.HOME)

const handleChangeSelect = (value: string) => setSelect(value)
const sendTransaction = async () => {
try {
const asset = balance.find(i => i.display === values.asset1)

const handleChangeAmout = (event: React.ChangeEvent<HTMLInputElement>) => {
const { value, notShow, valueFloat } = setOnlyNumberInput(
event.target.value
)
if (isNaN(valueFloat) || notShow) return
setAmount(value)
}
if (!asset || !values.reciever || !values.amount) return

const handleChangeMemo = (event: React.ChangeEvent<HTMLInputElement>) =>
setMemo(event.target.value)
const assetExponent = asset.exponent

const handleMax = () =>
setAmount(
String(
Number(select ? balance.find(i => i.display === select)?.amount : 0)
)
)
const client = createViewServiceClient()

const getTransactionPlan = async () => {
try {
const selectedAsset = balance.find(i => i.display === select)?.assetId
?.inner!
let address: Address | undefined

const addressIndex = {
account: 0,
}

const client = createPromiseClient(
ViewProtocolService,
extensionTransport(ViewProtocolService)
)
if (!values.hideAddress) {
const request = new AddressByIndexRequest({
addressIndex,
})
const addressByIndex = await client.addressByIndex(request)
address = addressByIndex.address
} else {
const request = new EphemeralAddressRequest({
addressIndex,
})

const ephemeralAddress = await client.ephemeralAddress(request)
address = ephemeralAddress.address
}

if (!address) return

const value = {
amount: {
lo: BigInt(
Number(values.amount) * (assetExponent ? 10 ** assetExponent : 1)
),
hi: BigInt(0),
},
assetId: { inner: asset.assetId?.inner },
}

const receiverAddress = {
altBech32m: values.reciever!,
inner: new Uint8Array(bech32m.decode(values.reciever!, 160).words),
}

const memo = {
text: values.memo,
sender: {
altBech32m: address?.altBech32m,
},
}

const transactionPlan = (
await client.transactionPlanner(
new TransactionPlannerRequest({
memo,
outputs: [
{
value: {
amount: {
lo: BigInt(
Number(amount) *
(balance.find(i => i.display === select)?.exponent!
? 10 **
balance.find(i => i.display === select)?.exponent!
: 1)
),
hi: BigInt(0),
},
assetId: { inner: selectedAsset },
},
address: {
inner: new Uint8Array(bech32m.decode(reciever, 160).words),
altBech32m: reciever,
},
value,
address: receiverAddress,
},
],
})
)
).plan

console.log(transactionPlan?.actions[0].action.value?.getType().typeName)
).plan!

const tx = await window.penumbra.signTransaction(
transactionPlan?.toJson()
)
const tx = await window.penumbra.signTransaction(transactionPlan.toJson())

if (tx.result.code === 0) {
push(`${routesPath.HOME}?tab=Activity`)
Expand All @@ -147,8 +147,6 @@ export default function Send() {
}
}

const handleBack = () => push(routesPath.HOME)

return (
<>
{auth!.walletAddress ? (
Expand All @@ -164,9 +162,9 @@ export default function Send() {
<p className='h1 mt-[24px]'>Send to address</p>
<Input
placeholder='Search address...'
value={reciever}
value={values.reciever}
isError={Object.values(isValidate).includes(false)}
onChange={handleChangeSearch}
onChange={handleChangeInput('reciever')}
leftSvg={
<span className='ml-[24px] mr-[9px]'>
<SearchSvg stroke='#E0E0E0' />
Expand All @@ -181,21 +179,21 @@ export default function Send() {
labelClassName='h3 mb-[8px]'
label='Assets :'
options={options}
handleChange={handleChangeSelect}
initialValue={select}
handleChange={handleChangeSelect('asset1')}
initialValue={values.asset1}
className='mb-[24px]'
/>
<Input
labelClassName='h3 text-light_grey mb-[8px]'
label='Total :'
value={amount}
value={values.amount}
isError={
select
? balance.find(i => select === i.display)!.amount <
Number(amount)
values.asset1
? balance.find(i => values.asset1 === i.display)!.amount <
Number(values.amount)
: false
}
onChange={handleChangeAmout}
onChange={handleChangeInput('amount')}
helperText={'You do not have enough token'}
rightElement={
<div
Expand All @@ -209,10 +207,15 @@ export default function Send() {
<Input
labelClassName='h3 text-light_grey mb-[8px]'
label='Memo :'
value={memo}
onChange={handleChangeMemo}
value={values.memo}
onChange={handleChangeInput('memo')}
className='mb-[24px]'
/>
<Toogle
checked={Boolean(values.hideAddress)}
label='Hide Sender from Recipient'
onChange={handleCheck}
/>
</div>
<div className='w-[100%] flex items-center gap-x-[8px] mt-[24px]'>
<Button
Expand All @@ -223,15 +226,15 @@ export default function Send() {
/>
<Button
mode='gradient'
onClick={getTransactionPlan}
onClick={sendTransaction}
title='Send'
className='h-[44px]'
disabled={
!Number(amount) ||
!select ||
balance.find(i => select === i.display)!.amount <
Number(amount) ||
!reciever ||
!Number(values.amount) ||
!values.asset1 ||
balance.find(i => values.asset1 === i.display)!.amount <
Number(values.amount) ||
!values.reciever ||
Object.values(isValidate).includes(false)
}
/>
Expand Down
Loading

0 comments on commit 632df26

Please sign in to comment.