Adding *MyCoin* to CryptoAssets library

Sections in this article

The @ledgerhq/cryptoassets package contains all definitions of cryptoassets that could be useful to Ledger Live.

Ledger Live deals with different kinds of currencies and assets: fiat currencies, cryptocurrencies, and tokens. They all share similar concepts but have specifics, which are defined as a Currency model.

All types can be found in @ledgerhq/cryptoassets/src/types.ts

The Currency model

Essentially all currencies share this common ground:

  • name: string: the display name of a currency. For instance "Bitcoin" or "Euro".
  • ticker: string: the ticker name in exchanges and used for rates (for instance BTC or EUR).
  • countervalueTicker?: string: an alias for the ticker (or alternative ticker)
  • units: Unit[]: all available Unit of the currency (see below what is a Unit). by convention, [0] is the default and has the “highest” magnitude.
  • disableCountervalue?: boolean: if available, this field expresses that we should assume there is not valid counter value for this coin. (because either we can’t trade it or it’s not available enough to assume enabling its value)
  • symbol?: string: if available, it’s a short symbol for the coin. In practice it’s currently not used and might be dropped.

Unit

type Unit = {
  // display name of a given unit (example: satoshi)
  name: string,
  // string to use when formatting the unit. like 'BTC' or 'USD'
  code: string,
  // number of digits after the '.' in context of this unit.
  magnitude: number,
  // should it always print all digits even if they are 0 (usually: true for fiats, false for cryptos)
  showAllDigits?: boolean
};

A unit describes a given representation of a currency for humans. A currency can have many units, for instance, we can assume Euro have euros and cents. We can define Bitcoin to have: bitcoin, mBTC, bit, satoshi (but that’s up to us really).

There are however two essential properties we must respect:

  • the first unit ([0]) in an array of units is the highest unit, typically the default and commonly used unit (euro, bitcoin)
  • the last unit must have a magnitude of 0: it is the smallest unit which in fine determines the magnitude of the coin (the most atomic unit representable in this currency) and drives integers representation.

Here is an example of Bitcoin units:

[
  {
    name: "bitcoin",
    code: "BTC",
    magnitude: 8
  },
  {
    name: "mBTC",
    code: "mBTC",
    magnitude: 5
  },
  {
    name: "bit",
    code: "bit",
    magnitude: 2
  },
  {
    name: "satoshi",
    code: "sat",
    magnitude: 0
  }
];

The field showAllDigits is generally unset for all cryptocurrencies and set for fiat currencies to true (but there are exceptions). It forces a unit to display all digits even if it’s all zeros.

We don’t want showAllDigits for currencies because they generally have a lot of magnitudes, for instance, Ethereum has 18 which would turn ETH 42.100000000000000000. Instead, we want ETH 42.1.

At the opposite, it is commonly wanted that for popular fiats like EUR we will always display EUR 42.10 and never EUR 42.1.

In live-common, our formatter is implemented by formatCurrencyUnit which takes a BigNumber value and a Unit (and many other options available).

CryptoCurrency specific fields

The crypto currency level introduces many fields that are exclusively specific to crypto currency.

type CryptoCurrency = CurrencyCommon & {
  type: "CryptoCurrency",
  // unique internal id of a crypto currency
  id: string,
  // define if a crypto is a fork from another coin. helps dealing with split/unsplit
  forkedFrom?: string,
  // name of the app as shown in the Manager
  managerAppName: string,
  // coin type according to slip44. THIS IS NOT GUARANTEED UNIQUE across currencies (e.g testnets,..)
  coinType: number,
  // the scheme name to use when formatting an URI (without the ':')
  scheme: string,
  // used for UI
  color: string,
  // a name for implementation (some coins share a common implementation like bitcoin or ethereum) - corresponds to live-common family folder name
  family: string,
  // the expected time of a block
  blockAvgTime?: number, // in seconds
  supportsSegwit?: boolean,
  supportsNativeSegwit?: boolean,
  // if defined this coin is a testnet for another crypto (id)};
  isTestnetFor?: string,
  // should be defined for bitcoin family
  bitcoinLikeInfo?: {
    P2PKH: number,
    P2SH: number
  },
  // should be defined for ethereum family
  ethereumLikeInfo?: {
    chainId: number
  },
  explorerViews: ExplorerView[],
  terminated?: {
    link: string
  }
};
Note
CoinType is generally found in github.com/satoshilabs/slips/blob/master/slip-0044.md, although unicity is not quaranteed across networks (testnets, etc...).

ExplorerView

You can define one or many explorers with urls, which will be used for external links in Ledger Live.

type ExplorerView = {
  // url for transaction with $hash param
  tx?: string,
  // url for address with $address param
  address?: string,
  // url for a token with $contractAddress and $address params
  token?: string
};
Note
Find a reliable explorer. If you find more than one explorer, list them from most to less popular. Ledger Live will likely use the first explorer as default.

TokenCurrency specific fields

Tokens are also available through the cryptoassets package. ERC20, TRC10 and TRC20 tokens are automatically maintained on a regular basis. But if your blockchain supports tokens and you would like to add them, feel free to contact us.

type TokenCurrency = CurrencyCommon & {
  type: "TokenCurrency",
  id: string,
  ledgerSignature?: string,
  contractAddress: string,
  // the currency it belongs to. e.g. 'ethereum'
  parentCurrency: CryptoCurrency,
  // the type of token in the blockchain it belongs. e.g. 'erc20'
  tokenType: string
};

Adding MyCoin

Ensure that before integrating your coin to Ledger Live, your coin is well defined in @ledgerhq/cryptoassets/src/currencies.js

 mycoin: {
   type: "CryptoCurrency",
   id: "mycoin",
   coinType: 8008, // The slip-0044 coin type if registered
   name: "MyCoin",
   managerAppName: "MyCoin", // name of the nano app in manager case-sensitive
   ticker: "MYC",
   countervalueTicker: "MYC", // depending on the counter value api
   scheme: "mycoin",
   color: "#E6007A", // color to be display on live-desktop and mobile
   family: "mycoin", // folder name in the live-common / desktop and mobile
   units: [
    {
       name: "MYC",
       code: "MYC",
       magnitude: 8,
    },
    {
       name: "SmallestUnit",
       code: "SMALLESTUNIT",
       magnitude: 0,
    },
  ],
   explorerViews: [
    {
       address: "https://mycoinexplorer.com/account/$address", // url for exploring an address
       tx: "https://mycoinexplorer.com/transaction/$hash", // url for exploring a transaction
       token: "https://mycoinexplorer.com/token/$contractAddress/?a=$address", // url for exploring a token address
    },
  ],
},

Did you find this page helpful?

What would you like to see here?
Introduction
Adding *MyCoin* Nano App JS Bindings
Getting Started
Theme Features
Customization