Skip to content

Commit 4fffa88

Browse files
committed
move non-fungible operations
1 parent f0693ea commit 4fffa88

18 files changed

Lines changed: 937 additions & 388 deletions

File tree

Lines changed: 159 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,159 @@
1+
'use client';
2+
3+
import * as z from 'zod';
4+
import {
5+
BytesValue,
6+
TypedValue,
7+
ContractCallPayloadBuilder,
8+
ContractFunction,
9+
BigUIntValue,
10+
AddressValue,
11+
Address,
12+
} from '@multiversx/sdk-core';
13+
import { useForm } from 'react-hook-form';
14+
import { zodResolver } from '@hookform/resolvers/zod';
15+
import { Form } from '@/components/ui/form';
16+
import { OperationsInputField } from '@/components/operations/operations-input-field';
17+
import { OperationsSubmitButton } from '@/components/operations/operations-submit-button';
18+
import { CommonOpertationContentProps } from '@/components/operations/operations-common-types';
19+
import { OperationsRadioGroup } from '@/components/operations/operations-radio-group';
20+
import BigNumber from 'bignumber.js';
21+
import { useConfig, useTransaction } from '@useelven/core';
22+
import axios from 'axios';
23+
import {
24+
builtInSC,
25+
commonOpertationsGasLimit,
26+
} from '@/components/operations/constants';
27+
import { useTxStatus } from '@/hooks/use-tx-status';
28+
import { OperationInfoBox } from '@/components/operation-info-box';
29+
30+
const formSchema = z.object({
31+
tokenId: z.string().min(1, 'The field is required'),
32+
type: z.enum(['freeze', 'unfreeze'], {
33+
required_error: 'Please choose the type of the operation (freeze/unfreeze)',
34+
}),
35+
accountAddressToFreeze: z.string().min(1, 'The field is required'),
36+
});
37+
38+
export const FreezeUnfreezeSingle = ({
39+
tokenType,
40+
}: {
41+
tokenType: CommonOpertationContentProps['tokenType'];
42+
}) => {
43+
const { triggerTx, error, txResult, transaction, pending } = useTransaction();
44+
const { apiAddress } = useConfig();
45+
46+
const form = useForm<z.infer<typeof formSchema>>({
47+
resolver: zodResolver(formSchema),
48+
defaultValues: {
49+
tokenId: '',
50+
type: 'freeze',
51+
accountAddressToFreeze: '',
52+
},
53+
});
54+
55+
useTxStatus({
56+
successHash: txResult?.hash,
57+
pendingHash: transaction?.getHash()?.toString(),
58+
error,
59+
pending,
60+
});
61+
62+
const onSubmit = async ({
63+
tokenId,
64+
type,
65+
accountAddressToFreeze,
66+
}: z.infer<typeof formSchema>) => {
67+
try {
68+
// TODO: replace with useElven useApiCall when ready to handle such cases
69+
const tokenOnNetwork = await axios.get<{
70+
nonce: number;
71+
collection: string;
72+
}>(`${apiAddress}/nfts/${tokenId.trim()}`, {
73+
headers: {
74+
'Content-Type': 'application/json',
75+
Accept: 'application/json',
76+
},
77+
});
78+
79+
const nonce = tokenOnNetwork?.data?.nonce;
80+
const collectionId = tokenOnNetwork?.data?.collection;
81+
82+
// TODO: show the error in the transaction status modal
83+
if (!nonce || !collectionId) {
84+
console.error(
85+
"Can't read the nonce or/and collection id of the token, using MultiversX API!"
86+
);
87+
return;
88+
}
89+
90+
const args: TypedValue[] = [
91+
BytesValue.fromUTF8(collectionId.trim()),
92+
new BigUIntValue(new BigNumber(nonce)),
93+
new AddressValue(new Address(accountAddressToFreeze.trim())),
94+
];
95+
96+
// TODO: replace ContractCallPayloadBuilder
97+
const data = new ContractCallPayloadBuilder()
98+
.setFunction(
99+
new ContractFunction(
100+
type === 'freeze' ? 'freezeSingleNFT' : 'unFreezeSingleNFT'
101+
)
102+
)
103+
.setArgs(args)
104+
.build();
105+
106+
triggerTx?.({
107+
address: builtInSC,
108+
gasLimit: commonOpertationsGasLimit,
109+
data,
110+
value: 0,
111+
});
112+
113+
form.reset();
114+
} catch (e) {
115+
console.error(
116+
"Can't read the nonce or/and collection id of the token, using MultiversX API!",
117+
e
118+
);
119+
}
120+
};
121+
122+
return (
123+
<>
124+
<OperationInfoBox error={error} txHash={txResult?.hash} />
125+
<Form {...form}>
126+
<form
127+
id="freeze-unfreeze-single-form"
128+
onSubmit={form.handleSubmit(onSubmit)}
129+
className="space-y-8"
130+
>
131+
<div className="flex-1 overflow-auto p-1">
132+
<OperationsRadioGroup
133+
items={[
134+
{ name: 'freeze', description: 'Freeze an address' },
135+
{ name: 'unfreeze', description: 'Unfreeze an address' },
136+
]}
137+
name="type"
138+
label="Operation type"
139+
description="Please choose the type of the operation. Freeze or Unfreeze."
140+
/>
141+
<OperationsInputField
142+
name="tokenId"
143+
label="Token id"
144+
placeholder="Example: MyToken-23432-01"
145+
description="Please provide your token id"
146+
/>
147+
<OperationsInputField
148+
name="accountAddressToFreeze"
149+
label="Account"
150+
placeholder="Example: erd1..."
151+
description={`Please provide the account that holds the ${tokenType} ESDT to freeze/unfreeze.`}
152+
/>
153+
</div>
154+
<OperationsSubmitButton formId="freeze-unfreeze-single-form" />
155+
</form>
156+
</Form>
157+
</>
158+
);
159+
};
Lines changed: 137 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,137 @@
1+
'use client';
2+
3+
import * as z from 'zod';
4+
import {
5+
BytesValue,
6+
TypedValue,
7+
ContractCallPayloadBuilder,
8+
ContractFunction,
9+
BigUIntValue,
10+
AddressValue,
11+
Address,
12+
} from '@multiversx/sdk-core';
13+
import { useForm } from 'react-hook-form';
14+
import { zodResolver } from '@hookform/resolvers/zod';
15+
import { Form } from '@/components/ui/form';
16+
import { OperationsInputField } from '@/components/operations/operations-input-field';
17+
import { OperationsSubmitButton } from '@/components/operations/operations-submit-button';
18+
import { CommonOpertationContentProps } from '@/components/operations/operations-common-types';
19+
import BigNumber from 'bignumber.js';
20+
import { useConfig, useTransaction } from '@useelven/core';
21+
import axios from 'axios';
22+
import {
23+
builtInSC,
24+
commonOpertationsGasLimit,
25+
} from '@/components/operations/constants';
26+
import { OperationInfoBox } from '@/components/operation-info-box';
27+
import { useTxStatus } from '@/hooks/use-tx-status';
28+
29+
const formSchema = z.object({
30+
tokenId: z.string().min(1, 'The field is required'),
31+
account: z.string().min(1, 'The field is required'),
32+
});
33+
34+
export const WipeSingle = ({
35+
tokenType,
36+
}: {
37+
tokenType: CommonOpertationContentProps['tokenType'];
38+
}) => {
39+
const { triggerTx, error, txResult, transaction, pending } = useTransaction();
40+
41+
const { apiAddress } = useConfig();
42+
const form = useForm<z.infer<typeof formSchema>>({
43+
resolver: zodResolver(formSchema),
44+
defaultValues: {
45+
tokenId: '',
46+
account: '',
47+
},
48+
});
49+
50+
useTxStatus({
51+
successHash: txResult?.hash,
52+
pendingHash: transaction?.getHash()?.toString(),
53+
error,
54+
pending,
55+
});
56+
57+
const onSubmit = async ({ tokenId, account }: z.infer<typeof formSchema>) => {
58+
try {
59+
// TODO: replace with useElven useApiCall when ready to handle such cases
60+
const tokenOnNetwork = await axios.get<{
61+
nonce: number;
62+
collection: string;
63+
}>(`${apiAddress}/nfts/${tokenId.trim()}`, {
64+
headers: {
65+
'Content-Type': 'application/json',
66+
Accept: 'application/json',
67+
},
68+
});
69+
70+
const nonce = tokenOnNetwork?.data?.nonce;
71+
const collectionId = tokenOnNetwork?.data?.collection;
72+
73+
// TODO: show the error in the transaction status modal
74+
if (!nonce || !collectionId) {
75+
console.error(
76+
"Can't read the nonce or/and collection id of the token, using MultiversX API!"
77+
);
78+
return;
79+
}
80+
81+
const args: TypedValue[] = [
82+
BytesValue.fromUTF8(collectionId.trim()),
83+
new BigUIntValue(new BigNumber(nonce)),
84+
new AddressValue(new Address(account.trim())),
85+
];
86+
87+
// TODO: replace ContractCallPayloadBuilder
88+
const data = new ContractCallPayloadBuilder()
89+
.setFunction(new ContractFunction('wipeSingleNFT'))
90+
.setArgs(args)
91+
.build();
92+
93+
triggerTx?.({
94+
address: builtInSC,
95+
gasLimit: commonOpertationsGasLimit,
96+
data,
97+
value: 0,
98+
});
99+
100+
form.reset();
101+
} catch (e) {
102+
console.error(
103+
"Can't read the nonce or/and collection id of the token, using MultiversX API!",
104+
e
105+
);
106+
}
107+
};
108+
109+
return (
110+
<>
111+
<OperationInfoBox error={error} txHash={txResult?.hash} />
112+
<Form {...form}>
113+
<form
114+
id="wipe-form"
115+
onSubmit={form.handleSubmit(onSubmit)}
116+
className="space-y-8"
117+
>
118+
<div className="flex-1 overflow-auto p-1">
119+
<OperationsInputField
120+
name="tokenId"
121+
label="Token id"
122+
placeholder="Example: MyToken-23432-01"
123+
description="Please provide your token id"
124+
/>
125+
<OperationsInputField
126+
name="account"
127+
label="Account"
128+
placeholder="Example: erd1..."
129+
description={`Please provide the account that holds the ${tokenType} ESDT to wipe.`}
130+
/>
131+
</div>
132+
<OperationsSubmitButton formId="wipe-form" />
133+
</form>
134+
</Form>
135+
</>
136+
);
137+
};

app/(operations)/fungible-tokens/change-properties/page.tsx

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,11 @@ const ChangePropertiesPage: NextPage = () => {
1313
The manager of an ESDT token may individually change any of the
1414
properties of the token, or multiple properties at once. The token
1515
should have the canUpgrade property set to true.
16+
<br />
17+
<br />
18+
<strong>
19+
Due to API caching, changes may not take effect immediately.
20+
</strong>
1621
</p>
1722
</div>
1823
<ChangeProperties tokenType="fungible" />

0 commit comments

Comments
 (0)