GithubHelp home page GithubHelp logo

uniswap / token-lists Goto Github PK

View Code? Open in Web Editor NEW
1.4K 164.0 931.0 324 KB

📚 The Token Lists specification

Home Page: https://tokenlists.org

License: MIT License

TypeScript 100.00%
uniswap tokens erc20

token-lists's Introduction

@uniswap/token-lists (beta)

Tests npm

This package includes a JSON schema for token lists, and TypeScript utilities for working with token lists.

The JSON schema represents the technical specification for a token list which can be used in a dApp interface, such as the Uniswap Interface.

What are token lists?

Uniswap Token Lists is a specification for lists of token metadata (e.g. address, decimals, ...) that can be used by any dApp interfaces that needs one or more lists of tokens.

Anyone can create and maintain a token list, as long as they follow the specification.

Specifically an instance of a token list is a JSON blob that contains a list of ERC20 token metadata for use in dApp user interfaces. Token list JSON must validate against the JSON schema in order to be used in the Uniswap Interface. Tokens on token lists, and token lists themselves, are tagged so that users can easily find tokens.

JSON Schema $id

The JSON schema ID is https://uniswap.org/tokenlist.schema.json

Validating token lists

This package does not include code for token list validation. You can easily do this by including a library such as ajv to perform the validation against the JSON schema. The schema is exported from the package for ease of use.

import { schema } from '@uniswap/token-lists'
import Ajv from 'ajv'
import addFormats from 'ajv-formats'
import fetch from 'node-fetch'

const ARBITRUM_LIST = 'https://bridge.arbitrum.io/token-list-42161.json'

async function validate() {
  const ajv = new Ajv({ allErrors: true, verbose: true })
  addFormats(ajv)
  const validator = ajv.compile(schema);
  const response = await fetch(ARBITRUM_LIST)
  const data = await response.json()
  const valid = validator(data)
  if (valid) {
    return valid
  }
  if (validator.errors) {
    throw validator.errors.map(error => {
      delete error.data
      return error
    })
  }
}

validate()
  .then(console.log("Valid List."))
  .catch(console.error)

Authoring token lists

Manual

The best way to manually author token lists is to use an editor that supports JSON schema validation. Most popular code editors do, such as IntelliJ or VSCode. Other editors can be found here.

The schema is registered in the SchemaStore, and any file that matches the pattern *.tokenlist.json should automatically utilize the JSON schema for the supported text editors.

In order for your token list to be able to be used, it must pass all JSON schema validation.

Automated

If you want to automate token listing, e.g. by pulling from a smart contract, or other sources, you can use this npm package to take advantage of the JSON schema for validation and the TypeScript types. Otherwise, you are simply working with JSON. All the usual tools apply, e.g.:

import { TokenList, schema } from '@uniswap/token-lists'

// generate your token list however you like.
const myList: TokenList = generateMyTokenList();

// use a tool like `ajv` to validate your generated token list
validateMyTokenList(myList, schema);

// print the resulting JSON to stdout
process.stdout.write(JSON.stringify(myList));

Semantic versioning

Lists include a version field, which follows semantic versioning.

List versions must follow the rules:

  • Increment major version when tokens are removed
  • Increment minor version when tokens are added
  • Increment patch version when tokens already on the list have minor details changed (name, symbol, logo URL, decimals)

Changing a token address or chain ID is considered both a remove and an add, and should be a major version update.

Note that list versioning is used to improve the user experience, but not for security, i.e. list versions are not meant to provide protection against malicious updates to a token list; i.e. the list semver is used as a lossy compression of the diff of list updates. List updates may still be diffed in the client dApp.

Deploying your list

Once you have authored the list, you can make it available at any URI. Prefer pinning your list to IPFS (e.g. via pinata.cloud) and referencing the list by an ENS name that resolves to the contenthash.

If hosted on HTTPS, make sure the endpoint is configured to send an access-control-allow-origin header to avoid CORS errors.

Linking an ENS name to the list

An ENS name can be assigned to an IPFS hash via the contenthash text record. This is the preferred way of referencing your list.

Examples

You can find a simple example of a token list in test/schema/example.tokenlist.json.

