Skip to content

Commit 3664a2e

Browse files
committed
Merge branch 'main' into greg/tool-2837-sdk-smart-accounts-use-6492-even-when-already-deployed
2 parents f4678cd + 4304759 commit 3664a2e

File tree

234 files changed

+4892
-1143
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

234 files changed

+4892
-1143
lines changed

.changeset/fair-planes-doubt.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"thirdweb": patch
3+
---
4+
5+
SDK: Fix chain switching in smart account transactions

.changeset/little-beds-dress.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"thirdweb": patch
3+
---
4+
5+
Add onTimeout callback to useAutoConnect

.changeset/pink-gorillas-try.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"thirdweb": patch
3+
---
4+
5+
SDK: Removed co.lobstr from the available wallets (an unsupported non-EVM wallet)

.changeset/yellow-experts-sparkle.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"thirdweb": patch
3+
---
4+
5+
SDK: Gracefully ignore chain with no chain ID in `fromEip1193Provider`

.github/pull_request_template.md

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,12 @@
1-
## Problem solved
1+
---
2+
title: "[SDK/Dashboard/Portal] Feature/Fix: Concise title for the changes"
3+
---
24

3-
Short description of the bug fixed or feature added
5+
If you did not copy the branch name from Linear, paste the issue tag here (format is TEAM-0000):
6+
7+
## Notes for the reviewer
8+
Anything important to call out? Be sure to also clarify these in your comments.
9+
10+
## How to test
11+
Unit tests, playground, etc.
412

.github/workflows/auto-assign.yml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ jobs:
1313
if: |
1414
github.event.pull_request.author_association == 'MEMBER' ||
1515
github.event.pull_request.author_association == 'OWNER' ||
16-
github.event.pull_request.author_association == 'COLLABORATOR'
16+
github.event.pull_request.author_association == 'COLLABORATOR' ||
17+
github.event.pull_request.author_association == 'CONTRIBUTOR'
1718
steps:
1819
- uses: toshimaru/auto-author-assign@v2.1.1

.github/workflows/issue.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ on:
55
types: [opened, edited, ready_for_review]
66

77
env:
8-
VALID_ISSUE_PREFIXES: "CORE|TOOL"
8+
VALID_ISSUE_PREFIXES: "CORE|TOOL|NEB|INFRA"
99

1010
jobs:
1111
linear:

.github/workflows/stale.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ jobs:
99
steps:
1010
- uses: actions/stale@v9
1111
with:
12-
stale-issue-message: 'This issue has been inactive for 30 days. It is now marked as stale and will be closed in 5 days if no further activity occurs.'
13-
stale-pr-message: 'This PR has been inactive for 30 days. It is now marked as stale and will be closed in 5 days if no further activity occurs.'
12+
stale-issue-message: 'This issue has been inactive for 7 days. It is now marked as stale and will be closed in 2 days if no further activity occurs.'
13+
stale-pr-message: 'This PR has been inactive for 7 days. It is now marked as stale and will be closed in 2 days if no further activity occurs.'
1414
days-before-stale: 7
1515
days-before-close: 2

apps/dashboard/next-env.d.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,4 +3,4 @@
33
/// <reference types="next/navigation-types/compat/navigation" />
44

55
// NOTE: This file should not be edited
6-
// see https://nextjs.org/docs/app/building-your-application/configuring/typescript for more information.
6+
// see https://nextjs.org/docs/app/api-reference/config/typescript for more information.

apps/dashboard/package.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,7 @@
6868
"ioredis": "^5.4.1",
6969
"ipaddr.js": "^2.2.0",
7070
"lucide-react": "0.468.0",
71-
"next": "15.1.0",
71+
"next": "15.1.3",
7272
"next-plausible": "^3.12.4",
7373
"next-seo": "^6.5.0",
7474
"next-themes": "^0.4.4",
@@ -85,7 +85,7 @@
8585
"react-dom": "19.0.0",
8686
"react-dropzone": "^14.3.5",
8787
"react-error-boundary": "^4.1.2",
88-
"react-hook-form": "7.53.2",
88+
"react-hook-form": "7.54.2",
8989
"react-markdown": "^9.0.1",
9090
"react-table": "^7.8.0",
9191
"recharts": "2.14.1",

