Skip to content

Commit

Permalink
untested
Browse files Browse the repository at this point in the history
  • Loading branch information
bryzettler committed Aug 16, 2023
1 parent b0da934 commit 3604692
Show file tree
Hide file tree
Showing 7 changed files with 187 additions and 32 deletions.
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,7 @@
"@rnmapbox/maps": "^10.0.7-rc.0",
"@shopify/restyle": "1.8.0",
"@solana/spl-account-compression": "0.1.4",
"@solana/spl-memo": "^0.2.3",
"@solana/spl-token": "0.3.6",
"@solana/spl-token-registry": "^0.2.4574",
"@solana/wallet-adapter-react": "^0.15.33",
Expand Down
89 changes: 89 additions & 0 deletions src/components/MemoInput.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
import { BoxProps } from '@shopify/restyle'
import React, { memo, useMemo } from 'react'
import { useTranslation } from 'react-i18next'
import { Theme } from '@theme/theme'
import Box from './Box'
import Text from './Text'
import TextInput from './TextInput'

export const DEFAULT_MEMO = 'AAAAAAAAAAA='
export const MEMO_MAX_BYTES = 8
export const encodeMemoString = (utf8Input: string | undefined) => {
if (!utf8Input) return undefined
const buff = Buffer.from(utf8Input, 'utf8')
return buff.toString('base64')
}

export const decodeMemoString = (base64String: string | undefined | null) => {
if (!base64String) return ''
const buff = Buffer.from(base64String, 'base64')
return buff.toString('utf8')
}

export const getMemoBytesLeft = (base64Memo?: string) => {
if (!base64Memo)
return { numBytes: MEMO_MAX_BYTES, valid: true, bytesUsed: 0 }
const buff = Buffer.from(base64Memo, 'base64')
const size = buff.byteLength
return {
bytesRemaining: MEMO_MAX_BYTES - size,
valid: size <= MEMO_MAX_BYTES,
bytesUsed: size,
}
}

export const getMemoStrValid = (memoStr?: string) => {
const base64Memo = encodeMemoString(memoStr)
if (!base64Memo) {
return true
}
const buff = Buffer.from(base64Memo, 'base64')
const size = buff.byteLength
return size <= MEMO_MAX_BYTES
}

export const useMemoValid = (txnMemo?: string) => {
return useMemo(() => {
const base64Memo = encodeMemoString(txnMemo)
return getMemoBytesLeft(base64Memo)
}, [txnMemo])
}

type Props = {
onChangeText?: ((text: string) => void) | undefined
value?: string | undefined
} & BoxProps<Theme>
const MemoInput = ({ onChangeText, value, ...boxProps }: Props) => {
const { t } = useTranslation()
const { bytesUsed, valid } = useMemoValid(value)

return (
<Box
justifyContent="center"
flexDirection="row"
alignItems="center"
{...boxProps}
>
<TextInput
flex={1}
variant="transparent"
textInputProps={{
placeholder: t('payment.enterMemo'),
onChangeText,
value,
editable: !!onChangeText,
returnKeyType: 'done',
}}
/>
<Box position="absolute" top={0} right={0}>
<Text variant="body3" color={valid ? 'white' : 'error'} marginRight="m">
{t('payment.memoBytes', {
used: bytesUsed,
total: MEMO_MAX_BYTES,
})}
</Text>
</Box>
</Box>
)
}
export default memo(MemoInput)
42 changes: 25 additions & 17 deletions src/features/burn/BurnScreen.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,7 @@ const BurnScreen = () => {
(reduxState: RootState) => reduxState.solana.delegate,
)
const [mint, setMint] = useState<PublicKey>(MOBILE_MINT)
const [memo, setMemo] = useState<string>('')
const { symbol } = useMetaplexMetadata(mint)
const tokenSelectorRef = useRef<TokenSelectorRef>(null)

