From ddef88866fcd586ac05f88ba43d3c4046e782f60 Mon Sep 17 00:00:00 2001 From: MananTank Date: Mon, 21 Jul 2025 20:42:32 +0000 Subject: [PATCH] [PRO-249] Portal: Update OG images (#7664) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ## PR-Codex overview This PR focuses on updating the metadata and image attributes across various pages in the `thirdweb` portal, particularly in the payments and vault sections. It modifies titles, icons, and descriptions to enhance clarity and consistency. ### Detailed summary - Changed `metadata` for payments to use "payments" icon and updated titles. - Updated vault metadata to include a new image with the "vault" icon. - Modified various page descriptions for clarity and consistency. - Added a new script for formatting in `package.json`. - Removed unused code in `api/og/route.tsx`. > ✨ Ask PR-Codex anything about this PR by commenting with `/codex {your question}` ## Summary by CodeRabbit * **New Features** * Added and updated metadata images and titles across several pages, including "Contracts", "Vault", and various "Payments" pages for improved visual representation. * Introduced support for a new "vault" icon in metadata image options. * **Style** * Improved formatting and removed extraneous blank lines in code examples and UI components for better readability. * Cleaned up whitespace in multiple example code snippets. * **Chores** * Added a new formatting script for consistent code style across the project. * **Refactor** * Simplified Open Graph image layouts by removing certain UI elements. --- apps/portal/package.json | 1 + apps/portal/public/og/background-1.png | Bin 5025 -> 6431 bytes .../og/icons/{contracts.svg => contract.svg} | 0 apps/portal/src/app/api/og/route.tsx | 51 ------------------ apps/portal/src/app/contracts/page.mdx | 4 ++ .../src/app/payments/custom-data/page.mdx | 6 +-- apps/portal/src/app/payments/layout.tsx | 2 +- apps/portal/src/app/payments/page.mdx | 4 +- .../portal/src/app/payments/products/page.mdx | 6 +-- apps/portal/src/app/payments/routes/page.mdx | 4 +- apps/portal/src/app/payments/sell/page.mdx | 4 +- apps/portal/src/app/payments/send/page.mdx | 8 +-- apps/portal/src/app/payments/tokens/page.mdx | 4 +- .../portal/src/app/payments/webhooks/page.mdx | 30 +++++------ apps/portal/src/app/vault/layout.tsx | 4 ++ apps/portal/src/app/vault/page.mdx | 4 ++ .../src/components/Document/metadata.ts | 3 +- 17 files changed, 49 insertions(+), 86 deletions(-) rename apps/portal/public/og/icons/{contracts.svg => contract.svg} (100%) diff --git a/apps/portal/package.json b/apps/portal/package.json index 40a45336830..f954824c382 100644 --- a/apps/portal/package.json +++ b/apps/portal/package.json @@ -70,6 +70,7 @@ "private": true, "scripts": { "build": "next build", + "format": "biome format ./src --write", "create-index": "pnpm tsx scripts/createEmptySearchIndex.ts", "dev": "next dev", "extract-llm-content": "pnpm tsx scripts/extractLLMData.ts", diff --git a/apps/portal/public/og/background-1.png b/apps/portal/public/og/background-1.png index a5992873fa51bb373a9af02af8b4b48819d7548c..fb24c14b46452533ad7a55fc6295e57f99bb5e47 100644 GIT binary patch literal 6431 zcmeHL_d6U~w;sLs6TL@`GRY{3VGt#P(M5Dd?}^@-h$smWohTv7D1$MP5iNQd6B50S zF2W#03xeyM?+>`Ye)qX&|F-vfp1t;Z-*>IO_ewO>*P^55qy_*0blML!i~#^r6aYXR zM0vdc@Q@IK0|4ybwKeXWhRkk{xB1Wk0KNM+HEPpF&3d)eZarWo$zwz1_Bt_oLt=Wk za%c-$sq==cZrd|&Uc5Qxv^-gumTXkO{=8e5f67Efz@385?W)qA7{{Ex3tmd`ucm%?0uQ#Ke$1(hv`7U3fj^a z{=}Utq}E?n9|Idxc9aGzK@SUmasyio{Nyc$F7P`$rvU=|=92j2)(g3LKHeF=$neym zF^N;zT)pm-CUhafuK&Dy#uGS264RSThdzn~7ygkej2iw}9qPXqF3)ork)wEen@1`? zYJQ0SdZQ`+#&+(cKAH3j*QU&=^ivQxBs=`{9*;CMKD>#8Q8LR*B6_+$dP=10Hhgta zcdj8(#NFYbTCb@=#LSe@w_>;XhXaMEJCm<*kLFV`aD`aH8N)s89(w8b{DLtRL=>H7 zTm_|$mLPGDrj|b;8fxh$Y1A${87Cj`;f)K~8-M^3*O^=D8+Q%tVUv zot0%3nK#@=@0&L5-P?q}%r`qedAjW}q7}!c(=(`&!UEHjT$dqm8_m+@Y=Zq|SFWaF zz8?UhWZ8HmYZ^n+BrB!Ro{hOH@5hwt*ObGtO&h3<9CE2MqvRBhL(=Zsmn$`VwTq+| zgoe@1(J-BtigGQT^-ihdte+FsW%bPxp00Un7If>J?=63K1~=|4HNFUM)YnrNgfdVX zlnyCh_GIhlJy(r}p9qqDYgD`YkJCifYD@_d?>d9MS)Y+m0HX*!NtpN?#2_QV<+1+c zr%wmF4Vz(HdyqOHM4-#P^3l5F+&5FOxn+DaD(IbqPa85{$(ik-#`C0tA{(YZZJb)( zMPwXck%W740Av95xTxhvq({qjn-OzgO8;7AB$Caf&zel#MdH&V7;*0TND(Rw62C*! zGZ(X-kiklW!@ZExDi!q9(*9<{qV!j)W9&3EMncf9kSPIlwSVx)!A<%f=k-C0-8O++ zRo0Go6{e(&Y#lkhJFBoVfIe40VPB^}mHS%}^;qa6?a|2iT`!jp=_3ML2KylqZ<_4| zd1c@~fXBmf4+pn~yAAB%n@u3Las(p0+_gMB?v<)wb-kpSZ%56`#!rlQMINv?va0`8 zNA{MuDFNM*)qLmWpoo?2L(=&r&O~^JwIR%x5eR4dYn+ZskRL@&g1@kh@(f0}F3<*4 z3}#>cQs!&+SQy)g9*)RC44)1u;5(cBl+^RAR`08*7Aa588n3g<8?vP|#^G9>_QuHx zI(r$>kK`?v$@X45RU%o^6U|a#hMMZ0O1!uB0U-`wWOl}fWT(O^NYTJ0@ye?zpVIlc zyYHHdH#;3_>S0mV*082E1Y>=8#_`Q^N0Lv8tXkWJeM)}Hy$D7#ijwN;YIq+Hs3Elv zDf)K6STTvaliz|f63#H7xiHhr3o@M~F*GA%0>$bQBu^$WN+ZXLj<++tpo$(K(3?KCj%m4#|q??G}J0*5a=z?1c^JX4uiboCSK!SHQ z;s9k4(Vh7gu!@{J!JQLN*I({V1b3pqmb-Ri7xOCW!hlSo6&kZ(X5>sAj?o4#vKJf^lZTBYiaI_$pXZ4zX zns#{%-DtyO4nb199xzBWAnh;^n#Ly^JfBT50OEsU~A~7g|@6F^$ zW=5$^I&4Hh8+2FRh<>Ij%}F#|y1dYMmIafAZhoAWL}%FV+%KhzL1qLkb8$QD_E$nv z9Bpc1o0h)T#09qUU>?p@9-Dkk*o9J+5gzRI{7A$6s>`+Oy!@>%_~}!ZpE$dElZ)!M zE$zfP(&@?w={{cZ!M3q&ZRb zcSvi@FA@vzK8c4+*KCu4;#6HYKCL)KoHzEBgk-kbNXK&$$CG=FLIqR)X5X?zgT9I) z8Lu30pW{;{(~IvCndfBC%NyNyYtM*aT$+b~OiZvhB~8MC!cxQ`X63esJA-5B zLq+r>@1t+|tXXAkSEMNGtjhuWC6zKKD#MtcGMfVdfQ4*tXeY^-H-`y;6Wvwi?vzej zLvEi7-ElI{_sJbC0encoV(_bFwJ2+9EI+Ym?{4?+fl$cC&6g#i4kt=oRcl&thktz> z=^jPgzQxHkl%AXUHJ5|!&r7EL?;}w8GP=`P;RDNIw+k@Nc}p&?F}cDa`;a1HoJS{^ zhCZdIZ?7~XpLi$n%ehw1oS;{>cSK&5uVi-GBFwZT{u^>*F$edfZ)qymdG0J&u*AY1 z+nPC2e}5T?;>`7!4a@G>bF*S8K+DFD1h{ffj?RXWr(nlv8kVk=Ak09Pi2v%;v}$xq z?m7FZV=w~6t)h!tBC@d5;9?XLX~UHi;zxPaG*x5m+M4(4Tf1f-yo%>6&l^?OC{Cu| z{2jVkr4yO5y!`Z&IOrFuK}Z7Gm=Ie0!cM18wkps3mTS&o$*uN;spfP)@}yOmpk zBgi!w?bq&C&e_14u9KMb)bS+Vjq51{kvd)JaMIdU^wd!EFRJQ1BnoQbPX*=-FYV52JS?3-pT0TdEPXL?pPLf&HOu#=K5Ut)Geb+! zHq!H_FLrd)gsR$MkJp_g*>(Wyo0j6UshSTUJ^Q})ccKFBT~qQZjJ;P7w?FVH?}0Q} zJP3%DKn6(qzHOZZi`!Gg@8wePX(~so=t*_A`P-oD!dFIKz zj@?qwbXKGX%y&5ZLe0auZF{ZPDRx2!@bdb0x(-rucp85i-4!+raX1#;|E?Ze()vEO z8`dxVUbYTpIh`|eSwAF>e8B<3J1fMlADy>Fzd~)ZyxX~w#67#PLn;=awoYq=gkMJ; z&c0GH5KBP~pQ*T$NQu%&=%-3ZJ~o#o6N=t0d?>0!rw_@Emo5?-C=lNOc}WP^DZ?^< zB?C)O*gIV|Rb?~*Qph*nf8JEa74Q-Pp6DH+RGSW#er&#&&~M(FOL9+kWmjmG;{HwO zs&Xy%;;{&t2w9qU;)OlhZ#QOO0;)=W5cc9*qsHCHqIn@2z3szWsOrvhkQAlhUEaAW z;n;X{3%x50<%N;;p^VE5?YV(ieZ69C{^4qL_+0L|C&76IFcSx^)tL#)Vl7JE9iy(! zq2Gk3DC>}4-GJHXhX!>9Z&P=SF@I_`FwcS_P_rQre`BxPOO@;Dn>Q{0BN(M?!Nkgs zE^(-pUWL65f>k$#}IGnD-@*(_yJRNpa5ZtatbaQzUf@^4I@{LU$R<*Mdk>xk;(lTA{I$i?WkC5q=y-BcoXieALJoARMb~P29 zikNUMk^S>8V>H!UZyLBPSN7Repu986iUx5XtugyH{5mOz^xic?-OGBpkzJ#Zj63%v zB)hC5)Xvx~9qxn}WQCHH{6}qK*9gt0egpBD`bG*)oX9B*!TXt7xcbWtqta0FSF7G* z2m`x@Ww@7>gd3c){Y|BcZC=ac53dH_J6!UcNC13PgwB6x%ub7`pR*N4FMMeXR72b_ zqcIp5KMsQDsbp>w48)OPyV+&lCH=2o@1;S{qX3g);mG1N0#sMAKYE9@eIEyutcK&48(G))Nldy*kim~B4WelNV2Ehur(90>4-?4d@t>#CN;#c|8-{W6dJDSfq!)0nRSR%O8z z`(`pLJnO&Rls-h}KdJ4x3gJ%&HKU>Q??k07zMa3)~ zrymz%T%JBL4;VNGmkSHDyD?wBJ}%HCg_DcafE~;+xe>v<-G5XQPFrZZf8fJz0LAy$ zNfUPT+atVQEb6giyt$*#gFGU7p}#@Jay{tB{`#e1(K>Rm zIUjHjbL}G1DQT4Dy=D>{rFkP|-K7Mm>E=&uM{mD2c%g?m5}AndSjIxc$K*}Uv(zaK zXb2gzTqTq*(f)pQ-~WETi49LfGFvk(0TG?sCnoG|i^Vat!kg20rY6P8)*?uEPdkvT zN^MQd1CDc1_FHVY7mH<%F;a`trPq5i4uBF0ilRmepCLW?QRlP_d#u@=5} zy2BE`O2)bL-rWSqNxmwgr$obWyMeqm|70)b=ks>zy*ok1=OKKmSNVVcH~yk^-7fq_ zVS46AA3mUibLYAbyp{;XgI#!h)Rv>1GIwnC0Hc(!RwxUH2SGr$l$hUiz4IB+s`=-{ zPo$-8Tr>D=Po{`u`Q>K|XDx=w!^a{SHP0H`p98@Ow0h6a7k=~{W&WKo*Hp8F#fVuD z=ll0O6xp^rh6oIN$++nkydo|>WDM##zuLw_d{~VBid$ZVuDtouizp7J#Fph8n29*6ju5*dO-AaWk-n{l`gfl`lneZ<93t5eWK|X zHI^8;x7>@|vbtFA?UdP%RZ&xzK=&5H*{hMA2$y!k>|0N11TSBJo{c-(iD%8u?82|< z>bf>8cEso4{QH?h-=!Pk@yD6KJh`bwh>`;L<>^lI&fB?NFkzeQm1P?Y0%^~QI`?bG zZ0Y1g{c;sAd?BF+=*c`wH~FodQ^W?Q`KCE?(srV|3UBFW_{h61 z>#&+P142v5S}nijp@j5|3r-0S97?uwmg9@*-SQ65yBM=Av&WG2FiP@Y z_p9!Z(j;8>t7tok9Vl5DulrU1mrYA-ih-)c*9|`YA6JARQm~qQESVQ2%`_t`N@YxozE|8HXOXndW_7)QiU`4XCx*~D}I%K1K%zE1;J1l3)G>q@{8 zL*_)u`sTVA{5$zyFkq^yKRyGhcFg-ft)&4^wyK<1v&D0A8Gp|64>j*;1rEzy*P#E7 c5%P_J>-M9XIk3tMN4v;BnukCC{kCw5mgLST>><1e}fm{39UDn;Ep#K`vCYSWR z&-eRz-}m{x@Athoodru(2{RG^04jT~tq_3dRshCT#f?KV?Rak@nrNeo%fvEAKIvlp zTFT9qL#^cJ5DtJPL*gh`B^0r8=%pDeelzqHj?r!_UTSpc99%Z6pmS?@SX5I`?5e4B zncaBCq6CXXA_6}YDNOSF7=e_mxWY@K|ME0}V~UAbX~oMNPAr?{A!gJXwK{xJ0%qae z9);yM^p+T$L9;k2`*u1v?IeXUD+^Z#nTPMh?Q1878=S1sRZa?-6*~^ zg>V?MXJ6m_xyCHW!{H!vX+dQ9YGo>X*o)x0@F+a=(aI^uFeTR{ z<&s6R;vCPq11{)RwuR`zsK9!}AjQK>FG{l&&-8d`Bxf~-3W)YHkjL~|y-vGev{SGG zBElzcj~EP&kW24TbQWSv{1(MvM6Dvf@Eqy^sF@H$-2@GW`VnMM6XH>~aef{90{~IA zG|J4Fi~x{Y7pS{3f8%oXHyJzV^2X*P+<_PNn^bd|?V4Q;=kupChcB$(>+k9czS#LG zA8J1N_L^z;CtQC1LSD*qZQTt=sAD^WMep{Stvz>}Zko@WGoOj7oU_{<*fH_*wxd&b z-VSx|PSoB@tnw|M*Y{p?%hg@ZZC~D5_xh=~(pP`6;(_pRRVSZS+J1J9<)gi;R!eyc zjx>}yx~BFy&mMq37g1ZEoi_Qnv0tkHz)?_gx6`eelvI1j@l*XDr+!br*H8*e0Zm1S(0i+%fkEL54hFrv9(t=@ZahdO;qiEC0ezW zt84k?vzhH3p=%#Dc6Y`0#5BEp{@_4T6PtBmK6-XV3syq~9`IWXM$#L3q3T*qc)^7L<$uZg6 diff --git a/apps/portal/public/og/icons/contracts.svg b/apps/portal/public/og/icons/contract.svg similarity index 100% rename from apps/portal/public/og/icons/contracts.svg rename to apps/portal/public/og/icons/contract.svg diff --git a/apps/portal/src/app/api/og/route.tsx b/apps/portal/src/app/api/og/route.tsx index 13f581c8e22..fdf9ec7b30f 100644 --- a/apps/portal/src/app/api/og/route.tsx +++ b/apps/portal/src/app/api/og/route.tsx @@ -64,37 +64,6 @@ export async function GET(request: Request) { width: "50%", }} > -
- - -
- Docs -
-
-
{title}
- -
-
- Read More -
-

Premium Course

Complete guide to web3 development

- + setTimeout(resolve, 3000)); // Wait 3 seconds } } while (swapStatus.status === "PENDING"); - + if (swapStatus.status === "FAILED") { throw new Error("Swap transaction failed"); } diff --git a/apps/portal/src/app/payments/tokens/page.mdx b/apps/portal/src/app/payments/tokens/page.mdx index 180a256d0f4..b226b483bcd 100644 --- a/apps/portal/src/app/payments/tokens/page.mdx +++ b/apps/portal/src/app/payments/tokens/page.mdx @@ -22,8 +22,8 @@ import { ExternalLink } from "lucide-react"; export const metadata = createMetadata({ image: { - title: "Payments", - icon: "pay", + title: "Get Token Prices", + icon: "payments", }, title: "Get Token Prices", description: "Use thirdweb Payments to get any token's current price and metadata.", diff --git a/apps/portal/src/app/payments/webhooks/page.mdx b/apps/portal/src/app/payments/webhooks/page.mdx index cd351329c6d..03e7a8cb538 100644 --- a/apps/portal/src/app/payments/webhooks/page.mdx +++ b/apps/portal/src/app/payments/webhooks/page.mdx @@ -21,8 +21,8 @@ import { export const metadata = createMetadata({ image: { - title: "Payments", - icon: "pay", + title: "Payments Webhooks", + icon: "payments", }, title: "Payments Webhooks", description: "Learn how to set up and handle webhooks for thirdweb Payments transactions.", @@ -49,17 +49,17 @@ import { Bridge } from "thirdweb"; export async function POST(request: Request) { const body = await request.text(); const headers = Object.fromEntries(request.headers.entries()); - + try { const webhook = await Bridge.Webhook.parse( body, headers, process.env.WEBHOOK_SECRET // Your webhook secret ); - + // Process the webhook console.log("Webhook received:", webhook); - + return Response.json({ success: true }); } catch (error) { console.error("Webhook verification failed:", error); @@ -162,30 +162,30 @@ If you prefer to handle verification manually, you can verify webhooks using the ```typescript async function verifyWebhook( - payload: string, - headers: Record, + payload: string, + headers: Record, secret: string, tolerance = 300 // 5 minutes ) { // Get the signature and timestamp from headers const receivedSignature = headers["x-payload-signature"] || headers["x-pay-signature"]; const receivedTimestamp = headers["x-timestamp"] || headers["x-pay-timestamp"]; - + if (!receivedSignature || !receivedTimestamp) { throw new Error("Missing required webhook headers: signature or timestamp"); } - + // Verify timestamp const now = Math.floor(Date.now() / 1000); const timestamp = parseInt(receivedTimestamp, 10); const diff = Math.abs(now - timestamp); - + if (diff > tolerance) { throw new Error( `Webhook timestamp is too old. Difference: ${diff}s, tolerance: ${tolerance}s` ); } - + // Generate signature using Web Crypto API const encoder = new TextEncoder(); const key = await crypto.subtle.importKey( @@ -195,23 +195,23 @@ async function verifyWebhook( false, ["sign"] ); - + const signature = await crypto.subtle.sign( "HMAC", key, encoder.encode(`${receivedTimestamp}.${payload}`) ); - + // Convert the signature to hex string const computedSignature = Array.from(new Uint8Array(signature)) .map((b) => b.toString(16).padStart(2, "0")) .join(""); - + // Compare signatures if (computedSignature !== receivedSignature) { throw new Error("Invalid webhook signature"); } - + // Parse and return the payload return JSON.parse(payload); } diff --git a/apps/portal/src/app/vault/layout.tsx b/apps/portal/src/app/vault/layout.tsx index ad52cf1ed38..3a7b1545838 100644 --- a/apps/portal/src/app/vault/layout.tsx +++ b/apps/portal/src/app/vault/layout.tsx @@ -14,4 +14,8 @@ export const metadata = createMetadata({ description: "Vault is an open-source non-custodial key management service, secured with TEE architecture (AWS Nitro Enclaves) and designed for blockchain applications.", title: "Vault", + image: { + icon: "vault", + title: "thirdweb Vault", + }, }); diff --git a/apps/portal/src/app/vault/page.mdx b/apps/portal/src/app/vault/page.mdx index 05af3e32bd5..d7b3263a1ab 100644 --- a/apps/portal/src/app/vault/page.mdx +++ b/apps/portal/src/app/vault/page.mdx @@ -6,6 +6,10 @@ import { ArrowLeftRightIcon, UserLockIcon, UsersIcon, WalletIcon } from "lucide- export const metadata = createMetadata({ title: "thirdweb Vault", description: "An open-source, secure key management service for storing, managing, and protecting cryptographic keys and secrets.", + image: { + icon: "vault", + title: "thirdweb Vault", + }, }); # Vault diff --git a/apps/portal/src/components/Document/metadata.ts b/apps/portal/src/components/Document/metadata.ts index 1550d450eaf..f67188254d1 100644 --- a/apps/portal/src/components/Document/metadata.ts +++ b/apps/portal/src/components/Document/metadata.ts @@ -14,7 +14,8 @@ type DynamicImageOptions = { | "wallets" | "auth" | "contract" - | "payment" + | "payments" + | "vault" | "infra" | "rpc" | "storage"