Skip to content

Commit b88f75b

Browse files
committed
Add successUrl support to payment page (#8341)
<!-- ## title your PR with this format: "[SDK/Dashboard/Portal] Feature/Fix: Concise title for the changes" If you did not copy the branch name from Linear, paste the issue tag here (format is TEAM-0000): ## Notes for the reviewer Anything important to call out? Be sure to also clarify these in your comments. ## How to test Unit tests, playground, etc. --> <!-- start pr-codex --> --- ## PR-Codex overview This PR introduces various configuration files, updates the `PayPage` component with URL validation, and enhances the fetch functionality with OAuth support. It also includes the addition of testing HTML and size limits for the package. ### Detailed summary - Added `wrap` export in `nexus-fetch.ts`. - Introduced `biome.json`, `.size-limit.json`, `tsconfig.json`, `tsconfig.build.json`, and `knip.json` for configuration. - Enhanced `PayPage` with `onlyUrl` validation and success URL handling. - Added testing HTML file for `nexus-fetch`. - Updated `package.json` with author and dependencies. - Improved fetch functionality with OAuth and error handling. > ✨ Ask PR-Codex anything about this PR by commenting with `/codex {your question}` <!-- end pr-codex --> <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit - **New Features** - Payment page now supports redirecting to a provided success URL after payment completes. - New nexus-fetch library adds automatic OAuth token management, PKCE-backed sign-in flow, automatic token refresh, and integrated handling of proxy payment flows for web requests. - **Chores** - Added build/configuration and size-limit files for the new nexus-fetch package. <!-- end of auto-generated comment: release notes by coderabbit.ai -->
1 parent c83f1c6 commit b88f75b

File tree

12 files changed

+811
-74
lines changed

12 files changed

+811
-74
lines changed

apps/dashboard/src/app/pay/page.tsx

Lines changed: 45 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -21,19 +21,44 @@ type SearchParams = {
2121
[key: string]: string | string[] | undefined;
2222
};
2323

24+
const onlyAddress = (v: string) => (isAddress(v) ? v : undefined);
25+
const onlyNumber = (v: string) =>
26+
Number.isNaN(Number(v)) ? undefined : Number(v);
27+
28+
/**
29+
* Validates and normalizes a URL string.
30+
* Only allows http: and https: protocols with a valid hostname.
31+
* @returns normalized URL string on success, undefined on failure
32+
*/
33+
const onlyUrl = (v: string): string | undefined => {
34+
try {
35+
const url = new URL(v);
36+
// Only allow http or https protocols
37+
if (url.protocol !== "http:" && url.protocol !== "https:") {
38+
return undefined;
39+
}
40+
// Ensure hostname is non-empty
41+
if (!url.hostname) {
42+
return undefined;
43+
}
44+
// Return normalized URL
45+
return url.toString();
46+
} catch {
47+
// Invalid URL format
48+
return undefined;
49+
}
50+
};
51+
2452
export default async function PayPage(props: {
2553
searchParams: Promise<SearchParams>;
2654
}) {
2755
const searchParams = await props.searchParams;
2856

29-
const onlyAddress = (v: string) => (isAddress(v) ? v : undefined);
30-
const onlyNumber = (v: string) =>
31-
Number.isNaN(Number(v)) ? undefined : Number(v);
32-
3357
const receiver = parse(searchParams.receiver, onlyAddress);
3458
const token = parse(searchParams.token, onlyAddress);
3559
const chain = parse(searchParams.chain, onlyNumber);
3660
const amount = parse(searchParams.amount, onlyNumber);
61+
const successUrl = parse(searchParams.successUrl, onlyUrl);
3762

3863
return (
3964
<ThemeProvider
@@ -51,6 +76,22 @@ export default async function PayPage(props: {
5176
tokenAddress={token}
5277
receiverAddress={receiver}
5378
amount={amount ? amount.toString() : undefined}
79+
onSuccess={() => {
80+
if (successUrl) {
81+
try {
82+
const url = new URL(successUrl);
83+
url.searchParams.set("success", "true");
84+
window.location.href = url.toString();
85+
} catch (error) {
86+
// Log URL construction error for debugging
87+
console.error(
88+
"Failed to construct redirect URL:",
89+
successUrl,
90+
error,
91+
);
92+
}
93+
}
94+
}}
5495
/>
5596
</div>
5697
</div>
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
[
2+
{
3+
"import": "*",
4+
"limit": "1 kB",
5+
"name": "@thirdweb-dev/nexus (esm)",
6+
"path": "./dist/esm/exports/nexus.js"
7+
},
8+
{
9+
"limit": "1 kB",
10+
"name": "@thirdweb-dev/nexus (cjs)",
11+
"path": "./dist/cjs/exports/nexus.js"
12+
}
13+
]

packages/nexus-fetch/biome.json

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
{
2+
"$schema": "https://biomejs.dev/schemas/2.0.6/schema.json",
3+
"extends": "//",
4+
"overrides": [
5+
{
6+
"assist": {
7+
"actions": {
8+
"source": {
9+
"useSortedKeys": "off"
10+
}
11+
}
12+
},
13+
"includes": ["package.json"]
14+
}
15+
]
16+
}

packages/nexus-fetch/knip.json

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
{
2+
"$schema": "https://unpkg.com/knip@5/schema.json",
3+
"entry": ["src/exports/**"],
4+
"ignore": ["src/**/__generated__/**", "**/*.bench.ts"],
5+
"ignoreBinaries": ["printf"],
6+
"ignoreDependencies": ["tslib"],
7+
"project": ["src/**/*.{ts,tsx}"],
8+
"rules": {
9+
"enumMembers": "off",
10+
"optionalPeerDependencies": "off"
11+
}
12+
}

packages/nexus-fetch/package.json

Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
{
2+
"author": "thirdweb eng <eng@thirdweb.com>",
3+
"browser": {
4+
"crypto": false
5+
},
6+
"bugs": {
7+
"url": "https://github.com/thirdweb-dev/js/issues"
8+
},
9+
"devDependencies": {
10+
"@biomejs/biome": "2.0.6",
11+
"@size-limit/preset-small-lib": "11.2.0",
12+
"knip": "5.60.2",
13+
"rimraf": "6.0.1",
14+
"size-limit": "11.2.0",
15+
"typescript": "5.8.3"
16+
},
17+
"engines": {
18+
"node": ">=22"
19+
},
20+
"exports": {
21+
".": {
22+
"types": "./dist/types/exports/nexus-fetch.d.ts",
23+
"import": "./dist/esm/exports/nexus-fetch.js",
24+
"default": "./dist/cjs/exports/nexus-fetch.js"
25+
}
26+
},
27+
"files": [
28+
"dist/*",
29+
"src/*",
30+
"!**/*.tsbuildinfo",
31+
"!**/*.test.ts",
32+
"!**/*.test.tsx",
33+
"!**/*.test.ts.snap",
34+
"!**/*.test-d.ts",
35+
"!**/*.bench.ts",
36+
"!tsconfig.build.json"
37+
],
38+
"license": "Apache-2.0",
39+
"main": "./dist/cjs/exports/nexus-fetch.js",
40+
"module": "./dist/esm/exports/nexus-fetch.js",
41+
"name": "@thirdweb-dev/fetch",
42+
"peerDependencies": {
43+
"typescript": ">=5.0.4"
44+
},
45+
"peerDependenciesMeta": {
46+
"typescript": {
47+
"optional": true
48+
}
49+
},
50+
"repository": {
51+
"type": "git",
52+
"url": "git+https://github.com/thirdweb-dev/js.git#main"
53+
},
54+
"scripts": {
55+
"build": "pnpm clean && pnpm build:types && pnpm build:cjs && pnpm build:esm",
56+
"build:cjs": "tsc --noCheck --project ./tsconfig.build.json --module commonjs --outDir ./dist/cjs --verbatimModuleSyntax false && printf '{\"type\":\"commonjs\"}' > ./dist/cjs/package.json",
57+
"build:esm": "tsc --noCheck --project ./tsconfig.build.json --module es2020 --outDir ./dist/esm && printf '{\"type\": \"module\",\"sideEffects\":false}' > ./dist/esm/package.json",
58+
"build:types": "tsc --project ./tsconfig.build.json --module nodenext --moduleResolution nodenext --declarationDir ./dist/types --emitDeclarationOnly --declaration --declarationMap",
59+
"clean": "rimraf dist",
60+
"dev": "tsc --project ./tsconfig.build.json --module nodenext --moduleResolution nodenext --outDir ./dist/esm --watch",
61+
"dev:cjs": "printf '{\"type\":\"commonjs\"}' > ./dist/cjs/package.json && tsc --noCheck --project ./tsconfig.build.json --module commonjs --outDir ./dist/cjs --verbatimModuleSyntax false --watch",
62+
"dev:esm": "printf '{\"type\": \"module\",\"sideEffects\":false}' > ./dist/esm/package.json && tsc --noCheck --project ./tsconfig.build.json --module es2020 --outDir ./dist/esm --watch",
63+
"fix": "biome check ./src --fix",
64+
"format": "biome format ./src --write",
65+
"knip": "knip",
66+
"lint": "knip && biome check ./src && tsc --project ./tsconfig.build.json --module nodenext --moduleResolution nodenext --noEmit",
67+
"size": "size-limit",
68+
"typecheck": "tsc --project ./tsconfig.build.json --module nodenext --moduleResolution nodenext --noEmit",
69+
"test:ui": "bun ./testing/test.html --watch"
70+
},
71+
"sideEffects": false,
72+
"type": "module",
73+
"types": "./dist/types/exports/nexus-fetch.d.ts",
74+
"typings": "./dist/types/exports/nexus-fetch.d.ts",
75+
"version": "0.0.0"
76+
}
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
export { wrap } from "../fetch.js";

0 commit comments

Comments
 (0)