Expand Down Expand Up @@ -180,6 +181,7 @@ const BurnScreen = () => {
delegateAddress,
amountBalance.toNumber(),
mint,
memo,
)
}
} catch (e) {
Expand All @@ -190,6 +192,7 @@ const BurnScreen = () => {
delegateAddress,
isDelegate,
mint,
memo,
submitDelegateDataCredits,
setSubmitError,
])
Expand Down Expand Up @@ -381,23 +384,28 @@ const BurnScreen = () => {
/>

{isDelegate ? (
<PaymentItem
index={0}
onAddressBookSelected={handleAddressBookSelected}
onEditAmount={onTokenItemPressed}
onEditAddress={({ address }) => {
setDelegateAddress(address)
handleAddressError({
address,
})
}}
handleAddressError={handleAddressError}
mint={DC_MINT}
address={delegateAddress}
amount={amountBalance}
hasError={hasError}
hideMemo
/>
<Box>
<PaymentItem
index={0}
onAddressBookSelected={handleAddressBookSelected}
onEditAmount={onTokenItemPressed}
onEditMemo={({ memo: m }) => {
setMemo(m)
}}
onEditAddress={({ address }) => {
setDelegateAddress(address)
handleAddressError({
address,
})
}}
handleAddressError={handleAddressError}
mint={DC_MINT}
address={delegateAddress}
amount={amountBalance}
memo={memo}
hasError={hasError}
/>
</Box>
) : (
<>
<AccountButton
Expand Down
34 changes: 32 additions & 2 deletions src/features/payment/PaymentItem.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import AccountIcon from '@components/AccountIcon'
import BackgroundFill from '@components/BackgroundFill'
import Box from '@components/Box'
import Text from '@components/Text'
import MemoInput from '@components/MemoInput'
import TextInput from '@components/TextInput'
import TouchableOpacityBox from '@components/TouchableOpacityBox'
import Address from '@helium/address'
Expand All @@ -16,7 +17,12 @@ import { useColors, useOpacity } from '@theme/themeHooks'
import { humanReadable } from '@utils/solanaUtils'
import BN from 'bn.js'
import { toUpper } from 'lodash'
import React, { memo, useCallback, useEffect, useMemo } from 'react'
import React, {
memo as reactMemo,
useCallback,
useEffect,
useMemo,
} from 'react'
import { useTranslation } from 'react-i18next'
import {
Keyboard,
Expand All @@ -33,6 +39,7 @@ export type Payment = {
amount?: BN
hasError?: boolean
max?: boolean
memo?: string
createTokenAccountFee?: BN
} & BoxProps<Theme>

Expand All @@ -44,6 +51,7 @@ type Props = {
onEditAmount: (opts: { address?: string; index: number }) => void
onToggleMax?: (opts: { address?: string; index: number }) => void
onEditAddress: (opts: { index: number; address: string }) => void
onEditMemo?: (opts: { address?: string; index: number; memo: string }) => void
handleAddressError: (opts: {
index: number
address: string
Expand All @@ -66,12 +74,15 @@ const PaymentItem = ({
fee,
handleAddressError,
hasError,
hideMemo,
index,
max,
memo,
netType,
onAddressBookSelected,
onEditAddress,
onEditAmount,
onEditMemo,
onRemove,
onToggleMax,
onUpdateError,
Expand Down Expand Up @@ -127,6 +138,15 @@ const PaymentItem = ({
[index, onEditAddress],
)

const handleEditMemo = useCallback(
(text?: string) => {
if (!onEditMemo) return

onEditMemo({ memo: text || '', address, index })
},
[address, index, onEditMemo],
)

const handleAddressBlur = useCallback(
(event?: NativeSyntheticEvent<TextInputEndEditingEventData>) => {
const text = event?.nativeEvent.text
Expand Down Expand Up @@ -297,7 +317,17 @@ const PaymentItem = ({
</TouchableOpacityBox>
</Box>
)}

{!hideMemo && (
<>
<Box height={1} backgroundColor="primaryBackground" />

<Box justifyContent="center" minHeight={ITEM_HEIGHT}>
<MemoInput value={memo} onChangeText={handleEditMemo} />
</Box>
</>
)}
</Box>
)
}
export default memo(PaymentItem)
export default reactMemo(PaymentItem)
8 changes: 7 additions & 1 deletion src/hooks/useSubmitTxn.ts
Original file line number Diff line number Diff line change
Expand Up @@ -386,7 +386,12 @@ export default () => {
)

const submitDelegateDataCredits = useCallback(
async (delegateAddress: string, amount: number, mint: PublicKey) => {
async (
delegateAddress: string,
amount: number,
mint: PublicKey,
memo: string,
) => {
if (!currentAccount || !anchorProvider || !walletSignBottomSheetRef) {
throw new Error(t('errors.account'))
}
Expand All @@ -396,6 +401,7 @@ export default () => {
delegateAddress,
amount,
mint,
memo,
)

const serializedTx = delegateDCTxn.serialize({
Expand Down
38 changes: 26 additions & 12 deletions src/utils/solanaUtils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ import {
SPL_ACCOUNT_COMPRESSION_PROGRAM_ID,
SPL_NOOP_PROGRAM_ID,
} from '@solana/spl-account-compression'
import { createMemoInstruction } from '@solana/spl-memo'
import {
ASSOCIATED_TOKEN_PROGRAM_ID,
AccountLayout,
Expand Down Expand Up @@ -654,6 +655,7 @@ export const delegateDataCredits = async (
delegateAddress: string,
amount: number,
mint: PublicKey,
memo: string,
) => {
try {
const { connection } = anchorProvider
Expand All @@ -662,22 +664,34 @@ export const delegateDataCredits = async (
const program = await dc.init(anchorProvider)
const subDao = subDaoKey(mint)[0]

const tx = await program.methods
.delegateDataCreditsV0({
amount: new BN(amount, 0),
routerKey: delegateAddress,
})
.accounts({
subDao,
})
.transaction()
const instructions: TransactionInstruction[] = []

instructions.push(createMemoInstruction(memo, [payer]))

instructions.push(
await program.methods
.delegateDataCreditsV0({
amount: new BN(amount, 0),
routerKey: delegateAddress,
})
.accounts({
subDao,
})
.instruction(),
)

const { blockhash } = await connection.getLatestBlockhash()

tx.recentBlockhash = blockhash
tx.feePayer = payer
const transaction = new Transaction()

return tx
instructions.forEach((instruction) => {
transaction.add(instruction)
})

transaction.recentBlockhash = blockhash
transaction.feePayer = payer

return transaction
} catch (e) {
Logger.error(e)
throw e as Error
Expand Down
7 changes: 7 additions & 0 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -3813,6 +3813,13 @@
js-sha3 "^0.8.0"
typescript-collections "^1.3.3"

"@solana/spl-memo@^0.2.3":
version "0.2.3"
resolved "https://registry.yarnpkg.com/@solana/spl-memo/-/spl-memo-0.2.3.tgz#594a28c37b40c0e22143f38f71b4f56d1f5b24fd"
integrity sha512-CNsKSsl85ebuVoeGq1LDYi5M/PMs1Pxv2/UsyTgS6b30qrYqZOXha5ouZzgGKtJtZ3C3dxfOAEw6caJPN1N63w==
dependencies:
buffer "^6.0.3"

"@solana/spl-token-registry@^0.2.4574":
version "0.2.4574"
resolved "https://registry.yarnpkg.com/@solana/spl-token-registry/-/spl-token-registry-0.2.4574.tgz#13f4636b7bec90d2bb43bbbb83512cd90d2ce257"
Expand Down

0 comments on commit 3604692

Please sign in to comment.