Skip to content

Commit

Permalink
refactor provider for clarity
Browse files Browse the repository at this point in the history
  • Loading branch information
brendan-defi committed Jan 28, 2025
1 parent 69cf65a commit 09bb620
Show file tree
Hide file tree
Showing 11 changed files with 359 additions and 165 deletions.
39 changes: 39 additions & 0 deletions src/api/buildTransferTransaction.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
import type { Call } from '@/transaction/types';
import { type Address, encodeFunctionData, erc20Abi } from 'viem';

type BuildTransferTransactionParams = {
recipientAddress: Address;
tokenAddress: Address | null;
amount: bigint;
};

export function buildTransferTransaction({
recipientAddress,
tokenAddress,
amount,
}: BuildTransferTransactionParams): Call[] {
// if no token address, we are sending native ETH
// and the data prop is empty
if (!tokenAddress) {
return [
{
to: recipientAddress,
data: '0x',
value: amount,
},
];
}

const transferCallData = encodeFunctionData({
abi: erc20Abi,
functionName: 'transfer',
args: [recipientAddress, amount],
});

return [
{
to: tokenAddress,
data: transferCallData,
},
];
}
44 changes: 44 additions & 0 deletions src/internal/hooks/useTransferTransaction.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
import { buildTransferTransaction } from '@/api/buildTransferTransaction';
import type { Token } from '@/token';
import type { Call } from '@/transaction/types';
import { type Address, parseUnits } from 'viem';

type UseTransferTransactionParams = {
recipientAddress: Address;
token: Token | null;
amount: string;
};

