Block Atlas provides access to blockchain data. It is used by Trust Wallet to query transaction information and stream new transactions.
A list of supported coins can be found in the config file.
While we are happy about any new coin integrations we cannot immediately accept every request. To keep our high security and reliability standards, every integration must be approved by the Trust Wallet team first.
Pull requests other than coin integrations are always welcome. You can contact the Trust Wallet team through our community site.
To integrate an approved coin with Block Atlas, please follow this guide:
Before starting development on Block Atlas integration, make sure that all of the following requirements are met:
- Your coin is based on the accounts-model and transactions have a single input & output (excluding fees). Integrate UTXO-based coins with BlockBook instead.
- You are NOT integrating a token that runs on top of another blockchain (ERC-20, TRX10, ...)
- Your coin is either
- supported by wallet-core
- OR a ready-for-review PR for wallet-core has been submitted
- Your coin has a public JSON-RPC or HTTP API.
- Said API supports querying a list of transactions by address
- Your coin is registered with SLIP-0044
- Your coin is not already supported
This project is powered by Go, Gin Gonic and Viper.
Try to use existing code of other coins as an example.
Avoid adding additional dependencies for security and performance reasons.
go.mod
contains a list of available third-party packages.
If you think adding a dependency is necessary, please provide an explanation in the respective pull request.
A library specific to your chain is not a necessary dependency.
Add your coin to the end of /coin/coins.yml
.
id
- Coin ID.symbol
- Coin symbol.handle
- Coin handle, this is going to be your coin path, eg:ethereum
:v1/ethereum/...
.name
- The coin name.decimals
- How many decimals your coin has.blockTime
- Time between two blocks.sampleAddress
- Arbitrary address holding coins. It is used to test the API.
Then, run make gen-coins
to re-generate the coin file.
(Optional) Add your coin icon to the end at /README.md
.
The config specifies how to reach your blockchain.
All coins have a <coin>.api
key pointing to the URL that provides your blockchain API.
Add your default config, like hosts and api keys, at /config.yml
.
For each Blockchain implementation, we have one platform, some platforms can be useful for other blockchains, like BTC, LTC, BHC, DASH, DOGE. You can find these implementations inside the platform
package.
Create a platform/<coin>/client.go
file with a Client
struct.
The only exported properties are "constructor"-like parameters.
For example, a client using JSON-RPC might look like this:
type Client struct {
blockatlas.Request
}
func (c *Client) Init() {
p.client = Client{blockatlas.InitClient(viper.GetString("ethereum.api"))}
}
Depending on your required feature set you'll need to expose these methods:
client.GetTxsOfAddress(address string)
client.CurrentBlockNumber(num int64)
&client.GetBlockByNumber()
They will be used in other files later.
/platform/<your_coin>/model.go
contains the data models returned by client.go
above.
Take care when unmarshalling (Go's term for deserializing) currency amounts. We never do floating point operations on currencies but operate on base 10 string representations instead. Use any of these data types in your model.
To make conversions from decimals numbers to satoshi/wei you can use the numbers package inside pkg/numbers
.
The Blockatlas use blockatlas.Amount
object to return value, this object is a type string. Internally, it carries an integer string of smallest units.
The models above are not ready to be used yet and need to be converted to the BlockAtlas generic model.
Define Normalize*
functions in api.go
that convert from model.go
types to blockatlas
transactions (lists).
Tx
can express different transaction types, for my details see the Transaction Format guide
Every coin implements the blockatlas.Platform
and some blockatlas.*API
interfaces.
Create a /platform/<coin>/base.go
file and implement the blockatlas.Platform
methods, Init() & Coin()
like this:
type Platform struct {
client Client
}
func (p *Platform) Init() error {
p.client = Client{blockatlas.InitClient(viper.GetString("ethereum.api"))}
p.client.Headers["X-APIKEY"] = viper.GetString("ethereum.key")
}
func (p *Platform) Coin() coin.Coin {
return coin.Coins[coin.ETH]
}
Then, link your platform at /platform/registry.go
.
TxAPI
can query transactions of an address. Needs to be implemented inside /platform/<coin>/transaction.go
.
Method signatures:
func (p *Platform) GetTxsByAddress(address string) (blockatlas.TxPage, error)
After implementation, a GET /v1/<coin>/<address>
route gets created.
BlockAPI
can tell the chain height and get blocks by their number. Needs to be implemented inside /platform/<coin>/block.go
.
Method signatures:
func (p *Platform) CurrentBlockNumber() (int64, error)
func (p *Platform) GetBlockByNumber(num int64) (*blockatlas.Block, error)
After implementation the observer API gets enabled (required for tx push notifications).
TokenTxAPI
provides token transaction lookups. Needs to be implemented inside /platform/<coin>/transaction.go
.
Method signatures:
GetTokenTxsByAddress(address, token string) (TxPage, error)
TokenAPI
provides token lookups. Needs to be implemented inside /platform/<coin>/token
.
Method signatures:
GetTokenListByAddress(address string) (TokenPage, error)
AddressAPI
provides an AddressAPI to fetch addresses for an account. Needs to be implemented inside /platform/<coin>/base.go
.
Method signatures:
GetAddressesFromXpub(xpub string) ([]string, error)
AddressAPI
provides custom HTTP routes. Needs to be implemented inside /platform/<coin>/collection.go
.
Method signatures:
GetCollections(owner string) (CollectionPage, error)
GetCollectibles(owner, collectibleID string) (CollectiblePage, error)
NamingServiceAPI
provides public name service domains HTTP routes. Needs to be implemented inside /platform/<coin>/domain.go
.
Method signatures:
Lookup(coins []uint64, name string) ([]Resolved, error)
CustomAPI
provides a custom public name service domains HTTP. Needs to be implemented inside /platform/<coin>/custom.go
.
Method signatures:
RegisterRoutes(router gin.IRouter)
Write a test at /platform/<your_coin>/<api>_test.go
to ensure correct normalization.
Try reading and normalizing a sample API response (copy paste output of REST client).
As soon as you are done, file a pull request from your fork to trustwallet:master
.
Our devs will get a notification and review your code soon.
In case of design problems or bugs, we will request changes via GitHub code review.
You can speed up integration and merge approval by making sure that:
- the Git history is relatively clean (
git rebase -i
to squash your commits) - only one pull request is filed (
git push -f
to overwrite the commit history of your PR). Please don't close and open PRs too often, our mail inboxes will be thankful. - no merge conflicts with
trustwallet:master
exist - all tests pass, your build gets a green tick
go lint
has no complaints about your code
After your code is merged, our Continous Delivery will deploy it to our servers and your part is done.
Thanks for contributing to Trust Wallet!