A snapshot of the Uniswap default list encoded as a token list is found in test/schema/bigexample.tokenlist.json.

token-lists's People

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

token-lists's Issues

Consider standardized representation of bridged asset relationships (L1 -> L2 or L1 -> L1)

Token lists may contain tokens on multiple chains, for example Ethereum Mainnet, Rinkeby and Optimism. These tokens can be 'bridged' versions of each other, e.g. DAI might be bridged from Ethereum Mainnet to Optimism. There could be a standard way to represent the relationship between these tokens.

One option for extending the schema:

 {
    "chainId": 1,
    "address": "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48",
    "symbol": "USDC",
    "name": "USD Coin",
    "decimals": 6,
    "otherChainAddresses": { "420161": "0xAAAA...AAAA" }
}

Other things we may want to include in the token list specification:

  • bridge function ABI
  • bridge contract address on layer 1 and/or layer 2

How we do this depends on the intended usage in the interface. For now, since there is not an obvious way for us to use it as with other token metadata, it's may be ok to use extensions.

## Change

Change

added a rich mode for more convenient local contract testing. In this mode gas params will default to large amount so all operations should not require at gas overrides anymore.

This is especially helpful for large contract tests with hardhat.

Test

Tested some local contract deployments without gas overrides:

  • when rich mode is enabled, contract creation succeed
  • when rich mode disabled, contract creation will fail by Error: evm.OutOfStorage: Storage usage exceeds storage limit

Originally posted by @shunjizhan in AcalaNetwork/bodhi.js#511

Originally posted by @Anastasia1510 in https://github.com/Anastasia1510/-/issues/1

"token-list detailed" standard

I would like to propose an extension to the token-list standard that allows more detailed information to encompass ERC1155 and ERC721. This extension would have, initially, a structure like this:

interface TokenListExtended extends TokenList {
  type: 1155 | 721 | 20
  id: number | null
}

This would allow discerning the difference between token type definitions, and allow explicit id calls to 1155s

YFIQ

{
"name": "YFIQ",
"logoURI": "https://yfiq.vip/logo.png",
"keywords": [
"YFIQ",
"YFIQ",
"yield"
],
"timestamp": "2020-10-24T01:40:34.305Z",
"tokens": [{
"chainId": 1,
"address": "0X52A5116ED13EFC08B8B4557C17BB8411F9056870",
"name": "YFIQ",
"symbol": "YFIQ",
"decimals": 18,
"logoURI": "https://yfiq.vip/logo.png"
}],
"version": {
"major": 0,
"minor": 0,
"patch": 0
}
}

Multi-chain token lists

Token lists are currently geared towards one-chain-per-token, and lead to workarounds such as Optimism's:

    {
      "chainId": 1,
      "address": "0xc011a73ee8576fb46f5e1c5751ca3b9fe0af2a6f",
      "name": "Synthetix",
      "symbol": "SNX",
      "decimals": 18,
      "logoURI": "https://ethereum-optimism.github.io/logos/SNX.svg",
      "extensions": {
        "optimismBridgeAddress": "0x39Ea01a0298C315d149a490E34B59Dbf2EC7e48F"
      }
    },
    {
      "chainId": 10,
      "address": "0x8700daec35af8ff88c16bdf0418774cb3d7599b4",
      "name": "Synthetix",
      "symbol": "SNX",
      "decimals": 18,
      "logoURI": "https://ethereum-optimism.github.io/logos/SNX.svg",
      "extensions": {
        "optimismBridgeAddress": "0x136b1EC699c62b0606854056f02dC7Bb80482d63"
      }
    },
    {
      "chainId": 42,
      "address": "0xc011a73ee8576fb46f5e1c5751ca3b9fe0af2a6f",
      "name": "Synthetix",
      "symbol": "SNX",
      "decimals": 18,
      "logoURI": "https://ethereum-optimism.github.io/logos/SNX.svg",
      "extensions": {
        "optimismBridgeAddress": "0xc00E7C2Bd7B0Fb95DbBF10d2d336399A939099ee"
      }
    },

