Skip to content

Commit 7536759

Browse files
committed
disable settings for new deployments
1 parent 2432067 commit 7536759

File tree

5 files changed

+232
-8
lines changed

5 files changed

+232
-8
lines changed

apps/dashboard/src/app/(dashboard)/(chain)/[chain_id]/[contractAddress]/settings/ContractSettingsPage.tsx

Lines changed: 21 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import { Flex, GridItem, SimpleGrid } from "@chakra-ui/react";
44
import type { ThirdwebContract } from "thirdweb";
55
import * as CommonExt from "thirdweb/extensions/common";
66
import { SettingsMetadata } from "./components/metadata";
7+
import { SettingsPlatformFees } from "./components/platform-fees";
78
import { SettingsPrimarySale } from "./components/primary-sale";
89
import { SettingsRoyalties } from "./components/royalties";
910

@@ -21,6 +22,7 @@ const ContractSettingsPageInner: React.FC<ContractSettingsPageProps> = ({
2122
isContractMetadataSupported,
2223
isPrimarySaleSupported,
2324
isRoyaltiesSupported,
25+
isPlatformFeesSupported,
2426
twAccount,
2527
}) => {
2628
return (
@@ -57,6 +59,16 @@ const ContractSettingsPageInner: React.FC<ContractSettingsPageProps> = ({
5759
/>
5860
</GridItem>
5961
)}
62+
63+
{contract && (
64+
<GridItem order={isPlatformFeesSupported ? 4 : 103}>
65+
<SettingsPlatformFees
66+
contract={contract}
67+
detectedState={isPlatformFeesSupported ? "enabled" : "disabled"}
68+
twAccount={twAccount}
69+
/>
70+
</GridItem>
71+
)}
6072
</SimpleGrid>
6173
</Flex>
6274
</Flex>
@@ -67,8 +79,9 @@ export function ContractSettingsPage(props: {
6779
contract: ThirdwebContract;
6880
functionSelectors: string[];
6981
twAccount: Account | undefined;
82+
hasFeeConfig: boolean;
7083
}) {
71-
const { functionSelectors, contract, twAccount } = props;
84+
const { functionSelectors, contract, twAccount, hasFeeConfig } = props;
7285
return (
7386
<ContractSettingsPageInner
7487
contract={contract}
@@ -84,10 +97,13 @@ export function ContractSettingsPage(props: {
8497
CommonExt.isGetDefaultRoyaltyInfoSupported(functionSelectors),
8598
CommonExt.isSetDefaultRoyaltyInfoSupported(functionSelectors),
8699
].every(Boolean)}
87-
isPlatformFeesSupported={[
88-
CommonExt.isGetPlatformFeeInfoSupported(functionSelectors),
89-
CommonExt.isSetPlatformFeeInfoSupported(functionSelectors),
90-
].every(Boolean)}
100+
isPlatformFeesSupported={
101+
!hasFeeConfig &&
102+
[
103+
CommonExt.isGetPlatformFeeInfoSupported(functionSelectors),
104+
CommonExt.isSetPlatformFeeInfoSupported(functionSelectors),
105+
].every(Boolean)
106+
}
91107
twAccount={twAccount}
92108
/>
93109
);
Lines changed: 195 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,195 @@
1+
"use client";
2+
import { AdminOnly } from "@3rdweb-sdk/react/components/roles/admin-only";
3+
import type { Account } from "@3rdweb-sdk/react/hooks/useApi";
4+
import { Flex, FormControl } from "@chakra-ui/react";
5+
import { zodResolver } from "@hookform/resolvers/zod";
6+
import type { ExtensionDetectedState } from "components/buttons/ExtensionDetectedState";
7+
import { TransactionButton } from "components/buttons/TransactionButton";
8+
import { BasisPointsInput } from "components/inputs/BasisPointsInput";
9+
import { AddressOrEnsSchema, BasisPointsSchema } from "constants/schemas";
10+
import { SolidityInput } from "contract-ui/components/solidity-inputs";
11+
import { useTrack } from "hooks/analytics/useTrack";
12+
import { useTxNotifications } from "hooks/useTxNotifications";
13+
import { useForm } from "react-hook-form";
14+
import type { ThirdwebContract } from "thirdweb";
15+
import {
16+
getPlatformFeeInfo,
17+
setPlatformFeeInfo,
18+
} from "thirdweb/extensions/common";
19+
import {
20+
useActiveAccount,
21+
useReadContract,
22+
useSendAndConfirmTransaction,
23+
} from "thirdweb/react";
24+
import {
25+
Card,
26+
FormErrorMessage,
27+
FormLabel,
28+
Heading,
29+
Text,
30+
} from "tw-components";
31+
import z from "zod";
32+
import { SettingDetectedState } from "./detected-state";
33+
34+
// @internal
35+
const CommonPlatformFeeSchema = z.object({
36+
/**
37+
* platform fee basis points
38+
*/
39+
platform_fee_basis_points: BasisPointsSchema,
40+
/**
41+
* platform fee recipient address
42+
*/
43+
platform_fee_recipient: AddressOrEnsSchema,
44+
});
45+
46+
export const SettingsPlatformFees = ({
47+
contract,
48+
detectedState,
49+
twAccount,
50+
}: {
51+
contract: ThirdwebContract;
52+
detectedState: ExtensionDetectedState;
53+
twAccount: Account | undefined;
54+
}) => {
55+
const trackEvent = useTrack();
56+
const address = useActiveAccount()?.address;
57+
const sendAndConfirmTx = useSendAndConfirmTransaction();
58+
const platformFeesQuery = useReadContract(getPlatformFeeInfo, { contract });
59+
const platformFeeInfo = platformFeesQuery.data
60+
? {
61+
platform_fee_recipient: platformFeesQuery.data[0],
62+
platform_fee_basis_points: platformFeesQuery.data[1],
63+
}
64+
: undefined;
65+
66+
const form = useForm<z.input<typeof CommonPlatformFeeSchema>>({
67+
resolver: zodResolver(CommonPlatformFeeSchema),
68+
defaultValues: platformFeeInfo,
69+
values: platformFeeInfo,
70+
});
71+
72+
const { onSuccess, onError } = useTxNotifications(
73+
"Platform fee settings updated",
74+
"Error updating platform fee settings",
75+
contract,
76+
);
77+
78+
return (
79+
<Card p={0} position="relative">
80+
<SettingDetectedState type="platformFee" detectedState={detectedState} />
81+
<Flex
82+
as="form"
83+
onSubmit={form.handleSubmit((data) => {
84+
trackEvent({
85+
category: "settings",
86+
action: "set-platform-fees",
87+
label: "attempt",
88+
});
89+
const transaction = setPlatformFeeInfo({
90+
contract,
91+
platformFeeRecipient: data.platform_fee_recipient,
92+
platformFeeBps: BigInt(data.platform_fee_basis_points),
93+
});
94+
sendAndConfirmTx.mutate(transaction, {
95+
onSuccess: () => {
96+
trackEvent({
97+
category: "settings",
98+
action: "set-platform-fees",
99+
label: "success",
100+
});
101+
form.reset(data);
102+
onSuccess();
103+
},
104+
onError: (error) => {
105+
trackEvent({
106+
category: "settings",
107+
action: "set-platform-fees",
108+
label: "error",
109+
error,
110+
});
111+
onError(error);
112+
},
113+
});
114+
})}
115+
direction="column"
116+
>
117+
<Flex p={{ base: 6, md: 10 }} as="section" direction="column" gap={4}>
118+
<Heading size="title.sm">Platform fee</Heading>
119+
<Text size="body.md" fontStyle="italic">
120+
The wallet address that should receive the revenue from platform
121+
fees.
122+
</Text>
123+
<Flex gap={4} direction={{ base: "column", md: "row" }}>
124+
<FormControl
125+
isInvalid={
126+
!!form.getFieldState("platform_fee_recipient", form.formState)
127+
.error
128+
}
129+
isDisabled={!address}
130+
>
131+
<FormLabel>Recipient Address</FormLabel>
132+
<SolidityInput
133+
solidityType="address"
134+
formContext={form}
135+
{...form.register("platform_fee_recipient")}
136+
disabled={!address || sendAndConfirmTx.isPending}
137+
/>
138+
<FormErrorMessage>
139+
{
140+
form.getFieldState("platform_fee_recipient", form.formState)
141+
.error?.message
142+
}
143+
</FormErrorMessage>
144+
</FormControl>
145+
<FormControl
146+
isDisabled={!address}
147+
maxW={{ base: "100%", md: "200px" }}
148+
isInvalid={
149+
!!form.getFieldState(
150+
"platform_fee_basis_points",
151+
form.formState,
152+
).error
153+
}
154+
>
155+
<FormLabel>Percentage</FormLabel>
156+
<BasisPointsInput
157+
value={form.watch("platform_fee_basis_points")}
158+
onChange={(value) =>
159+
form.setValue("platform_fee_basis_points", value, {
160+
shouldDirty: true,
161+
shouldTouch: true,
162+
})
163+
}
164+
disabled={sendAndConfirmTx.isPending}
165+
/>
166+
<FormErrorMessage>
167+
{
168+
form.getFieldState(
169+
"platform_fee_basis_points",
170+
form.formState,
171+
).error?.message
172+
}
173+
</FormErrorMessage>
174+
</FormControl>
175+
</Flex>
176+
</Flex>
177+
<AdminOnly contract={contract}>
178+
<TransactionButton
179+
twAccount={twAccount}
180+
txChainID={contract.chain.id}
181+
transactionCount={1}
182+
disabled={platformFeesQuery.isPending || !form.formState.isDirty}
183+
type="submit"
184+
isPending={sendAndConfirmTx.isPending}
185+
className="!rounded-t-none rounded-xl"
186+
>
187+
{sendAndConfirmTx.isPending
188+
? "Updating Platform Fee Settings"
189+
: "Update Platform Fee Settings"}
190+
</TransactionButton>
191+
</AdminOnly>
192+
</Flex>
193+
</Card>
194+
);
195+
};

apps/dashboard/src/app/(dashboard)/(chain)/[chain_id]/[contractAddress]/settings/page.tsx

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
1+
import { DEFAULT_FEE_RECIPIENT } from "constants/addresses";
12
import { notFound } from "next/navigation";
23
import { localhost } from "thirdweb/chains";
4+
import { getPlatformFeeInfo } from "thirdweb/extensions/common";
35
import { getRawAccount } from "../../../../../account/settings/getAccount";
46
import { getContractPageParamsInfo } from "../_utils/getContractFromParams";
57
import { getContractPageMetadata } from "../_utils/getContractPageMetadata";
@@ -33,11 +35,19 @@ export default async function Page(props: {
3335
getContractPageMetadata(info.contract),
3436
]);
3537

38+
let hasFeeConfig = true;
39+
try {
40+
const feeInfo = await getPlatformFeeInfo({ contract });
41+
hasFeeConfig =
42+
feeInfo[0].toLowerCase() === DEFAULT_FEE_RECIPIENT.toLowerCase();
43+
} catch {}
44+
3645
return (
3746
<ContractSettingsPage
3847
contract={info.contract}
3948
functionSelectors={metadata.functionSelectors}
4049
twAccount={account}
50+
hasFeeConfig={hasFeeConfig}
4151
/>
4252
);
4353
}

apps/dashboard/src/components/contract-components/contract-deploy-form/custom-contract.tsx

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ import { Flex, FormControl } from "@chakra-ui/react";
1515
import { useMutation, useQuery } from "@tanstack/react-query";
1616
import { verifyContract } from "app/(dashboard)/(chain)/[chain_id]/[contractAddress]/sources/ContractSourcesPage";
1717
import { NetworkSelectorButton } from "components/selects/NetworkSelectorButton";
18+
import { DEFAULT_FEE_BPS, DEFAULT_FEE_RECIPIENT } from "constants/addresses";
1819
import { SolidityInput } from "contract-ui/components/solidity-inputs";
1920
import { useTrack } from "hooks/analytics/useTrack";
2021
import { useTxNotifications } from "hooks/useTxNotifications";
@@ -113,9 +114,6 @@ const voteParamsSet = new Set([
113114
"_initialVoteQuorumFraction",
114115
]);
115116

116-
const DEFAULT_FEE_BPS = 250;
117-
const DEFAULT_FEE_RECIPIENT = "0x1af20c6b23373350ad464700b5965ce4b0d2ad94";
118-
119117
function checkTwPublisher(publisher: string | undefined) {
120118
switch (publisher) {
121119
case "deployer.thirdweb.eth":
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,7 @@
11
export const THIRDWEB_DEPLOYER_ADDRESS =
22
"0xdd99b75f095d0c4d5112aCe938e4e6ed962fb024";
3+
4+
export const DEFAULT_FEE_RECIPIENT =
5+
"0x1af20c6b23373350ad464700b5965ce4b0d2ad94";
6+
7+
export const DEFAULT_FEE_BPS = 250;

0 commit comments

Comments
 (0)