apps/dashboard/src/app/(dashboard)/(chain)/[chain_id]/[contractAddress]/(marketplace)/components/list-form.tsx

Lines changed: 20 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ import { CurrencySelector } from "components/shared/CurrencySelector";
1818
import { SolidityInput } from "contract-ui/components/solidity-inputs";
1919
import { useTrack } from "hooks/analytics/useTrack";
2020
import { useAllChainsData } from "hooks/chains/allChains";
21+
import { useTxNotifications } from "hooks/useTxNotifications";
2122
import { isAlchemySupported } from "lib/wallet/nfts/alchemy";
2223
import { isMoralisSupported } from "lib/wallet/nfts/moralis";
2324
import { isSimpleHashSupported } from "lib/wallet/nfts/simpleHash";
@@ -125,6 +126,15 @@ export const CreateListingsForm: React.FC<CreateListingsFormProps> = ({
125126
walletAddress: account?.address,
126127
});
127128
const sendAndConfirmTx = useSendAndConfirmTransaction();
129+
const listingNotifications = useTxNotifications(
130+
"NFT listed Successfully",
131+
"Failed to list NFT",
132+
);
133+
134+
const auctionNotifications = useTxNotifications(
135+
"Auction created successfully",
136+
"Failed to create an auction",
137+
);
128138

