diff --git a/_examples/basic/go.mod b/_examples/basic/go.mod deleted file mode 100644 index 0ef57e6..0000000 --- a/_examples/basic/go.mod +++ /dev/null @@ -1,17 +0,0 @@ -module main - -go 1.18 - -replace github.com/0xsequence/go-tokendirectory => ../../ - -require github.com/0xsequence/go-tokendirectory v0.0.0-00010101000000-000000000000 - -require ( - github.com/0xsequence/ethkit v1.20.24 // indirect - github.com/0xsequence/go-sequence v0.21.1 // indirect - github.com/mattn/go-colorable v0.1.13 // indirect - github.com/mattn/go-isatty v0.0.19 // indirect - github.com/rs/zerolog v1.30.0 // indirect - golang.org/x/crypto v0.12.0 // indirect - golang.org/x/sys v0.11.0 // indirect -) diff --git a/_examples/basic/go.sum b/_examples/basic/go.sum deleted file mode 100644 index c027e00..0000000 --- a/_examples/basic/go.sum +++ /dev/null @@ -1,29 +0,0 @@ -github.com/0xsequence/ethkit v1.20.24 h1:k7G36QuEJwF/ariRpE3lgnm4EU55ZR8IM4SWB3ac+9Y= -github.com/0xsequence/ethkit v1.20.24/go.mod h1:VYl7KyEwQC8h/pl/7yImJdLnMdGNYC5MPSxrK7JIBGE= -github.com/0xsequence/go-sequence v0.21.1 h1:nur4EXpCdtnApGMh559hOjuWHd4b0dYGV+9JjNFXE6M= -github.com/0xsequence/go-sequence v0.21.1/go.mod h1:bWA5HhpzhUJRwn2wFyA0lgBIpvZ4VYXkDFnIYLiVyQo= -github.com/coreos/go-systemd/v22 v22.5.0/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc= -github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= -github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= -github.com/mattn/go-colorable v0.1.12/go.mod h1:u5H1YNBxpqRaxsYJYSkiCWKzEfiAb1Gb520KVy5xxl4= -github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA= -github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg= -github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94= -github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= -github.com/mattn/go-isatty v0.0.19 h1:JITubQf0MOLdlGRuRq+jtsDlekdYPia9ZFsB8h/APPA= -github.com/mattn/go-isatty v0.0.19/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= -github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= -github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= -github.com/rs/xid v1.5.0/go.mod h1:trrq9SKmegXys3aeAKXMUTdJsYXVwGY3RLcfgqegfbg= -github.com/rs/zerolog v1.30.0 h1:SymVODrcRsaRaSInD9yQtKbtWqwsfoPcRff/oRXLj4c= -github.com/rs/zerolog v1.30.0/go.mod h1:/tk+P47gFdPXq4QYjvCmT5/Gsug2nagsFWBWhAiSi1w= -github.com/stretchr/testify v1.8.1 h1:w7B6lhMri9wdJUVmEZPGGhZzrYTPvgJArz7wNPgYKsk= -golang.org/x/crypto v0.12.0 h1:tFM/ta59kqch6LlvYnPa0yx5a83cL2nHflFhYKvv9Yk= -golang.org/x/crypto v0.12.0/go.mod h1:NF0Gs7EO5K4qLn+Ylc+fih8BSTeIjAP05siRnAh98yw= -golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.11.0 h1:eG7RXZHdqOJ1i+0lgLgCpSXAp6M3LYlAo6osgSi0xOM= -golang.org/x/sys v0.11.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= diff --git a/_examples/go.mod b/_examples/go.mod new file mode 100644 index 0000000..86cf757 --- /dev/null +++ b/_examples/go.mod @@ -0,0 +1,17 @@ +module main + +go 1.18 + +replace github.com/0xsequence/go-tokendirectory => ../ + +require github.com/0xsequence/go-tokendirectory v0.0.0-00010101000000-000000000000 + +require ( + github.com/0xsequence/ethkit v1.22.4 // indirect + github.com/0xsequence/go-sequence v0.23.3 // indirect + github.com/mattn/go-colorable v0.1.13 // indirect + github.com/mattn/go-isatty v0.0.20 // indirect + github.com/rs/zerolog v1.31.0 // indirect + golang.org/x/crypto v0.15.0 // indirect + golang.org/x/sys v0.14.0 // indirect +) diff --git a/_examples/go.sum b/_examples/go.sum new file mode 100644 index 0000000..9b50cff --- /dev/null +++ b/_examples/go.sum @@ -0,0 +1,27 @@ +github.com/0xsequence/ethkit v1.22.4 h1:hd6DYnQ/8l1mC7ZcUOyYlD3pgCfKKAClkrtpU2hOlFI= +github.com/0xsequence/ethkit v1.22.4/go.mod h1:wBcLTM7WpGCJnQyYUvUIRLbjurDrkSMHCKuOu/rylro= +github.com/0xsequence/go-sequence v0.23.3 h1:y5ieRB3tRRQChfMhjg89lCvM3NN3J9n+qrZYO2wL8II= +github.com/0xsequence/go-sequence v0.23.3/go.mod h1:v8bPQP0Vez83hKeVG7VAY1MwhfxQa6oJ8TToCvqwR1k= +github.com/coreos/go-systemd/v22 v22.5.0/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc= +github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= +github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= +github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA= +github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg= +github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= +github.com/mattn/go-isatty v0.0.19/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= +github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY= +github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= +github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= +github.com/rs/xid v1.5.0/go.mod h1:trrq9SKmegXys3aeAKXMUTdJsYXVwGY3RLcfgqegfbg= +github.com/rs/zerolog v1.31.0 h1:FcTR3NnLWW+NnTwwhFWiJSZr4ECLpqCm6QsEnyvbV4A= +github.com/rs/zerolog v1.31.0/go.mod h1:/7mN4D5sKwJLZQ2b/znpjC3/GQWY/xaDXUM0kKWRHss= +github.com/stretchr/testify v1.8.1 h1:w7B6lhMri9wdJUVmEZPGGhZzrYTPvgJArz7wNPgYKsk= +golang.org/x/crypto v0.15.0 h1:frVn1TEaCEaZcn3Tmd7Y2b5KKPaZ+I32Q2OA3kYp5TA= +golang.org/x/crypto v0.15.0/go.mod h1:4ChreQoLWfG3xLDer1WdlH5NdlQ3+mwnQq1YTKY+72g= +golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.14.0 h1:Vz7Qs629MkJkGyHxUlRHizWJRG2j8fbQKjELVSNhy7Q= +golang.org/x/sys v0.14.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= diff --git a/_examples/basic/main.go b/_examples/main.go similarity index 100% rename from _examples/basic/main.go rename to _examples/main.go diff --git a/go.mod b/go.mod index a304f5a..dc085dc 100644 --- a/go.mod +++ b/go.mod @@ -3,14 +3,14 @@ module github.com/0xsequence/go-tokendirectory go 1.18 require ( - github.com/0xsequence/go-sequence v0.22.0 - github.com/rs/zerolog v1.30.0 + github.com/0xsequence/go-sequence v0.23.3 + github.com/rs/zerolog v1.31.0 ) require ( - github.com/0xsequence/ethkit v1.20.25 // indirect + github.com/0xsequence/ethkit v1.22.4 // indirect github.com/mattn/go-colorable v0.1.13 // indirect - github.com/mattn/go-isatty v0.0.19 // indirect - golang.org/x/crypto v0.12.0 // indirect - golang.org/x/sys v0.11.0 // indirect + github.com/mattn/go-isatty v0.0.20 // indirect + golang.org/x/crypto v0.15.0 // indirect + golang.org/x/sys v0.14.0 // indirect ) diff --git a/go.sum b/go.sum index 4ce5f3c..9b50cff 100644 --- a/go.sum +++ b/go.sum @@ -1,29 +1,27 @@ -github.com/0xsequence/ethkit v1.20.25 h1:ytilh945CKY9Z5phQpJE3vSZWuJLz8ZBrfvD9s4bWrM= -github.com/0xsequence/ethkit v1.20.25/go.mod h1:VYl7KyEwQC8h/pl/7yImJdLnMdGNYC5MPSxrK7JIBGE= -github.com/0xsequence/go-sequence v0.22.0 h1:dwQobQJdMdwQLYMAPgtFgZrJpsZf7R0ryUW0mLZGiwE= -github.com/0xsequence/go-sequence v0.22.0/go.mod h1:RXLXAPwyJDytvYJEGEEW0+gZYpND/+nycwvTDe0cDwI= +github.com/0xsequence/ethkit v1.22.4 h1:hd6DYnQ/8l1mC7ZcUOyYlD3pgCfKKAClkrtpU2hOlFI= +github.com/0xsequence/ethkit v1.22.4/go.mod h1:wBcLTM7WpGCJnQyYUvUIRLbjurDrkSMHCKuOu/rylro= +github.com/0xsequence/go-sequence v0.23.3 h1:y5ieRB3tRRQChfMhjg89lCvM3NN3J9n+qrZYO2wL8II= +github.com/0xsequence/go-sequence v0.23.3/go.mod h1:v8bPQP0Vez83hKeVG7VAY1MwhfxQa6oJ8TToCvqwR1k= github.com/coreos/go-systemd/v22 v22.5.0/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= -github.com/mattn/go-colorable v0.1.12/go.mod h1:u5H1YNBxpqRaxsYJYSkiCWKzEfiAb1Gb520KVy5xxl4= github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA= github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg= -github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94= github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= -github.com/mattn/go-isatty v0.0.19 h1:JITubQf0MOLdlGRuRq+jtsDlekdYPia9ZFsB8h/APPA= github.com/mattn/go-isatty v0.0.19/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= +github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY= +github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/rs/xid v1.5.0/go.mod h1:trrq9SKmegXys3aeAKXMUTdJsYXVwGY3RLcfgqegfbg= -github.com/rs/zerolog v1.30.0 h1:SymVODrcRsaRaSInD9yQtKbtWqwsfoPcRff/oRXLj4c= -github.com/rs/zerolog v1.30.0/go.mod h1:/tk+P47gFdPXq4QYjvCmT5/Gsug2nagsFWBWhAiSi1w= +github.com/rs/zerolog v1.31.0 h1:FcTR3NnLWW+NnTwwhFWiJSZr4ECLpqCm6QsEnyvbV4A= +github.com/rs/zerolog v1.31.0/go.mod h1:/7mN4D5sKwJLZQ2b/znpjC3/GQWY/xaDXUM0kKWRHss= github.com/stretchr/testify v1.8.1 h1:w7B6lhMri9wdJUVmEZPGGhZzrYTPvgJArz7wNPgYKsk= -golang.org/x/crypto v0.12.0 h1:tFM/ta59kqch6LlvYnPa0yx5a83cL2nHflFhYKvv9Yk= -golang.org/x/crypto v0.12.0/go.mod h1:NF0Gs7EO5K4qLn+Ylc+fih8BSTeIjAP05siRnAh98yw= -golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/crypto v0.15.0 h1:frVn1TEaCEaZcn3Tmd7Y2b5KKPaZ+I32Q2OA3kYp5TA= +golang.org/x/crypto v0.15.0/go.mod h1:4ChreQoLWfG3xLDer1WdlH5NdlQ3+mwnQq1YTKY+72g= golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.11.0 h1:eG7RXZHdqOJ1i+0lgLgCpSXAp6M3LYlAo6osgSi0xOM= -golang.org/x/sys v0.11.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.14.0 h1:Vz7Qs629MkJkGyHxUlRHizWJRG2j8fbQKjELVSNhy7Q= +golang.org/x/sys v0.14.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= diff --git a/source_filter.go b/source_filter.go new file mode 100644 index 0000000..4c8196c --- /dev/null +++ b/source_filter.go @@ -0,0 +1,46 @@ +package tokendirectory + +import ( + "path" + "strings" +) + +type SourceFilter []string + +// Filter will filter the sources by the given filter list. A filter +// is a list of a full url, or the url base path. For example: +// for url https://example.com/tokens.json the base path is tokens.json +func (s SourceFilter) Filter(input Sources) Sources { + if len(s) == 0 { + return input + } + output := make(Sources, len(input)) + for chainID, sourceList := range input { + list := make([]string, 0, len(sourceList)) + for _, src := range sourceList { + if !s.accept(src) { + continue + } + list = append(list, src) + } + if len(list) == 0 { + continue + } + output[chainID] = list + } + return output +} + +func (s SourceFilter) accept(src string) bool { + name := path.Base(src) + for _, f := range s { + if src == f { + return true + } + if !strings.HasPrefix(name, f) { + continue + } + return true + } + return false +} diff --git a/sources.go b/sources.go index c90a93c..1cdea20 100644 --- a/sources.go +++ b/sources.go @@ -1,137 +1,247 @@ package tokendirectory -// Sources from github.com/0xsequence/token-directory and other token-list sources. +import "strings" +// Sources from github.com/0xsequence/token-directory and other token-list sources. type Sources map[uint64][]string +const builderSourceHost = "https://api.sequence.build" + // DefaultSources tokenDirectorySources, order of precedence is from top to bottom, meaning -// token info in lists higher up take precedence. +// token info in lists higher up take precedence. Listed in alphabetical order by chain name. var DefaultSources Sources = map[uint64][]string{ - // mainnet - 1: { - "https://raw.githubusercontent.com/0xsequence/token-directory/master/index/mainnet/erc20.json", - "https://raw.githubusercontent.com/0xsequence/token-directory/master/index/mainnet/erc721.json", - "https://raw.githubusercontent.com/0xsequence/token-directory/master/index/mainnet/erc1155.json", - "https://raw.githubusercontent.com/0xsequence/token-directory/master/index/mainnet/misc.json", - "https://unpkg.com/@uniswap/default-token-list@4.1.0/build/uniswap-default.tokenlist.json", - "https://unpkg.com/@sushiswap/default-token-list@34.0.0/build/sushiswap-default.tokenlist.json", - "https://tokens.coingecko.com/uniswap/all.json", - }, - // polygon - 137: { - "https://raw.githubusercontent.com/0xsequence/token-directory/master/index/polygon/erc20.json", - "https://raw.githubusercontent.com/0xsequence/token-directory/master/index/polygon/erc721.json", - "https://raw.githubusercontent.com/0xsequence/token-directory/master/index/polygon/erc1155.json", - "https://raw.githubusercontent.com/0xsequence/token-directory/master/index/polygon/misc.json", - "https://unpkg.com/@sushiswap/default-token-list@34.0.0/build/sushiswap-default.tokenlist.json", - }, - // polygon zkevm - 1101: { - "https://raw.githubusercontent.com/0xsequence/token-directory/master/index/polygon-zkevm/erc20.json", - "https://raw.githubusercontent.com/0xsequence/token-directory/master/index/polygon-zkevm/erc721.json", - "https://raw.githubusercontent.com/0xsequence/token-directory/master/index/polygon-zkevm/erc1155.json", - "https://raw.githubusercontent.com/0xsequence/token-directory/master/index/polygon-zkevm/misc.json", - }, - // goerli - 5: { - "https://raw.githubusercontent.com/0xsequence/token-directory/master/index/goerli/erc20.json", - "https://raw.githubusercontent.com/0xsequence/token-directory/master/index/goerli/erc721.json", - "https://raw.githubusercontent.com/0xsequence/token-directory/master/index/goerli/erc1155.json", - "https://raw.githubusercontent.com/0xsequence/token-directory/master/index/goerli/misc.json", - }, - // mumbai - 80001: { - "https://raw.githubusercontent.com/0xsequence/token-directory/master/index/mumbai/erc20.json", - "https://raw.githubusercontent.com/0xsequence/token-directory/master/index/mumbai/erc721.json", - "https://raw.githubusercontent.com/0xsequence/token-directory/master/index/mumbai/erc1155.json", - "https://raw.githubusercontent.com/0xsequence/token-directory/master/index/mumbai/misc.json", - }, - // BSC - 56: { - "https://raw.githubusercontent.com/0xsequence/token-directory/master/index/bnb/erc20.json", - "https://raw.githubusercontent.com/0xsequence/token-directory/master/index/bnb/erc721.json", - "https://raw.githubusercontent.com/0xsequence/token-directory/master/index/bnb/erc1155.json", - "https://raw.githubusercontent.com/0xsequence/token-directory/master/index/bnb/misc.json", - "https://raw.githubusercontent.com/pancakeswap/pancake-toolkit/master/packages/token-lists/lists/pancakeswap-default.json", - }, - // BSC-testnet - 97: { - "https://raw.githubusercontent.com/0xsequence/token-directory/master/index/bnb-testnet/erc20.json", - "https://raw.githubusercontent.com/0xsequence/token-directory/master/index/bnb-testnet/erc721.json", - "https://raw.githubusercontent.com/0xsequence/token-directory/master/index/bnb-testnet/erc1155.json", - "https://raw.githubusercontent.com/0xsequence/token-directory/master/index/bnb-testnet/misc.json", - }, // arbitrum 42161: { + "https://api.sequence.build/token-directory/arbitrum", "https://raw.githubusercontent.com/0xsequence/token-directory/master/index/arbitrum/erc20.json", "https://raw.githubusercontent.com/0xsequence/token-directory/master/index/arbitrum/erc721.json", "https://raw.githubusercontent.com/0xsequence/token-directory/master/index/arbitrum/erc1155.json", "https://raw.githubusercontent.com/0xsequence/token-directory/master/index/arbitrum/misc.json", }, + + // arbitrum-goerli + 421613: { + "https://api.sequence.build/token-directory/arbitrum-goerli", + }, + // arbitrum-nova 42170: { + "https://api.sequence.build/token-directory/arbitrum-nova", "https://raw.githubusercontent.com/0xsequence/token-directory/master/index/arbitrum-nova/erc20.json", "https://raw.githubusercontent.com/0xsequence/token-directory/master/index/arbitrum-nova/erc721.json", "https://raw.githubusercontent.com/0xsequence/token-directory/master/index/arbitrum-nova/erc1155.json", "https://raw.githubusercontent.com/0xsequence/token-directory/master/index/arbitrum-nova/misc.json", "https://raw.githubusercontent.com/sushiswap/list/master/lists/token-lists/default-token-list/tokens/arbitrum-nova.json", }, + + // arbitrum-sepolia + 421614: { + "https://api.sequence.build/token-directory/arbitrum-sepolia", + "https://raw.githubusercontent.com/0xsequence/token-directory/master/index/arbitrum-sepolia/erc20.json", + "https://raw.githubusercontent.com/0xsequence/token-directory/master/index/arbitrum-sepolia/erc721.json", + "https://raw.githubusercontent.com/0xsequence/token-directory/master/index/arbitrum-sepolia/erc1155.json", + "https://raw.githubusercontent.com/0xsequence/token-directory/master/index/arbitrum-sepolia/misc.json", + }, + // avalanche 43114: { + "https://api.sequence.build/token-directory/avalanche", "https://raw.githubusercontent.com/0xsequence/token-directory/master/index/avalanche/erc20.json", "https://raw.githubusercontent.com/0xsequence/token-directory/master/index/avalanche/erc721.json", "https://raw.githubusercontent.com/0xsequence/token-directory/master/index/avalanche/erc1155.json", "https://raw.githubusercontent.com/0xsequence/token-directory/master/index/avalanche/misc.json", "https://raw.githubusercontent.com/sushiswap/list/master/lists/token-lists/default-token-list/tokens/avalanche.json", }, - // optimism - 10: { - "https://raw.githubusercontent.com/0xsequence/token-directory/master/index/optimism/erc20.json", - "https://raw.githubusercontent.com/0xsequence/token-directory/master/index/optimism/erc721.json", - "https://raw.githubusercontent.com/0xsequence/token-directory/master/index/optimism/erc1155.json", - "https://raw.githubusercontent.com/0xsequence/token-directory/master/index/optimism/misc.json", - }, - // gnosis - 100: { - "https://raw.githubusercontent.com/0xsequence/token-directory/master/index/gnosis/erc20.json", - "https://raw.githubusercontent.com/0xsequence/token-directory/master/index/gnosis/erc721.json", - "https://raw.githubusercontent.com/0xsequence/token-directory/master/index/gnosis/erc1155.json", - "https://raw.githubusercontent.com/0xsequence/token-directory/master/index/gnosis/misc.json", - "https://raw.githubusercontent.com/sushiswap/list/master/lists/token-lists/default-token-list/tokens/xdai.json", + + // avalanche-testnet + 43113: { + "https://api.sequence.build/token-directory/43113", + "https://raw.githubusercontent.com/0xsequence/token-directory/master/index/avalanche-testnet/erc20.json", + "https://raw.githubusercontent.com/0xsequence/token-directory/master/index/avalanche-testnet/erc721.json", + "https://raw.githubusercontent.com/0xsequence/token-directory/master/index/avalanche-testnet/erc1155.json", + "https://raw.githubusercontent.com/0xsequence/token-directory/master/index/avalanche-testnet/misc.json", }, + // base 8453: { + "https://api.sequence.build/token-directory/base", "https://raw.githubusercontent.com/0xsequence/token-directory/master/index/base/erc20.json", "https://raw.githubusercontent.com/0xsequence/token-directory/master/index/base/erc721.json", "https://raw.githubusercontent.com/0xsequence/token-directory/master/index/base/erc1155.json", "https://raw.githubusercontent.com/0xsequence/token-directory/master/index/base/misc.json", }, + // base-goerli 84531: { + "https://api.sequence.build/token-directory/84531", "https://raw.githubusercontent.com/0xsequence/token-directory/master/index/base-goerli/erc20.json", "https://raw.githubusercontent.com/0xsequence/token-directory/master/index/base-goerli/erc721.json", "https://raw.githubusercontent.com/0xsequence/token-directory/master/index/base-goerli/erc1155.json", "https://raw.githubusercontent.com/0xsequence/token-directory/master/index/base-goerli/misc.json", }, - // sepolia - 11155111: { - "https://raw.githubusercontent.com/0xsequence/token-directory/master/index/sepolia/erc20.json", - "https://raw.githubusercontent.com/0xsequence/token-directory/master/index/sepolia/erc721.json", - "https://raw.githubusercontent.com/0xsequence/token-directory/master/index/sepolia/erc1155.json", - "https://raw.githubusercontent.com/0xsequence/token-directory/master/index/sepolia/misc.json", + + // base-sepolia + 84532: { + "https://api.sequence.build/token-directory/base-sepolia", + "https://raw.githubusercontent.com/0xsequence/token-directory/master/index/base-sepolia/erc20.json", + "https://raw.githubusercontent.com/0xsequence/token-directory/master/index/base-sepolia/erc721.json", + "https://raw.githubusercontent.com/0xsequence/token-directory/master/index/base-sepolia/erc1155.json", + "https://raw.githubusercontent.com/0xsequence/token-directory/master/index/base-sepolia/misc.json", }, + + // bsc + 56: { + "https://api.sequence.build/token-directory/bsc", + "https://raw.githubusercontent.com/0xsequence/token-directory/master/index/bnb/erc20.json", + "https://raw.githubusercontent.com/0xsequence/token-directory/master/index/bnb/erc721.json", + "https://raw.githubusercontent.com/0xsequence/token-directory/master/index/bnb/erc1155.json", + "https://raw.githubusercontent.com/0xsequence/token-directory/master/index/bnb/misc.json", + "https://raw.githubusercontent.com/pancakeswap/pancake-toolkit/master/packages/token-lists/lists/pancakeswap-default.json", + }, + + // bsc-testnet + 97: { + "https://api.sequence.build/token-directory/bsc-testnet", + "https://raw.githubusercontent.com/0xsequence/token-directory/master/index/bnb-testnet/erc20.json", + "https://raw.githubusercontent.com/0xsequence/token-directory/master/index/bnb-testnet/erc721.json", + "https://raw.githubusercontent.com/0xsequence/token-directory/master/index/bnb-testnet/erc1155.json", + "https://raw.githubusercontent.com/0xsequence/token-directory/master/index/bnb-testnet/misc.json", + }, + + // gnosis + 100: { + "https://api.sequence.build/token-directory/gnosis", + "https://raw.githubusercontent.com/0xsequence/token-directory/master/index/gnosis/erc20.json", + "https://raw.githubusercontent.com/0xsequence/token-directory/master/index/gnosis/erc721.json", + "https://raw.githubusercontent.com/0xsequence/token-directory/master/index/gnosis/erc1155.json", + "https://raw.githubusercontent.com/0xsequence/token-directory/master/index/gnosis/misc.json", + "https://raw.githubusercontent.com/sushiswap/list/master/lists/token-lists/default-token-list/tokens/xdai.json", + }, + + // goerli + 5: { + "https://api.sequence.build/token-directory/5", + "https://raw.githubusercontent.com/0xsequence/token-directory/master/index/goerli/erc20.json", + "https://raw.githubusercontent.com/0xsequence/token-directory/master/index/goerli/erc721.json", + "https://raw.githubusercontent.com/0xsequence/token-directory/master/index/goerli/erc1155.json", + "https://raw.githubusercontent.com/0xsequence/token-directory/master/index/goerli/misc.json", + }, + // homeverse 19011: { + "https://api.sequence.build/token-directory/homeverse", "https://raw.githubusercontent.com/0xsequence/token-directory/master/index/homeverse/erc20.json", "https://raw.githubusercontent.com/0xsequence/token-directory/master/index/homeverse/erc721.json", "https://raw.githubusercontent.com/0xsequence/token-directory/master/index/homeverse/erc1155.json", "https://raw.githubusercontent.com/0xsequence/token-directory/master/index/homeverse/misc.json", }, + // homeverse-testnet 40875: { + "https://api.sequence.build/token-directory/homeverse-testnet", "https://raw.githubusercontent.com/0xsequence/token-directory/master/index/homeverse-testnet/erc20.json", "https://raw.githubusercontent.com/0xsequence/token-directory/master/index/homeverse-testnet/erc721.json", "https://raw.githubusercontent.com/0xsequence/token-directory/master/index/homeverse-testnet/erc1155.json", "https://raw.githubusercontent.com/0xsequence/token-directory/master/index/homeverse-testnet/misc.json", }, + + // mainnet + 1: { + "https://api.sequence.build/token-directory/mainnet", + "https://raw.githubusercontent.com/0xsequence/token-directory/master/index/mainnet/erc20.json", + "https://raw.githubusercontent.com/0xsequence/token-directory/master/index/mainnet/erc721.json", + "https://raw.githubusercontent.com/0xsequence/token-directory/master/index/mainnet/erc1155.json", + "https://raw.githubusercontent.com/0xsequence/token-directory/master/index/mainnet/misc.json", + "https://unpkg.com/@uniswap/default-token-list@4.1.0/build/uniswap-default.tokenlist.json", + "https://unpkg.com/@sushiswap/default-token-list@34.0.0/build/sushiswap-default.tokenlist.json", + "https://tokens.coingecko.com/uniswap/all.json", + }, + + // mumbai + 80001: { + "https://api.sequence.build/token-directory/mumbai", + "https://raw.githubusercontent.com/0xsequence/token-directory/master/index/mumbai/erc20.json", + "https://raw.githubusercontent.com/0xsequence/token-directory/master/index/mumbai/erc721.json", + "https://raw.githubusercontent.com/0xsequence/token-directory/master/index/mumbai/erc1155.json", + "https://raw.githubusercontent.com/0xsequence/token-directory/master/index/mumbai/misc.json", + }, + + // optimism + 10: { + "https://api.sequence.build/token-directory/optimism", + "https://raw.githubusercontent.com/0xsequence/token-directory/master/index/optimism/erc20.json", + "https://raw.githubusercontent.com/0xsequence/token-directory/master/index/optimism/erc721.json", + "https://raw.githubusercontent.com/0xsequence/token-directory/master/index/optimism/erc1155.json", + "https://raw.githubusercontent.com/0xsequence/token-directory/master/index/optimism/misc.json", + }, + + // optimism-sepolia + 11155420: { + "https://api.sequence.build/token-directory/optimism-sepolia", + "https://raw.githubusercontent.com/0xsequence/token-directory/master/index/optimism-sepolia/erc20.json", + "https://raw.githubusercontent.com/0xsequence/token-directory/master/index/optimism-sepolia/erc721.json", + "https://raw.githubusercontent.com/0xsequence/token-directory/master/index/optimism-sepolia/erc1155.json", + "https://raw.githubusercontent.com/0xsequence/token-directory/master/index/optimism-sepolia/misc.json", + }, + + // polygon + 137: { + "https://api.sequence.build/token-directory/polygon", + "https://raw.githubusercontent.com/0xsequence/token-directory/master/index/polygon/erc20.json", + "https://raw.githubusercontent.com/0xsequence/token-directory/master/index/polygon/erc721.json", + "https://raw.githubusercontent.com/0xsequence/token-directory/master/index/polygon/erc1155.json", + "https://raw.githubusercontent.com/0xsequence/token-directory/master/index/polygon/misc.json", + "https://unpkg.com/@sushiswap/default-token-list@34.0.0/build/sushiswap-default.tokenlist.json", + }, + + // polygon-zkevm + 1101: { + "https://api.sequence.build/token-directory/polygon-zkevm", + "https://raw.githubusercontent.com/0xsequence/token-directory/master/index/polygon-zkevm/erc20.json", + "https://raw.githubusercontent.com/0xsequence/token-directory/master/index/polygon-zkevm/erc721.json", + "https://raw.githubusercontent.com/0xsequence/token-directory/master/index/polygon-zkevm/erc1155.json", + "https://raw.githubusercontent.com/0xsequence/token-directory/master/index/polygon-zkevm/misc.json", + }, + + // sepolia + 11155111: { + "https://api.sequence.build/token-directory/sepolia", + "https://raw.githubusercontent.com/0xsequence/token-directory/master/index/sepolia/erc20.json", + "https://raw.githubusercontent.com/0xsequence/token-directory/master/index/sepolia/erc721.json", + "https://raw.githubusercontent.com/0xsequence/token-directory/master/index/sepolia/erc1155.json", + "https://raw.githubusercontent.com/0xsequence/token-directory/master/index/sepolia/misc.json", + }, +} + +func (s Sources) SkipSourcePrefix(baseURL string) Sources { + out := make(Sources, len(s)) + for chainID, sourceList := range s { + list := make([]string, 0, len(sourceList)) + for _, src := range sourceList { + if strings.HasPrefix(src, baseURL) { + continue + } + list = append(list, src) + } + if len(list) == 0 { + continue + } + out[chainID] = list + } + return out +} + +func (s Sources) ByChainIDs(chainIDs []uint64) Sources { + out := make(Sources, len(chainIDs)) + for _, chainID := range chainIDs { + if sources, ok := s[chainID]; ok { + out[chainID] = sources + } + } + return out +} + +func (s Sources) AddSources(extra Sources) Sources { + // TODO + return s } diff --git a/tokendirectory.go b/tokendirectory.go index ad37085..3786527 100644 --- a/tokendirectory.go +++ b/tokendirectory.go @@ -16,7 +16,21 @@ import ( "github.com/rs/zerolog/log" ) -func NewTokenDirectory(sources Sources, updateInterval time.Duration, onUpdate ...onUpdateFunc) (*TokenDirectory, error) { +type Options struct { + // OnUpdate hook whenever token-directory updates the list + OnUpdate OnUpdateFunc + + // SkipBuilderSources using the default `builderSourceHost` host + SkipBuilderSources bool + + // ExtraSources which will be added to top of the list of sources + ExtraSources Sources + + // ChainIDs to include directory for only specific networks + ChainIDs []uint64 +} + +func NewTokenDirectory(sources Sources, updateInterval time.Duration, options ...Options) (*TokenDirectory, error) { if updateInterval == 0 { // default update every 15 minutes updateInterval = time.Minute * 15 @@ -25,11 +39,27 @@ func NewTokenDirectory(sources Sources, updateInterval time.Duration, onUpdate . return nil, fmt.Errorf("updateInterval must be greater then 1 minute") } - var updateFunc onUpdateFunc - if len(onUpdate) > 0 { - updateFunc = onUpdate[0] + var opts Options + if len(options) > 0 { + opts = options[0] + } + + // optionally skip builder sources + if opts.SkipBuilderSources { + sources = sources.SkipSourcePrefix(builderSourceHost) } + // optionally add extra sources + if len(opts.ExtraSources) > 0 { + sources = sources.AddSources(opts.ExtraSources) + } + + // optionally only include specific networks + if len(opts.ChainIDs) > 0 { + sources = sources.ByChainIDs(opts.ChainIDs) + } + + // build internal structures lists := make(map[uint64]map[string]*TokenList) contracts := make(map[uint64]map[prototyp.Hash]ContractInfo) @@ -44,7 +74,7 @@ func NewTokenDirectory(sources Sources, updateInterval time.Duration, onUpdate . contracts: contracts, httpClient: http.DefaultClient, updateInterval: updateInterval, - onUpdate: updateFunc, + onUpdate: opts.OnUpdate, } return f, nil @@ -58,7 +88,7 @@ type TokenDirectory struct { contractsMu sync.RWMutex updateInterval time.Duration - onUpdate onUpdateFunc + onUpdate OnUpdateFunc updateMu sync.Mutex httpClient *http.Client @@ -68,13 +98,17 @@ type TokenDirectory struct { running int32 } -type onUpdateFunc func(ctx context.Context, chainID uint64, contractInfoList []ContractInfo) +type OnUpdateFunc func(ctx context.Context, chainID uint64, contractInfoList []ContractInfo) // SetHttpClient sets the http client used to fetch token-lists from remote sources. func (f *TokenDirectory) SetHttpClient(client *http.Client) { f.httpClient = client } +func (f *TokenDirectory) SetOnUpdateFunc(onUpdate OnUpdateFunc) { + f.onUpdate = onUpdate +} + // Run starts the token directory fetcher. This method will block and poll in the current // go-routine. You'll be responsible for calling the Run method in your own gorutine. func (f *TokenDirectory) Run(ctx context.Context) error { @@ -127,6 +161,8 @@ func (f *TokenDirectory) updateChainSource(ctx context.Context, chainID uint64) f.updateMu.Lock() defer f.updateMu.Unlock() + // TODO: in future we can check builder-api dynamicly for the chainId + updatedContractInfo := []ContractInfo{} seen := map[string]bool{} diff --git a/types.go b/types.go index 4359e5a..d6a4ce5 100644 --- a/types.go +++ b/types.go @@ -31,7 +31,7 @@ type ContractInfo struct { OriginAddress string `json:"originAddress,omitempty"` Blacklist bool `json:"blacklist,omitempty"` ContractABIExtensions []string `json:"contractABIExtensions,omitempty"` - Featured bool `json:"featured,omitempty"` + Featured int32 `json:"featured,omitempty"` Mute bool `json:"mute,omitempty"` Verified bool `json:"verified"` VerifiedBy string `json:"verifiedBy,omitempty"`