Rather than doing this, I'd like to propose an update to the format along the following structure:

    {
     "deployments": [{
          "chainId": 1,
          "address": "0xc011a73ee8576fb46f5e1c5751ca3b9fe0af2a6f",
          "extensions": {},
        },{
          "chainId": 10,
          "address": "0x8700daec35af8ff88c16bdf0418774cb3d7599b4",
          "extensions": {},
        },{
          "chainId": 42,
          "address": "0xc011a73ee8576fb46f5e1c5751ca3b9fe0af2a6f",
          "extensions": {},
        }
      ],
      "name": "Synthetix",
      "symbol": "SNX",
      "decimals": 18,
      "logoURI": "https://ethereum-optimism.github.io/logos/SNX.svg",
      "extensions": {},
    }

This avoids people leveraging the token list from having to match symbols/names against eachother, which is a fairly perilous process with the larger token lists. Any suggestions here would be greatly appreciated.

`@uniswap/token-lists` was updated to allow objects to be nested 2 levels deep as of `1.0.0-beta.26`

@uniswap/token-lists was updated to allow objects to be nested 2 levels deep as of 1.0.0-beta.26

here is a proposed schema for representing the cross chain token info in the extensions:

bridgeInfo is an extension that contains a map of other chain ID to an object containing other token info, like so

"tokens": [
  {
    // ...
    "chainId": "<source chain id>",
    "extensions": {
      "bridgeInfo": { 
        "<destination chain id>": {
          "tokenAddress": "<token address on destination chain id>",
          "originBridgeAddress": "<optional address of the bridge contract on the source chain id>",
          "destBridgeAddress": "<optional address of the bridge contract on the destination chain id>"
        }
      }
    }
  }, 
  {
    // ...
    "chainId": "<destination chain id>",
    "extensions": {
      "bridgeInfo": { 
        "<source chain id>": {
          "tokenAddress": "<token address on source chain id>",
          "originBridgeAddress": "<optional address of the bridge contract on the destination chain id>",
          "destBridgeAddress": "<optional address of the bridge contract on the source chain id>"
        }
      }
    }
  }, 
  // ...
]

e.g.:
https://github.com/Uniswap/token-lists/blob/e2a796f3f021949b986b9ac9f84a17be92498702/test/schema/example-crosschain.tokenlist.json

Originally posted by @moodysalem in #51 (comment)

Added list not showing up?

Hi,

I created a list and uploaded the validated json to ipfs://QmQL3CDGu8iAWEgokV5MdNTyAL9vm15FKAt6uti4XqWXnX. I then linked the content record of burnthestate.eth to it. I don't see it appearing on https://tokenlists.org/, so not sure where I went wrong. Is there another step I need to do to add burnthestate.eth to the list? or does it populate automatically?

Thanks!

Duplicated line in Token list

Bug Description
https://tokens.coingecko.com/all.json
There are duplicates lines in this list.

Steps to Reproduce
Here is the duplicated line info.
{"chainId":1,"address":"0xed0d5747a9ab03a75fbfec3228cd55848245b75d","name":"e Money","symbol":"NGM","decimals":6,"logoURI":"https://assets.coingecko.com/coins/images/13722/thumb/nx5m_kZJt3oz9UM0XhE-IEeJ8TGjX1831iNfLVWeMvHuYoyDGwN0vh9Wj8u5hCxe1u5Kw56zT5kqX_ia5u1hsMElA-ioKCvK2jUK4EdJMDUx4J1GOnjqIu30iXHrLfmdzqO2SyucZZZnutFVLIAkxWMcTbIo1GDPZ3dZSj2onSeEOnIY4GJKR9B6ByR1XUZrJxtpY9QjwoWLfPC.jpg?1611182880"}

Expected Behavior
It should be unique token list.

Coingecko Token List [replace DeFi 100]

Hoping this is the right place to share this, wasn't sure if it should be here or in the other token-list section.

A great suggestion by the Coingecko founder on the Uniswap Governance Forum, which I believe belongs here. As it's more a 'replace with' than a 'vote to have Coingecko listed to the default list' situation.

https://gov.uniswap.org/t/add-the-coingecko-tokens-list-in-the-manage-lists-section/6205

