├── .github └── workflows │ ├── generate.yml │ └── validate.yml ├── .gitignore ├── .prettierrc.js ├── LICENSE ├── README.md ├── bin ├── generate.mjs └── validate.mjs ├── data ├── AAVE │ ├── data.json │ └── logo.svg ├── BAL │ ├── data.json │ └── logo.png ├── CRV │ ├── data.json │ └── logo.png ├── DAI │ ├── data.json │ └── logo.svg ├── DAPP │ ├── data.json │ └── logo.svg ├── DODO │ ├── data.json │ └── logo.svg ├── GHO │ ├── data.json │ └── logo.png ├── IBEX │ ├── data.json │ └── logo.svg ├── KNC │ ├── data.json │ └── logo.svg ├── LUSD │ ├── data.json │ └── logo.svg ├── PufETH │ ├── data.json │ └── logo.svg ├── TRB │ ├── data.json │ └── logo.svg ├── UNI │ ├── data.json │ └── logo.png ├── USDC │ ├── data.json │ └── logo.svg ├── USDT │ ├── data.json │ └── logo.svg ├── WBTC │ ├── data.json │ └── logo.svg ├── WETH │ ├── data.json │ └── logo.png ├── rETH │ ├── data.json │ └── logo.svg └── wstETH │ ├── data.json │ └── logo.svg ├── package.json ├── scroll.png ├── scroll.svg ├── scroll.tokenlist.json ├── src ├── chains.mjs ├── defaultTokens.mjs ├── generate.mjs ├── validate.mjs └── validate │ ├── data.json.mjs │ ├── helper.mjs │ └── logo.mjs └── yarn.lock /.github/workflows/generate.yml: -------------------------------------------------------------------------------- 1 | name: Generate Token List 2 | 3 | on: 4 | workflow_dispatch: 5 | push: 6 | branches: [main] 7 | 8 | jobs: 9 | generate: 10 | name: generate 11 | if: | 12 | github.event.head_commit.committer.username != 'github-actions[bot]' 13 | && github.repository == 'scroll-tech/token-list' 14 | 15 | runs-on: ubuntu-latest 16 | 17 | steps: 18 | - uses: actions/checkout@v4 19 | with: 20 | token: ${{ secrets.PAT }} 21 | fetch-depth: 0 22 | 23 | - name: Use Node.js 24 | uses: actions/setup-node@v3 25 | with: 26 | node-version: 18.x 27 | 28 | - name: Install dependencies 29 | run: yarn install --frozen-lockfile 30 | 31 | - name: Patch token list version 32 | run: | 33 | git config --global user.email "github-actions[bot]@users.noreply.github.com" 34 | git config --global user.name "github-actions" 35 | npm version patch 36 | git reset --soft HEAD~1 37 | 38 | - name: Generate token list 39 | run: | 40 | yarn generate 41 | 42 | - name: Commit token list 43 | uses: stefanzweifel/git-auto-commit-action@v4 44 | with: 45 | commit_message: 'bot(ci): generate token list' 46 | file_pattern: scroll.tokenlist.json 47 | -------------------------------------------------------------------------------- /.github/workflows/validate.yml: -------------------------------------------------------------------------------- 1 | name: Validate PR 2 | 3 | on: 4 | push: 5 | branches: [main] 6 | pull_request: 7 | branches: [main] 8 | 9 | jobs: 10 | validate: 11 | name: validate 12 | runs-on: ubuntu-latest 13 | 14 | steps: 15 | - uses: actions/checkout@v4 16 | with: 17 | fetch-depth: 0 18 | 19 | - name: Use Node.js 20 | uses: actions/setup-node@v3 21 | with: 22 | node-version: 18.x 23 | 24 | - name: Get changed files 25 | id: changed-files 26 | uses: tj-actions/changed-files@v39 27 | with: 28 | dir_names: true 29 | files: | 30 | data/** 31 | 32 | - name: List all changed tokens 33 | id: changed_tokens 34 | run: | 35 | tokens="" 36 | for file in ${{ steps.changed-files.outputs.all_changed_files }}; do 37 | token=$(echo -e "$file" | sed -nr "s|^data/([^/]*/?).*|\1|p") 38 | tokens+="${token}," 39 | done 40 | echo "changed tokens: ${tokens%,*}" 41 | echo "result=${tokens%,*}" >> $GITHUB_OUTPUT 42 | 43 | - name: yarn install 44 | if: ${{ steps.changed_tokens.outputs.result != '' }} 45 | run: | 46 | yarn install --frozen-lockfile 47 | 48 | - name: Validate token list 49 | if: ${{ steps.changed_tokens.outputs.result != '' }} 50 | run: | 51 | yarn validate ${{ steps.changed_tokens.outputs.result }} 2> err.txt 1> std.txt 52 | 53 | - name: Print validation output 54 | if: ${{ always() && steps.changed_tokens.outputs.result != '' }} 55 | run: | 56 | echo '=== std.txt ===' 57 | cat std.txt 58 | echo '=== err.txt ===' 59 | cat err.txt 60 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Created by https://www.toptal.com/developers/gitignore/api/node,macos 2 | # Edit at https://www.toptal.com/developers/gitignore?templates=node,macos 3 | 4 | /std.txt 5 | /err.txt 6 | 7 | ### macOS ### 8 | # General 9 | .DS_Store 10 | .AppleDouble 11 | .LSOverride 12 | 13 | # Icon must end with two \r 14 | Icon 15 | 16 | 17 | # Thumbnails 18 | ._* 19 | 20 | # Files that might appear in the root of a volume 21 | .DocumentRevisions-V100 22 | .fseventsd 23 | .Spotlight-V100 24 | .TemporaryItems 25 | .Trashes 26 | .VolumeIcon.icns 27 | .com.apple.timemachine.donotpresent 28 | 29 | # Directories potentially created on remote AFP share 30 | .AppleDB 31 | .AppleDesktop 32 | Network Trash Folder 33 | Temporary Items 34 | .apdisk 35 | 36 | ### macOS Patch ### 37 | # iCloud generated files 38 | *.icloud 39 | 40 | ### Node ### 41 | # Logs 42 | logs 43 | *.log 44 | npm-debug.log* 45 | yarn-debug.log* 46 | yarn-error.log* 47 | lerna-debug.log* 48 | .pnpm-debug.log* 49 | 50 | # Diagnostic reports (https://nodejs.org/api/report.html) 51 | report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json 52 | 53 | # Runtime data 54 | pids 55 | *.pid 56 | *.seed 57 | *.pid.lock 58 | 59 | # Directory for instrumented libs generated by jscoverage/JSCover 60 | lib-cov 61 | 62 | # Coverage directory used by tools like istanbul 63 | coverage 64 | *.lcov 65 | 66 | # nyc test coverage 67 | .nyc_output 68 | 69 | # Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files) 70 | .grunt 71 | 72 | # Bower dependency directory (https://bower.io/) 73 | bower_components 74 | 75 | # node-waf configuration 76 | .lock-wscript 77 | 78 | # Compiled binary addons (https://nodejs.org/api/addons.html) 79 | build/Release 80 | 81 | # Dependency directories 82 | node_modules/ 83 | jspm_packages/ 84 | 85 | # Snowpack dependency directory (https://snowpack.dev/) 86 | web_modules/ 87 | 88 | # TypeScript cache 89 | *.tsbuildinfo 90 | 91 | # Optional npm cache directory 92 | .npm 93 | 94 | # Optional eslint cache 95 | .eslintcache 96 | 97 | # Optional stylelint cache 98 | .stylelintcache 99 | 100 | # Microbundle cache 101 | .rpt2_cache/ 102 | .rts2_cache_cjs/ 103 | .rts2_cache_es/ 104 | .rts2_cache_umd/ 105 | 106 | # Optional REPL history 107 | .node_repl_history 108 | 109 | # Output of 'npm pack' 110 | *.tgz 111 | 112 | # Yarn Integrity file 113 | .yarn-integrity 114 | 115 | # dotenv environment variable files 116 | .env 117 | .env.development.local 118 | .env.test.local 119 | .env.production.local 120 | .env.local 121 | 122 | # parcel-bundler cache (https://parceljs.org/) 123 | .cache 124 | .parcel-cache 125 | 126 | # Next.js build output 127 | .next 128 | out 129 | 130 | # Nuxt.js build / generate output 131 | .nuxt 132 | dist 133 | 134 | # Gatsby files 135 | .cache/ 136 | # Comment in the public line in if your project uses Gatsby and not Next.js 137 | # https://nextjs.org/blog/next-9-1#public-directory-support 138 | # public 139 | 140 | # vuepress build output 141 | .vuepress/dist 142 | 143 | # vuepress v2.x temp and cache directory 144 | .temp 145 | 146 | # Docusaurus cache and generated files 147 | .docusaurus 148 | 149 | # Serverless directories 150 | .serverless/ 151 | 152 | # FuseBox cache 153 | .fusebox/ 154 | 155 | # DynamoDB Local files 156 | .dynamodb/ 157 | 158 | # TernJS port file 159 | .tern-port 160 | 161 | # Stores VSCode versions used for testing VSCode extensions 162 | .vscode-test 163 | 164 | # yarn v2 165 | .yarn/cache 166 | .yarn/unplugged 167 | .yarn/build-state.yml 168 | .yarn/install-state.gz 169 | .pnp.* 170 | 171 | ### Node Patch ### 172 | # Serverless Webpack directories 173 | .webpack/ 174 | 175 | # Optional stylelint cache 176 | 177 | # SvelteKit build / generate output 178 | .svelte-kit 179 | 180 | # End of https://www.toptal.com/developers/gitignore/api/node,macos 181 | -------------------------------------------------------------------------------- /.prettierrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | $schema: 'http://json.schemastore.org/prettierrc', 3 | trailingComma: 'es5', 4 | tabWidth: 2, 5 | semi: false, 6 | singleQuote: true, 7 | arrowParens: 'always', 8 | } 9 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2022 Scroll 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Scroll Token List 2 | 3 | The Scroll Token List serves as a source of truth for services such as the Scroll Bridge UI. 4 | 5 | ## Adding a token to the list 6 | 7 | ### Create a folder for your token 8 | 9 | Create a folder inside the [data folder](https://github.com/scroll-tech/token-list/tree/main/data) with the same name as the symbol of the token you are trying to add. For example, if you are adding a token with the symbol "ETH" you must create a folder called ETH. 10 | 11 | ### Add a logo to your folder 12 | 13 | Add a logo to the data folder you just created. Your logo MUST be an SVG called `logo.svg`. Your logo should be at least 200x200 pt minimum and 256x256 pt preferred. 14 | 15 | ### Create a data file 16 | 17 | Add a file to your folder called `data.json` with the following format: 18 | 19 | ```json 20 | { 21 | "name": "Token Name", 22 | "symbol": "SYMBOL", 23 | "decimals": 18, 24 | "description": "A multi-chain token", 25 | "website": "https://token.com", 26 | "twitter": "@token", 27 | "tokens": { 28 | "ethereum": { 29 | "address": "0x1234123412341234123412341234123412341234" 30 | }, 31 | "scroll": { 32 | "address": "0x2345234523452345234523452345234523452345" 33 | }, 34 | "sepolia": { 35 | "address": "0x5678567856785678567856785678567856785678" 36 | }, 37 | "scroll-sepolia": { 38 | "address": "0x6789678967896789678967896789678967896789" 39 | } 40 | } 41 | } 42 | ``` 43 | 44 | You can use the `getL2ERC20Address` method in [L1GatewayRouter.sol](https://github.com/scroll-tech/scroll/blob/develop/contracts/src/L1/gateways/L1GatewayRouter.sol) to get your L2 address. 45 | 46 | ### Create a pull request 47 | 48 | Open a [pull request](https://github.com/scroll-tech/token-list/pulls) targeting `main` branch with the changes that you've made. Please only add one token per pull request to simplify the review process. This means two new files inside one new folder. If you want to add multiple tokens, please open different PRs for each token. 49 | -------------------------------------------------------------------------------- /bin/generate.mjs: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | 3 | import fs from 'fs' 4 | import { generate } from '../src/generate.mjs' 5 | 6 | fs.writeFileSync('scroll.tokenlist.json', JSON.stringify(generate(), null, 2)) 7 | -------------------------------------------------------------------------------- /bin/validate.mjs: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | 3 | import { validate } from '../src/validate.mjs' 4 | 5 | const changedTokens = process.argv[2].split(',') 6 | 7 | ;(async () => validate(changedTokens))() 8 | -------------------------------------------------------------------------------- /data/AAVE/data.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "Aave", 3 | "symbol": "AAVE", 4 | "decimals": 18, 5 | "tokens": { 6 | "ethereum": { 7 | "address": "0x7Fc66500c84A76Ad7e9c93437bFc5Ac33E2DDaE9" 8 | }, 9 | "scroll": { 10 | "address": "0x79379C0E09a41d7978f883a56246290eE9a8c4d3" 11 | } 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /data/AAVE/logo.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /data/BAL/data.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "Balancer", 3 | "symbol": "BAL", 4 | "decimals": 18, 5 | "tokens": { 6 | "ethereum": { 7 | "address": "0xba100000625a3754423978a60c9317c58a424e3D" 8 | }, 9 | "scroll": { 10 | "address": "0x6a28e90582c583fcd3347931c544819C31e9D0e0" 11 | } 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /data/BAL/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/scroll-tech/token-list/e5dcbd3937d31bfcc120f6cdd95f4e1b10b87e24/data/BAL/logo.png -------------------------------------------------------------------------------- /data/CRV/data.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "Curve DAO", 3 | "symbol": "CRV", 4 | "decimals": 18, 5 | "tokens": { 6 | "ethereum": { 7 | "address": "0xd533a949740bb3306d119cc777fa900ba034cd52" 8 | }, 9 | "scroll": { 10 | "address": "0xB755039eDc7910C1F1BD985D48322E55A31AC0bF" 11 | } 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /data/CRV/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/scroll-tech/token-list/e5dcbd3937d31bfcc120f6cdd95f4e1b10b87e24/data/CRV/logo.png -------------------------------------------------------------------------------- /data/DAI/data.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "Dai", 3 | "symbol": "DAI", 4 | "decimals": 18, 5 | "tokens": { 6 | "ethereum": { 7 | "address": "0x6B175474E89094C44Da98b954EedeAC495271d0F" 8 | }, 9 | "scroll": { 10 | "address": "0xcA77eB3fEFe3725Dc33bccB54eDEFc3D9f764f97" 11 | } 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /data/DAI/logo.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /data/DAPP/data.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "Pencils Protocol Token", 3 | "symbol": "DAPP", 4 | "decimals": 18, 5 | "tokens": { 6 | "ethereum": { 7 | "address": "0x5FC429110A64bC51b57Ca86dCE1714FD0fBec303" 8 | }, 9 | "scroll": { 10 | "address": "0xb0643F7b3e2E2F10FE4e38728a763eC05f4ADeC3" 11 | } 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /data/DAPP/logo.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | logo 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /data/DODO/data.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "DODO bird", 3 | "symbol": "DODO", 4 | "decimals": 18, 5 | "description": "$DODO, DODO's native token, was created for two main functions: to incentivize growth and capture value.", 6 | "website": "https://dodoex.io", 7 | "twitter": "@BreederDodo", 8 | "tokens": { 9 | "ethereum": { 10 | "address": "0x43Dfc4159D86F3A37A5A4B3D4580b888ad7d4DDd" 11 | }, 12 | "scroll": { 13 | "address": "0x912aB742e1ab30ffa87038C425F9Bc8ED12B3EF4" 14 | } 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /data/DODO/logo.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 9 | 画板 10 | Created with Sketch. 11 | 12 | 13 | 14 | 20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /data/GHO/data.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "Gho Token", 3 | "symbol": "GHO", 4 | "decimals": 18, 5 | "tokens": { 6 | "sepolia": { 7 | "address": "0x5d00fab5f2F97C4D682C1053cDCAA59c2c37900D" 8 | }, 9 | "scroll-sepolia": { 10 | "address": "0xD9692f1748aFEe00FACE2da35242417dd05a8615" 11 | } 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /data/GHO/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/scroll-tech/token-list/e5dcbd3937d31bfcc120f6cdd95f4e1b10b87e24/data/GHO/logo.png -------------------------------------------------------------------------------- /data/IBEX/data.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "Impermax Finance", 3 | "symbol": "IBEX", 4 | "decimals": 18, 5 | "description": "The lending protocol for market makers", 6 | "website": "https://impermax.finance/", 7 | "twitter": "@ImpermaxFinance", 8 | "tokens": { 9 | "ethereum": { 10 | "address": "0xf655c8567e0f213e6c634cd2a68d992152161dc6" 11 | }, 12 | "scroll": { 13 | "address": "0x78ab77f7d590fb101aa18affc238cbfea31ead5b" 14 | } 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /data/IBEX/logo.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /data/KNC/data.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "Kyber Network Crystal", 3 | "symbol": "KNC", 4 | "decimals": 18, 5 | "tokens": { 6 | "ethereum": { 7 | "address": "0xdefa4e8a7bcba345f687a2f1456f5edd9ce97202" 8 | }, 9 | "scroll": { 10 | "address": "0x608ef9A3BffE206B86c3108218003b3cfBf99c84" 11 | } 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /data/KNC/logo.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /data/LUSD/data.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "Liquity USD", 3 | "symbol": "LUSD", 4 | "decimals": 18, 5 | "tokens": { 6 | "ethereum": { 7 | "address": "0x5f98805A4E8be255a32880FDeC7F6728C6568bA0" 8 | }, 9 | "scroll": { 10 | "address": "0xeDEAbc3A1e7D21fE835FFA6f83a710c70BB1a051" 11 | } 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /data/LUSD/logo.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /data/PufETH/data.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "Puffer Vault", 3 | "symbol": "PufETH", 4 | "decimals": 18, 5 | "description": "Anti-Slashing Liquid Restaking. Earn while decentralizing Ethereum.", 6 | "website": "https://www.puffer.fi/", 7 | "twitter": "@puffer_finance", 8 | "tokens": { 9 | "ethereum": { 10 | "address": "0xD9A442856C234a39a81a089C06451EBAa4306a72" 11 | }, 12 | "scroll": { 13 | "address": "0xc4d46E8402F476F269c379677C99F18E22Ea030e" 14 | }, 15 | "sepolia": { 16 | "address": "0xf2CB21124867a26455aE414A529B0ddfBfeAb224" 17 | }, 18 | "scroll-sepolia": { 19 | "address": "0xCd19E32F4f6F4c8D10A416c0397297169E93b464" 20 | } 21 | } 22 | } 23 | 24 | -------------------------------------------------------------------------------- /data/TRB/data.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "Tellor Tributes", 3 | "symbol": "TRB", 4 | "decimals": 18, 5 | "description": "the decentralized oracle", 6 | "website": "https://www.tellor.io", 7 | "twitter": "@WeAreTellor", 8 | "tokens": { 9 | "ethereum": { 10 | "address": "0x88dF592F8eb5D7Bd38bFeF7dEb0fBc02cf3778a0" 11 | }, 12 | "scroll": { 13 | "address": "0xfda87943Be918360413979ce7296E1249fcb987e" 14 | }, 15 | "sepolia": { 16 | "address": "0x80fc34a2f9FfE86F41580F47368289C402DEc660" 17 | }, 18 | "scroll-sepolia": { 19 | "address": "0xC8224ebfC539bD69848516384bF310abED504639" 20 | } 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /data/TRB/logo.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /data/UNI/data.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "Uniswap", 3 | "symbol": "UNI", 4 | "decimals": 18, 5 | "tokens": { 6 | "ethereum": { 7 | "address": "0x1f9840a85d5aF5bf1D1762F925BDADdC4201F984" 8 | }, 9 | "scroll": { 10 | "address": "0x434cdA25E8a2CA5D9c1C449a8Cb6bCbF719233E8" 11 | } 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /data/UNI/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/scroll-tech/token-list/e5dcbd3937d31bfcc120f6cdd95f4e1b10b87e24/data/UNI/logo.png -------------------------------------------------------------------------------- /data/USDC/data.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "USD Coin", 3 | "symbol": "USDC", 4 | "decimals": 6, 5 | "tokens": { 6 | "ethereum": { 7 | "address": "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48" 8 | }, 9 | "scroll": { 10 | "address": "0x06eFdBFf2a14a7c8E15944D1F4A48F9F95F663A4" 11 | }, 12 | "goerli": { 13 | "address": "0x07865c6E87B9F70255377e024ace6630C1Eaa37F" 14 | }, 15 | "scroll-goerli": { 16 | "address": "0x67aE69Fd63b4fc8809ADc224A9b82Be976039509" 17 | }, 18 | "sepolia": { 19 | "address": "0x1c7D4B196Cb0C7B01d743Fbc6116a902379C7238" 20 | }, 21 | "scroll-sepolia": { 22 | "address": "0x7878290DB8C4f02bd06E0E249617871c19508bE6" 23 | } 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /data/USDC/logo.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /data/USDT/data.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "Tether", 3 | "symbol": "USDT", 4 | "decimals": 6, 5 | "tokens": { 6 | "ethereum": { 7 | "address": "0xdAC17F958D2ee523a2206206994597C13D831ec7" 8 | }, 9 | "scroll": { 10 | "address": "0xf55BEC9cafDbE8730f096Aa55dad6D22d44099Df" 11 | } 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /data/USDT/logo.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /data/WBTC/data.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "Wrapped BTC", 3 | "symbol": "WBTC", 4 | "decimals": 8, 5 | "tokens": { 6 | "ethereum": { 7 | "address": "0x2260FAC5E5542a773Aa44fBCfeDf7C193bc2C599" 8 | }, 9 | "scroll": { 10 | "address": "0x3C1BCa5a656e69edCD0D4E36BEbb3FcDAcA60Cf1" 11 | } 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /data/WBTC/logo.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | wrapped-bitcoin-wbtc 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /data/WETH/data.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "Wrapped Ether", 3 | "symbol": "WETH", 4 | "decimals": 18, 5 | "tokens": { 6 | "ethereum": { 7 | "address": "0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2" 8 | }, 9 | "scroll": { 10 | "address": "0x5300000000000000000000000000000000000004" 11 | }, 12 | "sepolia": { 13 | "address": "0xfFf9976782d46CC05630D1f6eBAb18b2324d6B14" 14 | }, 15 | "scroll-sepolia": { 16 | "address": "0x5300000000000000000000000000000000000004" 17 | } 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /data/WETH/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/scroll-tech/token-list/e5dcbd3937d31bfcc120f6cdd95f4e1b10b87e24/data/WETH/logo.png -------------------------------------------------------------------------------- /data/rETH/data.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "Rocket Pool ETH", 3 | "symbol": "rETH", 4 | "decimals": 18, 5 | "tokens": { 6 | "ethereum": { 7 | "address": "0xae78736Cd615f374D3085123A210448E74Fc6393" 8 | }, 9 | "scroll": { 10 | "address": "0x53878B874283351D26d206FA512aEcE1Bef6C0dD" 11 | } 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /data/rETH/logo.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /data/wstETH/data.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "Wrapped stETH", 3 | "symbol": "wstETH", 4 | "decimals": 18, 5 | "tokens": { 6 | "ethereum": { 7 | "address": "0x7f39C581F595B53c5cb19bD0b3f8dA6c935E2Ca0" 8 | }, 9 | "scroll": { 10 | "address": "0xf610A9dfB7C89644979b4A0f27063E9e7d7Cda32" 11 | }, 12 | "sepolia": { 13 | "address": "0xB82381A3fBD3FaFA77B3a7bE693342618240067b" 14 | }, 15 | "scroll-sepolia": { 16 | "address": "0x2DAf22Caf40404ad8ff0Ab1E77F9C08Fef3953e2" 17 | } 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /data/wstETH/logo.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "tokenlist", 3 | "version": "0.0.22", 4 | "scripts": { 5 | "validate": "./bin/validate.mjs", 6 | "generate": "./bin/generate.mjs" 7 | }, 8 | "dependencies": {}, 9 | "license": "MIT", 10 | "devDependencies": { 11 | "ethers": "^6.7.1", 12 | "glob": "^10.3.10" 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /scroll.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/scroll-tech/token-list/e5dcbd3937d31bfcc120f6cdd95f4e1b10b87e24/scroll.png -------------------------------------------------------------------------------- /scroll.tokenlist.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "Scroll Token List", 3 | "logoURI": "https://scroll-tech.github.io/token-list/scroll.png", 4 | "keywords": [ 5 | "scaling", 6 | "layer2", 7 | "infrastructure" 8 | ], 9 | "timestamp": "2024-10-29T15:03:34.892Z", 10 | "tokens": [ 11 | { 12 | "chainId": 1, 13 | "address": "0x7Fc66500c84A76Ad7e9c93437bFc5Ac33E2DDaE9", 14 | "name": "Aave", 15 | "symbol": "AAVE", 16 | "decimals": 18, 17 | "logoURI": "https://scroll-tech.github.io/token-list/data/AAVE/logo.svg", 18 | "extensions": { 19 | "scrollListId": "default", 20 | "scrollTokenId": "AAVE" 21 | } 22 | }, 23 | { 24 | "chainId": 534352, 25 | "address": "0x79379C0E09a41d7978f883a56246290eE9a8c4d3", 26 | "name": "Aave", 27 | "symbol": "AAVE", 28 | "decimals": 18, 29 | "logoURI": "https://scroll-tech.github.io/token-list/data/AAVE/logo.svg", 30 | "extensions": { 31 | "scrollListId": "default", 32 | "scrollTokenId": "AAVE" 33 | } 34 | }, 35 | { 36 | "chainId": 1, 37 | "address": "0xba100000625a3754423978a60c9317c58a424e3D", 38 | "name": "Balancer", 39 | "symbol": "BAL", 40 | "decimals": 18, 41 | "logoURI": "https://scroll-tech.github.io/token-list/data/BAL/logo.png", 42 | "extensions": { 43 | "scrollListId": "default", 44 | "scrollTokenId": "BAL" 45 | } 46 | }, 47 | { 48 | "chainId": 534352, 49 | "address": "0x6a28e90582c583fcd3347931c544819C31e9D0e0", 50 | "name": "Balancer", 51 | "symbol": "BAL", 52 | "decimals": 18, 53 | "logoURI": "https://scroll-tech.github.io/token-list/data/BAL/logo.png", 54 | "extensions": { 55 | "scrollListId": "default", 56 | "scrollTokenId": "BAL" 57 | } 58 | }, 59 | { 60 | "chainId": 1, 61 | "address": "0xd533a949740bb3306d119cc777fa900ba034cd52", 62 | "name": "Curve DAO", 63 | "symbol": "CRV", 64 | "decimals": 18, 65 | "logoURI": "https://scroll-tech.github.io/token-list/data/CRV/logo.png", 66 | "extensions": { 67 | "scrollListId": "default", 68 | "scrollTokenId": "CRV" 69 | } 70 | }, 71 | { 72 | "chainId": 534352, 73 | "address": "0xB755039eDc7910C1F1BD985D48322E55A31AC0bF", 74 | "name": "Curve DAO", 75 | "symbol": "CRV", 76 | "decimals": 18, 77 | "logoURI": "https://scroll-tech.github.io/token-list/data/CRV/logo.png", 78 | "extensions": { 79 | "scrollListId": "default", 80 | "scrollTokenId": "CRV" 81 | } 82 | }, 83 | { 84 | "chainId": 1, 85 | "address": "0x6B175474E89094C44Da98b954EedeAC495271d0F", 86 | "name": "Dai", 87 | "symbol": "DAI", 88 | "decimals": 18, 89 | "logoURI": "https://scroll-tech.github.io/token-list/data/DAI/logo.svg", 90 | "extensions": { 91 | "scrollListId": "default", 92 | "scrollTokenId": "DAI" 93 | } 94 | }, 95 | { 96 | "chainId": 534352, 97 | "address": "0xcA77eB3fEFe3725Dc33bccB54eDEFc3D9f764f97", 98 | "name": "Dai", 99 | "symbol": "DAI", 100 | "decimals": 18, 101 | "logoURI": "https://scroll-tech.github.io/token-list/data/DAI/logo.svg", 102 | "extensions": { 103 | "scrollListId": "default", 104 | "scrollTokenId": "DAI" 105 | } 106 | }, 107 | { 108 | "chainId": 1, 109 | "address": "0x5FC429110A64bC51b57Ca86dCE1714FD0fBec303", 110 | "name": "Pencils Protocol Token", 111 | "symbol": "DAPP", 112 | "decimals": 18, 113 | "logoURI": "https://scroll-tech.github.io/token-list/data/DAPP/logo.svg", 114 | "extensions": { 115 | "scrollListId": "extended", 116 | "scrollTokenId": "DAPP" 117 | } 118 | }, 119 | { 120 | "chainId": 534352, 121 | "address": "0xb0643F7b3e2E2F10FE4e38728a763eC05f4ADeC3", 122 | "name": "Pencils Protocol Token", 123 | "symbol": "DAPP", 124 | "decimals": 18, 125 | "logoURI": "https://scroll-tech.github.io/token-list/data/DAPP/logo.svg", 126 | "extensions": { 127 | "scrollListId": "extended", 128 | "scrollTokenId": "DAPP" 129 | } 130 | }, 131 | { 132 | "chainId": 1, 133 | "address": "0x43Dfc4159D86F3A37A5A4B3D4580b888ad7d4DDd", 134 | "name": "DODO bird", 135 | "symbol": "DODO", 136 | "decimals": 18, 137 | "logoURI": "https://scroll-tech.github.io/token-list/data/DODO/logo.svg", 138 | "extensions": { 139 | "scrollListId": "extended", 140 | "scrollTokenId": "DODO" 141 | } 142 | }, 143 | { 144 | "chainId": 534352, 145 | "address": "0x912aB742e1ab30ffa87038C425F9Bc8ED12B3EF4", 146 | "name": "DODO bird", 147 | "symbol": "DODO", 148 | "decimals": 18, 149 | "logoURI": "https://scroll-tech.github.io/token-list/data/DODO/logo.svg", 150 | "extensions": { 151 | "scrollListId": "extended", 152 | "scrollTokenId": "DODO" 153 | } 154 | }, 155 | { 156 | "chainId": 11155111, 157 | "address": "0x5d00fab5f2F97C4D682C1053cDCAA59c2c37900D", 158 | "name": "Gho Token", 159 | "symbol": "GHO", 160 | "decimals": 18, 161 | "logoURI": "https://scroll-tech.github.io/token-list/data/GHO/logo.png", 162 | "extensions": { 163 | "scrollListId": "default", 164 | "scrollTokenId": "GHO" 165 | } 166 | }, 167 | { 168 | "chainId": 534351, 169 | "address": "0xD9692f1748aFEe00FACE2da35242417dd05a8615", 170 | "name": "Gho Token", 171 | "symbol": "GHO", 172 | "decimals": 18, 173 | "logoURI": "https://scroll-tech.github.io/token-list/data/GHO/logo.png", 174 | "extensions": { 175 | "scrollListId": "extended", 176 | "scrollTokenId": "GHO" 177 | } 178 | }, 179 | { 180 | "chainId": 1, 181 | "address": "0xf655c8567e0f213e6c634cd2a68d992152161dc6", 182 | "name": "Impermax Finance", 183 | "symbol": "IBEX", 184 | "decimals": 18, 185 | "logoURI": "https://scroll-tech.github.io/token-list/data/IBEX/logo.svg", 186 | "extensions": { 187 | "scrollListId": "extended", 188 | "scrollTokenId": "IBEX" 189 | } 190 | }, 191 | { 192 | "chainId": 534352, 193 | "address": "0x78ab77f7d590fb101aa18affc238cbfea31ead5b", 194 | "name": "Impermax Finance", 195 | "symbol": "IBEX", 196 | "decimals": 18, 197 | "logoURI": "https://scroll-tech.github.io/token-list/data/IBEX/logo.svg", 198 | "extensions": { 199 | "scrollListId": "extended", 200 | "scrollTokenId": "IBEX" 201 | } 202 | }, 203 | { 204 | "chainId": 1, 205 | "address": "0xdefa4e8a7bcba345f687a2f1456f5edd9ce97202", 206 | "name": "Kyber Network Crystal", 207 | "symbol": "KNC", 208 | "decimals": 18, 209 | "logoURI": "https://scroll-tech.github.io/token-list/data/KNC/logo.svg", 210 | "extensions": { 211 | "scrollListId": "default", 212 | "scrollTokenId": "KNC" 213 | } 214 | }, 215 | { 216 | "chainId": 534352, 217 | "address": "0x608ef9A3BffE206B86c3108218003b3cfBf99c84", 218 | "name": "Kyber Network Crystal", 219 | "symbol": "KNC", 220 | "decimals": 18, 221 | "logoURI": "https://scroll-tech.github.io/token-list/data/KNC/logo.svg", 222 | "extensions": { 223 | "scrollListId": "default", 224 | "scrollTokenId": "KNC" 225 | } 226 | }, 227 | { 228 | "chainId": 1, 229 | "address": "0x5f98805A4E8be255a32880FDeC7F6728C6568bA0", 230 | "name": "Liquity USD", 231 | "symbol": "LUSD", 232 | "decimals": 18, 233 | "logoURI": "https://scroll-tech.github.io/token-list/data/LUSD/logo.svg", 234 | "extensions": { 235 | "scrollListId": "default", 236 | "scrollTokenId": "LUSD" 237 | } 238 | }, 239 | { 240 | "chainId": 534352, 241 | "address": "0xeDEAbc3A1e7D21fE835FFA6f83a710c70BB1a051", 242 | "name": "Liquity USD", 243 | "symbol": "LUSD", 244 | "decimals": 18, 245 | "logoURI": "https://scroll-tech.github.io/token-list/data/LUSD/logo.svg", 246 | "extensions": { 247 | "scrollListId": "default", 248 | "scrollTokenId": "LUSD" 249 | } 250 | }, 251 | { 252 | "chainId": 1, 253 | "address": "0xD9A442856C234a39a81a089C06451EBAa4306a72", 254 | "name": "Puffer Vault", 255 | "symbol": "PufETH", 256 | "decimals": 18, 257 | "logoURI": "https://scroll-tech.github.io/token-list/data/PufETH/logo.svg", 258 | "extensions": { 259 | "scrollListId": "extended", 260 | "scrollTokenId": "PufETH" 261 | } 262 | }, 263 | { 264 | "chainId": 534352, 265 | "address": "0xc4d46E8402F476F269c379677C99F18E22Ea030e", 266 | "name": "Puffer Vault", 267 | "symbol": "PufETH", 268 | "decimals": 18, 269 | "logoURI": "https://scroll-tech.github.io/token-list/data/PufETH/logo.svg", 270 | "extensions": { 271 | "scrollListId": "extended", 272 | "scrollTokenId": "PufETH" 273 | } 274 | }, 275 | { 276 | "chainId": 11155111, 277 | "address": "0xf2CB21124867a26455aE414A529B0ddfBfeAb224", 278 | "name": "Puffer Vault", 279 | "symbol": "PufETH", 280 | "decimals": 18, 281 | "logoURI": "https://scroll-tech.github.io/token-list/data/PufETH/logo.svg", 282 | "extensions": { 283 | "scrollListId": "extended", 284 | "scrollTokenId": "PufETH" 285 | } 286 | }, 287 | { 288 | "chainId": 534351, 289 | "address": "0xCd19E32F4f6F4c8D10A416c0397297169E93b464", 290 | "name": "Puffer Vault", 291 | "symbol": "PufETH", 292 | "decimals": 18, 293 | "logoURI": "https://scroll-tech.github.io/token-list/data/PufETH/logo.svg", 294 | "extensions": { 295 | "scrollListId": "extended", 296 | "scrollTokenId": "PufETH" 297 | } 298 | }, 299 | { 300 | "chainId": 1, 301 | "address": "0xae78736Cd615f374D3085123A210448E74Fc6393", 302 | "name": "Rocket Pool ETH", 303 | "symbol": "rETH", 304 | "decimals": 18, 305 | "logoURI": "https://scroll-tech.github.io/token-list/data/rETH/logo.svg", 306 | "extensions": { 307 | "scrollListId": "default", 308 | "scrollTokenId": "rETH" 309 | } 310 | }, 311 | { 312 | "chainId": 534352, 313 | "address": "0x53878B874283351D26d206FA512aEcE1Bef6C0dD", 314 | "name": "Rocket Pool ETH", 315 | "symbol": "rETH", 316 | "decimals": 18, 317 | "logoURI": "https://scroll-tech.github.io/token-list/data/rETH/logo.svg", 318 | "extensions": { 319 | "scrollListId": "default", 320 | "scrollTokenId": "rETH" 321 | } 322 | }, 323 | { 324 | "chainId": 1, 325 | "address": "0x88dF592F8eb5D7Bd38bFeF7dEb0fBc02cf3778a0", 326 | "name": "Tellor Tributes", 327 | "symbol": "TRB", 328 | "decimals": 18, 329 | "logoURI": "https://scroll-tech.github.io/token-list/data/TRB/logo.svg", 330 | "extensions": { 331 | "scrollListId": "extended", 332 | "scrollTokenId": "TRB" 333 | } 334 | }, 335 | { 336 | "chainId": 534352, 337 | "address": "0xfda87943Be918360413979ce7296E1249fcb987e", 338 | "name": "Tellor Tributes", 339 | "symbol": "TRB", 340 | "decimals": 18, 341 | "logoURI": "https://scroll-tech.github.io/token-list/data/TRB/logo.svg", 342 | "extensions": { 343 | "scrollListId": "extended", 344 | "scrollTokenId": "TRB" 345 | } 346 | }, 347 | { 348 | "chainId": 11155111, 349 | "address": "0x80fc34a2f9FfE86F41580F47368289C402DEc660", 350 | "name": "Tellor Tributes", 351 | "symbol": "TRB", 352 | "decimals": 18, 353 | "logoURI": "https://scroll-tech.github.io/token-list/data/TRB/logo.svg", 354 | "extensions": { 355 | "scrollListId": "extended", 356 | "scrollTokenId": "TRB" 357 | } 358 | }, 359 | { 360 | "chainId": 534351, 361 | "address": "0xC8224ebfC539bD69848516384bF310abED504639", 362 | "name": "Tellor Tributes", 363 | "symbol": "TRB", 364 | "decimals": 18, 365 | "logoURI": "https://scroll-tech.github.io/token-list/data/TRB/logo.svg", 366 | "extensions": { 367 | "scrollListId": "extended", 368 | "scrollTokenId": "TRB" 369 | } 370 | }, 371 | { 372 | "chainId": 1, 373 | "address": "0x1f9840a85d5aF5bf1D1762F925BDADdC4201F984", 374 | "name": "Uniswap", 375 | "symbol": "UNI", 376 | "decimals": 18, 377 | "logoURI": "https://scroll-tech.github.io/token-list/data/UNI/logo.png", 378 | "extensions": { 379 | "scrollListId": "default", 380 | "scrollTokenId": "UNI" 381 | } 382 | }, 383 | { 384 | "chainId": 534352, 385 | "address": "0x434cdA25E8a2CA5D9c1C449a8Cb6bCbF719233E8", 386 | "name": "Uniswap", 387 | "symbol": "UNI", 388 | "decimals": 18, 389 | "logoURI": "https://scroll-tech.github.io/token-list/data/UNI/logo.png", 390 | "extensions": { 391 | "scrollListId": "default", 392 | "scrollTokenId": "UNI" 393 | } 394 | }, 395 | { 396 | "chainId": 1, 397 | "address": "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48", 398 | "name": "USD Coin", 399 | "symbol": "USDC", 400 | "decimals": 6, 401 | "logoURI": "https://scroll-tech.github.io/token-list/data/USDC/logo.svg", 402 | "extensions": { 403 | "scrollListId": "default", 404 | "scrollTokenId": "USDC" 405 | } 406 | }, 407 | { 408 | "chainId": 534352, 409 | "address": "0x06eFdBFf2a14a7c8E15944D1F4A48F9F95F663A4", 410 | "name": "USD Coin", 411 | "symbol": "USDC", 412 | "decimals": 6, 413 | "logoURI": "https://scroll-tech.github.io/token-list/data/USDC/logo.svg", 414 | "extensions": { 415 | "scrollListId": "default", 416 | "scrollTokenId": "USDC" 417 | } 418 | }, 419 | { 420 | "chainId": 5, 421 | "address": "0x07865c6E87B9F70255377e024ace6630C1Eaa37F", 422 | "name": "USD Coin", 423 | "symbol": "USDC", 424 | "decimals": 6, 425 | "logoURI": "https://scroll-tech.github.io/token-list/data/USDC/logo.svg", 426 | "extensions": { 427 | "scrollListId": "default", 428 | "scrollTokenId": "USDC" 429 | } 430 | }, 431 | { 432 | "chainId": 534353, 433 | "address": "0x67aE69Fd63b4fc8809ADc224A9b82Be976039509", 434 | "name": "USD Coin", 435 | "symbol": "USDC", 436 | "decimals": 6, 437 | "logoURI": "https://scroll-tech.github.io/token-list/data/USDC/logo.svg", 438 | "extensions": { 439 | "scrollListId": "default", 440 | "scrollTokenId": "USDC" 441 | } 442 | }, 443 | { 444 | "chainId": 11155111, 445 | "address": "0x1c7D4B196Cb0C7B01d743Fbc6116a902379C7238", 446 | "name": "USD Coin", 447 | "symbol": "USDC", 448 | "decimals": 6, 449 | "logoURI": "https://scroll-tech.github.io/token-list/data/USDC/logo.svg", 450 | "extensions": { 451 | "scrollListId": "default", 452 | "scrollTokenId": "USDC" 453 | } 454 | }, 455 | { 456 | "chainId": 534351, 457 | "address": "0x7878290DB8C4f02bd06E0E249617871c19508bE6", 458 | "name": "USD Coin", 459 | "symbol": "USDC", 460 | "decimals": 6, 461 | "logoURI": "https://scroll-tech.github.io/token-list/data/USDC/logo.svg", 462 | "extensions": { 463 | "scrollListId": "default", 464 | "scrollTokenId": "USDC" 465 | } 466 | }, 467 | { 468 | "chainId": 1, 469 | "address": "0xdAC17F958D2ee523a2206206994597C13D831ec7", 470 | "name": "Tether", 471 | "symbol": "USDT", 472 | "decimals": 6, 473 | "logoURI": "https://scroll-tech.github.io/token-list/data/USDT/logo.svg", 474 | "extensions": { 475 | "scrollListId": "default", 476 | "scrollTokenId": "USDT" 477 | } 478 | }, 479 | { 480 | "chainId": 534352, 481 | "address": "0xf55BEC9cafDbE8730f096Aa55dad6D22d44099Df", 482 | "name": "Tether", 483 | "symbol": "USDT", 484 | "decimals": 6, 485 | "logoURI": "https://scroll-tech.github.io/token-list/data/USDT/logo.svg", 486 | "extensions": { 487 | "scrollListId": "default", 488 | "scrollTokenId": "USDT" 489 | } 490 | }, 491 | { 492 | "chainId": 1, 493 | "address": "0x2260FAC5E5542a773Aa44fBCfeDf7C193bc2C599", 494 | "name": "Wrapped BTC", 495 | "symbol": "WBTC", 496 | "decimals": 8, 497 | "logoURI": "https://scroll-tech.github.io/token-list/data/WBTC/logo.svg", 498 | "extensions": { 499 | "scrollListId": "default", 500 | "scrollTokenId": "WBTC" 501 | } 502 | }, 503 | { 504 | "chainId": 534352, 505 | "address": "0x3C1BCa5a656e69edCD0D4E36BEbb3FcDAcA60Cf1", 506 | "name": "Wrapped BTC", 507 | "symbol": "WBTC", 508 | "decimals": 8, 509 | "logoURI": "https://scroll-tech.github.io/token-list/data/WBTC/logo.svg", 510 | "extensions": { 511 | "scrollListId": "default", 512 | "scrollTokenId": "WBTC" 513 | } 514 | }, 515 | { 516 | "chainId": 1, 517 | "address": "0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2", 518 | "name": "Wrapped Ether", 519 | "symbol": "WETH", 520 | "decimals": 18, 521 | "logoURI": "https://scroll-tech.github.io/token-list/data/WETH/logo.png", 522 | "extensions": { 523 | "scrollListId": "default", 524 | "scrollTokenId": "WETH" 525 | } 526 | }, 527 | { 528 | "chainId": 534352, 529 | "address": "0x5300000000000000000000000000000000000004", 530 | "name": "Wrapped Ether", 531 | "symbol": "WETH", 532 | "decimals": 18, 533 | "logoURI": "https://scroll-tech.github.io/token-list/data/WETH/logo.png", 534 | "extensions": { 535 | "scrollListId": "default", 536 | "scrollTokenId": "WETH" 537 | } 538 | }, 539 | { 540 | "chainId": 11155111, 541 | "address": "0xfFf9976782d46CC05630D1f6eBAb18b2324d6B14", 542 | "name": "Wrapped Ether", 543 | "symbol": "WETH", 544 | "decimals": 18, 545 | "logoURI": "https://scroll-tech.github.io/token-list/data/WETH/logo.png", 546 | "extensions": { 547 | "scrollListId": "default", 548 | "scrollTokenId": "WETH" 549 | } 550 | }, 551 | { 552 | "chainId": 534351, 553 | "address": "0x5300000000000000000000000000000000000004", 554 | "name": "Wrapped Ether", 555 | "symbol": "WETH", 556 | "decimals": 18, 557 | "logoURI": "https://scroll-tech.github.io/token-list/data/WETH/logo.png", 558 | "extensions": { 559 | "scrollListId": "default", 560 | "scrollTokenId": "WETH" 561 | } 562 | }, 563 | { 564 | "chainId": 1, 565 | "address": "0x7f39C581F595B53c5cb19bD0b3f8dA6c935E2Ca0", 566 | "name": "Wrapped stETH", 567 | "symbol": "wstETH", 568 | "decimals": 18, 569 | "logoURI": "https://scroll-tech.github.io/token-list/data/wstETH/logo.svg", 570 | "extensions": { 571 | "scrollListId": "default", 572 | "scrollTokenId": "wstETH" 573 | } 574 | }, 575 | { 576 | "chainId": 534352, 577 | "address": "0xf610A9dfB7C89644979b4A0f27063E9e7d7Cda32", 578 | "name": "Wrapped stETH", 579 | "symbol": "wstETH", 580 | "decimals": 18, 581 | "logoURI": "https://scroll-tech.github.io/token-list/data/wstETH/logo.svg", 582 | "extensions": { 583 | "scrollListId": "default", 584 | "scrollTokenId": "wstETH" 585 | } 586 | }, 587 | { 588 | "chainId": 11155111, 589 | "address": "0xB82381A3fBD3FaFA77B3a7bE693342618240067b", 590 | "name": "Wrapped stETH", 591 | "symbol": "wstETH", 592 | "decimals": 18, 593 | "logoURI": "https://scroll-tech.github.io/token-list/data/wstETH/logo.svg", 594 | "extensions": { 595 | "scrollListId": "default", 596 | "scrollTokenId": "wstETH" 597 | } 598 | }, 599 | { 600 | "chainId": 534351, 601 | "address": "0x2DAf22Caf40404ad8ff0Ab1E77F9C08Fef3953e2", 602 | "name": "Wrapped stETH", 603 | "symbol": "wstETH", 604 | "decimals": 18, 605 | "logoURI": "https://scroll-tech.github.io/token-list/data/wstETH/logo.svg", 606 | "extensions": { 607 | "scrollListId": "default", 608 | "scrollTokenId": "wstETH" 609 | } 610 | } 611 | ], 612 | "version": { 613 | "major": 0, 614 | "minor": 0, 615 | "patch": 22 616 | } 617 | } -------------------------------------------------------------------------------- /src/chains.mjs: -------------------------------------------------------------------------------- 1 | export const NETWORK_DATA = { 2 | ethereum: { 3 | id: 1, 4 | name: 'Mainnet', 5 | // provider: new ethers.providers.InfuraProvider('homestead'), 6 | layer: 1, 7 | }, 8 | scroll: { 9 | id: 534352, 10 | name: 'Scroll', 11 | layer: 2, 12 | }, 13 | goerli: { 14 | id: 5, 15 | name: 'Goerli', 16 | // provider: new ethers.providers.InfuraProvider('goerli'), 17 | layer: 1, 18 | }, 19 | sepolia: { 20 | id: 11155111, 21 | name: 'Sepolia', 22 | // provider: new ethers.providers.StaticJsonRpcProvider( 23 | // `https://sepolia.infura.io/v3/${DEFAULT_INFURA_KEY}`, 24 | // 11155111 25 | // ), 26 | layer: 1, 27 | }, 28 | 'scroll-sepolia': { 29 | id: 534351, 30 | name: 'Scroll Sepolia', 31 | layer: 2, 32 | }, 33 | 'scroll-goerli': { 34 | id: 534353, 35 | name: 'Scroll Goerli', 36 | layer: 2, 37 | }, 38 | } 39 | -------------------------------------------------------------------------------- /src/defaultTokens.mjs: -------------------------------------------------------------------------------- 1 | export const defaultTokenDataFolders = new Set([ 2 | 'WETH', 3 | 'WBTC', 4 | 'USDC', 5 | 'LUSD', 6 | 'USDT', 7 | 'DAI', 8 | 'wstETH', 9 | 'rETH', 10 | 'KNC', 11 | 'BAL', 12 | 'AAVE', 13 | 'UNI', 14 | 'CRV', 15 | ]) 16 | 17 | export const defaultTokenDataFoldersEachChain = { 18 | sepolia: new Set(['GHO']), 19 | } 20 | -------------------------------------------------------------------------------- /src/generate.mjs: -------------------------------------------------------------------------------- 1 | import fs from 'fs' 2 | import path from 'path' 3 | 4 | import { glob } from 'glob' 5 | 6 | import packageJson from '../package.json' assert { type: 'json' } 7 | import { NETWORK_DATA } from './chains.mjs' 8 | import { 9 | defaultTokenDataFolders, 10 | defaultTokenDataFoldersEachChain, 11 | } from './defaultTokens.mjs' 12 | 13 | const version = packageJson.version 14 | 15 | const BASE_URL = 'https://scroll-tech.github.io/token-list' 16 | const datadir = 'data' 17 | 18 | export function generate() { 19 | return fs 20 | .readdirSync(datadir) 21 | .sort((a, b) => { 22 | return a.toLowerCase().localeCompare(b.toLowerCase()) 23 | }) 24 | .map((folder) => { 25 | const data = JSON.parse( 26 | fs.readFileSync(path.join(datadir, folder, 'data.json'), 'utf8') 27 | ) 28 | const logofiles = glob.sync( 29 | `${path.join(datadir, folder)}/logo.{png,svg}` 30 | ) 31 | const logoext = logofiles[0].endsWith('png') ? 'png' : 'svg' 32 | return Object.entries(data.tokens).map(([chain, token]) => { 33 | // const bridges = !data.nobridge 34 | // ? Object.assign({}, ...getBridges(data, chain, token)) 35 | // : {} 36 | const out = { 37 | chainId: NETWORK_DATA[chain].id, 38 | address: token.address, 39 | name: token.overrides?.name ?? data.name, 40 | symbol: token.overrides?.symbol ?? data.symbol, 41 | decimals: token.overrides?.decimals ?? data.decimals, 42 | logoURI: `${BASE_URL}/data/${folder}/logo.${logoext}`, 43 | extensions: { 44 | // ...bridges, 45 | scrollListId: 46 | defaultTokenDataFolders.has(folder) || 47 | defaultTokenDataFoldersEachChain[chain]?.has(folder) 48 | ? 'default' 49 | : 'extended', 50 | scrollTokenId: folder, 51 | }, 52 | } 53 | return out 54 | }) 55 | }) 56 | .reduce( 57 | (list, tokens) => { 58 | list.tokens = list.tokens.concat(tokens) 59 | return list 60 | }, 61 | { 62 | name: 'Scroll Token List', 63 | logoURI: `${BASE_URL}/scroll.png`, 64 | keywords: ['scaling', 'layer2', 'infrastructure'], 65 | timestamp: new Date().toISOString(), 66 | tokens: [], 67 | version: { 68 | major: parseInt(version.split('.')[0], 10), 69 | minor: parseInt(version.split('.')[1], 10), 70 | patch: parseInt(version.split('.')[2], 10), 71 | }, 72 | } 73 | ) 74 | } 75 | -------------------------------------------------------------------------------- /src/validate.mjs: -------------------------------------------------------------------------------- 1 | import fs from 'fs' 2 | import {validate as validateDataDotJson} from './validate/data.json.mjs' 3 | import {validate as validateLogo} from './validate/logo.mjs' 4 | 5 | function readDataDotJson(tokenName) { 6 | try { 7 | JSON.parse(fs.readFileSync(`./data/${tokenName}/data.json`)) 8 | return JSON.parse(fs.readFileSync(`./data/${tokenName}/data.json`)) 9 | } catch (err) { 10 | console.error(err) 11 | throw new Error(`unable to parse data.json for token ${tokenName}`) 12 | } 13 | } 14 | 15 | export async function validate(tokenFolders) { 16 | console.info(` 17 | # validation start 18 | `) 19 | console.info(`validate folders ${tokenFolders}`) 20 | const tokenData = tokenFolders.map((name) => ({ 21 | name, 22 | json: readDataDotJson(name), 23 | })) 24 | 25 | for (const { name, json } of tokenData) { 26 | await validateDataDotJson(name, json) 27 | await validateLogo(name) 28 | } 29 | console.info(` 30 | # validation end 31 | `) 32 | } 33 | -------------------------------------------------------------------------------- /src/validate/data.json.mjs: -------------------------------------------------------------------------------- 1 | import assert from 'node:assert' 2 | import { isObject, noDuplicateStringInArray, parseURL } from './helper.mjs' 3 | import { getAddress } from 'ethers' 4 | 5 | import { NETWORK_DATA } from '../chains.mjs' 6 | 7 | function validateGlobalKeys(dataDotJsonObject) { 8 | const GLOBAL_KEYS = [ 9 | 'name', 10 | 'symbol', 11 | 'decimals', 12 | 'tokens', 13 | 'description', 14 | 'website', 15 | 'twitter', 16 | // 'nobridge', 17 | // 'nonstandard', 18 | ] 19 | 20 | const keys = Object.keys(dataDotJsonObject) 21 | 22 | // prettier-ignore 23 | { 24 | // no duplicate keys 25 | assert(noDuplicateStringInArray(keys), `found duplicate key, expected keys ${GLOBAL_KEYS.toString()}`) 26 | // no invalid keys 27 | assert(keys.every((key) => GLOBAL_KEYS.includes(key)), `found invalid key, valid keys are ${GLOBAL_KEYS.toString()}`) 28 | 29 | // name 30 | assert.equal(typeof dataDotJsonObject.name, 'string', 'expect name to be a string') 31 | // symbol 32 | assert.equal(typeof dataDotJsonObject.symbol, 'string', 'expect symbol to be a string') 33 | // decimals 34 | assert(Number.isInteger(dataDotJsonObject.decimals), 'expect decimal to be a string') 35 | // tokens 36 | assert(isObject(dataDotJsonObject.tokens), 'expect tokens to be a map') 37 | 38 | // optional keys 39 | // description 40 | if (dataDotJsonObject.description) 41 | assert.equal(typeof dataDotJsonObject.description, 'string', 'expect description to be a string') 42 | if (dataDotJsonObject.description) 43 | assert(dataDotJsonObject.description.length < 1000, 'expect description to under 1000 characters') 44 | // website 45 | if (dataDotJsonObject.website) 46 | assert(parseURL(dataDotJsonObject.website), 'expect website to be a valid URL') 47 | // twitter 48 | if (dataDotJsonObject.twitter) 49 | assert(typeof dataDotJsonObject.twitter === 'string' && dataDotJsonObject.twitter.startsWith('@'), 'expect twitter to be a string starts with @') 50 | // nobridge 51 | if (dataDotJsonObject.nobridge !== undefined) 52 | assert(dataDotJsonObject.nobridge === true, 'expect nobridge to be true, omit nobridge if you want it to be false') 53 | // nonstandard 54 | if (dataDotJsonObject.nonstandard !== undefined) 55 | assert(dataDotJsonObject.nonstandard === true, 'expect nonstandard to be true, omit nobridge if you want it to be false') 56 | } 57 | } 58 | 59 | function validateName() {} 60 | 61 | function validateSymbol() {} 62 | 63 | function validateDecimals(decimals) { 64 | assert(decimals > 0, 'invalid decimals, must > 0') 65 | assert(decimals <= 18, 'invalid decimals, must <= 18') 66 | } 67 | 68 | function validateTokens(tokens) { 69 | const CHAIN_NAMES = Object.keys(NETWORK_DATA) 70 | const keys = Object.keys(tokens) 71 | 72 | // prettier-ignore 73 | { 74 | assert(noDuplicateStringInArray(keys), `found duplicate key, valid keys are ${CHAIN_NAMES.toString()}`) 75 | assert(keys.every((key) => CHAIN_NAMES.includes(key)), `found invalid key, valid keys are ${CHAIN_NAMES.toString()}`) 76 | } 77 | } 78 | 79 | function validateToken([_chainName, token]) { 80 | const TOKEN_KEYS = ['address'] 81 | const keys = Object.keys(token) 82 | 83 | // prettier-ignore 84 | { 85 | assert(noDuplicateStringInArray(keys), `found duplicate key, valid keys are ${TOKEN_KEYS.toString()}`) 86 | assert(keys.every((key) => TOKEN_KEYS.includes(key)), `found invalid key, valid keys are ${TOKEN_KEYS.toString()}`) 87 | } 88 | 89 | getAddress(token.address) 90 | } 91 | 92 | export async function validate(tokenFolderName, dataDotJsonObject) { 93 | console.info(` 94 | ## validating ${tokenFolderName} 95 | input data.json: 96 | ${JSON.stringify(dataDotJsonObject, null, 2)}`) 97 | 98 | assert(isObject, `invalid data.json`) 99 | validateGlobalKeys(dataDotJsonObject) 100 | 101 | const { name, symbol, decimals, tokens } = dataDotJsonObject 102 | 103 | // prettier-ignore 104 | assert.equal(tokenFolderName, symbol, 'require token symbol = token folder name') 105 | validateName(name) 106 | validateSymbol(symbol) 107 | validateDecimals(decimals) 108 | validateTokens(tokens) 109 | Object.entries(tokens).forEach((token) => validateToken(token)) 110 | } 111 | -------------------------------------------------------------------------------- /src/validate/helper.mjs: -------------------------------------------------------------------------------- 1 | export function isObject(x) { 2 | return Object.prototype.toString.call(x).slice(8, -1) === 'Object' 3 | } 4 | 5 | // assume everything in arr is string 6 | export function noDuplicateStringInArray(arr) { 7 | if (!arr.length) return true 8 | return Boolean( 9 | arr.sort().reduce((a, b) => { 10 | if (!a) return false 11 | if (a === b) return false 12 | return b 13 | }) 14 | ) 15 | } 16 | 17 | export function parseURL(str) { 18 | try { 19 | return new URL(str) 20 | } catch (_err) {} 21 | } 22 | -------------------------------------------------------------------------------- /src/validate/logo.mjs: -------------------------------------------------------------------------------- 1 | import assert from 'node:assert' 2 | import fs from 'fs' 3 | 4 | function exits(tokenFolderName) { 5 | assert( 6 | fs.existsSync(`./data/${tokenFolderName}/logo.svg`) || 7 | fs.existsSync(`./data/${tokenFolderName}/logo.png`), 8 | `Missing logo for token ${tokenFolderName}` 9 | ) 10 | } 11 | 12 | export async function validate(tokenFolderName) { 13 | console.info(` 14 | ## validating ${tokenFolderName} logo`) 15 | exits(tokenFolderName) 16 | } 17 | -------------------------------------------------------------------------------- /yarn.lock: -------------------------------------------------------------------------------- 1 | # THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. 2 | # yarn lockfile v1 3 | 4 | 5 | "@adraffy/ens-normalize@1.9.2": 6 | version "1.9.2" 7 | resolved "https://registry.yarnpkg.com/@adraffy/ens-normalize/-/ens-normalize-1.9.2.tgz#60111a5d9db45b2e5cbb6231b0bb8d97e8659316" 8 | integrity sha512-0h+FrQDqe2Wn+IIGFkTCd4aAwTJ+7834Ek1COohCyV26AXhwQ7WQaz+4F/nLOeVl/3BtWHOHLPsq46V8YB46Eg== 9 | 10 | "@isaacs/cliui@^8.0.2": 11 | version "8.0.2" 12 | resolved "https://registry.yarnpkg.com/@isaacs/cliui/-/cliui-8.0.2.tgz#b37667b7bc181c168782259bab42474fbf52b550" 13 | integrity sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA== 14 | dependencies: 15 | string-width "^5.1.2" 16 | string-width-cjs "npm:string-width@^4.2.0" 17 | strip-ansi "^7.0.1" 18 | strip-ansi-cjs "npm:strip-ansi@^6.0.1" 19 | wrap-ansi "^8.1.0" 20 | wrap-ansi-cjs "npm:wrap-ansi@^7.0.0" 21 | 22 | "@noble/hashes@1.1.2": 23 | version "1.1.2" 24 | resolved "https://registry.yarnpkg.com/@noble/hashes/-/hashes-1.1.2.tgz#e9e035b9b166ca0af657a7848eb2718f0f22f183" 25 | integrity sha512-KYRCASVTv6aeUi1tsF8/vpyR7zpfs3FUzy2Jqm+MU+LmUKhQ0y2FpfwqkCcxSg2ua4GALJd8k2R76WxwZGbQpA== 26 | 27 | "@noble/secp256k1@1.7.1": 28 | version "1.7.1" 29 | resolved "https://registry.yarnpkg.com/@noble/secp256k1/-/secp256k1-1.7.1.tgz#b251c70f824ce3ca7f8dc3df08d58f005cc0507c" 30 | integrity sha512-hOUk6AyBFmqVrv7k5WAw/LpszxVbj9gGN4JRkIX52fdFAj1UA61KXmZDvqVEm+pOyec3+fIeZB02LYa/pWOArw== 31 | 32 | "@pkgjs/parseargs@^0.11.0": 33 | version "0.11.0" 34 | resolved "https://registry.yarnpkg.com/@pkgjs/parseargs/-/parseargs-0.11.0.tgz#a77ea742fab25775145434eb1d2328cf5013ac33" 35 | integrity sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg== 36 | 37 | "@types/node@18.15.13": 38 | version "18.15.13" 39 | resolved "https://registry.yarnpkg.com/@types/node/-/node-18.15.13.tgz#f64277c341150c979e42b00e4ac289290c9df469" 40 | integrity sha512-N+0kuo9KgrUQ1Sn/ifDXsvg0TTleP7rIy4zOBGECxAljqvqfqpTfzx0Q1NUedOixRMBfe2Whhb056a42cWs26Q== 41 | 42 | aes-js@4.0.0-beta.5: 43 | version "4.0.0-beta.5" 44 | resolved "https://registry.yarnpkg.com/aes-js/-/aes-js-4.0.0-beta.5.tgz#8d2452c52adedebc3a3e28465d858c11ca315873" 45 | integrity sha512-G965FqalsNyrPqgEGON7nIx1e/OVENSgiEIzyC63haUMuvNnwIgIjMs52hlTCKhkBny7A2ORNlfY9Zu+jmGk1Q== 46 | 47 | ansi-regex@^5.0.1: 48 | version "5.0.1" 49 | resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-5.0.1.tgz#082cb2c89c9fe8659a311a53bd6a4dc5301db304" 50 | integrity sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ== 51 | 52 | ansi-regex@^6.0.1: 53 | version "6.0.1" 54 | resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-6.0.1.tgz#3183e38fae9a65d7cb5e53945cd5897d0260a06a" 55 | integrity sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA== 56 | 57 | ansi-styles@^4.0.0: 58 | version "4.3.0" 59 | resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-4.3.0.tgz#edd803628ae71c04c85ae7a0906edad34b648937" 60 | integrity sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg== 61 | dependencies: 62 | color-convert "^2.0.1" 63 | 64 | ansi-styles@^6.1.0: 65 | version "6.2.1" 66 | resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-6.2.1.tgz#0e62320cf99c21afff3b3012192546aacbfb05c5" 67 | integrity sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug== 68 | 69 | balanced-match@^1.0.0: 70 | version "1.0.2" 71 | resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.2.tgz#e83e3a7e3f300b34cb9d87f615fa0cbf357690ee" 72 | integrity sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw== 73 | 74 | brace-expansion@^2.0.1: 75 | version "2.0.1" 76 | resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-2.0.1.tgz#1edc459e0f0c548486ecf9fc99f2221364b9a0ae" 77 | integrity sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA== 78 | dependencies: 79 | balanced-match "^1.0.0" 80 | 81 | color-convert@^2.0.1: 82 | version "2.0.1" 83 | resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-2.0.1.tgz#72d3a68d598c9bdb3af2ad1e84f21d896abd4de3" 84 | integrity sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ== 85 | dependencies: 86 | color-name "~1.1.4" 87 | 88 | color-name@~1.1.4: 89 | version "1.1.4" 90 | resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.4.tgz#c2a09a87acbde69543de6f63fa3995c826c536a2" 91 | integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA== 92 | 93 | cross-spawn@^7.0.0: 94 | version "7.0.3" 95 | resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-7.0.3.tgz#f73a85b9d5d41d045551c177e2882d4ac85728a6" 96 | integrity sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w== 97 | dependencies: 98 | path-key "^3.1.0" 99 | shebang-command "^2.0.0" 100 | which "^2.0.1" 101 | 102 | eastasianwidth@^0.2.0: 103 | version "0.2.0" 104 | resolved "https://registry.yarnpkg.com/eastasianwidth/-/eastasianwidth-0.2.0.tgz#696ce2ec0aa0e6ea93a397ffcf24aa7840c827cb" 105 | integrity sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA== 106 | 107 | emoji-regex@^8.0.0: 108 | version "8.0.0" 109 | resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-8.0.0.tgz#e818fd69ce5ccfcb404594f842963bf53164cc37" 110 | integrity sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A== 111 | 112 | emoji-regex@^9.2.2: 113 | version "9.2.2" 114 | resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-9.2.2.tgz#840c8803b0d8047f4ff0cf963176b32d4ef3ed72" 115 | integrity sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg== 116 | 117 | ethers@^6.7.1: 118 | version "6.7.1" 119 | resolved "https://registry.yarnpkg.com/ethers/-/ethers-6.7.1.tgz#9c65e8b5d8e9ad77b7e8cf1c46099892cfafad49" 120 | integrity sha512-qX5kxIFMfg1i+epfgb0xF4WM7IqapIIu50pOJ17aebkxxa4BacW5jFrQRmCJpDEg2ZK2oNtR5QjrQ1WDBF29dA== 121 | dependencies: 122 | "@adraffy/ens-normalize" "1.9.2" 123 | "@noble/hashes" "1.1.2" 124 | "@noble/secp256k1" "1.7.1" 125 | "@types/node" "18.15.13" 126 | aes-js "4.0.0-beta.5" 127 | tslib "2.4.0" 128 | ws "8.5.0" 129 | 130 | foreground-child@^3.1.0: 131 | version "3.1.1" 132 | resolved "https://registry.yarnpkg.com/foreground-child/-/foreground-child-3.1.1.tgz#1d173e776d75d2772fed08efe4a0de1ea1b12d0d" 133 | integrity sha512-TMKDUnIte6bfb5nWv7V/caI169OHgvwjb7V4WkeUvbQQdjr5rWKqHFiKWb/fcOwB+CzBT+qbWjvj+DVwRskpIg== 134 | dependencies: 135 | cross-spawn "^7.0.0" 136 | signal-exit "^4.0.1" 137 | 138 | glob@^10.3.10: 139 | version "10.3.10" 140 | resolved "https://registry.yarnpkg.com/glob/-/glob-10.3.10.tgz#0351ebb809fd187fe421ab96af83d3a70715df4b" 141 | integrity sha512-fa46+tv1Ak0UPK1TOy/pZrIybNNt4HCv7SDzwyfiOZkvZLEbjsZkJBPtDHVshZjbecAoAGSC20MjLDG/qr679g== 142 | dependencies: 143 | foreground-child "^3.1.0" 144 | jackspeak "^2.3.5" 145 | minimatch "^9.0.1" 146 | minipass "^5.0.0 || ^6.0.2 || ^7.0.0" 147 | path-scurry "^1.10.1" 148 | 149 | is-fullwidth-code-point@^3.0.0: 150 | version "3.0.0" 151 | resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz#f116f8064fe90b3f7844a38997c0b75051269f1d" 152 | integrity sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg== 153 | 154 | isexe@^2.0.0: 155 | version "2.0.0" 156 | resolved "https://registry.yarnpkg.com/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10" 157 | integrity sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw== 158 | 159 | jackspeak@^2.3.5: 160 | version "2.3.6" 161 | resolved "https://registry.yarnpkg.com/jackspeak/-/jackspeak-2.3.6.tgz#647ecc472238aee4b06ac0e461acc21a8c505ca8" 162 | integrity sha512-N3yCS/NegsOBokc8GAdM8UcmfsKiSS8cipheD/nivzr700H+nsMOxJjQnvwOcRYVuFkdH0wGUvW2WbXGmrZGbQ== 163 | dependencies: 164 | "@isaacs/cliui" "^8.0.2" 165 | optionalDependencies: 166 | "@pkgjs/parseargs" "^0.11.0" 167 | 168 | "lru-cache@^9.1.1 || ^10.0.0": 169 | version "10.0.1" 170 | resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-10.0.1.tgz#0a3be479df549cca0e5d693ac402ff19537a6b7a" 171 | integrity sha512-IJ4uwUTi2qCccrioU6g9g/5rvvVl13bsdczUUcqbciD9iLr095yj8DQKdObriEvuNSx325N1rV1O0sJFszx75g== 172 | 173 | minimatch@^9.0.1: 174 | version "9.0.3" 175 | resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-9.0.3.tgz#a6e00c3de44c3a542bfaae70abfc22420a6da825" 176 | integrity sha512-RHiac9mvaRw0x3AYRgDC1CxAP7HTcNrrECeA8YYJeWnpo+2Q5CegtZjaotWTWxDG3UeGA1coE05iH1mPjT/2mg== 177 | dependencies: 178 | brace-expansion "^2.0.1" 179 | 180 | "minipass@^5.0.0 || ^6.0.2 || ^7.0.0": 181 | version "7.0.4" 182 | resolved "https://registry.yarnpkg.com/minipass/-/minipass-7.0.4.tgz#dbce03740f50a4786ba994c1fb908844d27b038c" 183 | integrity sha512-jYofLM5Dam9279rdkWzqHozUo4ybjdZmCsDHePy5V/PbBcVMiSZR97gmAy45aqi8CK1lG2ECd356FU86avfwUQ== 184 | 185 | path-key@^3.1.0: 186 | version "3.1.1" 187 | resolved "https://registry.yarnpkg.com/path-key/-/path-key-3.1.1.tgz#581f6ade658cbba65a0d3380de7753295054f375" 188 | integrity sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q== 189 | 190 | path-scurry@^1.10.1: 191 | version "1.10.1" 192 | resolved "https://registry.yarnpkg.com/path-scurry/-/path-scurry-1.10.1.tgz#9ba6bf5aa8500fe9fd67df4f0d9483b2b0bfc698" 193 | integrity sha512-MkhCqzzBEpPvxxQ71Md0b1Kk51W01lrYvlMzSUaIzNsODdd7mqhiimSZlr+VegAz5Z6Vzt9Xg2ttE//XBhH3EQ== 194 | dependencies: 195 | lru-cache "^9.1.1 || ^10.0.0" 196 | minipass "^5.0.0 || ^6.0.2 || ^7.0.0" 197 | 198 | shebang-command@^2.0.0: 199 | version "2.0.0" 200 | resolved "https://registry.yarnpkg.com/shebang-command/-/shebang-command-2.0.0.tgz#ccd0af4f8835fbdc265b82461aaf0c36663f34ea" 201 | integrity sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA== 202 | dependencies: 203 | shebang-regex "^3.0.0" 204 | 205 | shebang-regex@^3.0.0: 206 | version "3.0.0" 207 | resolved "https://registry.yarnpkg.com/shebang-regex/-/shebang-regex-3.0.0.tgz#ae16f1644d873ecad843b0307b143362d4c42172" 208 | integrity sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A== 209 | 210 | signal-exit@^4.0.1: 211 | version "4.1.0" 212 | resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-4.1.0.tgz#952188c1cbd546070e2dd20d0f41c0ae0530cb04" 213 | integrity sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw== 214 | 215 | "string-width-cjs@npm:string-width@^4.2.0", string-width@^4.1.0: 216 | name string-width-cjs 217 | version "4.2.3" 218 | resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010" 219 | integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g== 220 | dependencies: 221 | emoji-regex "^8.0.0" 222 | is-fullwidth-code-point "^3.0.0" 223 | strip-ansi "^6.0.1" 224 | 225 | string-width@^5.0.1, string-width@^5.1.2: 226 | version "5.1.2" 227 | resolved "https://registry.yarnpkg.com/string-width/-/string-width-5.1.2.tgz#14f8daec6d81e7221d2a357e668cab73bdbca794" 228 | integrity sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA== 229 | dependencies: 230 | eastasianwidth "^0.2.0" 231 | emoji-regex "^9.2.2" 232 | strip-ansi "^7.0.1" 233 | 234 | "strip-ansi-cjs@npm:strip-ansi@^6.0.1", strip-ansi@^6.0.0, strip-ansi@^6.0.1: 235 | name strip-ansi-cjs 236 | version "6.0.1" 237 | resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9" 238 | integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A== 239 | dependencies: 240 | ansi-regex "^5.0.1" 241 | 242 | strip-ansi@^7.0.1: 243 | version "7.1.0" 244 | resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-7.1.0.tgz#d5b6568ca689d8561370b0707685d22434faff45" 245 | integrity sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ== 246 | dependencies: 247 | ansi-regex "^6.0.1" 248 | 249 | tslib@2.4.0: 250 | version "2.4.0" 251 | resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.4.0.tgz#7cecaa7f073ce680a05847aa77be941098f36dc3" 252 | integrity sha512-d6xOpEDfsi2CZVlPQzGeux8XMwLT9hssAsaPYExaQMuYskwb+x1x7J371tWlbBdWHroy99KnVB6qIkUbs5X3UQ== 253 | 254 | which@^2.0.1: 255 | version "2.0.2" 256 | resolved "https://registry.yarnpkg.com/which/-/which-2.0.2.tgz#7c6a8dd0a636a0327e10b59c9286eee93f3f51b1" 257 | integrity sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA== 258 | dependencies: 259 | isexe "^2.0.0" 260 | 261 | "wrap-ansi-cjs@npm:wrap-ansi@^7.0.0": 262 | version "7.0.0" 263 | resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz#67e145cff510a6a6984bdf1152911d69d2eb9e43" 264 | integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q== 265 | dependencies: 266 | ansi-styles "^4.0.0" 267 | string-width "^4.1.0" 268 | strip-ansi "^6.0.0" 269 | 270 | wrap-ansi@^8.1.0: 271 | version "8.1.0" 272 | resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-8.1.0.tgz#56dc22368ee570face1b49819975d9b9a5ead214" 273 | integrity sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ== 274 | dependencies: 275 | ansi-styles "^6.1.0" 276 | string-width "^5.0.1" 277 | strip-ansi "^7.0.1" 278 | 279 | ws@8.5.0: 280 | version "8.5.0" 281 | resolved "https://registry.yarnpkg.com/ws/-/ws-8.5.0.tgz#bfb4be96600757fe5382de12c670dab984a1ed4f" 282 | integrity sha512-BWX0SWVgLPzYwF8lTzEy1egjhS4S4OEAHfsO8o65WOVsrnSRGaSiUaa9e0ggGlkMTtBlmOpEXiie9RUcBO86qg== 283 | --------------------------------------------------------------------------------