Skip to content

Commit e659e4c

Browse files
committed
tx status
1 parent f6745f2 commit e659e4c

15 files changed

Lines changed: 529 additions & 432 deletions

File tree

app/(operations)/general-operations/send-egld/components/send.tsx

Lines changed: 42 additions & 66 deletions
Original file line numberDiff line numberDiff line change
@@ -7,12 +7,10 @@ import { Form } from '@/components/ui/form';
77
import { OperationsInputField } from '@/components/operations/operations-input-field';
88
import { OperationsSubmitButton } from '@/components/operations/operations-submit-button';
99
import BigNumber from 'bignumber.js';
10-
import { ESDTType, useConfig, useTokenTransfer } from '@useelven/core';
11-
import { transfersOperationsGasLimit } from '@/components/operations/constants';
10+
import { ESDTType, useTokenTransfer } from '@useelven/core';
1211
import { OperationsTokenIdAmountInput } from '@/components/operations/operations-tokenid-amount-input';
13-
import { ExternalToast, toast } from 'sonner';
14-
import { useEffect, useRef } from 'react';
15-
import { Spinner } from '@/components/ui/spinner';
12+
import { OperationInfoBox } from '@/components/operation-info-box';
13+
import { useTxStatus } from '@/hooks/use-tx-status';
1614