129139
const form = useForm<ListForm>({
130140
defaultValues:
@@ -351,14 +361,11 @@ export const CreateListingsForm: React.FC<CreateListingsFormProps> = ({
351361
endTimestamp,
352362
});
353363

354-
const promise = sendAndConfirmTx.mutateAsync(transaction, {
364+
await sendAndConfirmTx.mutateAsync(transaction, {
355365
onSuccess: () => setOpen(false),
356366
});
357-
toast.promise(promise, {
358-
loading: "Listing NFT",
359-
success: "NFT listed successfully",
360-
error: "Failed to list NFT",
361-
});
367+
368+
listingNotifications.onSuccess();
362369
} else if (formData.listingType === "auction") {
363370
let minimumBidAmountWei: bigint;
364371
let buyoutBidAmountWei: bigint;
@@ -403,7 +410,7 @@ export const CreateListingsForm: React.FC<CreateListingsFormProps> = ({
403410
buyoutBidAmountWei: buyoutBidAmountWei * selectedQuantity,
404411
});
405412

406-
const promise = sendAndConfirmTx.mutateAsync(transaction, {
413+
await sendAndConfirmTx.mutateAsync(transaction, {
407414
onSuccess: () => {
408415
trackEvent({
409416
category: "marketplace",
@@ -423,15 +430,15 @@ export const CreateListingsForm: React.FC<CreateListingsFormProps> = ({
423430
});
424431
},
425432
});
426-
toast.promise(promise, {
427-
loading: "Creating auction",
428-
success: "Auction created successfully",
429-
error: "Failed to create auction",
430-
});
433+
auctionNotifications.onSuccess();
431434
}
432435
} catch (err) {
433436
console.error(err);
434-
toast.error("Failed to list NFT");
437+
if (formData.listingType === "auction") {
438+
auctionNotifications.onError(err);
439+
} else {
440+
listingNotifications.onError(err);
441+
}
435442
}
436443

437444
setIsFormLoading(false);

apps/dashboard/src/app/(dashboard)/(chain)/[chain_id]/[contractAddress]/nfts/[tokenId]/components/airdrop-tab.tsx

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ import { cn } from "@/lib/utils";
1212
import type { Account } from "@3rdweb-sdk/react/hooks/useApi";
1313
import { TransactionButton } from "components/buttons/TransactionButton";
1414
import { useTrack } from "hooks/analytics/useTrack";
15+
import { useTxNotifications } from "hooks/useTxNotifications";
1516
import { UploadIcon } from "lucide-react";
1617
import { useState } from "react";
1718
import { useForm } from "react-hook-form";
@@ -49,6 +50,10 @@ const AirdropTab: React.FC<AirdropTabProps> = ({
4950
const sendAndConfirmTx = useSendAndConfirmTransaction();
5051
const addresses = watch("addresses");
5152
const [open, setOpen] = useState(false);
53+
const airdropNotifications = useTxNotifications(
54+
"NFTs airdropped successfully",
55+
"Failed to airdrop NFTs",
56+
);
5257

5358
return (
5459
<div className="flex w-full flex-col gap-2">
@@ -86,7 +91,7 @@ const AirdropTab: React.FC<AirdropTabProps> = ({
8691
}),
8792
);
8893
const transaction = multicall({ contract, data });
89-
const promise = sendAndConfirmTx.mutateAsync(transaction, {
94+
await sendAndConfirmTx.mutateAsync(transaction, {
9095
onSuccess: () => {
9196
trackEvent({
9297
category: "nft",
@@ -108,14 +113,11 @@ const AirdropTab: React.FC<AirdropTabProps> = ({
108113
});
109114
},
110115
});
111-
toast.promise(promise, {
112-
loading: "Airdropping NFTs",
113-
success: "Airdropped successfully",
114-
error: "Failed to airdrop",
115-
});
116+
117+
airdropNotifications.onSuccess();
116118
} catch (err) {
117119
console.error(err);
118-
toast.error("Failed to airdrop NFTs");
120+
airdropNotifications.onError(err);
119121
}
120122
})}
121123
>

apps/dashboard/src/app/(dashboard)/(chain)/[chain_id]/[contractAddress]/nfts/[tokenId]/components/update-metadata-form.tsx

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ import { PropertiesFormControl } from "components/contract-pages/forms/propertie
1818
import { FileInput } from "components/shared/FileInput";
1919
import { useTrack } from "hooks/analytics/useTrack";
2020
import { useImageFileOrUrl } from "hooks/useImageFileOrUrl";
21+
import { useTxNotifications } from "hooks/useTxNotifications";
2122
import { type Dispatch, type SetStateAction, useMemo } from "react";
2223
import { useForm } from "react-hook-form";
2324
import { toast } from "sonner";
@@ -166,12 +167,16 @@ export const UpdateNftMetadata: React.FC<UpdateNftMetadataForm> = ({
166167
watch("animation_url") instanceof File ||
167168
watch("external_url") instanceof File;
168169
const sendAndConfirmTx = useSendAndConfirmTransaction();
170+
const updateMetadataNotifications = useTxNotifications(
171+
"NFT metadata updated successfully",
172+
"Failed to update NFT metadata",
173+
);
169174

170175
return (
171176
<form
172177
className="flex flex-col gap-6"
173178
id={UPDATE_METADATA_FORM_ID}
174-
onSubmit={handleSubmit((data) => {
179+
onSubmit={handleSubmit(async (data) => {
175180
if (!address) {
176181
toast.error("Please connect your wallet to update metadata.");
177182
return;
@@ -217,7 +222,7 @@ export const UpdateNftMetadata: React.FC<UpdateNftMetadataForm> = ({
217222
tokenId: BigInt(nft.id),
218223
newMetadata,
219224
});
220-
const promise = sendAndConfirmTx.mutateAsync(transaction, {
225+
await sendAndConfirmTx.mutateAsync(transaction, {
221226
onSuccess: () => {
222227
trackEvent({
223228
category: "nft",
@@ -237,13 +242,10 @@ export const UpdateNftMetadata: React.FC<UpdateNftMetadataForm> = ({
237242
},
238243
});
239244

240-
toast.promise(promise, {
241-
error: "Failed to update NFT metadata",
242-
success: "NFT metadata updated successfully",
243-
});
245+
updateMetadataNotifications.onSuccess();
244246
} catch (err) {
245247
console.error(err);
246-
toast.error("Failed to update NFT metadata");
248+
updateMetadataNotifications.onError(err);
247249
}
248250
})}
249251
>

apps/dashboard/src/app/(dashboard)/(chain)/[chain_id]/[contractAddress]/nfts/components/claim-button.tsx

Lines changed: 29 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -12,11 +12,12 @@ import type { Account } from "@3rdweb-sdk/react/hooks/useApi";
1212
import { FormControl, Input } from "@chakra-ui/react";
1313
import { TransactionButton } from "components/buttons/TransactionButton";
1414
import { useTrack } from "hooks/analytics/useTrack";
15+
import { useTxNotifications } from "hooks/useTxNotifications";
1516
import { GemIcon } from "lucide-react";
1617
import { useState } from "react";
1718
import { useForm } from "react-hook-form";
1819
import { toast } from "sonner";
19-
import { type ThirdwebContract, ZERO_ADDRESS } from "thirdweb";
20+
import { type ThirdwebContract, ZERO_ADDRESS, isAddress } from "thirdweb";
2021
import { getApprovalForTransaction } from "thirdweb/extensions/erc20";
2122
import { claimTo } from "thirdweb/extensions/erc721";
2223
import { useActiveAccount, useSendAndConfirmTransaction } from "thirdweb/react";
@@ -39,13 +40,17 @@ export const NFTClaimButton: React.FC<NFTClaimButtonProps> = ({
3940
}) => {
4041
const trackEvent = useTrack();
4142
const address = useActiveAccount()?.address;
42-
const { register, handleSubmit, formState } = useForm({
43+
const { register, handleSubmit, formState, setValue } = useForm({
4344
defaultValues: { amount: "1", to: address },
4445
});
4546
const { errors } = formState;
4647
const sendAndConfirmTx = useSendAndConfirmTransaction();
4748
const account = useActiveAccount();
4849
const [open, setOpen] = useState(false);
50+
const claimNFTNotifications = useTxNotifications(
51+
"NFT claimed successfully",
52+
"Failed to claim NFT",
53+
);
4954

5055
return (
5156
<Sheet open={open} onOpenChange={setOpen}>
@@ -62,7 +67,24 @@ export const NFTClaimButton: React.FC<NFTClaimButtonProps> = ({
6267
<div className="flex w-full flex-col gap-6 md:flex-row">
6368
<FormControl isRequired isInvalid={!!errors.to}>
6469
<FormLabel>To Address</FormLabel>
65-
<Input placeholder={ZERO_ADDRESS} {...register("to")} />
70+
<Input
71+
placeholder={ZERO_ADDRESS}
72+
{...register("to", {
73+
validate: (value) => {
74+
if (!value) {
75+
return "Enter a recipient address";
76+
}
77+
if (!isAddress(value.trim())) {
78+
return "Invalid EVM address";
79+
}
80+
},
81+
onChange: (e) => {
82+
setValue("to", e.target.value.trim(), {
83+
shouldValidate: true,
84+
});
85+
},
86+
})}
87+
/>
6688
<FormHelperText>Enter the address to claim to.</FormHelperText>
6789
<FormErrorMessage>{errors.to?.message}</FormErrorMessage>
6890
</FormControl>
@@ -110,7 +132,7 @@ export const NFTClaimButton: React.FC<NFTClaimButtonProps> = ({
110132

111133
const transaction = claimTo({
112134
contract,
113-
to: d.to,
135+
to: d.to.trim(),
114136
quantity: BigInt(d.amount),
115137
from: account.address,
116138
});
@@ -135,7 +157,7 @@ export const NFTClaimButton: React.FC<NFTClaimButtonProps> = ({
135157
await promise;
136158
}
137159

138-
const promise = sendAndConfirmTx.mutateAsync(transaction, {
160+
await sendAndConfirmTx.mutateAsync(transaction, {
139161
onSuccess: () => {
140162
trackEvent({
141163
category: "nft",
@@ -154,14 +176,10 @@ export const NFTClaimButton: React.FC<NFTClaimButtonProps> = ({
154176
},
155177
});
156178

157-
toast.promise(promise, {
158-
loading: "Claiming NFT(s)",
159-
success: "NFT(s) claimed successfully",
160-
error: "Failed to claim NFT(s)",
161-
});
179+
claimNFTNotifications.onSuccess();
162180
} catch (error) {
163181
console.error(error);
164-
toast.error((error as Error).message || "Error claiming NFT");
182+
claimNFTNotifications.onError(error);
165183
trackEvent({
166184
category: "nft",
167185
action: "claim",

0 commit comments

Comments
 (0)