Skip to content

Commit e03621c

Browse files
authored
Merge branch 'main' into yash/extension-input
2 parents cd89363 + d9091bd commit e03621c

File tree

151 files changed

+7524
-3331
lines changed

Some content is hidden

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

151 files changed

+7524
-3331
lines changed

.changeset/fifty-hoops-build.md

Lines changed: 0 additions & 5 deletions
This file was deleted.

.changeset/silver-chairs-return.md

Lines changed: 0 additions & 5 deletions
This file was deleted.

apps/dashboard/package.json

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -67,8 +67,8 @@
6767
"input-otp": "^1.4.1",
6868
"ioredis": "^5.6.0",
6969
"ipaddr.js": "^2.2.0",
70-
"lucide-react": "0.482.0",
71-
"next": "15.2.2",
70+
"lucide-react": "0.483.0",
71+
"next": "15.2.3",
7272
"next-plausible": "^3.12.4",
7373
"next-themes": "^0.4.6",
7474
"nextjs-toploader": "^1.6.12",
@@ -106,8 +106,8 @@
106106
"devDependencies": {
107107
"@chakra-ui/cli": "^2.4.1",
108108
"@chromatic-com/storybook": "3.2.6",
109-
"@next/bundle-analyzer": "15.2.2",
110-
"@next/eslint-plugin-next": "15.2.2",
109+
"@next/bundle-analyzer": "15.2.3",
110+
"@next/eslint-plugin-next": "15.2.3",
111111
"@playwright/test": "1.51.1",
112112
"@storybook/addon-essentials": "8.6.4",
113113
"@storybook/addon-interactions": "8.6.4",

apps/dashboard/src/@/api/sms.ts

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
import { API_SERVER_URL, THIRDWEB_API_SECRET } from "../constants/env";
2+
3+
export type SMSCountryTiers = {
4+
tier1: string[];
5+
tier2: string[];
6+
tier3: string[];
7+
tier4: string[];
8+
tier5: string[];
9+
};
10+
11+
export async function getSMSCountryTiers() {
12+
if (!THIRDWEB_API_SECRET) {
13+
throw new Error("API_SERVER_SECRET is not set");
14+
}
15+
const res = await fetch(`${API_SERVER_URL}/v1/sms/list-country-tiers`, {
16+
headers: {
17+
"Content-Type": "application/json",
18+
"x-service-api-key": THIRDWEB_API_SECRET,
19+
},
20+
next: {
21+
revalidate: 15 * 60, //15 minutes
22+
},
23+
});
24+
25+
if (!res.ok) {
26+
console.error(
27+
"Failed to fetch sms country tiers",
28+
res.status,
29+
res.statusText,
30+
);
31+
res.body?.cancel();
32+
return {
33+
tier1: [],
34+
tier2: [],
35+
tier3: [],
36+
tier4: [],
37+
tier5: [],
38+
};
39+
}
40+
41+
try {
42+
return (await res.json()).data as SMSCountryTiers;
43+
} catch (e) {
44+
console.error("Failed to parse sms country tiers", e);
45+
return {
46+
tier1: [],
47+
tier2: [],
48+
tier3: [],
49+
tier4: [],
50+
tier5: [],
51+
};
52+
}
53+
}

apps/dashboard/src/app/nebula-app/(app)/data/examplePrompts.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,15 +22,15 @@ Send native and ERC-20 currencies
2222
2323
### Deploy
2424
Deploy published contracts
25-
- Deploy a Token ERC20 Contract
25+
- Deploy a Token ERC20 Contract with name "Hello World" and description "My Hello Contract" on Ethereum.
2626
- Deploy a Split contract with two recipients.
2727
- Deploy an ERC1155 Contract named 'Hello World' with description 'Hello badges on Ethereum'
2828
2929
### Understand
3030
Retrieve information about smart contracts.
3131
- What ERC standards are implemented by contract address 0x59325733eb952a92e069C87F0A6168b29E80627f on Ethereum?
3232
- What functions can I use to mint more of my contract's NFTs?
33-
- What is the total supply of NFTs for my contract?
33+
- What is the total supply of NFTs on 0x8a90CAb2b38dba80c64b7734e58Ee1dB38B8992e?
3434
3535
### Interact
3636
Query wallet balances, addresses, and token holdings.

apps/dashboard/src/app/team/[team_slug]/(team)/~/engine/(instance)/[engineId]/wallet-credentials/components/credential-form.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,7 @@ export const CredentialForm = ({
7979
<DialogTitle>{title}</DialogTitle>
8080
<DialogDescription>
8181
<TrackedLinkTW
82-
href="https://portal.thirdweb.com/infrastructure/engine/features/wallet-credentials"
82+
href="https://portal.thirdweb.com/engine/features/wallet-credentials"
8383
target="_blank"
8484
label="learn-more"
8585
category="engine"

apps/dashboard/src/app/team/[team_slug]/(team)/~/engine/(instance)/[engineId]/wallet-credentials/components/wallet-credentials.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@ export const WalletCredentialsSection: React.FC<WalletCredentialsProps> = ({
6565
<p className="text-muted-foreground text-sm leading-relaxed">
6666
Manage your wallet credentials for different providers.{" "}
6767
<Link
68-
href="https://portal.thirdweb.com/infrastructure/engine/features/wallet-credentials"
68+
href="https://portal.thirdweb.com/engine/features/wallet-credentials"
6969
target="_blank"
7070
>
7171
Learn more about wallet credentials.

apps/dashboard/src/app/team/[team_slug]/[project_slug]/connect/in-app-wallets/settings/page.tsx

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import { getProject } from "@/api/projects";
2+
import { getSMSCountryTiers } from "@/api/sms";
23
import { getTeamBySlug } from "@/api/team";
34
import { redirect } from "next/navigation";
45
import { InAppWalletSettingsPage } from "../../../../../../../components/embedded-wallets/Configure";
@@ -9,9 +10,10 @@ export default async function Page(props: {
910
}) {
1011
const { team_slug, project_slug } = await props.params;
1112

12-
const [team, project] = await Promise.all([
13+
const [team, project, smsCountryTiers] = await Promise.all([
1314
getTeamBySlug(team_slug),
1415
getProject(team_slug, project_slug),
16+
getSMSCountryTiers(),
1517
]);
1618

1719
if (!team) {
@@ -29,6 +31,7 @@ export default async function Page(props: {
2931
trackingCategory="in-app-wallet-project-settings"
3032
teamSlug={team_slug}
3133
validTeamPlan={getValidTeamPlan(team)}
34+
smsCountryTiers={smsCountryTiers}
3235
/>
3336
);
3437
}

apps/dashboard/src/components/embedded-wallets/Configure/InAppWalletSettingsUI.stories.tsx

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,14 @@ function Variants(props: {
6464
isUpdating={false}
6565
trackingCategory="foo"
6666
updateApiKey={() => {}}
67+
smsCountryTiers={{
68+
// scaffold some countries to play around with the UI
69+
tier1: ["US", "CA"],
70+
tier2: ["GB", "AU", "NZ"],
71+
tier3: ["FR", "DE", "ES", "IT"],
72+
tier4: ["JP", "KR", "MX", "RU"],
73+
tier5: ["BR", "AR", "CO", "CL", "PE", "VE", "SA"],
74+
}}
6775
/>
6876
</div>
6977
</div>

apps/dashboard/src/components/embedded-wallets/Configure/index.tsx

Lines changed: 76 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
"use client";
22

33
import type { Project } from "@/api/projects";
4+
import type { SMSCountryTiers } from "@/api/sms";
45
import { DynamicHeight } from "@/components/ui/DynamicHeight";
56
import { Spinner } from "@/components/ui/Spinner/Spinner";
67
import { UnderlineLink } from "@/components/ui/UnderlineLink";
@@ -36,13 +37,15 @@ import { type UseFormReturn, useFieldArray, useForm } from "react-hook-form";
3637
import { toast } from "sonner";
3738
import { toArrFromList } from "utils/string";
3839
import type { Team } from "../../../@/api/team";
40+
import CountrySelector from "./sms-country-select/country-selector";
3941

4042
type InAppWalletSettingsPageProps = {
4143
trackingCategory: string;
4244
project: Project;
4345
teamId: string;
4446
teamSlug: string;
4547
validTeamPlan: Team["billingPlan"];
48+
smsCountryTiers: SMSCountryTiers;
4649
};
4750

4851
const TRACKING_CATEGORY = "embedded-wallet";
@@ -108,6 +111,7 @@ export function InAppWalletSettingsPage(props: InAppWalletSettingsPageProps) {
108111
canEditAdvancedFeatures={props.validTeamPlan !== "free"}
109112
updateApiKey={handleUpdateProject}
110113
isUpdating={updateProject.isPending}
114+
smsCountryTiers={props.smsCountryTiers}
111115
/>
112116
);
113117
}
@@ -120,6 +124,7 @@ const InAppWalletSettingsPageUI: React.FC<
120124
trackingData: UpdateAPIKeyTrackingData,
121125
) => void;
122126
isUpdating: boolean;
127+
smsCountryTiers: SMSCountryTiers;
123128
}
124129
> = (props) => {
125130
const embeddedWalletService = props.project.services.find(
@@ -185,6 +190,11 @@ export const InAppWalletSettingsUI: React.FC<
185190
}
186191
: undefined),
187192
redirectUrls: (config.redirectUrls || []).join("\n"),
193+
smsEnabledCountryISOs: config.smsEnabledCountryISOs
194+
? config.smsEnabledCountryISOs
195+
: canEditAdvancedFeatures
196+
? ["US", "CA"]
197+
: [],
188198
},
189199
});
190200

@@ -228,6 +238,7 @@ export const InAppWalletSettingsUI: React.FC<
228238
applicationImageUrl: branding?.applicationImageUrl,
229239
applicationName: branding?.applicationName || props.project.name,
230240
redirectUrls: toArrFromList(redirectUrls || "", true),
241+
smsEnabledCountryISOs: values.smsEnabledCountryISOs,
231242
};
232243
});
233244

@@ -256,6 +267,8 @@ export const InAppWalletSettingsUI: React.FC<
256267
canEditAdvancedFeatures={canEditAdvancedFeatures}
257268
/>
258269

270+
<NativeAppsFieldset form={form} />
271+
259272
{/* Authentication */}
260273
<Fieldset legend="Authentication">
261274
<JSONWebTokenFields
@@ -269,9 +282,15 @@ export const InAppWalletSettingsUI: React.FC<
269282
form={form}
270283
canEditAdvancedFeatures={canEditAdvancedFeatures}
271284
/>
272-
</Fieldset>
273285

274-
<NativeAppsFieldset form={form} />
286+
<div className="h-5" />
287+
288+
<SMSCountryFields
289+
form={form}
290+
canEditAdvancedFeatures={canEditAdvancedFeatures}
291+
smsCountryTiers={props.smsCountryTiers}
292+
/>
293+
</Fieldset>
275294

276295
<div className="flex justify-end">
277296
<Button type="submit" variant="primary" className="gap-2">
@@ -364,6 +383,61 @@ function BrandingFieldset(props: {
364383
);
365384
}
366385

386+
function SMSCountryFields(props: {
387+
form: UseFormReturn<ApiKeyEmbeddedWalletsValidationSchema>;
388+
canEditAdvancedFeatures: boolean;
389+
smsCountryTiers: SMSCountryTiers;
390+
}) {
391+
return (
392+
<div>
393+
<SwitchContainer
394+
switchId="sms-switch"
395+
title="SMS"
396+
description="Optionally allow users in selected countries to login via SMS OTP."
397+
>
398+
<GatedSwitch
399+
id="sms-switch"
400+
trackingLabel="sms"
401+
checked={
402+
!!props.form.watch("smsEnabledCountryISOs").length &&
403+
props.canEditAdvancedFeatures
404+
}
405+
upgradeRequired={!props.canEditAdvancedFeatures}
406+
onCheckedChange={(checked) =>
407+
props.form.setValue(
408+
"smsEnabledCountryISOs",
409+
checked
410+
? // by default, enable US and CA only
411+
["US", "CA"]
412+
: [],
413+
)
414+
}
415+
/>
416+
</SwitchContainer>
417+
418+
<AdvancedConfigurationContainer
419+
className="grid grid-cols-1"
420+
show={
421+
props.canEditAdvancedFeatures &&
422+
!!props.form.watch("smsEnabledCountryISOs").length
423+
}
424+
>
425+
<FormField
426+
control={props.form.control}
427+
name="smsEnabledCountryISOs"
428+
render={({ field }) => (
429+
<CountrySelector
430+
countryTiers={props.smsCountryTiers}
431+
selected={field.value}
432+
onChange={field.onChange}
433+
/>
434+
)}
435+
/>
436+
</AdvancedConfigurationContainer>
437+
</div>
438+
);
439+
}
440+
367441
function JSONWebTokenFields(props: {
368442
form: UseFormReturn<ApiKeyEmbeddedWalletsValidationSchema>;
369443
canEditAdvancedFeatures: boolean;

0 commit comments

Comments
 (0)