1
1
import type { Metadata } from "next" ;
2
+ import Image from "next/image" ;
2
3
import { defineChain , getContract } from "thirdweb" ;
3
4
import { getCurrencyMetadata } from "thirdweb/extensions/erc20" ;
5
+ import { resolveScheme } from "thirdweb/storage" ;
4
6
import { checksumAddress } from "thirdweb/utils" ;
5
7
import { getPaymentLink } from "@/api/universal-bridge/links" ;
8
+ import { NEXT_PUBLIC_THIRDWEB_API_HOST } from "@/constants/public-envs" ;
9
+ import { API_SERVER_SECRET } from "@/constants/server-envs" ;
6
10
import { getClientThirdwebClient } from "@/constants/thirdweb-client.client" ;
7
11
import { PayPageWidget } from "../components/client/PayPageWidget.client" ;
12
+ import { payAppThirdwebClient } from "../constants" ;
8
13
9
14
const title = "thirdweb Pay" ;
10
15
const description = "Fast, secure, and simple payments." ;
@@ -38,13 +43,15 @@ export default async function PayPage({
38
43
chain : defineChain ( Number ( paymentLink . destinationToken . chainId ) ) ,
39
44
client : getClientThirdwebClient ( undefined ) ,
40
45
} ) ;
41
- const {
42
- symbol,
43
- decimals,
44
- name : tokenName ,
45
- } = await getCurrencyMetadata ( {
46
+ const currencyMetadataPromise = getCurrencyMetadata ( {
46
47
contract : tokenContract ,
47
48
} ) ;
49
+
50
+ const projectMetadataPromise = getProjectMetadata ( paymentLink . clientId ) ;
51
+
52
+ const [ { symbol, decimals, name : tokenName } , projectMetadata ] =
53
+ await Promise . all ( [ currencyMetadataPromise , projectMetadataPromise ] ) ;
54
+
48
55
const token = {
49
56
address : checksumAddress ( paymentLink . destinationToken . address ) ,
50
57
chainId : Number ( paymentLink . destinationToken . chainId ) ,
@@ -54,18 +61,62 @@ export default async function PayPage({
54
61
} ;
55
62
56
63
return (
57
- < PayPageWidget
58
- amount = { paymentLink . amount ? BigInt ( paymentLink . amount ) : undefined }
59
- chainId = { Number ( paymentLink . destinationToken . chainId ) }
60
- clientId = { undefined } // Payment links don't need to use the same client ID to be executed
61
- image = { paymentLink . imageUrl }
62
- name = { paymentLink . title }
63
- paymentLinkId = { id }
64
- purchaseData = { paymentLink . purchaseData }
65
- recipientAddress = { paymentLink . receiver }
66
- redirectUri = { redirectUri }
67
- theme = { theme }
68
- token = { token }
69
- />
64
+ < div className = "flex z-10 flex-col lg:flex-row h-full w-full" >
65
+ < header className = "min-w-full lg:min-w-[500px] border-b lg:border-r lg:h-full bg-card flex flex-col gap-4 items-start p-4 lg:p-8" >
66
+ < div className = "flex flex-row items-center justify-center gap-4" >
67
+ { projectMetadata . image && (
68
+ < Image
69
+ src = { resolveScheme ( {
70
+ uri : projectMetadata . image ,
71
+ client : payAppThirdwebClient ,
72
+ } ) }
73
+ alt = { projectMetadata . name }
74
+ width = { 25 }
75
+ height = { 25 }
76
+ className = "rounded-full overflow-hidden"
77
+ />
78
+ ) }
79
+ < h2 className = "text-xl font-bold" > { projectMetadata . name } </ h2 >
80
+ </ div >
81
+ { projectMetadata . description && (
82
+ < p className = "text-sm text-muted-foreground" >
83
+ { projectMetadata . description }
84
+ </ p >
85
+ ) }
86
+ </ header >
87
+ < main className = "flex justify-center p-12 w-full items-center" >
88
+ < PayPageWidget
89
+ amount = { paymentLink . amount ? BigInt ( paymentLink . amount ) : undefined }
90
+ chainId = { Number ( paymentLink . destinationToken . chainId ) }
91
+ clientId = { undefined } // Payment links don't need to use the same client ID to be executed
92
+ image = { paymentLink . imageUrl }
93
+ name = { paymentLink . title }
94
+ paymentLinkId = { id }
95
+ purchaseData = { paymentLink . purchaseData }
96
+ recipientAddress = { paymentLink . receiver }
97
+ redirectUri = { redirectUri }
98
+ theme = { theme }
99
+ token = { token }
100
+ />
101
+ </ main >
102
+ </ div >
70
103
) ;
71
104
}
105
+
106
+ async function getProjectMetadata ( clientId : string ) {
107
+ const url = new URL ( `${ NEXT_PUBLIC_THIRDWEB_API_HOST } /v2/keys/lookup` ) ;
108
+ url . searchParams . append ( "clientId" , clientId ) ;
109
+ const response = await fetch ( url . toString ( ) , {
110
+ headers : {
111
+ "x-service-api-key" : API_SERVER_SECRET ,
112
+ } ,
113
+ } ) ;
114
+ if ( ! response . ok ) {
115
+ throw new Error ( "Failed to fetch project" ) ;
116
+ }
117
+
118
+ const { data } = ( await response . json ( ) ) as {
119
+ data : { name : string ; image : string | null ; description : string | null } ;
120
+ } ;
121
+ return data ;
122
+ }
0 commit comments