Currently Uniswap offers the 'Coingecko DeFi 100' list. However, I quote:
''I would like to propose to have that CoinGecko tokens list to be in the default “Manage List” section replacing the CoinGecko DeFi 100 for the following reasons:-

  • CoinGecko tokens list updates every hour with all the latest updates/changes (new tokens, contract address change, etc…)
  • CoinGecko DeFi 100 list was our first attempt, and we noticed that a list with all tokens is a better user experience as Uniswap traders don’t have to switch in/out to find the address they are looking for
  • We did not implement DeFi 100 in the best way; which makes it difficult for us to get it updated with any changes in token details in our backend, and we should deprecate it''

''by making it easier for general Uniswap users to access the CoinGecko token lists

  • Users will get the latest changes to the token as timely as possible (contract address, decimals, any metadata related) in order to trade the correct token
  • Users get to find all the tokens that are curated on CoinGecko.com
  • Users can look up in the list using symbols''

Kind Regards,
TMod_Marco

Add USD+ to token list

"chainId": 137,
"address": "0x236eeC6359fb44CCe8f97E99387aa7F8cd5cdE1f",
"decimals": 6,
"extensions": {},

"chainId": 56,
"address": "0x73cb180bf0521828d8849bc8CF2B920918e23032",
"decimals": 18,
"extensions": {},

"chainId": 43114,
"address": "0xe80772Eaf6e2E18B651F160Bc9158b2A5caFCA65",
"decimals": 6,
"extensions": {},

"chainId": 10,
"address": "0xe80772Eaf6e2E18B651F160Bc9158b2A5caFCA65",
"decimals": 6,
"extensions": {},

"name": "USD+",
"symbol": "USD+",
"logoURI": "https://2173993027-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F9HhCCgYexXiRot0OWAJY%2Fuploads%2FHCzDW3p9ZkqGuC42prEh%2FUSD%2B_NEW.png?alt=media&token=5700174c-1ad1-4726-bc9f-94abe8dac1d2",
"extensions": {},

