Account Sequence UI.
This commit is contained in:
		
							
								
								
									
										71
									
								
								components/Sequence.tsx
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										71
									
								
								components/Sequence.tsx
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,71 @@
 | 
			
		||||
import { FC, useCallback, useState } from 'react'
 | 
			
		||||
import state from '../state'
 | 
			
		||||
import { Flex, Input, Button } from '.'
 | 
			
		||||
import fetchAccountInfo from '../utils/accountInfo'
 | 
			
		||||
import { useSnapshot } from 'valtio'
 | 
			
		||||
 | 
			
		||||
interface AccountSequenceProps {
 | 
			
		||||
  address?: string
 | 
			
		||||
}
 | 
			
		||||
const AccountSequence: FC<AccountSequenceProps> = ({ address }) => {
 | 
			
		||||
  const { accounts } = useSnapshot(state)
 | 
			
		||||
  const account = accounts.find(acc => acc.address === address)
 | 
			
		||||
  const [isLoading, setIsLoading] = useState(false)
 | 
			
		||||
  const setSequence = useCallback(
 | 
			
		||||
    (sequence: number) => {
 | 
			
		||||
      const acc = state.accounts.find(acc => acc.address == address)
 | 
			
		||||
      if (!acc) return
 | 
			
		||||
      acc.sequence = sequence
 | 
			
		||||
    },
 | 
			
		||||
    [address]
 | 
			
		||||
  )
 | 
			
		||||
  const handleUpdateSequence = useCallback(
 | 
			
		||||
    async (silent?: boolean) => {
 | 
			
		||||
      if (!account) return
 | 
			
		||||
      setIsLoading(true)
 | 
			
		||||
 | 
			
		||||
      const info = await fetchAccountInfo(account.address, { silent })
 | 
			
		||||
      if (info) {
 | 
			
		||||
        setSequence(info.Sequence)
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      setIsLoading(false)
 | 
			
		||||
    },
 | 
			
		||||
    [account, setSequence]
 | 
			
		||||
  )
 | 
			
		||||
  const disabled = !account
 | 
			
		||||
  return (
 | 
			
		||||
    <Flex row align="center" fluid>
 | 
			
		||||
      <Input
 | 
			
		||||
        placeholder="Account sequence"
 | 
			
		||||
        value={account?.sequence}
 | 
			
		||||
        disabled={!account}
 | 
			
		||||
        type="number"
 | 
			
		||||
        readOnly={true}
 | 
			
		||||
      />
 | 
			
		||||
      <Button
 | 
			
		||||
        size="xs"
 | 
			
		||||
        variant="primary"
 | 
			
		||||
        type="button"
 | 
			
		||||
        outline
 | 
			
		||||
        disabled={disabled}
 | 
			
		||||
        isDisabled={disabled}
 | 
			
		||||
        isLoading={isLoading}
 | 
			
		||||
        css={{
 | 
			
		||||
          background: '$backgroundAlt',
 | 
			
		||||
          position: 'absolute',
 | 
			
		||||
          right: '$2',
 | 
			
		||||
          fontSize: '$xs',
 | 
			
		||||
          cursor: 'pointer',
 | 
			
		||||
          alignContent: 'center',
 | 
			
		||||
          display: 'flex'
 | 
			
		||||
        }}
 | 
			
		||||
        onClick={() => handleUpdateSequence()}
 | 
			
		||||
      >
 | 
			
		||||
        Update
 | 
			
		||||
      </Button>
 | 
			
		||||
    </Flex>
 | 
			
		||||
  )
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export default AccountSequence
 | 
			
		||||
@@ -21,6 +21,7 @@ import { prepareDeployHookTx, sha256 } from '../state/actions/deployHook'
 | 
			
		||||
import estimateFee from '../utils/estimateFee'
 | 
			
		||||
import { getParameters, getInvokeOptions, transactionOptions, SetHookData } from '../utils/setHook'
 | 
			
		||||
import { capitalize } from '../utils/helpers'
 | 
			
		||||
import AccountSequence from './Sequence'
 | 
			
		||||
 | 
			
		||||
export const SetHookDialog: React.FC<{ accountAddress: string }> = React.memo(
 | 
			
		||||
  ({ accountAddress }) => {
 | 
			
		||||
@@ -190,6 +191,10 @@ export const SetHookDialog: React.FC<{ accountAddress: string }> = React.memo(
 | 
			
		||||
                    onChange={(acc: any) => setSelectedAccount(acc)}
 | 
			
		||||
                  />
 | 
			
		||||
                </Box>
 | 
			
		||||
                <Box css={{ width: '100%', position: 'relative' }}>
 | 
			
		||||
                  <Label>Sequence</Label>
 | 
			
		||||
                  <AccountSequence address={selectedAccount?.value} />
 | 
			
		||||
                </Box>
 | 
			
		||||
                <Box css={{ width: '100%' }}>
 | 
			
		||||
                  <Label>Invoke on transactions</Label>
 | 
			
		||||
                  <Controller
 | 
			
		||||
 
 | 
			
		||||
@@ -19,6 +19,7 @@ import { Button } from '..'
 | 
			
		||||
import Textarea from '../Textarea'
 | 
			
		||||
import { getFlags } from '../../state/constants/flags'
 | 
			
		||||
import { Plus, Trash } from 'phosphor-react'
 | 
			
		||||
import AccountSequence from '../Sequence'
 | 
			
		||||
 | 
			
		||||
interface UIProps {
 | 
			
		||||
  setState: (pTx?: Partial<TransactionState> | undefined) => TransactionState | undefined
 | 
			
		||||
@@ -161,6 +162,9 @@ export const TxUI: FC<UIProps> = ({
 | 
			
		||||
            onChange={(acc: any) => handleSetAccount(acc)} // TODO make react-select have correct types for acc
 | 
			
		||||
          />
 | 
			
		||||
        </TxField>
 | 
			
		||||
        <TxField label="Sequence">
 | 
			
		||||
          <AccountSequence address={selectedAccount?.value} />
 | 
			
		||||
        </TxField>
 | 
			
		||||
        {richFields.includes('Destination') && (
 | 
			
		||||
          <TxField label="Destination account">
 | 
			
		||||
            <Select
 | 
			
		||||
@@ -347,7 +351,7 @@ export const TxUI: FC<UIProps> = ({
 | 
			
		||||
                  row
 | 
			
		||||
                  css={{
 | 
			
		||||
                    flexWrap: 'wrap',
 | 
			
		||||
                    width: '100%',
 | 
			
		||||
                    width: '100%'
 | 
			
		||||
                  }}
 | 
			
		||||
                >
 | 
			
		||||
                  <Input
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										31
									
								
								utils/accountInfo.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										31
									
								
								utils/accountInfo.ts
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,31 @@
 | 
			
		||||
import toast from 'react-hot-toast'
 | 
			
		||||
 | 
			
		||||
import { xrplSend } from '../state/actions/xrpl-client'
 | 
			
		||||
 | 
			
		||||
interface AccountInfo {
 | 
			
		||||
    Account: string,
 | 
			
		||||
    Sequence: number,
 | 
			
		||||
    Flags: number,
 | 
			
		||||
    Balance?: string,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
const fetchAccountInfo = async (
 | 
			
		||||
    address: string,
 | 
			
		||||
    opts: { silent?: boolean } = {}
 | 
			
		||||
): Promise<AccountInfo | undefined> => {
 | 
			
		||||
    try {
 | 
			
		||||
        const res = await xrplSend({
 | 
			
		||||
            id: `hooks-builder-req-info-${address}`,
 | 
			
		||||
            command: 'account_info',
 | 
			
		||||
            account: address
 | 
			
		||||
        })
 | 
			
		||||
        return res.account_data;
 | 
			
		||||
    } catch (err) {
 | 
			
		||||
        if (!opts.silent) {
 | 
			
		||||
            console.error(err)
 | 
			
		||||
            toast.error('Could not fetch account info!')
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export default fetchAccountInfo
 | 
			
		||||
		Reference in New Issue
	
	Block a user