-
Notifications
You must be signed in to change notification settings - Fork 4
feat: add a /developers landing page #104
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
0xApotheosis
merged 12 commits into
shapeshift:develop
from
swdiscordia:feat/developers-landing-page
Sep 8, 2026
Merged
Changes from 11 commits
Commits
Show all changes
12 commits
Select commit
Hold shift + click to select a range
f8bf632
feat(developers): add a /developers landing page for integration part…
swdiscordia 8372678
fix(developers): allow api.shapeshift.com in CSP so swap rates resolve
swdiscordia eaf1899
fix(developers): simplify CSP to match how the widget is actually doc…
swdiscordia f3b1c6d
fix(developers): scope CSP to exactly what asset selection and rates …
swdiscordia 3afc25d
fix(developers): match the documented integration exactly, fix real C…
swdiscordia f7d5ce4
fix(developers): propagate CSP headers on locale rewrite, hard-nav to…
swdiscordia dfa4499
fix(developers): correct API/URL content against the real API and docs
swdiscordia 5456fb1
fix(developers): theme-switcher focus guard, box alignment, footer grid
swdiscordia 39e0d15
fix(developers): dedupe CTA background image
swdiscordia a78efd8
fix(developers): drop the "snapshot" disclaimer under the stats row
swdiscordia 663f2e9
fix(developers): reserve space for swap quotes
0xApotheosis 4a62057
fix(developers): configure wallet access and address review feedback
0xApotheosis File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,75 @@ | ||
| import { motion } from 'framer-motion' | ||
|
|
||
| import { Button } from '@/app/[lang]/_components/Button' | ||
| import { LocalizedLink } from '@/app/[lang]/_components/LocalizedLink' | ||
| import { appDevelopers, developerDocsUrl } from '@/app/[lang]/_utils/constants' | ||
| import { DEVELOPERS_DICT } from '@/app/[lang]/_utils/dictionary/developers' | ||
|
|
||
| import { expandAnimation } from './animations' | ||
|
|
||
| import type { TAppLink } from '@/app/[lang]/_utils/constants' | ||
| import type { ReactNode } from 'react' | ||
|
|
||
| function DeveloperItem({ | ||
| name, | ||
| href, | ||
| target, | ||
| description, | ||
| icon, | ||
| onClick, | ||
| }: TAppLink & { onClick: () => void }): ReactNode { | ||
| return ( | ||
| <LocalizedLink | ||
| href={href} | ||
| target={target} | ||
| className={ | ||
| 'flex w-1/3 max-w-[232px] grow gap-2 rounded-lg px-6 py-4 transition-colors duration-300 hover:bg-white/10' | ||
| } | ||
| onClick={onClick} | ||
| > | ||
| <div className={'w-6 shrink-0'}>{icon}</div> | ||
| <div className={'ml-4 flex max-h-[120px] flex-col gap-1'}> | ||
| <span className={'whitespace-normal break-words text-sm font-medium leading-5'}>{name}</span> | ||
| {description && ( | ||
| <span className={'whitespace-normal break-words text-xs leading-5 text-gray-500'}>{description}</span> | ||
| )} | ||
| </div> | ||
| </LocalizedLink> | ||
| ) | ||
| } | ||
|
|
||
| export function DevelopersExpand({ setCurrentTab }: { setCurrentTab: (tab: string) => void }): ReactNode { | ||
| return ( | ||
| <motion.div className={'grid grid-cols-12'} {...expandAnimation}> | ||
| <div className={'col-span-4 flex flex-col border-r border-white/5 p-16'}> | ||
| <p className={'mb-4 text-2xl font-medium'}> | ||
| {DEVELOPERS_DICT.expand.titleLine1} <br /> | ||
| {DEVELOPERS_DICT.expand.titleLine2} | ||
| </p> | ||
| <p className={'mb-10 max-w-[327px] text-sm text-gray-500'}>{DEVELOPERS_DICT.expand.description}</p> | ||
| <Button | ||
| variant={'blue'} | ||
| className={'whitespace-nowrap'} | ||
| title={DEVELOPERS_DICT.expand.ctaButton} | ||
| href={developerDocsUrl} | ||
| /> | ||
| </div> | ||
|
|
||
| <div className={'col-span-8 p-16'}> | ||
| <div className={'flex flex-row flex-wrap gap-4'}> | ||
| {appDevelopers.map((developerResource) => ( | ||
| <DeveloperItem | ||
| onClick={() => setCurrentTab('empty')} | ||
| key={developerResource.name} | ||
| name={developerResource.name} | ||
| href={developerResource.href} | ||
| description={developerResource.description} | ||
| icon={developerResource.icon} | ||
| target={developerResource.target} | ||
| /> | ||
| ))} | ||
| </div> | ||
| </div> | ||
| </motion.div> | ||
| ) | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,18 @@ | ||
| import type { ReactNode, SVGProps } from 'react' | ||
|
|
||
| export function IconSettings(props: SVGProps<SVGSVGElement>): ReactNode { | ||
| return ( | ||
| <svg {...props} width={'24'} height={'24'} viewBox={'0 0 24 24'} fill={'none'} xmlns={'http://www.w3.org/2000/svg'}> | ||
| <circle cx={'12'} cy={'12'} r={'3'} stroke={'currentColor'} strokeWidth={'2'} /> | ||
| <path | ||
| d={ | ||
| 'M19.4 15a1.65 1.65 0 0 0 .33 1.82l.06.06a2 2 0 1 1-2.83 2.83l-.06-.06a1.65 1.65 0 0 0-1.82-.33 1.65 1.65 0 0 0-1 1.51V21a2 2 0 0 1-4 0v-.09A1.65 1.65 0 0 0 9 19.4a1.65 1.65 0 0 0-1.82.33l-.06.06a2 2 0 1 1-2.83-2.83l.06-.06a1.65 1.65 0 0 0 .33-1.82A1.65 1.65 0 0 0 3 13.09H2.91a2 2 0 0 1 0-4H3a1.65 1.65 0 0 0 1.51-1 1.65 1.65 0 0 0-.33-1.82l-.06-.06a2 2 0 1 1 2.83-2.83l.06.06a1.65 1.65 0 0 0 1.82.33H9a1.65 1.65 0 0 0 1-1.51V2.91a2 2 0 0 1 4 0V3a1.65 1.65 0 0 0 1 1.51 1.65 1.65 0 0 0 1.82-.33l.06-.06a2 2 0 1 1 2.83 2.83l-.06.06a1.65 1.65 0 0 0-.33 1.82V9a1.65 1.65 0 0 0 1.51 1h.09a2 2 0 0 1 0 4h-.09a1.65 1.65 0 0 0-1.51 1z' | ||
| } | ||
| stroke={'currentColor'} | ||
| strokeWidth={'2'} | ||
| strokeLinecap={'round'} | ||
| strokeLinejoin={'round'} | ||
| /> | ||
| </svg> | ||
| ) | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,82 @@ | ||
| export const DEVELOPERS_DICT = { | ||
| expand: { | ||
| titleLine1: 'Build with', | ||
| titleLine2: 'ShapeShift.', | ||
| description: 'Explore API documentation, integration guides, and reference material for crypto applications.', | ||
| ctaButton: 'View API Docs', | ||
| }, | ||
| page: { | ||
| widget: { | ||
| title: 'Your brand. Make it feel native.', | ||
| description: | ||
| 'Choose a theme, set the default assets, and preview a swap experience that feels built into your product.', | ||
| ctaButton: 'Open the widget sandbox', | ||
| }, | ||
| api: { | ||
| title: 'Skip the UI and build your own', | ||
| description: | ||
| 'Use the same routing engine through a REST API. We return unsigned transactions for your users to sign and broadcast.', | ||
| endpoints: [ | ||
| { | ||
| method: 'GET /v1/assets', | ||
| title: 'List chains and assets', | ||
| description: 'Enumerate what your users can trade, by CAIP-19 ID.', | ||
| }, | ||
| { | ||
| method: 'GET /v1/swap/rates', | ||
| title: 'Fetch rates for a pair', | ||
| description: 'One call returns a rate from every available swapper. No transaction yet.', | ||
| }, | ||
| { | ||
| method: 'POST /v1/swap/quote', | ||
| title: 'Get an executable quote', | ||
| description: 'Returns transaction data. Your user signs it in their own wallet, funds never touch us.', | ||
| }, | ||
| ], | ||
| }, | ||
| economics: { | ||
| title: 'How the revenue share works', | ||
| description: 'One partner code follows every swap to on-chain settlement. No invoices or payout schedules.', | ||
| }, | ||
| stats: { | ||
| chains: { value: '48+', title: 'Supported chains' }, | ||
|
swdiscordia marked this conversation as resolved.
|
||
| assets: { value: '30,000+', title: 'Tradable assets' }, | ||
| volume: { value: '$1.7B+', title: 'Lifetime swap volume' }, | ||
| }, | ||
| faq: { | ||
| title: 'Questions partners ask', | ||
| items: [ | ||
| { | ||
| question: 'Which chains are supported?', | ||
| answer: | ||
| 'Bitcoin, Ethereum and the major L2s (Arbitrum, Base, Optimism), Solana, Avalanche, BNB Chain, Cosmos, and more. 48+ chains today, with new routes added as the underlying aggregators support them. The full, current list is served by the API: https://api.shapeshift.com/v1/chains', | ||
| hasChainsLink: true, | ||
| }, | ||
| { | ||
| question: 'What does it cost to integrate?', | ||
| answer: | ||
| 'Nothing. There is no license fee or API key charge. Your affiliate fee is added on top of the protocol fee and paid directly to you.', | ||
| hasChainsLink: false, | ||
| }, | ||
| { | ||
| question: 'Who holds user funds?', | ||
| answer: | ||
| 'Swaps are non-custodial end to end. Users sign transactions from their own wallets, and funds move directly through the underlying protocols.', | ||
| hasChainsLink: false, | ||
| }, | ||
| { | ||
| question: 'What support do partners get?', | ||
| hasChainsLink: false, | ||
| answer: | ||
| 'Support does not stop at launch. Partners get a direct channel to our integration engineers for the lifetime of the integration, on both technical and marketing questions, plus example repos and a staging affiliate ID for testing.', | ||
| }, | ||
| ], | ||
| }, | ||
| cta: { | ||
| title: 'Integrate multichain swaps in your product', | ||
| description: 'Configure the Widget, preview your theme, create a partner code, and start earning on every swap.', | ||
| ctaPrimary: 'Configure the Widget', | ||
| ctaSecondary: 'Talk with us', | ||
| }, | ||
| }, | ||
| } as const | ||
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.