SyntaxError: Invalid regular expression: /^[ \w.'+\-%/À-ÖØ-öø-ÿ\:]+$/: Invalid escape

The following line is throwing the error SyntaxError: Invalid regular expression: /^[ \w.'+\-%/À-ÖØ-öø-ÿ\:]+$/: Invalid escape:

"pattern": "^[ \\w.'+\\-%/À-ÖØ-öø-ÿ\\:]+$",

These are the package versions I'm using:

"@uniswap/token-lists": "^1.0.0-beta.24",
"ajv": "^7.2.4",
"ajv-formats": "^1.6.1",

This is the validation script:

const ajv = new AJV();
addFormats(ajv);
const validate = ajv.compile(schema);
const valid = validate(tokenList); // a valid tokenList json

Using node v14.17.1

Add KCK/KOCAKI

chainId": 137,
"name": "KOCAKI",
"symbol": "KCK",
"decimals": 18,
"address": "0x9459C2da825fa8f16bD6Fe25158589fd42294fF8",
"logoURI": "https://ibb.co/vZbRSMz",
"tags": [
"erc20"
]

Optimism token list shows duplicates of each token

When I navigate to the Optimism list:
https://tokenlists.org/token-list?url=https://static.optimism.io/optimism.tokenlist.json

I see 4 of each major token. It seems like some logic with the filtering is broken - it appears this contains the contract addresses for a token on Ethereum, Optimism, Optimistic Kovan and Kovan.
Image 2022-04-11 at 7 56 25 AM

Looking at the tokenlist.json:
https://static.optimism.io/optimism.tokenlist.json
It does appear there are tokens with chainId other than 10.

Incorrect number of token decimals in the Coin Market Cap Token List

This problem is found in the Coin Market Cap Token List but not the Coin Gecko List, however it's not clear to us why Token Lists should allow a Token List submitted by a third party to over-ride the number of decimals specified in the contract itself. This bug is causing Uniswap not to work properly with default settings because the first result suggested for CGT is from the Coin Market Cap list. If the user manually disables the Coin Market Cap list and instead enables the Coin Gecko list everything works properly.

https://api.coinmarketcap.com/data-api/v3/uniswap/all.json

{"chainId":1,"name":"CACHE Gold","address":"0xf5238462e7235c7b62811567e63dd17d12c2eaa0","decimals":18,"symbol":"CGT","logoURI":"https://s2.coinmarketcap.com/static/img/coins/64x64/5719.png"}

"decimals":18, should be "decimals":8,

Screen shot

This issue would affect any of the other 6000+ tokens on the Coin Market Cap Token List that have an incorrect number of decimals specified. Perhaps Coin Market Cap should not be used as the default list on Uniswap.

List validation does not capture duplicates

If you have a duplicate entry in your list, it won't work on some UI's.

SushiSwap seems to be immune to that, but QuickSwap will not show the list, etc. I haven't tested all forks!

Anyway, I have added a script in my validation routine that checks dupilicate symbols and addresses.

I use my DYI Python script so I can't really post my 'fix' to this repo, but you get the idea.

Inviting feedback on EEA Community Project's L2 WG Token List Standard Proposal

@moodysalem @haydenadams

The EEA Community Project’s L2 WG has drafted a proposal for a standard for a Token List for L1s, L2s, and Sidechains to address the current ecosystem problem of defining and listing of tokens on any Layer 1 (L1), Layer 2 (L2), and Sidechain systems because there needs to be a consensus on the “canonical” token on chain B that corresponds to some token on chain A. When one wants to bridge token X from chain A to chain B, one must create some new representation of the token on chain B. It is worth noting that this problem is not limited to L2s – every chain connected via bridges must deal with the same issue.

The L2 WG is soliciting input from the wider Ethereum ecosystem interested to contribute to this proposal and ensure that when the standard is released, it will be widely adopted.

We thought it would be great to cross-post here to get your feedback and invite you to participate in the WG meetings. The next meeting is on 8/24.

Looking forward to hearing from you,
the L2 WG

cc @Tasd @dshaw

Allow any valid JSON in `extensions` field

Hi tokenlist team!

I would like to request that the tokenlist schema allow for any valid JSON in the extensions field. It seems a bit unnecessary to have a such a strict schema enforced on vendor-defined properties, which will always vary by use-case.

For example:

  • At Element, we need to store an array of addresses in order to describe the make up of an LP token (not currently supported, see #97). In this scenario, the index of the addresses is meaningful so an array is the best way to model it.

  • In other cases, we need to store a Balancer pool id, which is an opaque string that happens to be greater than the current string limit allowed by extensions (PR submitted, but never reviewed/merged, see #45).

Based on the number of issues and PRs filed here, having a free-form extensions object would solve many problems for tokenlist builders. And since it's JSON, it will still compress nicely w/ standard solutions like gzip to avoid issues with file size on the network.

I'm also happy to submit a PR for this change. Thanks for this awesome project, and I'm curious to hear the team's thoughts on this!

Add Conditional Tokens List to tokenlists.org

The Conditional Tokens Framework is the underlying technology that prediction markets like Omen and Polymarket are built on. They are ERC1155 tokens, but we have deployed an ERC20 wrapper so that they can be used with contracts and applications that support ERC20 but do not support ERC1155.

One feature of the ERC20 wrapper is that the name and symbol of each token is identical ("wrapped multi token" and WMT), this is to make it more generally useful.

To remedy this, we have started curating a list of wrapped conditional tokens and would like to add it to the default list at tokenlists.org.

The list can be found here:
https://github.com/gnosis/conditional-tokens-list/blob/main/conditional-token-list.json

Allow Diacritics in token name

Hello,

Some tokens have diacritics in their name, these should be allowed in the standard.

Examples:

Currently the validation of such tokens fails, even if they are valid (eg: In this case Kleros curated):

{
  keyword: 'pattern',
  dataPath: '.tokens[445].name',
  schemaPath: '#/properties/name/pattern',
  params: { pattern: "^[ \\w.'+\\-%/]+$" },
  message: `should match pattern "^[ \\w.'+\\-%/]+$"`,
  schema: "^[ \\w.'+\\-%/]+$",
  parentSchema: {
    type: 'string',
    description: 'The name of the token',
    minLength: 1,
    maxLength: 40,
    pattern: "^[ \\w.'+\\-%/]+$",
    examples: [ 'USD Coin' ]
  },
  data: 'Líf'
}

Proposed regular expression for names: ^[ \w.'+-%/À-ÖØ-öø-ÿ]+$

Best Regards

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.