mirror of
https://github.com/luxfi/assets.git
synced 2026-07-27 04:37:14 +00:00
Add Injective assets (#27191)
* Create logo .png * Create logo.png * Create info.json * Create logo.png * Create info.json * Create info.json * Create logo.png * Create info.json * Create logo.png * Create info.json * Update info.json * Update info.json * Update info.json * Update info.json * Update info.json * Create logo.png * Delete logo .png * tokens * tokens * tokens * tokens * tokens * tokens --------- Co-authored-by: Denis <136321897+defisaur@users.noreply.github.com>
This commit is contained in:
committed by
GitHub
co-authored by
Denis
parent
f82bade254
commit
2204745e34
@@ -1,25 +1,27 @@
|
|||||||
name: Fix (Dry run)
|
#Disabled, we have 'check' job, 'fix' job do invisible changes which is not convenient to debug
|
||||||
on:
|
|
||||||
pull_request:
|
|
||||||
branches: [ master ]
|
|
||||||
|
|
||||||
jobs:
|
#name: Fix (Dry run)
|
||||||
fix-dryrun:
|
#on:
|
||||||
runs-on: ubuntu-latest
|
# pull_request:
|
||||||
steps:
|
# branches: [ master ]
|
||||||
- name: Set up Go
|
#
|
||||||
uses: actions/setup-go@v4
|
#jobs:
|
||||||
with:
|
# fix-dryrun:
|
||||||
go-version: 1.18
|
# runs-on: ubuntu-latest
|
||||||
|
# steps:
|
||||||
- name: Check out code
|
# - name: Set up Go
|
||||||
uses: actions/checkout@v3
|
# uses: actions/setup-go@v4
|
||||||
|
# with:
|
||||||
- name: Run fix
|
# go-version: 1.18
|
||||||
run: make fix
|
#
|
||||||
|
# - name: Check out code
|
||||||
- name: Show fix result (diff)
|
# uses: actions/checkout@v3
|
||||||
run: |
|
#
|
||||||
git config core.ignorecase false
|
# - name: Run fix
|
||||||
git status
|
# run: make fix
|
||||||
git diff
|
#
|
||||||
|
# - name: Show fix result (diff)
|
||||||
|
# run: |
|
||||||
|
# git config core.ignorecase false
|
||||||
|
# git status
|
||||||
|
# git diff
|
||||||
|
|||||||
+47
-45
@@ -1,46 +1,48 @@
|
|||||||
name: Fix All
|
#Disabled, we have 'check' job, 'fix' job do invisible changes which is not convenient to debug
|
||||||
|
|
||||||
on:
|
#name: Fix All
|
||||||
push:
|
#
|
||||||
branches:
|
#on:
|
||||||
- '*'
|
# push:
|
||||||
workflow_dispatch:
|
# branches:
|
||||||
|
# - '*'
|
||||||
jobs:
|
# workflow_dispatch:
|
||||||
fix-all:
|
#
|
||||||
runs-on: ubuntu-latest
|
#jobs:
|
||||||
|
# fix-all:
|
||||||
if: github.repository_owner == 'trustwallet' && github.event.repository.fork == false
|
# runs-on: ubuntu-latest
|
||||||
|
#
|
||||||
steps:
|
# if: github.repository_owner == 'trustwallet' && github.event.repository.fork == false
|
||||||
- name: Checkout (trustwallet repo, secret token)
|
#
|
||||||
uses: actions/checkout@v3
|
# steps:
|
||||||
with:
|
# - name: Checkout (trustwallet repo, secret token)
|
||||||
# Use trust-ci fine-grained PAT to checkout and later commit the code
|
# uses: actions/checkout@v3
|
||||||
# Do not use for forked repos
|
# with:
|
||||||
token: ${{ secrets.CI_GITHUB_TOKEN }}
|
# # Use trust-ci fine-grained PAT to checkout and later commit the code
|
||||||
ref: ${{ github.ref }}
|
# # Do not use for forked repos
|
||||||
|
# token: ${{ secrets.CI_GITHUB_TOKEN }}
|
||||||
- name: Set up Go
|
# ref: ${{ github.ref }}
|
||||||
uses: actions/setup-go@v4
|
#
|
||||||
with:
|
# - name: Set up Go
|
||||||
go-version: 1.18
|
# uses: actions/setup-go@v4
|
||||||
|
# with:
|
||||||
- name: Run fix
|
# go-version: 1.18
|
||||||
run: make fix
|
#
|
||||||
|
# - name: Run fix
|
||||||
- name: Show fix result (diff)
|
# run: make fix
|
||||||
run: |
|
#
|
||||||
git status
|
# - name: Show fix result (diff)
|
||||||
git diff
|
# run: |
|
||||||
|
# git status
|
||||||
- name: Run check
|
# git diff
|
||||||
run: make check
|
#
|
||||||
|
# - name: Run check
|
||||||
- name: Commit changes
|
# run: make check
|
||||||
if: success()
|
#
|
||||||
uses: stefanzweifel/git-auto-commit-action@v4.16.0
|
# - name: Commit changes
|
||||||
with:
|
# if: success()
|
||||||
commit_user_name: trust-ci
|
# uses: stefanzweifel/git-auto-commit-action@v4.16.0
|
||||||
commit_user_email: "117647528+trust-ci@users.noreply.github.com"
|
# with:
|
||||||
commit_message: Auto fix all (sanity and consistency)
|
# commit_user_name: trust-ci
|
||||||
|
# commit_user_email: "117647528+trust-ci@users.noreply.github.com"
|
||||||
|
# commit_message: Auto fix all (sanity and consistency)
|
||||||
|
|||||||
@@ -192,7 +192,6 @@ linters:
|
|||||||
- deadcode
|
- deadcode
|
||||||
- depguard
|
- depguard
|
||||||
- dogsled
|
- dogsled
|
||||||
- dupl
|
|
||||||
- errcheck
|
- errcheck
|
||||||
- exportloopref
|
- exportloopref
|
||||||
- exhaustive
|
- exhaustive
|
||||||
|
|||||||
+29
@@ -0,0 +1,29 @@
|
|||||||
|
{
|
||||||
|
"name": "Arbitrum",
|
||||||
|
"type": "INJECTIVE",
|
||||||
|
"symbol": "ARB",
|
||||||
|
"decimals": 8,
|
||||||
|
"website": "https://arbitrum.foundation/",
|
||||||
|
"description": "$ARB tokens can be used to vote on Arbitrum DAO governance proposals, allowing $ARB holders to collectively shape the future of Arbitrum protocols and chains. Token holders can also delegate their voting power to delegates.",
|
||||||
|
"explorer": "https://explorer.injective.network/asset/?tokenType=tokenFactory&denom=factory/inj14ejqjyq8um4p3xfqj74yld5waqljf88f9eneuk/inj1d5vz0uzwlpfvgwrwulxg6syy82axa58y4fuszd",
|
||||||
|
"status": "active",
|
||||||
|
"id": "inj1d5vz0uzwlpfvgwrwulxg6syy82axa58y4fuszd",
|
||||||
|
"links": [
|
||||||
|
{
|
||||||
|
"name": "twitter",
|
||||||
|
"url": "https://twitter.com/arbitrum"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "whitepaper",
|
||||||
|
"url": "https://docs.arbitrum.foundation/deployment-addresses"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "discord",
|
||||||
|
"url": "https://discord.com/arbitrum"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "coinmarketcap",
|
||||||
|
"url": "https://coinmarketcap.com/ru/currencies/arbitrum-iou/"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
BIN
Binary file not shown.
|
After Width: | Height: | Size: 36 KiB |
+21
@@ -0,0 +1,21 @@
|
|||||||
|
{
|
||||||
|
"name": "Talis",
|
||||||
|
"website": "https://injective.talis.art",
|
||||||
|
"description": "In the dynamic landscape of NFTs and cryptocurrency, platforms that offer innovative solutions and tools play a crucial role in shaping the ecosystem.",
|
||||||
|
"explorer": "https://explorer.injective.network/asset/?tokenType=tokenFactory&denom=factory/inj1maeyvxfamtn8lfyxpjca8kuvauuf2qeu6gtxm3/Talis",
|
||||||
|
"type": "INJECTIVE",
|
||||||
|
"symbol": "TALIS",
|
||||||
|
"decimals": 6,
|
||||||
|
"status": "active",
|
||||||
|
"id": "inj1maeyvxfamtn8lfyxpjca8kuvauuf2qeu6gtxm3",
|
||||||
|
"links": [
|
||||||
|
{
|
||||||
|
"name": "twitter",
|
||||||
|
"url": "https://twitter.com/ProtocolTalis"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "telegram",
|
||||||
|
"url": "https://t.me/talisprotocol"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
BIN
Binary file not shown.
|
After Width: | Height: | Size: 34 KiB |
+40
@@ -0,0 +1,40 @@
|
|||||||
|
{
|
||||||
|
"name": "Chiliz",
|
||||||
|
"website": "https://chiliz.com",
|
||||||
|
"description": "Chiliz, powering Socios.com, aims to give sports and esports fans the ability to crowd-manage their favorite teams, games, leagues, and events.",
|
||||||
|
"explorer": "https://explorer.injective.network/asset/?tokenType=tokenFactory&denom=factory/inj14ejqjyq8um4p3xfqj74yld5waqljf88f9eneuk/inj1q6kpxy6ar5lkxqudjvryarrrttmakwsvzkvcyh",
|
||||||
|
"type": "INJECTIVE",
|
||||||
|
"symbol": "CHZ",
|
||||||
|
"decimals": 8,
|
||||||
|
"status": "active",
|
||||||
|
"id": "inj1q6kpxy6ar5lkxqudjvryarrrttmakwsvzkvcyh",
|
||||||
|
"tags": [
|
||||||
|
"nft"
|
||||||
|
],
|
||||||
|
"links": [
|
||||||
|
{
|
||||||
|
"name": "telegram",
|
||||||
|
"url": "https://t.me/chiliz_io"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "twitter",
|
||||||
|
"url": "https://twitter.com/chiliZ/"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "facebook",
|
||||||
|
"url": "https://facebook.com/chiliZdotcom/"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "blog",
|
||||||
|
"url": "https://medium.com/chiliz"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "whitepaper",
|
||||||
|
"url": "https://chiliz.com/docs/CHZ_whitepaper.pdf"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "coingecko",
|
||||||
|
"url": "https://coingecko.com/en/coins/chiliz/"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
BIN
Binary file not shown.
|
After Width: | Height: | Size: 6.2 KiB |
+37
@@ -0,0 +1,37 @@
|
|||||||
|
{
|
||||||
|
"name": "USD Coin",
|
||||||
|
"website": "https://centre.io/usdc",
|
||||||
|
"description": "USDC is a fully collateralized US dollar stablecoin, an Ethereum powered coin and is the brainchild of CENTRE, an open source project bootstrapped by contributions from Circle and Coinbase.",
|
||||||
|
"explorer": "https://explorer.injective.network/asset/?tokenType=tokenFactory&denom=factory/inj14ejqjyq8um4p3xfqj74yld5waqljf88f9eneuk/inj1q6zlut7gtkzknkk773jecujwsdkgq882akqksk",
|
||||||
|
"type": "INJECTIVE",
|
||||||
|
"symbol": "USDCET",
|
||||||
|
"decimals": 6,
|
||||||
|
"status": "active",
|
||||||
|
"id": "inj1q6zlut7gtkzknkk773jecujwsdkgq882akqksk",
|
||||||
|
"tags": [
|
||||||
|
"defi",
|
||||||
|
"stablecoin"
|
||||||
|
],
|
||||||
|
"links": [
|
||||||
|
{
|
||||||
|
"name": "github",
|
||||||
|
"url": "https://github.com/centrehq"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "medium",
|
||||||
|
"url": "https://medium.com/centre-blog"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "whitepaper",
|
||||||
|
"url": "https://centre.io/pdfs/centre-whitepaper.pdf"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "coinmarketcap",
|
||||||
|
"url": "https://coinmarketcap.com/currencies/usd-coin/"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "coingecko",
|
||||||
|
"url": "https://coingecko.com/en/coins/usd-coin/"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
BIN
Binary file not shown.
|
After Width: | Height: | Size: 20 KiB |
+32
@@ -0,0 +1,32 @@
|
|||||||
|
{
|
||||||
|
"name": "Solana",
|
||||||
|
"website": "https://solana.com/",
|
||||||
|
"description": "Solana is the worlds most performant blockchain in the world at 710k transactions per second. 710k TPS is achieved by encoding the passage of time as data.",
|
||||||
|
"explorer": "https://explorer.injective.network/asset/?tokenType=tokenFactory&denom=factory/inj14ejqjyq8um4p3xfqj74yld5waqljf88f9eneuk/inj1sthrn5ep8ls5vzz8f9gp89khhmedahhdkqa8z3",
|
||||||
|
"symbol": "SOL",
|
||||||
|
"type": "INJECTIVE",
|
||||||
|
"decimals": 8,
|
||||||
|
"status": "active",
|
||||||
|
"id": "inj1sthrn5ep8ls5vzz8f9gp89khhmedahhdkqa8z3",
|
||||||
|
"tags": [
|
||||||
|
"staking-native"
|
||||||
|
],
|
||||||
|
"links": [
|
||||||
|
{
|
||||||
|
"name": "github",
|
||||||
|
"url": "https://github.com/solana-labs"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "twitter",
|
||||||
|
"url": "https://twitter.com/solana"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "reddit",
|
||||||
|
"url": "https://reddit.com/solana"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "whitepaper",
|
||||||
|
"url": "https://github.com/solana-labs/whitepaper"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
BIN
Binary file not shown.
|
After Width: | Height: | Size: 11 KiB |
@@ -7,7 +7,7 @@ require (
|
|||||||
github.com/spf13/cobra v1.7.0
|
github.com/spf13/cobra v1.7.0
|
||||||
github.com/trustwallet/assets-go-libs v0.3.7
|
github.com/trustwallet/assets-go-libs v0.3.7
|
||||||
github.com/trustwallet/go-libs v0.7.3
|
github.com/trustwallet/go-libs v0.7.3
|
||||||
github.com/trustwallet/go-primitives v0.1.16
|
github.com/trustwallet/go-primitives v0.1.17
|
||||||
)
|
)
|
||||||
|
|
||||||
require (
|
require (
|
||||||
|
|||||||
@@ -264,6 +264,14 @@ github.com/trustwallet/go-primitives v0.1.16-0.20240109124104-7cbe07e453d4 h1:sY
|
|||||||
github.com/trustwallet/go-primitives v0.1.16-0.20240109124104-7cbe07e453d4/go.mod h1:GN9WNIOvtz9j77FSYLEqC7apbMlzQnFLNO9LOCMy5Mc=
|
github.com/trustwallet/go-primitives v0.1.16-0.20240109124104-7cbe07e453d4/go.mod h1:GN9WNIOvtz9j77FSYLEqC7apbMlzQnFLNO9LOCMy5Mc=
|
||||||
github.com/trustwallet/go-primitives v0.1.16 h1:vpHVXlAYYK0o7GpWYadbauY+H4GOJ0bKVp/k6gZbH6I=
|
github.com/trustwallet/go-primitives v0.1.16 h1:vpHVXlAYYK0o7GpWYadbauY+H4GOJ0bKVp/k6gZbH6I=
|
||||||
github.com/trustwallet/go-primitives v0.1.16/go.mod h1:GN9WNIOvtz9j77FSYLEqC7apbMlzQnFLNO9LOCMy5Mc=
|
github.com/trustwallet/go-primitives v0.1.16/go.mod h1:GN9WNIOvtz9j77FSYLEqC7apbMlzQnFLNO9LOCMy5Mc=
|
||||||
|
github.com/trustwallet/go-primitives v0.1.17-0.20240112104809-d94379365003 h1:0XkIncqfu2hBCkkhMrVw7hx/lraoyZ+G1BENh+CFtVA=
|
||||||
|
github.com/trustwallet/go-primitives v0.1.17-0.20240112104809-d94379365003/go.mod h1:GN9WNIOvtz9j77FSYLEqC7apbMlzQnFLNO9LOCMy5Mc=
|
||||||
|
github.com/trustwallet/go-primitives v0.1.17-0.20240112110133-ea920360531b h1:akbAfXaD987dDl5nbQbCiBSRP65pIWZdg9SNqY/pkfY=
|
||||||
|
github.com/trustwallet/go-primitives v0.1.17-0.20240112110133-ea920360531b/go.mod h1:GN9WNIOvtz9j77FSYLEqC7apbMlzQnFLNO9LOCMy5Mc=
|
||||||
|
github.com/trustwallet/go-primitives v0.1.17-0.20240112111413-aca39bd29cc2 h1:3tt6/BPEtZWpQlagvqEoGz9Z53Jx0vrU+uPtxT/lCWg=
|
||||||
|
github.com/trustwallet/go-primitives v0.1.17-0.20240112111413-aca39bd29cc2/go.mod h1:GN9WNIOvtz9j77FSYLEqC7apbMlzQnFLNO9LOCMy5Mc=
|
||||||
|
github.com/trustwallet/go-primitives v0.1.17 h1:X0vVRbJZoDcrQJTQ2vi5gubPfXEn43M9mpxkfRg/Fok=
|
||||||
|
github.com/trustwallet/go-primitives v0.1.17/go.mod h1:GN9WNIOvtz9j77FSYLEqC7apbMlzQnFLNO9LOCMy5Mc=
|
||||||
github.com/ugorji/go/codec v1.1.7 h1:2SvQaVZ1ouYrrKKwoSk2pzd4A9evlKJb9oTL+OaLUSs=
|
github.com/ugorji/go/codec v1.1.7 h1:2SvQaVZ1ouYrrKKwoSk2pzd4A9evlKJb9oTL+OaLUSs=
|
||||||
github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||||
github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||||
|
|||||||
@@ -0,0 +1,56 @@
|
|||||||
|
package info
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/trustwallet/assets-go-libs/validation"
|
||||||
|
"github.com/trustwallet/go-primitives/coin"
|
||||||
|
)
|
||||||
|
|
||||||
|
func ValidateAsset(a AssetModel, chain coin.Coin, addr string) error {
|
||||||
|
if err := ValidateAssetRequiredKeys(a); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// All fields validated for nil and can be safety used.
|
||||||
|
compErr := validation.NewErrComposite()
|
||||||
|
if err := ValidateAssetType(*a.Type, chain); err != nil {
|
||||||
|
compErr.Append(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := ValidateAssetID(*a.ID, addr); err != nil {
|
||||||
|
compErr.Append(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := ValidateDecimals(*a.Decimals); err != nil {
|
||||||
|
compErr.Append(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := ValidateAssetDecimalsAccordingType(*a.Type, *a.Decimals); err != nil {
|
||||||
|
compErr.Append(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := ValidateStatus(*a.Status); err != nil {
|
||||||
|
compErr.Append(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := ValidateDescription(*a.Description); err != nil {
|
||||||
|
compErr.Append(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := ValidateDescriptionWebsite(*a.Description, *a.Website); err != nil {
|
||||||
|
compErr.Append(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := ValidateExplorer(*a.Explorer, *a.Name, chain, addr, *a.Type); err != nil {
|
||||||
|
compErr.Append(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := ValidateLinks(a.Links); err != nil {
|
||||||
|
compErr.Append(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if compErr.Len() > 0 {
|
||||||
|
return compErr
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
@@ -0,0 +1,47 @@
|
|||||||
|
package info
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/trustwallet/assets-go-libs/validation"
|
||||||
|
)
|
||||||
|
|
||||||
|
func ValidateCoin(c CoinModel, allowedTags []string) error {
|
||||||
|
if err := ValidateCoinRequiredKeys(c); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// All fields validated for nil and can be safety used.
|
||||||
|
compErr := validation.NewErrComposite()
|
||||||
|
if err := ValidateCoinType(*c.Type); err != nil {
|
||||||
|
compErr.Append(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := ValidateDecimals(*c.Decimals); err != nil {
|
||||||
|
compErr.Append(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := ValidateStatus(*c.Status); err != nil {
|
||||||
|
compErr.Append(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := ValidateTags(c.Tags, allowedTags); err != nil {
|
||||||
|
compErr.Append(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := ValidateDescription(*c.Description); err != nil {
|
||||||
|
compErr.Append(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := ValidateDescriptionWebsite(*c.Description, *c.Website); err != nil {
|
||||||
|
compErr.Append(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := ValidateLinks(c.Links); err != nil {
|
||||||
|
compErr.Append(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if compErr.Len() > 0 {
|
||||||
|
return compErr
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
Vendored
+35
@@ -0,0 +1,35 @@
|
|||||||
|
package external
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"strconv"
|
||||||
|
|
||||||
|
"github.com/trustwallet/assets-go-libs/http"
|
||||||
|
)
|
||||||
|
|
||||||
|
const ethAPIURL = "https://api.ethplorer.io/getTokenInfo/%s?apiKey=freekey"
|
||||||
|
|
||||||
|
type TokenInfoERC20 struct {
|
||||||
|
Decimals string `json:"decimals"`
|
||||||
|
HoldersCount int `json:"holdersCount"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func GetTokenInfoForERC20(tokenID string) (*TokenInfo, error) {
|
||||||
|
url := fmt.Sprintf(ethAPIURL, tokenID)
|
||||||
|
|
||||||
|
var result TokenInfoERC20
|
||||||
|
err := http.GetHTTPResponse(url, &result)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
decimals, err := strconv.Atoi(result.Decimals)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return &TokenInfo{
|
||||||
|
Decimals: decimals,
|
||||||
|
HoldersCount: result.HoldersCount,
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
Vendored
+85
@@ -0,0 +1,85 @@
|
|||||||
|
package external
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"regexp"
|
||||||
|
"strconv"
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
"github.com/trustwallet/assets-go-libs/http"
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
holdersRegexp = regexp.MustCompile(`(\d+)\saddresses`)
|
||||||
|
decimalsRegexp = regexp.MustCompile(`(\d+)\s+<\/div>`)
|
||||||
|
symbolRegexp = regexp.MustCompile(`<b>(\w+)<\/b>\s<span`)
|
||||||
|
)
|
||||||
|
|
||||||
|
type TokenInfo struct {
|
||||||
|
Symbol string
|
||||||
|
Decimals int
|
||||||
|
HoldersCount int
|
||||||
|
}
|
||||||
|
|
||||||
|
func GetTokenInfo(tokenID, tokentType string) (*TokenInfo, error) {
|
||||||
|
switch strings.ToLower(tokentType) {
|
||||||
|
case "erc20":
|
||||||
|
return GetTokenInfoForERC20(tokenID)
|
||||||
|
case "bep20":
|
||||||
|
return GetTokenInfoByScraping(fmt.Sprintf("https://bscscan.com/token/%s", tokenID))
|
||||||
|
case "fantom":
|
||||||
|
return GetTokenInfoByScraping(fmt.Sprintf("https://ftmscan.com/token/%s", tokenID))
|
||||||
|
case "polygon":
|
||||||
|
return GetTokenInfoByScraping(fmt.Sprintf("https://polygonscan.com/token/%s", tokenID))
|
||||||
|
case "avalanche":
|
||||||
|
return GetTokenInfoByScraping(fmt.Sprintf("https://snowtrace.io/token/%s", tokenID))
|
||||||
|
case "spl":
|
||||||
|
return GetTokenInfoForSPL(tokenID)
|
||||||
|
case "trc20":
|
||||||
|
return GetTokenInfoForTRC20(tokenID)
|
||||||
|
case "trc10":
|
||||||
|
return GetTokenInfoForTRC10(tokenID)
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func GetTokenInfoByScraping(url string) (*TokenInfo, error) {
|
||||||
|
data, err := http.GetHTTPResponseBytes(url)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Remove all "," from content.
|
||||||
|
pageContent := strings.ReplaceAll(string(data), ",", "")
|
||||||
|
|
||||||
|
var holders, decimals int
|
||||||
|
var symbol string
|
||||||
|
|
||||||
|
match := symbolRegexp.FindStringSubmatch(pageContent)
|
||||||
|
if len(match) > 1 {
|
||||||
|
symbol = match[1]
|
||||||
|
}
|
||||||
|
|
||||||
|
match = decimalsRegexp.FindStringSubmatch(pageContent)
|
||||||
|
if len(match) > 1 {
|
||||||
|
decimals, err = strconv.Atoi(match[1])
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
match = holdersRegexp.FindStringSubmatch(pageContent)
|
||||||
|
if len(match) > 1 {
|
||||||
|
holders, err = strconv.Atoi(match[1])
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return &TokenInfo{
|
||||||
|
Symbol: symbol,
|
||||||
|
Decimals: decimals,
|
||||||
|
HoldersCount: holders,
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
Vendored
+37
@@ -0,0 +1,37 @@
|
|||||||
|
package external
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
|
||||||
|
"github.com/trustwallet/assets-go-libs/http"
|
||||||
|
)
|
||||||
|
|
||||||
|
const splAPIURL = "https://public-api.solscan.io/token/holders?tokenAddress=%s"
|
||||||
|
|
||||||
|
type TokenInfoSPL struct {
|
||||||
|
Data []Data `json:"data"`
|
||||||
|
HoldersCount int `json:"total"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type Data struct {
|
||||||
|
Decimals int `json:"decimals"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func GetTokenInfoForSPL(tokenID string) (*TokenInfo, error) {
|
||||||
|
url := fmt.Sprintf(splAPIURL, tokenID)
|
||||||
|
|
||||||
|
var result TokenInfoSPL
|
||||||
|
err := http.GetHTTPResponse(url, &result)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(result.Data) == 0 {
|
||||||
|
return nil, fmt.Errorf("failed to get token info for SPL token")
|
||||||
|
}
|
||||||
|
|
||||||
|
return &TokenInfo{
|
||||||
|
Decimals: result.Data[0].Decimals,
|
||||||
|
HoldersCount: result.HoldersCount,
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
Vendored
+38
@@ -0,0 +1,38 @@
|
|||||||
|
package external
|
||||||
|
|
||||||
|
import (
|
||||||
|
"errors"
|
||||||
|
"fmt"
|
||||||
|
|
||||||
|
"github.com/trustwallet/assets-go-libs/http"
|
||||||
|
)
|
||||||
|
|
||||||
|
const trc10APIURL = "https://apilist.tronscan.io/api/token?id=%s"
|
||||||
|
|
||||||
|
type TRC10TokensResponse struct {
|
||||||
|
Data []struct {
|
||||||
|
Symbol string `json:"abbr"`
|
||||||
|
Decimals int `json:"precision"`
|
||||||
|
HoldersCount int `json:"nrOfTokenHolders"`
|
||||||
|
} `json:"data"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func GetTokenInfoForTRC10(tokenID string) (*TokenInfo, error) {
|
||||||
|
url := fmt.Sprintf(trc10APIURL, tokenID)
|
||||||
|
|
||||||
|
var res TRC10TokensResponse
|
||||||
|
err := http.GetHTTPResponse(url, &res)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(res.Data) == 0 {
|
||||||
|
return nil, errors.New("not found")
|
||||||
|
}
|
||||||
|
|
||||||
|
return &TokenInfo{
|
||||||
|
Symbol: res.Data[0].Symbol,
|
||||||
|
Decimals: res.Data[0].Decimals,
|
||||||
|
HoldersCount: res.Data[0].HoldersCount,
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
Vendored
+38
@@ -0,0 +1,38 @@
|
|||||||
|
package external
|
||||||
|
|
||||||
|
import (
|
||||||
|
"errors"
|
||||||
|
"fmt"
|
||||||
|
|
||||||
|
"github.com/trustwallet/assets-go-libs/http"
|
||||||
|
)
|
||||||
|
|
||||||
|
const trc20APIURL = "https://apilist.tronscan.io/api/token_trc20?contract=%s"
|
||||||
|
|
||||||
|
type TRC20TokensResponse struct {
|
||||||
|
TRC20Tokens []struct {
|
||||||
|
Symbol string `json:"symbol"`
|
||||||
|
Decimals int `json:"decimals"`
|
||||||
|
HoldersCount int `json:"holders_count"`
|
||||||
|
} `json:"trc20_tokens"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func GetTokenInfoForTRC20(tokenID string) (*TokenInfo, error) {
|
||||||
|
url := fmt.Sprintf(trc20APIURL, tokenID)
|
||||||
|
|
||||||
|
var res TRC20TokensResponse
|
||||||
|
err := http.GetHTTPResponse(url, &res)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(res.TRC20Tokens) == 0 {
|
||||||
|
return nil, errors.New("not found")
|
||||||
|
}
|
||||||
|
|
||||||
|
return &TokenInfo{
|
||||||
|
Symbol: res.TRC20Tokens[0].Symbol,
|
||||||
|
Decimals: res.TRC20Tokens[0].Decimals,
|
||||||
|
HoldersCount: res.TRC20Tokens[0].HoldersCount,
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
@@ -0,0 +1,263 @@
|
|||||||
|
package info
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
str "github.com/trustwallet/assets-go-libs/strings"
|
||||||
|
"github.com/trustwallet/assets-go-libs/validation"
|
||||||
|
"github.com/trustwallet/go-primitives/coin"
|
||||||
|
"github.com/trustwallet/go-primitives/types"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Asset info specific validators.
|
||||||
|
|
||||||
|
func ValidateAssetRequiredKeys(a AssetModel) error {
|
||||||
|
var fields []string
|
||||||
|
if a.Name != nil && !isEmpty(*a.Name) {
|
||||||
|
fields = append(fields, "name")
|
||||||
|
}
|
||||||
|
if a.Symbol != nil && !isEmpty(*a.Symbol) {
|
||||||
|
fields = append(fields, "symbol")
|
||||||
|
}
|
||||||
|
if a.Type != nil && !isEmpty(*a.Type) {
|
||||||
|
fields = append(fields, "type")
|
||||||
|
}
|
||||||
|
if a.Decimals != nil {
|
||||||
|
fields = append(fields, "decimals")
|
||||||
|
}
|
||||||
|
if a.Description != nil && !isEmpty(*a.Description) {
|
||||||
|
fields = append(fields, "description")
|
||||||
|
}
|
||||||
|
if a.Website != nil {
|
||||||
|
fields = append(fields, "website")
|
||||||
|
}
|
||||||
|
if a.Explorer != nil && !isEmpty(*a.Explorer) {
|
||||||
|
fields = append(fields, "explorer")
|
||||||
|
}
|
||||||
|
if a.Status != nil && !isEmpty(*a.Status) {
|
||||||
|
fields = append(fields, "status")
|
||||||
|
}
|
||||||
|
if a.ID != nil && !isEmpty(*a.ID) {
|
||||||
|
fields = append(fields, "id")
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(fields) != len(requiredAssetFields) {
|
||||||
|
return fmt.Errorf("%w: %s", validation.ErrMissingField,
|
||||||
|
strings.Join(str.Difference(requiredAssetFields, fields), ", "))
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func ValidateAssetType(assetType string, chain coin.Coin) error {
|
||||||
|
chainFromType, err := types.GetChainFromAssetType(assetType)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("failed to get chain from asset type: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if chainFromType != chain {
|
||||||
|
return fmt.Errorf("%w: asset type field", validation.ErrInvalidField)
|
||||||
|
}
|
||||||
|
|
||||||
|
if strings.ToUpper(assetType) != assetType {
|
||||||
|
return fmt.Errorf("%w: asset type should be ALLCAPS", validation.ErrInvalidField)
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func ValidateAssetID(id, address string) error {
|
||||||
|
if id != address {
|
||||||
|
if !strings.EqualFold(id, address) {
|
||||||
|
return fmt.Errorf("%w: invalid id field", validation.ErrInvalidField)
|
||||||
|
}
|
||||||
|
|
||||||
|
return fmt.Errorf("%w: invalid case for id field", validation.ErrInvalidField)
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func ValidateAssetDecimalsAccordingType(assetType string, decimals int) error {
|
||||||
|
if assetType == "BEP2" && decimals != 8 {
|
||||||
|
return fmt.Errorf("%w: invalid decimals field, BEP2 tokens have 8 decimals", validation.ErrInvalidField)
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// CoinModel info specific validators.
|
||||||
|
|
||||||
|
func ValidateCoinRequiredKeys(c CoinModel) error {
|
||||||
|
var fields []string
|
||||||
|
if c.Name != nil && !isEmpty(*c.Name) {
|
||||||
|
fields = append(fields, "name")
|
||||||
|
}
|
||||||
|
if c.Symbol != nil && !isEmpty(*c.Symbol) {
|
||||||
|
fields = append(fields, "symbol")
|
||||||
|
}
|
||||||
|
if c.Type != nil && !isEmpty(*c.Type) {
|
||||||
|
fields = append(fields, "type")
|
||||||
|
}
|
||||||
|
if c.Decimals != nil {
|
||||||
|
fields = append(fields, "decimals")
|
||||||
|
}
|
||||||
|
if c.Description != nil && !isEmpty(*c.Description) {
|
||||||
|
fields = append(fields, "description")
|
||||||
|
}
|
||||||
|
if c.Website != nil && !isEmpty(*c.Website) {
|
||||||
|
fields = append(fields, "website")
|
||||||
|
}
|
||||||
|
if c.Explorer != nil && !isEmpty(*c.Explorer) {
|
||||||
|
fields = append(fields, "explorer")
|
||||||
|
}
|
||||||
|
if c.Status != nil && !isEmpty(*c.Status) {
|
||||||
|
fields = append(fields, "status")
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(fields) != len(requiredCoinFields) {
|
||||||
|
return fmt.Errorf("%w: %s", validation.ErrMissingField,
|
||||||
|
strings.Join(str.Difference(requiredCoinFields, fields), ", "))
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func ValidateLinks(links []Link) error {
|
||||||
|
if len(links) < 2 {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, l := range links {
|
||||||
|
if l.Name == nil || l.URL == nil {
|
||||||
|
return fmt.Errorf("%w: missing required fields links.url and links.name", validation.ErrMissingField)
|
||||||
|
}
|
||||||
|
|
||||||
|
if !linkNameAllowed(*l.Name) {
|
||||||
|
return fmt.Errorf("invalid value for links.name filed, allowed only: %s",
|
||||||
|
strings.Join(supportedLinkNames(), ", "))
|
||||||
|
}
|
||||||
|
|
||||||
|
prefix := allowedLinkKeys[*l.Name]
|
||||||
|
if prefix != "" {
|
||||||
|
if !strings.HasPrefix(*l.URL, prefix) {
|
||||||
|
return fmt.Errorf("invalid value '%s' for %s link url, allowed only with prefix: %s",
|
||||||
|
*l.URL, *l.Name, prefix)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if !strings.HasPrefix(*l.URL, "https://") {
|
||||||
|
return fmt.Errorf("invalid value for links.url field, allowed only with https:// prefix")
|
||||||
|
}
|
||||||
|
|
||||||
|
if *l.Name == "medium" {
|
||||||
|
if !strings.Contains(*l.URL, "medium.com") {
|
||||||
|
return fmt.Errorf("invalid value for links.url field, should contain medium.com")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func ValidateCoinType(assetType string) error {
|
||||||
|
if assetType != "coin" {
|
||||||
|
return fmt.Errorf("%w: only \"coin\" type allowed for coin field", validation.ErrInvalidField)
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func ValidateTags(tags, allowedTags []string) error {
|
||||||
|
for _, t := range tags {
|
||||||
|
if !str.Contains(t, allowedTags) {
|
||||||
|
return fmt.Errorf("%w: tag '%s' not allowed", validation.ErrInvalidField, t)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Both infos can be validated by this validators.
|
||||||
|
|
||||||
|
func ValidateDecimals(decimals int) error {
|
||||||
|
if decimals > 30 || decimals < 0 {
|
||||||
|
return fmt.Errorf("%w: decimals field", validation.ErrInvalidField)
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func ValidateStatus(status string) error {
|
||||||
|
for _, f := range allowedStatusValues {
|
||||||
|
if f == status {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return fmt.Errorf("%w: allowed status field values: %s", validation.ErrInvalidField,
|
||||||
|
strings.Join(allowedStatusValues, ", "))
|
||||||
|
}
|
||||||
|
|
||||||
|
func ValidateDescription(description string) error {
|
||||||
|
if len(description) > 600 {
|
||||||
|
return fmt.Errorf("%w: invalid length for description field", validation.ErrInvalidField)
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, ch := range whiteSpaceCharacters {
|
||||||
|
if strings.Contains(description, ch) {
|
||||||
|
return fmt.Errorf("%w: description contains not allowed characters (new line, double space)",
|
||||||
|
validation.ErrInvalidField)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func ValidateDescriptionWebsite(description, website string) error {
|
||||||
|
if description != "-" && website == "" {
|
||||||
|
return fmt.Errorf("%w: website field", validation.ErrMissingField)
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func ValidateExplorer(explorer, name string, chain coin.Coin, addr, tokenType string) error {
|
||||||
|
// explorer url is composed with values outside info.json.
|
||||||
|
if chain == coin.Nativeinjective() {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
explorerExpected, err := coin.GetCoinExploreURL(chain, addr, tokenType)
|
||||||
|
if err != nil {
|
||||||
|
explorerExpected = ""
|
||||||
|
}
|
||||||
|
|
||||||
|
explorerActual := explorer
|
||||||
|
|
||||||
|
if !strings.EqualFold(explorerActual, explorerExpected) {
|
||||||
|
explorerAlt := explorerURLAlternatives(chain.Handle, name)
|
||||||
|
if len(explorerAlt) == 0 {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
var matchCount int
|
||||||
|
|
||||||
|
for _, e := range explorerAlt {
|
||||||
|
if strings.EqualFold(e, explorerActual) {
|
||||||
|
matchCount++
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if matchCount == 0 {
|
||||||
|
return fmt.Errorf("invalid value for explorer field, %s insted of %s", explorerActual, explorerExpected)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func isEmpty(field string) bool {
|
||||||
|
return field == ""
|
||||||
|
}
|
||||||
@@ -0,0 +1,55 @@
|
|||||||
|
package info
|
||||||
|
|
||||||
|
type (
|
||||||
|
CoinModel struct {
|
||||||
|
Name *string `json:"name,omitempty"`
|
||||||
|
Website *string `json:"website,omitempty"`
|
||||||
|
Description *string `json:"description,omitempty"`
|
||||||
|
Explorer *string `json:"explorer,omitempty"`
|
||||||
|
Research string `json:"research,omitempty"`
|
||||||
|
Symbol *string `json:"symbol,omitempty"`
|
||||||
|
Type *string `json:"type,omitempty"`
|
||||||
|
Decimals *int `json:"decimals,omitempty"`
|
||||||
|
Status *string `json:"status,omitempty"`
|
||||||
|
Tags []string `json:"tags,omitempty"`
|
||||||
|
Links []Link `json:"links,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
AssetModel struct {
|
||||||
|
Name *string `json:"name,omitempty"`
|
||||||
|
Symbol *string `json:"symbol,omitempty"`
|
||||||
|
Type *string `json:"type,omitempty"`
|
||||||
|
Decimals *int `json:"decimals,omitempty"`
|
||||||
|
Description *string `json:"description,omitempty"`
|
||||||
|
Website *string `json:"website,omitempty"`
|
||||||
|
Explorer *string `json:"explorer,omitempty"`
|
||||||
|
Research string `json:"research,omitempty"`
|
||||||
|
Status *string `json:"status,omitempty"`
|
||||||
|
ID *string `json:"id,omitempty"`
|
||||||
|
Links []Link `json:"links,omitempty"`
|
||||||
|
ShortDesc *string `json:"short_desc,omitempty"`
|
||||||
|
Audit *string `json:"audit,omitempty"`
|
||||||
|
AuditReport *string `json:"audit_report,omitempty"`
|
||||||
|
Tags []string `json:"tags,omitempty"`
|
||||||
|
Code *string `json:"code,omitempty"`
|
||||||
|
Ticker *string `json:"ticker,omitempty"`
|
||||||
|
ExplorerEth *string `json:"explorer-ETH,omitempty"`
|
||||||
|
Address *string `json:"address,omitempty"`
|
||||||
|
Twitter *string `json:"twitter,omitempty"`
|
||||||
|
CoinMarketcap *string `json:"coinmarketcap,omitempty"`
|
||||||
|
DataSource *string `json:"data_source,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
Link struct {
|
||||||
|
Name *string `json:"name,omitempty"`
|
||||||
|
URL *string `json:"url,omitempty"`
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
func (a *AssetModel) GetStatus() string {
|
||||||
|
if a.Status == nil {
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
|
||||||
|
return *a.Status
|
||||||
|
}
|
||||||
@@ -0,0 +1,79 @@
|
|||||||
|
package info
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
"github.com/trustwallet/go-primitives/coin"
|
||||||
|
)
|
||||||
|
|
||||||
|
//nolint:gochecknoglobals
|
||||||
|
var (
|
||||||
|
requiredCoinFields = []string{
|
||||||
|
"name", "type", "symbol", "decimals",
|
||||||
|
"description", "website", "explorer", "status",
|
||||||
|
}
|
||||||
|
|
||||||
|
requiredAssetFields = []string{
|
||||||
|
"name", "type", "symbol", "decimals",
|
||||||
|
"description", "website", "explorer", "status", "id",
|
||||||
|
}
|
||||||
|
|
||||||
|
allowedStatusValues = []string{"active", "spam", "abandoned"}
|
||||||
|
|
||||||
|
allowedLinkKeys = map[string]string{
|
||||||
|
"github": "https://github.com/",
|
||||||
|
"whitepaper": "",
|
||||||
|
"twitter": "https://twitter.com/",
|
||||||
|
"telegram": "https://t.me/",
|
||||||
|
"telegram_news": "https://t.me/", // Read-only announcement channel.
|
||||||
|
"medium": "", // URL contains 'medium.com'.
|
||||||
|
"discord": "https://discord.com/",
|
||||||
|
"reddit": "https://reddit.com/",
|
||||||
|
"facebook": "https://facebook.com/",
|
||||||
|
"youtube": "https://youtube.com/",
|
||||||
|
"coinmarketcap": "https://coinmarketcap.com/",
|
||||||
|
"coingecko": "https://coingecko.com/",
|
||||||
|
"blog": "", // Blog, other than medium.
|
||||||
|
"forum": "", // Community site.
|
||||||
|
"docs": "",
|
||||||
|
"source_code": "", // Other than github.
|
||||||
|
}
|
||||||
|
|
||||||
|
whiteSpaceCharacters = []string{"\n", " "}
|
||||||
|
)
|
||||||
|
|
||||||
|
func explorerURLAlternatives(chain, name string) []string {
|
||||||
|
var altUrls []string
|
||||||
|
|
||||||
|
if name != "" {
|
||||||
|
nameNorm := strings.ReplaceAll(strings.ReplaceAll(strings.ReplaceAll(
|
||||||
|
strings.ToLower(name), " ", ""), ")", ""), "(", "")
|
||||||
|
|
||||||
|
if strings.ToLower(chain) == coin.Coins[coin.ETHEREUM].Name {
|
||||||
|
altUrls = append(altUrls, fmt.Sprintf("https://etherscan.io/token/%s", nameNorm))
|
||||||
|
}
|
||||||
|
|
||||||
|
altUrls = append(altUrls, fmt.Sprintf("https://explorer.%s.io", nameNorm))
|
||||||
|
altUrls = append(altUrls, fmt.Sprintf("https://scan.%s.io", nameNorm))
|
||||||
|
}
|
||||||
|
|
||||||
|
return altUrls
|
||||||
|
}
|
||||||
|
|
||||||
|
func linkNameAllowed(str string) bool {
|
||||||
|
if _, exists := allowedLinkKeys[str]; !exists {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
func supportedLinkNames() []string {
|
||||||
|
names := make([]string, 0, len(allowedLinkKeys))
|
||||||
|
for k := range allowedLinkKeys {
|
||||||
|
names = append(names, k)
|
||||||
|
}
|
||||||
|
|
||||||
|
return names
|
||||||
|
}
|
||||||
@@ -8,10 +8,10 @@ import (
|
|||||||
"github.com/trustwallet/assets-go-libs/file"
|
"github.com/trustwallet/assets-go-libs/file"
|
||||||
"github.com/trustwallet/assets-go-libs/path"
|
"github.com/trustwallet/assets-go-libs/path"
|
||||||
"github.com/trustwallet/assets-go-libs/validation"
|
"github.com/trustwallet/assets-go-libs/validation"
|
||||||
"github.com/trustwallet/assets-go-libs/validation/info"
|
|
||||||
"github.com/trustwallet/assets-go-libs/validation/list"
|
"github.com/trustwallet/assets-go-libs/validation/list"
|
||||||
"github.com/trustwallet/assets-go-libs/validation/tokenlist"
|
"github.com/trustwallet/assets-go-libs/validation/tokenlist"
|
||||||
"github.com/trustwallet/assets/internal/config"
|
"github.com/trustwallet/assets/internal/config"
|
||||||
|
"github.com/trustwallet/assets/internal/info"
|
||||||
"github.com/trustwallet/go-primitives/coin"
|
"github.com/trustwallet/go-primitives/coin"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user