export function useTransferTransaction({
recipientAddress,
token,
amount,
}: UseTransferTransactionParams): { calls: Call[] } {
if (!token) {
return { calls: [] };
}

if (!token.address) {
if (token.symbol !== 'ETH') {
return { calls: [] };
}
const parsedAmount = parseUnits(amount, token.decimals);
return {
calls: buildTransferTransaction({
recipientAddress,
tokenAddress: null,
amount: parsedAmount,
}),
};
}

const parsedAmount = parseUnits(amount.toString(), token.decimals);

return {
calls: buildTransferTransaction({
recipientAddress,
tokenAddress: token.address,
amount: parsedAmount,
}),
};
}
Original file line number Diff line number Diff line change
Expand Up @@ -11,34 +11,30 @@ type AddressInputProps = {
export function AddressInput({ className }: AddressInputProps) {
const {
selectedRecipientAddress,
setSelectedRecipientAddress,
setValidatedRecipientAddress,
recipientInput,
setRecipientInput,
handleRecipientInputChange,
} = useSendContext();

const inputValue = selectedRecipientAddress
? getSlicedAddress(selectedRecipientAddress)
: recipientInput;

const handleFocus = useCallback((e: React.FocusEvent<HTMLInputElement>) => {
if (selectedRecipientAddress) {
setRecipientInput(selectedRecipientAddress);
setTimeout(() => {
// TODO: This is a hack to get the cursor to the end of the input, how to remove timeout?
e.target.setSelectionRange(selectedRecipientAddress.length, selectedRecipientAddress.length);
e.target.scrollLeft = e.target.scrollWidth;

}, 0);
setSelectedRecipientAddress(null);
setValidatedRecipientAddress(null);
}
}, [
selectedRecipientAddress,
setSelectedRecipientAddress,
setValidatedRecipientAddress,
setRecipientInput,
]);
const handleFocus = useCallback(
(e: React.FocusEvent<HTMLInputElement>) => {
if (selectedRecipientAddress) {
handleRecipientInputChange(selectedRecipientAddress);
setTimeout(() => {
// TODO: This is a hack to get the cursor to the end of the input, how to remove timeout?
e.target.setSelectionRange(
selectedRecipientAddress.length,
selectedRecipientAddress.length,
);
e.target.scrollLeft = e.target.scrollWidth;
}, 0);
}
},
[selectedRecipientAddress, handleRecipientInputChange],
);

return (
<div
Expand All @@ -56,7 +52,7 @@ export function AddressInput({ className }: AddressInputProps) {
inputMode="text"
placeholder="Basename, ENS, or Address"
value={inputValue ?? ''}
onChange={setRecipientInput}
onChange={handleRecipientInputChange}
onFocus={handleFocus}
aria-label="Input Receiver Address"
className={cn(background.default, 'w-full outline-none')}
Expand Down
4 changes: 2 additions & 2 deletions src/wallet/components/WalletAdvancedSend/components/Send.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { useMemo, type ReactNode } from 'react';
import { SendHeader } from './SendHeader';
import { SendProvider, useSendContext } from './SendProvider';
import { AddressInput } from '@/wallet/components/WalletAdvancedSend/components/AddressInput';
import { AddressSelector } from '@/wallet/components/WalletAdvancedSend/components/AddressSelector';
import { SendAddressSelector } from '@/wallet/components/WalletAdvancedSend/components/SendAddressSelector';
import { SendTokenSelector } from '@/wallet/components/WalletAdvancedSend/components/SendTokenSelector';
import { SendAmountInput } from '@/wallet/components/WalletAdvancedSend/components/SendAmountInput';
import { SendFundingWallet } from '@/wallet/components/WalletAdvancedSend/components/SendFundingWallet';
Expand Down Expand Up @@ -74,7 +74,7 @@ function SendDefaultChildren() {
<>
<AddressInput />
{context.validatedRecipientAddress && (
<AddressSelector address={context.validatedRecipientAddress} />
<SendAddressSelector address={context.validatedRecipientAddress} />
)}
</>
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,11 @@ import { background, border, cn, pressable } from '@/styles/theme';
import { useCallback } from 'react';
import type { Address as AddressType } from 'viem';

type AddressSelectorProps = {
type SendAddressSelectorProps = {
address: AddressType;
};

export function AddressSelector({ address }: AddressSelectorProps) {
export function SendAddressSelector({ address }: SendAddressSelectorProps) {
const { senderChain, handleAddressSelection } = useSendContext();

const handleClick = useCallback(() => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,15 +7,15 @@ import { useSendContext } from '@/wallet/components/WalletAdvancedSend/component

export function SendAmountInput({ className }: { className?: string }) {
const {
fiatAmount,
cryptoAmount,
selectedToken,
setFiatAmount,
setCryptoAmount,
exchangeRate,
exchangeRateLoading,
cryptoAmount,
handleCryptoAmountChange,
fiatAmount,
handleFiatAmountChange,
selectedInputType,
setSelectedInputType,
exchangeRate,
exchangeRateLoading,
} = useSendContext();

return (
Expand All @@ -28,8 +28,8 @@ export function SendAmountInput({ className }: { className?: string }) {
currency={'USD'}
selectedInputType={selectedInputType}
className={className}
setFiatAmount={setFiatAmount}
setCryptoAmount={setCryptoAmount}
setFiatAmount={handleFiatAmountChange}
setCryptoAmount={handleCryptoAmountChange}
exchangeRate={String(exchangeRate)}
/>

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,8 @@ import {
TransactionStatusAction,
TransactionStatusLabel,
} from '@/transaction';
import type { Call } from '@/transaction/types';
import { useSendContext } from '@/wallet/components/WalletAdvancedSend/components/SendProvider';
import { useMemo, useState } from 'react';
import { useMemo } from 'react';

type SendButtonProps = {
label?: string;
Expand All @@ -30,10 +29,9 @@ export function SendButton({
}: SendButtonProps) {
const isSponsored = false;
const chainId = 8453;
const [callData, setCallData] = useState<Call[]>([]);
const [sendError, setSendError] = useState<string | null>(null);

const { cryptoAmount, selectedToken } = useSendContext();
const { cryptoAmount, selectedToken, callData, sendTransactionError } =
useSendContext();

const handleOnStatus = () => {};

Expand Down Expand Up @@ -81,15 +79,15 @@ export function SendButton({
errorOverride={errorOverride}
disabled={isDisabled}
/>
{!sendError && <TransactionSponsor />}
{!sendTransactionError && <TransactionSponsor />}
<TransactionStatus>
<TransactionStatusLabel />
<TransactionStatusAction />
</TransactionStatus>
</Transaction>
{sendError && (
{sendTransactionError && (
<div className={cn(text.label2, color.foregroundMuted, 'pb-2')}>
{sendError}
{sendTransactionError}
</div>
)}
</>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,22 +11,22 @@ export function SendHeader({ label = 'Send' }: { label?: string }) {

const {
selectedRecipientAddress,
setSelectedRecipientAddress,
selectedToken,
setSelectedToken,
handleResetTokenSelection,
handleRecipientInputChange,
} = useSendContext();

const handleBack = useCallback(() => {
if (selectedToken) {
setSelectedToken(null);
handleResetTokenSelection();
} else if (selectedRecipientAddress) {
setSelectedRecipientAddress(null);
handleRecipientInputChange(selectedRecipientAddress);
}
}, [
selectedRecipientAddress,
selectedToken,
setSelectedRecipientAddress,
setSelectedToken,
handleResetTokenSelection,
handleRecipientInputChange,
]);

const handleClose = useCallback(() => {
Expand Down
Loading

0 comments on commit 09bb620

Please sign in to comment.