{"id":13566876,"url":"https://github.com/dydxprotocol/v4-web","last_synced_at":"2026-03-16T23:03:40.228Z","repository":{"id":193593568,"uuid":"679908689","full_name":"dydxprotocol/v4-web","owner":"dydxprotocol","description":null,"archived":false,"fork":false,"pushed_at":"2026-01-10T01:01:49.000Z","size":94968,"stargazers_count":107,"open_issues_count":14,"forks_count":108,"subscribers_count":13,"default_branch":"main","last_synced_at":"2026-01-10T20:15:58.450Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/dydxprotocol.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":".github/CODEOWNERS","security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2023-08-17T22:41:14.000Z","updated_at":"2026-01-10T00:33:14.000Z","dependencies_parsed_at":"2023-11-26T22:27:03.711Z","dependency_job_id":"1e1eb85f-db78-4e7d-a4fe-146100c5188e","html_url":"https://github.com/dydxprotocol/v4-web","commit_stats":null,"previous_names":["dydxprotocol/v4-web"],"tags_count":348,"template":false,"template_full_name":null,"purl":"pkg:github/dydxprotocol/v4-web","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dydxprotocol%2Fv4-web","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dydxprotocol%2Fv4-web/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dydxprotocol%2Fv4-web/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dydxprotocol%2Fv4-web/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/dydxprotocol","download_url":"https://codeload.github.com/dydxprotocol/v4-web/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dydxprotocol%2Fv4-web/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28338972,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-12T10:58:46.209Z","status":"ssl_error","status_checked_at":"2026-01-12T10:58:42.742Z","response_time":98,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.5:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-08-01T13:02:18.648Z","updated_at":"2026-01-12T11:40:55.422Z","avatar_url":"https://github.com/dydxprotocol.png","language":"TypeScript","funding_links":[],"categories":["TypeScript"],"sub_categories":[],"readme":"\u003cp align=\"center\"\u003e\u003cimg src=\"https://dydx.exchange/icon.svg?\" width=\"256\" /\u003e\u003c/p\u003e\n\n\u003ch1 align=\"center\"\u003edYdX Chain Web\u003c/h1\u003e\n\n\u003cdiv align=\"center\"\u003e\n  \u003ca href='https://github.com/dydxprotocol/v4-web/blob/main/LICENSE'\u003e\n    \u003cimg src='https://img.shields.io/badge/License-AGPL_v3-blue.svg' alt='License' /\u003e\n  \u003c/a\u003e\n\u003c/div\u003e\n\n## Prerequisites\n\n- Node.js version 22 and `pnpm` installed on your system\n- Wallet Connect account\n\nFor deploying with Vercel, create an account with [Vercel](https://vercel.com/signup) if you don't have one already.\n\nFor deploying to IPFS, choose one of the following:\n\n- **Option 1:** A free [web3.storage](https://web3.storage/) account\n- **Option 2:** An IPFS client such as [IPFS Kubo](https://docs.ipfs.tech/install/command-line/)\n\nFor web3.storage, sign up for an account and generate an API token on the [API tokens page](https://web3.storage/manage/tokens). web3.storage offers an easy-to-use interface for storing and retrieving content on IPFS.\n\nAlternatively, follow the [IPFS Kubo installation guide](https://docs.ipfs.tech/install/command-line/) to download the IPFS command-line tool.\n\n## Part 1: Setting up your local environment\n\n### 1. Clone the repo\n\nClone the repository and navigate to its directory:\n\n```bash\ngit clone https://github.com/dydxprotocol/v4-web.git\ncd v4-web\n```\n\n### 2. Install pnpm and dependencies\n\nInstall pnpm and the project dependencies:\n\n```bash\nnpm i -g pnpm\npnpm i\n```\n\n## Part 2: Running the project locally\n\nRun the following command in the project directory to start the development server:\n\n```bash\npnpm dev\n```\n\nThe development server will be running at `http://localhost:5173` (or the port number displayed in the terminal). Visit this URL to interact with the web app and see your changes in real-time.\n\nTo view component stories:\n\n```bash\npnpm ladle\n```\n\nThis will automatically open your default browser at `http://localhost:61000`.\n\n## Part 3: Configuring environment\n\nAdd or modify the relevant endpoints, links and options in `/public/configs/v1/env.json`.\n\nYou'll need to provide a Wallet Connect project id to enable onboarding and wallet connection:\n\n- Create a project on https://cloud.walletconnect.com/app\n- Copy over the project ID into this [field](https://github.com/dydxprotocol/v4-web/blob/67ecbd75b43e0c264b7b4d2d9b3d969830b0621c/public/configs/env.json#L822C33-L822C46)\n\n## Part 4: Set Enviornment variables\n\nSet environment variables via `.env`.\n\n- `VITE_BASE_URL` (required): The base URL of the deployment (e.g., `https://www.example.com`).\n- `VITE_ALCHEMY_API_KEY` (optional): Add an Alchemy API key for EVM interactions; the app will fall back to public RPCs if not provided.\n- `VITE_PK_ENCRYPTION_KEY` (optional): AES encryption key used for signature obfuscation; necessary for enabling the \"Remember Me\" feature.\n- `VITE_V3_TOKEN_ADDRESS` (optional): Address of the V3 $DYDX token.\n- `VITE_TOKEN_MIGRATION_URI` (optional): The URL of the token migration website.\n- `AMPLITUDE_API_KEY` (optional): Amplitude API key for enabling Amplitude; used with `pnpm run build:inject-amplitude`.\n- `AMPLITUDE_SERVER_URL` (optional): Custom Amplitude server URL\n- `AMPLITUDE_SERVER_ZONE` (optional): Custom Amplitude server zone; if provided, `AMPLITUDE_SERVER_URL` must be provided too.\n- `GOOGLE_TAG_MANAGER_CONTAINER_ID` (optional): Id for a google tag manager container; used with `pnpm run build:inject-google-tag-manager`.\n- `HOTJAR_SITE_ID`, `HOTJAR_VERSION` (optional): used for enabling Hotjar tracking; used with `pnpm run build:inject-hotjar`\n- `BUGSNAG_API_KEY` (optional): API key for enabling Bugsnag; used with `pnpm run build:inject-bugsnag`.\n- `IOS_APP_ID` (optional): iOS app ID used for enabling deep linking to the iOS app; used with `pnpm run build:inject-app-deeplinks`.\n- `INTERCOM_APP_ID` (optional): Used for enabling Intercom; utilized with `pnpm run build:inject-intercom`.\n- `STATUS_PAGE_SCRIPT_URI` (optional): Used for enabling the status page; used with `pnpm run build:inject-statuspage`.\n- `SMARTBANNER_APP_NAME`, `SMARTBANNER_ORG_NAME`, `SMARTBANNER_ICON_URL`, `SMARTBANNER_APPSTORE_URL` (optional): Used for enabling the smart app banner; used with `pnpm run build:inject-smartbanner`.\n- `VITE_PRIVY_APP_ID` (optional): App ID used for enabling Privy authentication. For deployment of DYDX token holders use `clua5njf801bncvpa0woolzq4`.\n- `VITE_PRIVY_APP_CLIENT_ID` (optional): App Client ID used for enabling Privy authentication.\n- `VITE_ROBOTS` (optional): Value of the HTML meta tag \"robots\"; recommended values: `index, follow` or `noindex`.\n\n## Part 5: Configure entry points\n\n### HTML files\n\nEdit `scripts/generate-entry-points.js` and set up entry points according to your SEO needs. At least one entry point must be configured,\ni.e. at least one element must be present in the `ENTRY_POINTS` array. This array consists of objects of the form:\n\n```\n{\n    title: 'Page title',\n    description: 'Page description.',\n    fileName: 'HTML entry point file name, e.g.: index.html',\n},\n```\n\nThe build script will traverse these entries and create files in `entry-points` directory, modifying the `template.html` file accordingly\nfor each entry. The `rollupOptions` config option in `vite.config.ts` informs the framework about the location of all the entry points\ncreated above.\n\n### Rewrite rules\n\nEdit `vercel.json` and configure the `rewrites` configuration option. It is an array of objects of the form:\n\n```\n    {\n      \"source\": \"Regexp for matching the URL path, e.g.: /portfolio(/?.*)\",\n      \"destination\": \"Entry point file to use, e.g.: /entry-points/portfolio.html\"\n    },\n```\n\nNote: The first matching rule takes precedence over anything defined afterwards in the array.\n\n## Part 6: Configure sitemap generation (optional)\n\n1. Edit `public/configs/sitemap.json`. Provide the base site URL and the list of static URLs that you wish to appear in the sitemap.\n2. Edit the deploy command and ensure that `node scripts/generate-sitemap.js` is run before `pnpm run build`.\n\nThe sitemap will be generated at build time.\nIt will contain the static URLs as well as up-to-date URLs for market pairs.\nThe market pairs are evaluated by inspecting an appropriate REST API of a full node.\n\n# Testing\n\n## Unit testing\n\nRun unit tests with the following command: `pnpm run test`\n\n## Functional Testing\n\nFunctional testing is supported via Browserstack. To run the tests you need to set the following environment variables:\n\n- `BROWSERSTACK_USERNAME`: username of your browserstack account\n- `BROWSERSTACK_ACCESS_KEY`: access key of your browserstack account\n- `E2E_ENVIRONMENT_URL`: the URL you want to run the functional tests against\n\nTo run the tests run: `pnpm run wdio`\n\n# Local Client-js Development\n\n## Directory structure\n\nOur tooling assumes that the [v4-clients repo](https://github.com/dydxprotocol/v4-clients) is checked out alongside v4-web:\n\n```\n--- parent folder\n |___ v4-web\n |___ v4-clients\n```\n\n## Using your local v4-clients repo\n\nWhenever you have changes in v4-clients that you'd like to test in your local v4-web branch, use the following command:\n\n```\npnpm run install-local-client-js --clean\n```\n\nThe `--clean` option will uninstall the package first, **it is not needed on subsequent runs.**\n\n## Reverting to remote clients\n\nRevert any changes to @dydxprotocol/v4-clients in package.json and pnpm-lock.yaml. If you haven't made any other package changes, you can use:\n\n```\ngit restore main package.json\ngit restore main pnpm-lock.yaml\n```\n\nThen run `pnpm install`\n\n**Remember to revert to remote v4-clients before making a PR.**\n\n# Local Localization (l10n) Development\n\n## Directory structure\n\nOur tooling assumes that the [v4-localization repo](https://github.com/dydxprotocol/v4-localization) is checked out alongside v4-web:\n\n```\n--- parent folder\n |___ v4-web\n |___ v4-localization\n```\n\n## Using your local v4-localization repo\n\nWhen you want to begin developing in v4-localization:\n**kill your dev server first** then use the following command:\n\n```\npnpm run install-local-l10n\n```\n\n## Reverting to remote localization\n\nYou'll need to unlink your local localization package with the following command:\n\n```\npnpm run remove-local-l10n\n```\n\nYou will need to **restart your dev server** to see the revert take effect.\n\n# Deployments\n\n## Deploying with Vercel\n\n### Step 1: Connect your repository to Vercel\n\nSelect \"Import Git Repository\" from your dashboard, and provide the URL of this repository or your forked repository.\n\n### Step 2: Configure your project\n\nFor the \"Build \u0026 Development Settings\", we recommend the following:\n\n- Framework Preset: `Vite`\n- Build Command (override): `pnpm run build`\n\nBy default, the dev server runs in development mode and the build command runs in production mode. To override the default mode, you can pass in the `--mode` option flag. For example, if you want to build your app for testnet:\n\n```\npnpm run build --mode testnet\n```\n\nIf you wish to incorporate analytics via Amplitude, Hotjar and Bugsnag, you can use our scripts:\n`pnpm run build:inject-amplitude`, `pnpm run build:inject-hotjar` and `pnpm run build:inject-bugsnag`. You will need to provide your own API keys for these services. In the Environment Variables section, name the variables as `AMPLITUDE_API_KEY`, `HOTJAR_SITE_ID`, `HOTJAR_VERSION` and `BUGSNAG_API_KEY` and provide the respective keys as their values.\nTo incorporate all three services with a single command use `pnpm run build:inject-analytics`.\n\nIf you wish to incorporate smart banner for iOS and/or Android apps, you can use our scripts:\n`pnpm run build:inject-smartbanner`. You will need to provide your own app configurations for these services. In the Environment Variables section, name the variables as `SMARTBANNER_APP_NAME`, `SMARTBANNER_ORG_NAME`, `SMARTBANNER_ICON_URL` and `SMARTBANNER_APPSTORE_URL` or `SMARTBANNER_GOOGLEPLAY_URL` and provide the respective values.\n\nFor more details, check out Vercel's [official documentation](https://vercel.com/docs).\n\n## Deploying to IPFS\n\n### Must Enable HashRouting\n\nAdd the following to `.env` file\n\n```\nVITE_ROUTER_TYPE=hash\n```\n\n### web3.storage: deploy to IPFS via web3.storage using the provided script\n\nExport the API token as an environment variable (replace `your_token` with the generated token), and run the script to build and deploy to IPFS:\n\n```bash\nexport WEB3_STORAGE_TOKEN=your_token\npnpm run deploy:ipfs\n```\n\nSave the URL provided in the output, as it is the link to your deployed content on IPFS.\n\n### IPFS client: deploy with the command-line tool\n\nTo use the IPFS command-line tool, run:\n\n```bash\nipfs add -r dist\n```\n\nSave the CID provided in the output.\n\n### Accessing your content on IPFS\n\nTo access your content on IPFS:\n\n1. **Native IPFS support in a browser:** Use a browser with native IPFS support, such as Brave or Opera. Enable a local IPFS node and visit the URL directly using the IPNS protocol, like `ipfs://your_cid`.\n\n2. **Public IPFS gateway:** Access your content via a public IPFS gateway, such as [https://dweb.link](https://dweb.link/) or [https://w3s.link/](https://w3s.link/). Use the gateway URL with your CID appended, like `https://dweb.link/ipfs/your_cid`.\n\nReplace `your_cid` with the actual CID.\n\n## Cloudflare Settings\n\nWe recommend that you add your website to Cloudflare for additional security settings.\n\nTo block OFAC Sanctioned countries:\n\n1. Navigate Websites \u003e Domain \u003e Security \u003e WAF\n\n2. Create Rule with the following settings:\n\n- If incoming requests match\n  `(ip.geoip.country eq \"CU\") or (ip.geoip.country eq \"IR\") or (ip.geoip.country eq \"KP\") or (ip.geoip.country eq \"SY\") or (ip.geoip.country eq \"MM\") or (ip.geoip.subdivision_1_iso_code eq \"UA-09\") or (ip.geoip.subdivision_1_iso_code eq \"UA-14\") or (ip.geoip.subdivision_1_iso_code eq \"UA-43\")`\n- This rule will bring up a Cloudflare page when a restricted geography tries to access your site. You will have the option to display:\n  1. Custom Text\n  - (e.g. `Because you appear to be a resident of, or trading from, a jurisdiction that violates our terms of use, or have engaged in activity that violates our terms of use, you have been blocked. You may withdraw your funds from the protocol at any time.`)\n  2. Default Cloudflare WAF block page\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdydxprotocol%2Fv4-web","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdydxprotocol%2Fv4-web","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdydxprotocol%2Fv4-web/lists"}