1715
const formSchema = z.object({
1816
tokenId: z.string().min(1, 'The field is required'),
@@ -28,9 +26,6 @@ const formSchema = z.object({
2826
export const Send = () => {
2927
const { transfer, transaction, txResult, error, pending } =
3028
useTokenTransfer();
31-
const { explorerAddress } = useConfig();
32-
33-
const toastId = useRef<string | number>();
3429

3530
const form = useForm<z.infer<typeof formSchema>>({
3631
resolver: zodResolver(formSchema),
@@ -41,77 +36,58 @@ export const Send = () => {
4136
},
4237
});
4338

44-
// TODO: move to separate hook
45-
// TODO: make custom contents for toasters or display more data about the transactions somewhere
46-
// TODO: add information where to confirm signing process
47-
useEffect(() => {
48-
const pendingHash = transaction?.getHash().toString();
49-
const successHash = txResult?.hash;
50-
const toasterOptions: ExternalToast = {
51-
id: toastId?.current,
52-
position: 'top-right',
53-
...(explorerAddress
54-
? {
55-
action: (
56-
<a
57-
className="flex items-center justify-between gap-2 text-xs underline"
58-
href={`${explorerAddress}/transactions/${pendingHash || successHash}`}
59-
>
60-
{pending && <Spinner size={20} />}{' '}
61-
<span>Check in the Explorer!</span>
62-
</a>
63-
),
64-
}
65-
: {}),
66-
};
67-
if (pending) {
68-
toastId.current = toast.info('Transaction is pending', toasterOptions);
69-
} else if (successHash) {
70-
toast.success('Transaction success', toasterOptions);
71-
} else if (error) {
72-
toast.error('Transaction error', toasterOptions);
73-
}
74-
}, [txResult?.hash, transaction, error, explorerAddress, pending]);
39+
useTxStatus({
40+
successHash: txResult?.hash,
41+
pendingHash: transaction?.getHash()?.toString(),
42+
error,
43+
pending,
44+
});
7545

7646
const onSubmit = async ({
7747
tokenId,
7848
address,
7949
amount,
8050
}: z.infer<typeof formSchema>) => {
8151
transfer?.({
82-
type: ESDTType.FungibleESDT,
83-
tokenId: tokenId.trim(),
52+
tokens: [
53+
{
54+
type: ESDTType.FungibleESDT,
55+
amount: amount.trim(),
56+
tokenId: tokenId.trim(),
57+
},
58+
],
8459
receiver: address.trim(),
85-
amount: amount.trim(),
86-
gasLimit: transfersOperationsGasLimit,
8760
});
8861

8962
form.reset();
9063
};
9164

9265
return (
93-
<Form {...form}>
94-
<form onSubmit={form.handleSubmit(onSubmit)} className="space-y-8">
95-
<div className="flex-1 overflow-auto p-1">
96-
<OperationsTokenIdAmountInput
97-
tokenType="fungible"
98-
onlyOwner={false}
99-
/>
100-
<OperationsInputField
101-
name="address"
102-
label="Address"
103-
placeholder="Example: erd1..."
104-
description="Please provide the address to where the amount will be send"
105-
/>
106-
<OperationsInputField
107-
name="amount"
108-
label="Amount"
109-
placeholder="Example: 22.5"
110-
description="Please provide the amount of ESDT to send (ex. 22.5 is 22.5 amount of an ESDT token. Don't worry about the decimal places here)."
111-
/>
112-
</div>
113-
<OperationsSubmitButton pending={pending} />
114-
</form>
115-
</Form>
66+
<>
67+
<OperationInfoBox error={error} message={''} txHash={txResult?.hash} />
68+
<Form {...form}>
69+
<form onSubmit={form.handleSubmit(onSubmit)} className="space-y-8">
70+
<div className="flex-1 overflow-auto p-1">
71+
<OperationsTokenIdAmountInput
72+
tokenType="fungible"
73+
onlyOwner={false}
74+
/>
75+
<OperationsInputField
76+
name="address"
77+
label="Address"
78+
placeholder="Example: erd1..."
79+
description="Please provide the address to where the amount will be send"
80+
/>
81+
<OperationsInputField
82+
name="amount"
83+
label="Amount"
84+
placeholder="Example: 22.5"
85+
description="Please provide the amount of ESDT to send (ex. 22.5 is 22.5 amount of an ESDT token. Don't worry about the decimal places here)."
86+
/>
87+
</div>
88+
<OperationsSubmitButton pending={pending} />
89+
</form>
90+
</Form>
91+
</>
11692
);
11793
};

app/(operations)/general-operations/send-egld/page.tsx

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -16,15 +16,15 @@ const SendEgld: NextPage = () => {
1616
</div>
1717
<Send />
1818
<Separator className="my-12" />
19-
<div>
19+
<div className="text-xs">
2020
<p>
2121
Transferring eGold (EGLD) between wallets on MultiversX is
2222
straightforward and doesn&apos;t always need a smart contract. This
2323
process involves a few important steps to ensure that the EGLD reaches
2424
the right person safely and securely. Here&apos;s a simpler breakdown
2525
of how it works:
2626
</p>
27-
<h2 className="py-2 text-lg font-semibold">
27+
<h2 className="py-2 text-sm font-semibold">
2828
Getting the Transaction Ready
2929
</h2>
3030
<p>
@@ -33,20 +33,20 @@ const SendEgld: NextPage = () => {
3333
need a nonce, which is just a fancy way of saying a unique number for
3434
each transaction you make, to keep things in order and secure.
3535
</p>{' '}
36-
<h2 className="py-2 text-lg font-semibold">Signing the Transaction</h2>
36+
<h2 className="py-2 text-sm font-semibold">Signing the Transaction</h2>
3737
<p>
3838
Next, you sign the transaction with your private key. Think of this
3939
like putting your digital signature on a document. It proves that you
4040
are really you and that you approve this transaction. This step is
4141
crucial for keeping your EGLD safe.
4242
</p>{' '}
43-
<h2 className="py-2 text-lg font-semibold">Sending it Off</h2>{' '}
43+
<h2 className="py-2 text-sm font-semibold">Sending it Off</h2>{' '}
4444
<p>
4545
Once signed, your transaction is ready to fly. You broadcast it,
4646
meaning you send it out to the MultiversX network. Now, it&apos;s in
4747
the hands of the network&apos;s validators.{' '}
4848
</p>
49-
<h2 className="py-2 text-lg font-semibold">
49+
<h2 className="py-2 text-sm font-semibold">
5050
Validators Check and Confirm
5151
</h2>
5252
<p>
@@ -56,7 +56,7 @@ const SendEgld: NextPage = () => {
5656
matches up. If all is good, they include your transaction in the next
5757
block of transactions that gets added to the blockchain.
5858
</p>
59-
<h2 className="py-2 text-lg font-semibold">All Done!</h2>
59+
<h2 className="py-2 text-sm font-semibold">All Done!</h2>
6060
<p>
6161
After your transaction is safely tucked into a block on the
6262
blockchain, it&apos;s considered confirmed. This means it&apos;s

app/layout.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ export default function RootLayout({
4646
<ThemeProvider attribute="class" defaultTheme="system" enableSystem>
4747
{children}
4848
</ThemeProvider>
49-
<Toaster expand={true} />
49+
<Toaster expand={true} style={{ top: 85 }} />
5050
</body>
5151
</html>
5252
);

components/home-cards.tsx

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@ export const HomeCards = () => {
55
return (
66
<>
77
<div className="mb-6 flex flex-row flex-wrap gap-6">
8-
{/* TODO: replace all onClicks with paths when all pages are ready */}
98
<HomeCard
109
title="General operations"
1110
description="General operations on the chain. Like managing accounts, herotags, multi-transfers, and interaction with custom smart contracts. New ones will be added over time."

components/operation-info-box.tsx

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
import { Alert, AlertDescription, AlertTitle } from '@/components/ui/alert';
2+
import { useConfig } from '@useelven/core';
3+
4+
type OperationInfoBoxProps = {
5+
txHash?: string;
6+
error?: string;
7+
message?: string;
8+
};
9+
10+
export const OperationInfoBox = ({
11+
txHash,
12+
error,
13+
message,
14+
}: OperationInfoBoxProps) => {
15+
const { explorerAddress } = useConfig();
16+
17+
if (!error && !message && !txHash) {
18+
return null;
19+
}
20+
21+
return (
22+
<Alert variant={error ? 'destructive' : 'default'} className="mb-3">
23+
<AlertTitle className="mb-2">Transaction status</AlertTitle>
24+
<AlertDescription>
25+
<div>{error || message}</div>
26+
<div>
27+
Check in the explorer:
28+
<a
29+
href={`${explorerAddress}/transactions/${txHash}`}
30+
target="_blank"
31+
className="ml-2 break-all font-semibold underline"
32+
>
33+
{txHash}
34+
</a>
35+
</div>
36+
</AlertDescription>
37+
</Alert>
38+
);
39+
};

components/operations/fungible-tokens/send.tsx

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,6 @@ import { OperationsSubmitButton } from '@/components/operations/operations-submi
1313
import { OperationContentProps } from '@/components/operations/operations-common-types';
1414
import BigNumber from 'bignumber.js';
1515
import { ESDTType } from '@useelven/core';
16-
import { transfersOperationsGasLimit } from '@/components/operations/constants';
1716
import { OperationsTokenIdAmountInput } from '../operations-tokenid-amount-input';
1817

1918
const formSchema = z.object({
@@ -43,11 +42,14 @@ export const Send = ({ transfer, close }: OperationContentProps) => {
4342
amount,
4443
}: z.infer<typeof formSchema>) => {
4544
transfer?.({
46-
type: ESDTType.FungibleESDT,
47-
tokenId: tokenId.trim(),
45+
tokens: [
46+
{
47+
type: ESDTType.FungibleESDT,
48+
amount: amount.trim(),
49+
tokenId: tokenId.trim(),
50+
},
51+
],
4852
receiver: address.trim(),
49-
amount: amount.trim(),
50-
gasLimit: transfersOperationsGasLimit,
5153
});
5254

5355
form.reset();

components/operations/general/multi-transfer.tsx

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ import { OperationsInputField } from '@/components/operations/operations-input-f
1212
import { OperationsSubmitButton } from '@/components/operations/operations-submit-button';
1313
import { OperationContentProps } from '@/components/operations/operations-common-types';
1414
import BigNumber from 'bignumber.js';
15-
import { MultiTransferToken, ESDTType } from '@useelven/core';
15+
import { ESDTType, MultiTransferToken } from '@useelven/core';
1616

1717
const formSchema = z
1818
.object({
@@ -130,10 +130,7 @@ const formSchema = z
130130
}
131131
);
132132

133-
export const MultiTransfer = ({
134-
multiTransfer,
135-
close,
136-
}: OperationContentProps) => {
133+
export const MultiTransfer = ({ transfer, close }: OperationContentProps) => {
137134
const form = useForm<z.infer<typeof formSchema>>({
138135
resolver: zodResolver(formSchema),
139136
defaultValues: {
@@ -173,7 +170,6 @@ export const MultiTransfer = ({
173170
if (nonFungibleTokenId && nonFungibleAmount) {
174171
tokens.push({
175172
type: ESDTType.NonFungibleESDT,
176-
amount: nonFungibleAmount,
177173
tokenId: nonFungibleTokenId,
178174
});
179175
}
@@ -194,8 +190,8 @@ export const MultiTransfer = ({
194190
});
195191
}
196192

197-
if (multiTransfer) {
198-
multiTransfer({ tokens, receiver: receiverAddress });
193+
if (transfer) {
194+
transfer({ tokens, receiver: receiverAddress });
199195

200196
form.reset();
201197
close();

components/operations/meta-tokens/send.tsx

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,6 @@ import { OperationsInputField } from '@/components/operations/operations-input-f
1212
import { OperationsSubmitButton } from '@/components/operations/operations-submit-button';
1313
import { OperationContentProps } from '@/components/operations/operations-common-types';
1414
import { ESDTType } from '@useelven/core';
15-
import { transfersOperationsGasLimit } from '@/components/operations/constants';
1615
import BigNumber from 'bignumber.js';
1716

1817
const formSchema = z.object({
@@ -42,11 +41,14 @@ export const Send = ({ transfer, close }: OperationContentProps) => {
4241
amount,
4342
}: z.infer<typeof formSchema>) => {
4443
transfer?.({
45-
type: ESDTType.MetaESDT,
46-
tokenId,
44+
tokens: [
45+
{
46+
type: ESDTType.MetaESDT,
47+
amount: amount.trim(),
48+
tokenId: tokenId.trim(),
49+
},
50+
],
4751
receiver: address.trim(),
48-
amount: amount.trim(),
49-
gasLimit: transfersOperationsGasLimit,
5052
});
5153

5254
form.reset();

components/operations/non-fungible-tokens/send.tsx

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,6 @@ import { OperationsInputField } from '@/components/operations/operations-input-f
1212
import { OperationsSubmitButton } from '@/components/operations/operations-submit-button';
1313
import { OperationContentProps } from '@/components/operations/operations-common-types';
1414
import { ESDTType } from '@useelven/core';
15-
import { transfersOperationsGasLimit } from '@/components/operations/constants';
1615

1716
const formSchema = z.object({
1817
tokenId: z.string().min(1, 'The field is required'),
@@ -30,10 +29,13 @@ export const Send = ({ transfer, close }: OperationContentProps) => {
3029

3130
const onSubmit = async ({ tokenId, address }: z.infer<typeof formSchema>) => {
3231
transfer?.({
33-
type: ESDTType.NonFungibleESDT,
34-
tokenId,
32+
tokens: [
33+
{
34+
type: ESDTType.NonFungibleESDT,
35+
tokenId: tokenId.trim(),
36+
},
37+
],
3538
receiver: address.trim(),
36-
gasLimit: transfersOperationsGasLimit,
3739
});
3840

3941
form.reset();

components/operations/operations-common-types.tsx

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,4 @@
1-
import {
2-
TransactionParams,
3-
useTokenTransfer,
4-
useMultiTokenTransfer,
5-
} from '@useelven/core';
1+
import { TransactionParams, useTokenTransfer } from '@useelven/core';
62

73
export type OperationContentProps = {
84
close: () => void;
@@ -13,7 +9,6 @@ export type OperationContentProps = {
139
value,
1410
}: TransactionParams) => Promise<void>;
1511
transfer?: ReturnType<typeof useTokenTransfer>['transfer'];
16-
multiTransfer?: ReturnType<typeof useMultiTokenTransfer>['transfer'];
1712
};
1813

1914
export interface CommonOpertationContentProps extends OperationContentProps {

0 commit comments

Comments
 (0)