Skip to content

Commit f0693ea

Browse files
committed
move non fungible operations in progress
1 parent c02fd63 commit f0693ea

11 files changed

Lines changed: 764 additions & 11 deletions

File tree

Lines changed: 150 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,150 @@
1+
'use client';
2+
3+
import * as z from 'zod';
4+
import {
5+
TokenTransfer,
6+
BytesValue,
7+
TypedValue,
8+
ContractCallPayloadBuilder,
9+
ContractFunction,
10+
} from '@multiversx/sdk-core';
11+
import { useForm } from 'react-hook-form';
12+
import { zodResolver } from '@hookform/resolvers/zod';
13+
import { Form } from '@/components/ui/form';
14+
import {
15+
sftNftTokenProperties,
16+
issueTokenPayment,
17+
commonOpertationsGasLimit,
18+
builtInSC,
19+
} from '@/components/operations/constants';
20+
import { OperationsInputField } from '@/components/operations/operations-input-field';
21+
import { OperationsCheckboxGroup } from '@/components/operations/operations-checkbox-group';
22+
import { OperationsSubmitButton } from '@/components/operations/operations-submit-button';
23+
import { CommonOpertationContentProps } from '@/components/operations/operations-common-types';
24+
import { useTransaction } from '@useelven/core';
25+
import { useTxStatus } from '@/hooks/use-tx-status';
26+
import { OperationInfoBox } from '@/components/operation-info-box';
27+
28+
const formSchema = z.object({
29+
name: z
30+
.string()
31+
.min(3, 'Name must have min 3 characters.')
32+
.max(20, 'Name must have max 20 characters.')
33+
.refine(
34+
(value) => new RegExp(/^[a-zA-Z0-9]+$/).test(value),
35+
'Alphanumeric characters only.'
36+
),
37+
ticker: z
38+
.string()
39+
.min(3, 'Name must have min 3 characters.')
40+
.max(10, 'Name must have max 10 characters.')
41+
.refine(
42+
(value) => new RegExp(/^[A-Z0-9]+$/).test(value),
43+
'Alphanumeric UPPERCASE only.'
44+
),
45+
properties: z.array(z.string()),
46+
});
47+
48+
const functionMap: Record<string, string> = {
49+
'non-fungible': 'issueNonFungible',
50+
'semi-fungible': 'issueSemiFungible',
51+
};
52+
53+
export const IssueNftSft = ({
54+
tokenType,
55+
}: {
56+
tokenType: CommonOpertationContentProps['tokenType'];
57+
}) => {
58+
const { triggerTx, error, txResult, transaction, pending } = useTransaction();
59+
60+
const form = useForm<z.infer<typeof formSchema>>({
61+
resolver: zodResolver(formSchema),
62+
defaultValues: {
63+
name: '',
64+
ticker: '',
65+
properties: sftNftTokenProperties.map((property) => property.name),
66+
},
67+
});
68+
69+
useTxStatus({
70+
successHash: txResult?.hash,
71+
pendingHash: transaction?.getHash()?.toString(),
72+
error,
73+
pending,
74+
});
75+
76+
const onSubmit = ({
77+
name,
78+
ticker,
79+
properties,
80+
}: z.infer<typeof formSchema>) => {
81+
const payment = TokenTransfer.egldFromAmount(issueTokenPayment);
82+
83+
const args: TypedValue[] = [
84+
BytesValue.fromUTF8(name),
85+
BytesValue.fromUTF8(ticker),
86+
];
87+
88+
for (const property of sftNftTokenProperties) {
89+
let propertyEnabled = false;
90+
91+
if (properties.includes(property.name)) {
92+
propertyEnabled = true;
93+
}
94+
95+
args.push(BytesValue.fromUTF8(property.name));
96+
args.push(BytesValue.fromUTF8(propertyEnabled.toString()));
97+
}
98+
99+
const data = new ContractCallPayloadBuilder()
100+
.setFunction(new ContractFunction(functionMap[tokenType]))
101+
.setArgs(args)
102+
.build();
103+
104+
triggerTx?.({
105+
address: builtInSC,
106+
gasLimit: commonOpertationsGasLimit,
107+
data,
108+
value: payment,
109+
});
110+
111+
form.reset();
112+
};
113+
114+
return (
115+
<>
116+
<OperationInfoBox error={error} txHash={txResult?.hash} />
117+
<Form {...form}>
118+
<form
119+
id="sft-nft-issue-form"
120+
onSubmit={form.handleSubmit(onSubmit)}
121+
className="space-y-8"
122+
>
123+
<div className="flex-1 overflow-auto p-1">
124+
<OperationsInputField
125+
name="name"
126+
label="Name"
127+
placeholder="Example: MyToken"
128+
description="Please provide the token name (3-20 characters, alphanumeric)"
129+
/>
130+
<OperationsInputField
131+
name="ticker"
132+
label="Ticker"
133+
placeholder="Example: MYTOK"
134+
description="Please provide the token ticker (3-10 characters,
135+
alphanumeric, uppercase)"
136+
/>
137+
<OperationsCheckboxGroup
138+
items={sftNftTokenProperties}
139+
name="properties"
140+
label="Token properties"
141+
description="Every ESDT has a set of properties which control
142+
what operations are possible with it."
143+
/>
144+
</div>
145+
<OperationsSubmitButton formId="sft-nft-issue-form" />
146+
</form>
147+
</Form>
148+
</>
149+
);
150+
};
Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
'use client';
2+
3+
import * as z from 'zod';
4+
import {
5+
BytesValue,
6+
TypedValue,
7+
ContractCallPayloadBuilder,
8+
ContractFunction,
9+
} from '@multiversx/sdk-core';
10+
import { useForm } from 'react-hook-form';
11+
import { zodResolver } from '@hookform/resolvers/zod';
12+
import { Form } from '@/components/ui/form';
13+
import {
14+
commonOpertationsGasLimit,
15+
builtInSC,
16+
} from '@/components/operations/constants';
17+
import { OperationsSubmitButton } from '@/components/operations/operations-submit-button';
18+
import { CommonOpertationContentProps } from '@/components/operations/operations-common-types';
19+
import { OperationsTokenIdInput } from '@/components/operations/operations-tokenid-input';
20+
import { useTransaction } from '@useelven/core';
21+
import { useTxStatus } from '@/hooks/use-tx-status';
22+
import { OperationInfoBox } from '@/components/operation-info-box';
23+
24+
const formSchema = z.object({
25+
tokenId: z.string().min(1, 'The field is required!'),
26+
});
27+
28+
export const StopCreation = ({
29+
tokenType,
30+
}: {
31+
tokenType: CommonOpertationContentProps['tokenType'];
32+
}) => {
33+
const { triggerTx, error, txResult, transaction, pending } = useTransaction();
34+
35+
const form = useForm<z.infer<typeof formSchema>>({
36+
resolver: zodResolver(formSchema),
37+
defaultValues: {
38+
tokenId: '',
39+
},
40+
});
41+
42+
useTxStatus({
43+
successHash: txResult?.hash,
44+
pendingHash: transaction?.getHash()?.toString(),
45+
error,
46+
pending,
47+
});
48+
49+
const onSubmit = ({ tokenId }: z.infer<typeof formSchema>) => {
50+
const args: TypedValue[] = [BytesValue.fromUTF8(tokenId.trim())];
51+
52+
// TODO: replace ContractCallPayloadBuilder
53+
const data = new ContractCallPayloadBuilder()
54+
.setFunction(new ContractFunction('stopNFTCreate'))
55+
.setArgs(args)
56+
.build();
57+
58+
triggerTx?.({
59+
address: builtInSC,
60+
gasLimit: commonOpertationsGasLimit,
61+
data,
62+
value: 0,
63+
});
64+
65+
form.reset();
66+
};
67+
68+
return (
69+
<>
70+
<OperationInfoBox error={error} txHash={txResult?.hash} />
71+
<Form {...form}>
72+
<form
73+
id="stop-creation-form"
74+
onSubmit={form.handleSubmit(onSubmit)}
75+
className="space-y-8"
76+
>
77+
<div className="flex-1 overflow-auto p-1">
78+
<OperationsTokenIdInput tokenType={tokenType} />
79+
</div>
80+
<OperationsSubmitButton formId="stop-creation-form" />
81+
</form>
82+
</Form>
83+
</>
84+
);
85+
};
Lines changed: 112 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,112 @@
1+
'use client';
2+
3+
import * as z from 'zod';
4+
import {
5+
BytesValue,
6+
TypedValue,
7+
ContractCallPayloadBuilder,
8+
ContractFunction,
9+
AddressValue,
10+
Address,
11+
} from '@multiversx/sdk-core';
12+
import { useForm } from 'react-hook-form';
13+
import { zodResolver } from '@hookform/resolvers/zod';
14+
import { Form } from '@/components/ui/form';
15+
import {
16+
commonOpertationsGasLimit,
17+
builtInSC,
18+
} from '@/components/operations/constants';
19+
import { OperationsInputField } from '@/components/operations/operations-input-field';
20+
import { OperationsSubmitButton } from '@/components/operations/operations-submit-button';
21+
import { CommonOpertationContentProps } from '@/components/operations/operations-common-types';
22+
import { OperationsTokenIdInput } from '@/components/operations/operations-tokenid-input';
23+
import { OperationInfoBox } from '@/components/operation-info-box';
24+
import { useTxStatus } from '@/hooks/use-tx-status';
25+
import { useTransaction } from '@useelven/core';
26+
27+
const formSchema = z.object({
28+
addressWithRole: z.string().min(1, 'The field is required'),
29+
newAddressForRole: z.string().min(1, 'The field is required'),
30+
tokenId: z.string().min(1, 'The field is required!'),
31+
});
32+
33+
export const TransferCreationRole = ({
34+
tokenType,
35+
}: {
36+
tokenType: CommonOpertationContentProps['tokenType'];
37+
}) => {
38+
const { triggerTx, error, txResult, transaction, pending } = useTransaction();
39+
40+
const form = useForm<z.infer<typeof formSchema>>({
41+
resolver: zodResolver(formSchema),
42+
defaultValues: {
43+
addressWithRole: '',
44+
newAddressForRole: '',
45+
tokenId: '',
46+
},
47+
});
48+
49+
useTxStatus({
50+
successHash: txResult?.hash,
51+
pendingHash: transaction?.getHash()?.toString(),
52+
error,
53+
pending,
54+
});
55+
56+
const onSubmit = ({
57+
tokenId,
58+
addressWithRole,
59+
newAddressForRole,
60+
}: z.infer<typeof formSchema>) => {
61+
const args: TypedValue[] = [
62+
BytesValue.fromUTF8(tokenId.trim()),
63+
new AddressValue(new Address(addressWithRole.trim())),
64+
new AddressValue(new Address(newAddressForRole.trim())),
65+
];
66+
67+
// TODO: replace ContractCallPayloadBuilder
68+
const data = new ContractCallPayloadBuilder()
69+
.setFunction(new ContractFunction('transferNFTCreateRole'))
70+
.setArgs(args)
71+
.build();
72+
73+
triggerTx?.({
74+
address: builtInSC,
75+
gasLimit: commonOpertationsGasLimit,
76+
data,
77+
value: 0,
78+
});
79+
80+
form.reset();
81+
};
82+
83+
return (
84+
<>
85+
<OperationInfoBox error={error} txHash={txResult?.hash} />
86+
<Form {...form}>
87+
<form
88+
id="transfer-creation-role-form"
89+
onSubmit={form.handleSubmit(onSubmit)}
90+
className="space-y-8"
91+
>
92+
<div className="flex-1 overflow-auto p-1">
93+
<OperationsTokenIdInput tokenType={tokenType} />
94+
<OperationsInputField
95+
name="addressWithRole"
96+
label="Current address with create role"
97+
placeholder="Example: erd1..."
98+
description="Please provide the address to transfer the role from"
99+
/>
100+
<OperationsInputField
101+
name="newAddressForRole"
102+
label="New address for create role"
103+
placeholder="Example: erd1..."
104+
description="Please provide the address to transfer the role to"
105+
/>
106+
</div>
107+
<OperationsSubmitButton formId="transfer-creation-role-form" />
108+
</form>
109+
</Form>
110+
</>
111+
);
112+
};

app/(operations)/layout.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ export default function OperationsLayout({
3434
children: React.ReactNode;
3535
}) {
3636
return (
37-
<div className="flex h-screen flex-col w-full fixed">
37+
<div className="fixed flex h-screen w-full flex-col">
3838
<OperationHeader />
3939
<div className="flex flex-1 flex-col overflow-hidden lg:flex-row">
4040
<nav className="border-r border-border bg-background px-3 lg:w-64 lg:px-6 lg:py-8">

0 commit comments

Comments
 (0)