diff --git a/.codecov.yml b/.codecov.yml new file mode 100644 index 000000000..4d43e123f --- /dev/null +++ b/.codecov.yml @@ -0,0 +1,22 @@ +coverage: + range: 70..100 + round: down + precision: 0 + + status: + project: + default: + # basic + target: 30% + + patch: no + + ignore: + - "mock" + - "config" + - "tests" + - "services" + - "scripts" + - "docs" + - "db/models" + - "Makefile" diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 000000000..73cfcd162 --- /dev/null +++ b/.gitattributes @@ -0,0 +1,2 @@ +mock/ext-api-dyson/* linguist-vendored +*.json linguist-vendored diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS new file mode 100644 index 000000000..5fd563ee3 --- /dev/null +++ b/.github/CODEOWNERS @@ -0,0 +1 @@ +* @hewigovens \ No newline at end of file diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md index 893ece13a..599037255 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.md +++ b/.github/ISSUE_TEMPLATE/bug_report.md @@ -1,22 +1,19 @@ --- name: Bug report -about: Create a report to help us improve +about: Report a bug title: '' -labels: 'Type: Bug' +labels: 'Bug' assignees: '' --- - - ## Summary of Bug +## Expected Behavior + + ## Steps to Reproduce @@ -24,9 +21,13 @@ v Please also ensure that this is not a duplicate issue :) ____ -#### For Admin Use +## More Info (for devs / optional) +##### Request details: +``` +{} +``` -- [ ] Not duplicate issue -- [ ] Appropriate labels applied -- [ ] Appropriate contributors tagged -- [ ] Contributor assigned/self-assigned +##### Response details: +``` +{} +``` diff --git a/.github/ISSUE_TEMPLATE/feature_request.md b/.github/ISSUE_TEMPLATE/feature_request.md index 926d5e5b9..a06a5e183 100644 --- a/.github/ISSUE_TEMPLATE/feature_request.md +++ b/.github/ISSUE_TEMPLATE/feature_request.md @@ -1,36 +1,41 @@ --- name: Feature request -about: Suggest an idea for this project +about: Suggest new feature title: '' -labels: 'Type: New Feature' +labels: 'New Feature' assignees: '' --- - - ## Summary -## Problem Definition +## Problem Definition / Why? +## Where/how shows? + + + ## Proposal ____ -#### For Admin Use +## More Info (for devs / optional) +##### Request details: +`v1/market/example` +``` +{} +``` + +##### Response details: +``` +{} +``` -- [ ] Not duplicate issue -- [ ] Appropriate labels applied -- [ ] Appropriate contributors tagged -- [ ] Contributor assigned/self-assigned diff --git a/.github/ISSUE_TEMPLATE/question.md b/.github/ISSUE_TEMPLATE/question.md deleted file mode 100644 index 9f8258add..000000000 --- a/.github/ISSUE_TEMPLATE/question.md +++ /dev/null @@ -1,17 +0,0 @@ ---- -name: Question -about: Ask anything related to this repo -title: '' -labels: 'Type: Question' -assignees: '' - ---- - - - -## How can we help ? - - diff --git a/.github/PULL_REQUEST_TEMPLATE/new_blockchain.md b/.github/PULL_REQUEST_TEMPLATE/new_blockchain.md deleted file mode 100644 index cd52368d0..000000000 --- a/.github/PULL_REQUEST_TEMPLATE/new_blockchain.md +++ /dev/null @@ -1,25 +0,0 @@ -# Adding a new blockchain - -Please follow this checklist: - - - `platform/mycoin` - - [ ] `model.go`: Platform-specific models - - [ ] `client.go`: Platform getter methods (API, RPC) - - [ ] `api.go`: - - Gin route: _GET /mycoin/txs_ - - Getting blockchain info - - Normalizing platform-specific - models to BlockAtlas model - - [ ] `api_test.go` - - Unit tests - - Check if normalization from - response body matches expected model - - [ ] `test/main.go`: - Add example address for integration test - - [ ] `loaders.go`: Add route - - [ ] `config.yml`: Add default config - (comment out if no public endpoint) - - [ ] `config.go`: Add default config - -If you have any questions, contact us at -https://t.me/walletcore or @terorie / @vikmeup on Telegram. diff --git a/.github/config.yml b/.github/config.yml new file mode 100644 index 000000000..13299ed72 --- /dev/null +++ b/.github/config.yml @@ -0,0 +1,3 @@ +todo: + label: "Bot: Todo" + \ No newline at end of file diff --git a/.github/stale.yml b/.github/stale.yml index 3ce7f764e..406105238 100644 --- a/.github/stale.yml +++ b/.github/stale.yml @@ -1,5 +1,5 @@ # Number of days of inactivity before an issue becomes stale -daysUntilStale: 90 +daysUntilStale: 5 # Number of days of inactivity before a stale issue is closed daysUntilClose: 7 # Issues with these labels will never be considered stale @@ -14,4 +14,4 @@ markComment: > recent activity. It will be closed if no further activity occurs. Thank you for your contributions. # Comment to post when closing a stale issue. Set to `false` to disable -closeComment: false \ No newline at end of file +closeComment: false diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 000000000..c13894169 --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,54 @@ +name: Tests + +on: + push: + branches: [ master ] + pull_request: + branches: [ master ] + +jobs: + test: + name: Unit + runs-on: ubuntu-latest + steps: + - name: Set up Go 1.x + uses: actions/setup-go@v2 + with: + go-version: ^1.15.6 + id: go + + - name: Check out code + uses: actions/checkout@v2 + + - name: Get dependencies + run: | + go get -v -t -d ./... + + - name: Unit Test + run: make test + + - name: Lint + run: make lint + + - name: Upload coverage + run: bash <(curl -s https://codecov.io/bash) -f coverage.txt + + integration: + name: Integration + runs-on: ubuntu-latest + steps: + - name: Set up Go 1.x + uses: actions/setup-go@v2 + with: + go-version: ^1.13 + id: go + + - name: Check out code + uses: actions/checkout@v2 + + - name: Get dependencies + run: | + go get -v -t -d ./... + + - name: Integration Test + run: make integration diff --git a/.gitignore b/.gitignore index 62cbbd67c..0780fb7c5 100644 --- a/.gitignore +++ b/.gitignore @@ -2,12 +2,94 @@ /blockatlas /blockatlas.exe /bin/* +*-bin + +### APP ### +*.csv +*.log +Build +dist/* +bin/* +test/* # Dev environment -.DS_Store .idea/ .vscode/ cmd/__debug_bin config_*.yml *.orig *~ +coverage.txt + +### macOS ### +*.DS_Store +.AppleDouble +.LSOverride + +# Icon must end with two \r +Icon + +# Thumbnails +._* + +# Files that might appear in the root of a volume +.DocumentRevisions-V100 +.fseventsd +.Spotlight-V100 +.TemporaryItems +.Trashes +.VolumeIcon.icns +.com.apple.timemachine.donotpresent + +# Directories potentially created on remote AFP share +.AppleDB +.AppleDesktop +Network Trash Folder +Temporary Items +.apdisk + +### Go ### +# Binaries for programs and plugins +*.exe +*.exe~ +*.dll +*.so +*.dylib + +# Test binary, build with `go test -c` +*.test + +# Output of the go coverage tool, specifically when used with LiteIDE +*.out + +# Compiled Object files, Static and Dynamic libs (Shared Objects) +*.o +*.a +*.so + +# Folders +_obj +_test + +# Architecture specific extensions/prefixes +*.[568vq] +[568vq].out + +*.cgo1.go +*.cgo2.c +_cgo_defun.c +_cgo_gotypes.go +_cgo_export.* + +_testmain.go +__debug_bin + +*.exe +*.test +*.prof + +# govendor cache +.cache + +# npm-installed stuff +node_modules diff --git a/CODE_OF_CONDUCT.md b/CODE_OF_CONDUCT.md deleted file mode 100644 index 5624ce360..000000000 --- a/CODE_OF_CONDUCT.md +++ /dev/null @@ -1,2 +0,0 @@ -* There are no stupid questions -* Be respectful :) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index af68667c6..1b839ea8e 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -52,23 +52,20 @@ E is a convenience function for creating errors quickly: `func E(args ...interface{}) *Error` Usage: - - Wrap a generic error: `errors.E(err)` - - Wrap error with message: `errors.E(err, "new message to append")` - - Annotate error with type: `errors.E(err, errors.TypePlatformRequest)` + - Wrap a generic error: `errors.New(err)` + - Wrap error with message: `errors.New(err, "new message to append")` + - Annotate error with type: `errors.New(err, errors.TypePlatformRequest)` - Error with type and metadata: ``` -errors.E(err, errors.TypePlatformRequest, errors.Params{ +errors.New(err, errors.TypePlatformRequest, errors.Params{ "coin": "Ethereum", "method": "CurrentBlockNumber", }) ``` - Any other combinations above -You can send the errors to sentry using `.PushToSentry()` -`errors.E(err, errors.TypePlatformRequest).PushToSentry()` - -*All fatal errors emitted by logger package already send the error to Sentry* +*All fatal errors emitted by logger package already send the error to * __[List of error types](https://godoc.org/github.com/trustwallet/blockatlas/pkg/errors#Type)__ @@ -78,29 +75,29 @@ Use the package `pkg/logger` for logging. The order of function parameters is arbitrary when using the logger functions. Examples: - - Log message: `logger.Info("Loading Observer API")` - - Log message with params: `logger.Info("Running application", logger.Params{"bind": bind})` - - Fatal with error: `logger.Fatal("Application failed", err)` - - Create a simple error log: `logger.Error(err)` - - Create an error log with a message: `logger.Error("Failed to initialize API", err)` + - Log message: `log.Info("Loading Observer API")` + - Log message with params: `log.Info("Running application", log.Params{"bind": bind})` + - Fatal with error: `log.Fatal("Application failed", err)` + - Create a simple error log: `log.Error(err)` + - Create an error log with a message: `log.Error("Failed to initialize API", err)` - Create an error log, with error, message, and params: ``` -p := logger.Params{ +p := log.Params{ "platform": handle, "coin": platform.Coin(), } err := platform.Init() if err != nil { - logger.Error("Failed to initialize API", err, p) + log.Error("Failed to initialize API", err, p) } ``` - Debug log: - `logger.Debug("Loading Observer API")` + `log.Debug("Loading Observer API")` or - `logger.Debug("Loading Observer API", logger.Params{"bind": bind})` + `log.Debug("Loading Observer API", log.Params{"bind": bind})` - Warning log: - `logger.Warn("Warning", err)` + `log.Warn("Warning", err)` or - `logger.Warn(err, "Warning")` + `log.Warn(err, "Warning")` or - `logger.Warn("Warning", err, logger.Params{"bind": bind})` + `log.Warn("Warning", err, log.Params{"bind": bind})` diff --git a/Dockerfile b/Dockerfile index 173f8b68a..b8267f344 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,13 +1,19 @@ -FROM golang:alpine as builder -ADD . /go/src/github.com/trustwallet/blockatlas -RUN apk add git \ - && go get -d -v github.com/trustwallet/blockatlas \ - && CGO_ENABLED=0 go install -a \ - -ldflags='-s -w -extldflags "-static"' \ - github.com/trustwallet/blockatlas - -FROM scratch +FROM golang:1.13.6-alpine as builder + +ARG SERVICE + +RUN apk add --update --no-cache git build-base musl-dev linux-headers +RUN mkdir /build +WORKDIR /build +COPY go.mod . +COPY go.sum . +RUN go mod download +COPY . . +RUN go build -o bin/blockatlas ./cmd/$SERVICE + +FROM alpine:latest +COPY --from=builder /build/bin /bin/ +COPY --from=builder /build/config.yml /config/ COPY --from=builder /etc/ssl/certs/ca-certificates.crt /etc/ssl/certs/ -COPY --from=builder /go/bin/blockatlas /bin/blockatlas -COPY --from=builder /go/src/github.com/trustwallet/blockatlas/config.yml /config.yml -CMD ["/bin/blockatlas", "api"] + +ENTRYPOINT ["/bin/blockatlas", "-c", "/config/config.yml"] diff --git a/Dockerfile.runner b/Dockerfile.runner new file mode 100644 index 000000000..1bcbbbe7e --- /dev/null +++ b/Dockerfile.runner @@ -0,0 +1,5 @@ +FROM golang:1.13.6-stretch +ARG SERVICE +COPY ./bin/$SERVICE /app/main +COPY ./config.yml /config/ +ENTRYPOINT ["/app/main", "-c", "/config/config.yml"] diff --git a/Makefile b/Makefile index 01d78d8e6..c3e58625d 100644 --- a/Makefile +++ b/Makefile @@ -1,36 +1,49 @@ +#! /usr/bin/make -f + # Project variables. -VERSION := $(shell git describe --tags) +PACKAGE := github.com/trustwallet/blockatlas +VERSION := $(shell git describe --tags 2>/dev/null || git describe --all) BUILD := $(shell git rev-parse --short HEAD) +DATETIME := $(shell date +"%Y.%m.%d-%H:%M:%S") PROJECT_NAME := $(shell basename "$(PWD)") -API_COMMAND := api -OBSERVER_COMMAND := observer -SYNC_COMMAND := sync-markets +API := api +CONSUMER := consumer +PARSER := parser COIN_FILE := coin/coins.yml COIN_GO_FILE := coin/coins.go GEN_COIN_FILE := coin/gen.go +DOCKER_LOCAL_DB_IMAGE_NAME := test_db +DOCKER_LOCAL_MQ_IMAGE_NAME := mq +DOCKER_LOCAL_DB_USER :=user +DOCKER_LOCAL_DB_PASS :=pass +DOCKER_LOCAL_DB := blockatlas # Go related variables. GOBASE := $(shell pwd) GOBIN := $(GOBASE)/bin GOPKG := $(.) +# A valid GOPATH is required to use the `go get` command. +# If $GOPATH is not specified, $HOME/go will be used by default +GOPATH := $(if $(GOPATH),$(GOPATH),~/go) # Environment variables -TEST_CONFIG=$(GOBASE)/config.yml +CONFIG_FILE=$(GOBASE)/config.yml +CONFIG_MOCK_FILE=$(GOBASE)/configmock.yml # Go files GOFMT_FILES?=$$(find . -name '*.go' | grep -v vendor) # Use linker flags to provide version/build settings -LDFLAGS=-ldflags "-X=main.Version=$(VERSION) -X=main.Build=$(BUILD)" +LDFLAGS=-ldflags "-X=$(PACKAGE)/build.Version=$(VERSION) -X=$(PACKAGE)/build.Build=$(BUILD) -X=$(PACKAGE)/build.Date=$(DATETIME)" # Redirect error output to a file, so we can show it in development mode. STDERR := /tmp/.$(PROJECT_NAME)-stderr.txt # PID file will keep the process id of the server -PID_API := /tmp/.$(PROJECT_NAME).$(API_COMMAND).pid -PID_OBSERVER := /tmp/.$(PROJECT_NAME).$(OBSERVER_COMMAND).pid -PID_SYNC := /tmp/.$(PROJECT_NAME).$(SYNC_COMMAND).pid - +PID_API := /tmp/.$(PROJECT_NAME).$(API).pid +PID_CONSUMER := /tmp/.$(PROJECT_NAME).$(CONSUMER).pid +PID_PARSER := /tmp/.$(PROJECT_NAME).$(PARSER).pid +PID_MOCKSERVER := /tmp/.$(PROJECT_NAME).mockserver.pid # Make is verbose in Linux. Make it silent. MAKEFLAGS += --silent @@ -39,41 +52,50 @@ install: go-get ## start: Start API, Observer and Sync in development mode. start: - @bash -c "$(MAKE) clean compile start-api start-observer start-sync" + @bash -c "$(MAKE) clean compile start-api start-parser start-consumer" -## stop: Stop development mode. -stop: stop-server +## start-api: Start platform api in development mode. +start-api: stop + @echo " > Starting $(PROJECT_NAME)" + @-$(GOBIN)/$(API)/api -c $(CONFIG_FILE) 2>&1 & echo $$! > $(PID_API) + @cat $(PID_API) | sed "/^/s/^/ \> Api PID: /" + @echo " > Error log: $(STDERR)" -## start-api: Start API in development mode. -start-api: stop-server +# start-platform-api-mock: Start API. Similar to start-platform-api, but uses config file with mock URLs, and port 8437. +start-api-mock: stop start-mockserver @echo " > Starting $(PROJECT_NAME) API" - @-$(GOBIN)/$(PROJECT_NAME) $(API_COMMAND) 2>&1 & echo $$! > $(PID_API) - @cat $(PID_API) | sed "/^/s/^/ \> API PID: /" + @-$(GOBIN)/$(API)/api -p 8437 -c $(CONFIG_MOCK_FILE) 2>&1 & echo $$! > $(PID_API) + @cat $(PID_API) | sed "/^/s/^/ \> Mock PID: /" @echo " > Error log: $(STDERR)" -## start-observer: Start Observer in development mode. -start-observer: stop-server - @echo " > Starting $(PROJECT_NAME) Observer" - @-$(GOBIN)/$(PROJECT_NAME) $(OBSERVER_COMMAND) 2>&1 & echo $$! > $(PID_OBSERVER) - @cat $(PID_OBSERVER) | sed "/^/s/^/ \> Observer PID: /" +## start-parser: Start observer-parser in development mode. +start-parser: stop + @echo " > Starting $(PROJECT_NAME)" + @-$(GOBIN)/$(PARSER)/parser -c $(CONFIG_FILE) 2>&1 & echo $$! > $(PID_PARSER) + @cat $(PID_PARSER) | sed "/^/s/^/ \> Parser PID: /" @echo " > Error log: $(STDERR)" -## start-sync-markets: Start Sync markets in development mode. -start-sync-markets: stop-server - @echo " > Starting $(PROJECT_NAME) Sync" - @-$(GOBIN)/$(PROJECT_NAME) $(SYNC_COMMAND) 2>&1 & echo $$! > $(PID_SYNC) - @cat $(PID_SYNC) | sed "/^/s/^/ \> Sync PID: /" +## start-consumer: Start observer-consumer in development mode. +start-consumer: stop + @echo " > Starting $(PROJECT_NAME)" + @-$(GOBIN)/$(CONSUMER)/consumer -c $(CONFIG_FILE) 2>&1 & echo $$! > $(PID_CONSUMER) + @cat $(PID_CONSUMER) | sed "/^/s/^/ \> consumer PID: /" @echo " > Error log: $(STDERR)" -stop-server: - @-touch $(PID_API) $(PID_OBSERVER) +## stop: Stop development mode. +stop: + @-touch $(PID_API) $(PID_CONSUMER) $(PID_PARSER) @-kill `cat $(PID_API)` 2> /dev/null || true - @-kill `cat $(PID_OBSERVER)` 2> /dev/null || true - @-rm $(PID_API) $(PID_OBSERVER) + @-kill `cat $(PID_CONSUMER)` 2> /dev/null || true + @-kill `cat $(PID_PARSER)` 2> /dev/null || true + @-rm $(PID_API) $(PID_CONSUMER) $(PID_PARSER) -restart-server: stop-server start-server +stop-mockserver: + @-touch $(PID_MOCKSERVER) + @kill `cat $(PID_MOCKSERVER)` 2> /dev/null || true + @rm $(PID_MOCKSERVER) -## compile: Compile the binary. +## compile: Compile the project. compile: @-touch $(STDERR) @-rm $(STDERR) @@ -95,6 +117,16 @@ test: go-test ## integration: Run all integration tests. integration: go-integration +## start-mockserver: Start Mockserver with mocks of external services. Test that it is operational (nasty case if port is taken). +start-mockserver: stop-mockserver + @echo " > Starting Mockserver" + GOBIN=$(GOBIN) go build -o $(GOBIN)/mockserver/mockserver ./mock/mockserver + @-./bin/mockserver/mockserver & echo $$! > $(PID_MOCKSERVER) + @echo " > Mockserver started with PID: " `cat $(PID_MOCKSERVER)` + @sleep 1 + # Check that mock is running, by making a test with simple call (e.g. may fail due to unavailable port) + @newman run tests/postman/blockatlas.postman_collection.json --folder mock-healthcheck --env-var "host=http://localhost:8437" + ## fmt: Run `go fmt` for all go files. fmt: go-fmt @@ -106,11 +138,97 @@ remove-coin-file: @echo " > Removing "$(PROJECT_NAME)"" @-rm $(GOBASE)/$(COIN_GO_FILE) +## goreleaser: Release the last tag version with GoReleaser. +goreleaser: go-goreleaser + +## govet: Run go vet. +govet: go-vet + +## golint: Run golint. +lint: go-lint-install go-lint + + +install-swag: +ifeq (,$(wildcard test -f $(GOPATH)/bin/swag)) + @echo " > Installing swagger" + @-bash -c "go get github.com/swaggo/swag/cmd/swag" +endif + +swag: install-swag + @bash -c "$(GOPATH)/bin/swag init --parseDependency -g ./cmd/api/main.go -o ./docs" + +## install-newman: Install Postman Newman for tests. +install-newman: +ifeq (,$(shell which newman)) + @echo " > Installing Postman Newman" + @-sudo npm install -g newman +endif + +## newman-mocked: Run mocked Postman Newman tests. +newman-mocked: install-newman go-compile + @bash -c "$(MAKE) newman-mocked-params host=http://localhost:8437" + +## newman-mocked-params: Run mocked Postman Newman tests, after starting platform api. +## The host parameter is required. +## E.g.: $ make newman-mocked-params test=transaction host=http://localhost:8437 +newman-mocked-params: start-api-mock +ifeq (,$(test)) + @bash -c "$(MAKE) newman-run test=transaction host=$(host) && \ + $(MAKE) newman-run test=staking host=$(host) && \ + $(MAKE) newman-run test=token host=$(host) && \ + $(MAKE) newman-run test=collection host=$(host)" + @bash -c "$(MAKE) stop" +else + @bash -c "$(MAKE) newman-run test=$(test) host=$(host)" + @bash -c "$(MAKE) stop" +endif + +## newman: Run Postman Newman test, the host parameter is required, and you can specify the name of the test do you wanna run (transaction, token, staking, collection, healthcheck, observer). e.g $ make newman test=staking host=http://localhost:8420 +newman: install-newman +ifeq (,$(test)) + @bash -c "$(MAKE) newman-run test=transaction host=$(host)" + @bash -c "$(MAKE) newman-run test=token host=$(host)" + @bash -c "$(MAKE) newman-run test=staking host=$(host)" + @bash -c "$(MAKE) newman-run test=collection host=$(host)" + @bash -c "$(MAKE) newman-run test=healthcheck host=$(host)" +else + @bash -c "$(MAKE) newman-run test=$(test) host=$(host)" +endif + +## newman-run: Run chosen Newman tests. See newman target. +newman-run: +ifeq (,$(host)) + @echo " > Host parameter is missing. e.g: make newman test=staking host=http://localhost:8437" + @exit 1 +endif + @echo " > Running $(test) tests" + @newman run tests/postman/blockatlas.postman_collection.json --folder $(test) -d tests/postman/$(test)_data.json --env-var "host=$(host)" + go-compile: go-get go-build -go-build: - @echo " > Building binary..." - GOBIN=$(GOBIN) go build $(LDFLAGS) -o $(GOBIN)/$(PROJECT_NAME) -v . +go-build: go-build-api go-build-consumer go-build-parser + +docker-shutdown: + @echo " > Shutdown docker containers..." + @-bash -c "docker rm -f $(DOCKER_LOCAL_DB_IMAGE_NAME) 2> /dev/null" + @-bash -c "docker rm -f $(DOCKER_LOCAL_MQ_IMAGE_NAME) 2> /dev/null" + +start-docker-services: docker-shutdown + @echo " > Starting docker containers" + docker run -d -p 5432:5432 --name $(DOCKER_LOCAL_DB_IMAGE_NAME) -e POSTGRES_USER=$(DOCKER_LOCAL_DB_USER) -e POSTGRES_PASSWORD=$(DOCKER_LOCAL_DB_PASS) -e POSTGRES_DB=$(DOCKER_LOCAL_DB) postgres + docker run -d -p 5672:5672 --name $(DOCKER_LOCAL_MQ_IMAGE_NAME) rabbitmq + +go-build-api: + @echo " > Building api binary..." + GOBIN=$(GOBIN) go build $(LDFLAGS) -o $(GOBIN)/$(API)/api ./cmd/$(API) + +go-build-consumer: + @echo " > Building consumer binary..." + GOBIN=$(GOBIN) go build $(LDFLAGS) -o $(GOBIN)/$(CONSUMER)/consumer ./cmd/$(CONSUMER) + +go-build-parser: + @echo " > Building parser binary..." + GOBIN=$(GOBIN) go build $(LDFLAGS) -o $(GOBIN)/$(PARSER)/parser ./cmd/$(PARSER) go-generate: @echo " > Generating dependency files..." @@ -118,7 +236,7 @@ go-generate: go-get: @echo " > Checking if there is any missing dependencies..." - GOBIN=$(GOBIN) go get $(get) + GOBIN=$(GOBIN) go get cmd/... $(get) go-install: GOBIN=$(GOBIN) go install $(GOPKG) @@ -128,12 +246,15 @@ go-clean: GOBIN=$(GOBIN) go clean go-test: - @echo " > Runing unit tests" - GOBIN=$(GOBIN) go test -cover -v ./... + @echo " > Running unit tests" + GOBIN=$(GOBIN) go test -cover -race -coverprofile=coverage.txt -covermode=atomic -v ./... + +go-dockertest-install: + GOBIN=$(GOBIN) go get -u github.com/ory/dockertest/v3 -go-integration: - @echo " > Runing integration tests" - GOBIN=$(GOBIN) TEST_CONFIG=$(TEST_CONFIG) go test -tags=integration -v ./pkg/integration +go-integration: go-dockertest-install + @echo " > Running integration tests" + GOBIN=$(GOBIN) TEST_CONFIG=$(CONFIG_FILE) go test -race -tags=integration -v ./tests/integration/... go-fmt: @echo " > Format all go files" @@ -143,6 +264,24 @@ go-gen-coins: @echo " > Generating coin file" COIN_FILE=$(COIN_FILE) COIN_GO_FILE=$(COIN_GO_FILE) GOBIN=$(GOBIN) go run -tags=coins $(GEN_COIN_FILE) +go-goreleaser: + @echo " > Releasing a new version" + GOBIN=$(GOBIN) scripts/goreleaser --rm-dist + +go-vet: + @echo " > Running go vet" + GOBIN=$(GOBIN) go vet ./... + +go-lint-install: +ifeq (,$(wildcard test -f bin/golangci-lint)) + @echo " > Installing golint" + curl -sSfL https://raw.githubusercontent.com/golangci/golangci-lint/master/install.sh | sh -s +endif + +go-lint: + @echo " > Running golint" + bin/golangci-lint run --timeout=2m + .PHONY: help all: help help: Makefile diff --git a/Procfile b/Procfile index 9d96f6d4c..c06f6e448 100644 --- a/Procfile +++ b/Procfile @@ -1,3 +1,7 @@ -web: bin/blockatlas api :$PORT -observer: bin/blockatlas observer -market: bin/blockatlas sync-markets +release: bin/setup -c $HOME/config.yml +web: bin/api -c $HOME/config.yml -p $PORT +consumer_transactions: CONSUMER_SERVICE=transactions bin/consumer -c $HOME/config.yml +consumer_subscriptions: CONSUMER_SERVICE=subscriptions bin/consumer -c $HOME/config.yml +consumer_subscriptions_tokens: CONSUMER_SERVICE=subscriptions_tokens bin/consumer -c $HOME/config.yml +consumer_tokens: CONSUMER_SERVICE=tokens bin/consumer -c $HOME/config.yml +parser: bin/parser -c $HOME/config.yml diff --git a/README.md b/README.md index 48edec99a..8360baa74 100644 --- a/README.md +++ b/README.md @@ -1,112 +1,164 @@ # Block Atlas by Trust Wallet +THIS REPO IS NO LONGER MAINTAINED + +--- + ![Go Version](https://img.shields.io/github/go-mod/go-version/TrustWallet/blockatlas) -[![GoDoc](https://godoc.org/github.com/TrustWallet/blockatlas?status.svg)](https://godoc.org/github.com/TrustWallet/blockatlas) -[![Build Status](https://dev.azure.com/TrustWallet/Trust%20BlockAtlas/_apis/build/status/TrustWallet.blockatlas?branchName=master)](https://dev.azure.com/TrustWallet/Trust%20BlockAtlas/_build/latest?definitionId=27&branchName=master) -[![Codacy Badge](https://api.codacy.com/project/badge/Grade/43834b0c94ad4f6088629aa3e3bb5e94)](https://www.codacy.com/app/TrustWallet/blockatlas?utm_source=github.com&utm_medium=referral&utm_content=TrustWallet/blockatlas&utm_campaign=Badge_Grade) +[![codecov](https://codecov.io/gh/trustwallet/blockatlas/branch/master/graph/badge.svg)](https://codecov.io/gh/trustwallet/blockatlas) [![Go Report Card](https://goreportcard.com/badge/trustwallet/blockatlas)](https://goreportcard.com/report/TrustWallet/blockatlas) -[![Docker](https://img.shields.io/docker/cloud/build/trustwallet/blockatlas.svg)](https://hub.docker.com/r/trustwallet/blockatlas) > BlockAtlas is a clean explorer API and transaction observer for cryptocurrencies. BlockAtlas connects to nodes or explorer APIs of the supported coins and maps transaction data, -account transaction history and market data into a generic, easy to work with JSON format. -It is in production use at the [Trust Wallet app](https://trustwallet.com/), -the official cryptocurrency wallet of Binance. Also is in production at the [BUTTON Wallet](https://buttonwallet.com), Telegram based non-custodial wallet. -The observer API watches the chain for new transactions and generates notifications by webhooks. +account transaction history into a generic, easy to work with JSON format. + +The observer API watches the chain for new transactions and generates notifications by guids. #### Supported Coins - - - - - - - - - - - - - - - - - - - - - - +Block Atlas supports more than 25 blockchains: Bitcoin, Ethereum, Binance Chain etc, The full feature matrix is [here](docs/features.csv). + +## Architecture + +Blockatlas allows to: + +- Get information about transactions, tokens, staking details, collectibles for supported coins. +- Subscribe for price notifications via Rabbit MQ + +Platform API is independent service and can work with the specific blockchain only (like Bitcoin, Ethereum, etc) + +Notifications: + +- Subscriber Producer - Create new blockatlas.SubscriptionEvent [Not implemented at Atlas, write it on your own] + +- Subscriber - Get subscriptions from queue, set them to the DB + +- Parser - Parse the block, convert block to the transactions batch, send to queue + +- Notifier - Check each transaction for having the same address as stored at DB, if so - send tx data and id to the next queue + +- Notifier Consumer - Notify the user [Not implemented at Atlas, write it on your own] + + +``` +New Subscriptions --(Rabbit MQ)--> Subscriber --> DB + | + Parser --(Rabbit MQ)--> Notifier --(Rabbit MQ)--> Notifier Consumer --> User + +``` + +The whole flow is not available at Atlas repo. We will have integration tests with it. Also there will be examples of all instances soon. ## Setup -### Requirements +### Prerequisite - * [Go Toolchain](https://golang.org/doc/install) versions 1.13+ - * [Redis](https://redis.io/topics/quickstart) instance (Transaction Observer only) +- [Go Toolchain](https://golang.org/doc/install) versions 1.14+ -### From Source + Depends on what type of Blockatlas service you would like to run will also be needed. +- [Postgres](https://www.postgresql.org/download) to store user subscriptions and latest parsed block number +- [Rabbit MQ](https://www.rabbitmq.com/#getstarted) to pass subscriptions and send transaction notifications + +### Quick Start + +#### Get source code + +Download source to `GOPATH` ```shell -# Download source to $GOPATH go get -u github.com/trustwallet/blockatlas cd $(go env GOPATH)/src/github.com/trustwallet/blockatlas +``` -# Start API server at port 8420 -go build -o blockatlas . && ./blockatlas api :8420 +#### Build and run -# Start Observer -go build -o blockatlas . && ./blockatlas observer +Read [configuration](#configuration) info -# Start sync worker for market prices and rates -go build -o blockatlas . && ./blockatlas sync-markets +```shell +# Start Platform API server at port 8420 with the path to the config.yml ./ +go build -o api-bin cmd/api/main.go && ./api-bin -p 8420 + +# Start parser with the path to the config.yml ./ +go build -o parser-bin cmd/parser/main.go && ./parser-bin + +# Start notifier with the path to the config.yml ./ +go build -o notifier-bin cmd/notifier/main.go && ./notifier-bin + +# Start subscriber with the path to the config.yml ./ +go build -o subscriber-bin cmd/subscriber/main.go && ./subscriber-bin ``` -### Docker +### make command + +Build and start all services: + +```shell +make go-build +make start +``` -From Docker Hub: +Build and start individual service: + +```shell +make go-build-api +make start +``` -`docker run -it -p 8420:8420 trustwallet/blockatlas` +### Docker -Build and run from local Dockerfile: +Build and run all services: ```shell -docker build -t blockatlas . -docker run -p 8420:8420 blockatlas +docker-compose build +docker-compose up ``` -### Heroku +Build and run individual service: -[![Deploy](https://www.herokucdn.com/deploy/button.svg)](https://www.heroku.com/deploy/?template=https://github.com/TrustWallet/blockatlas) +```shell +docker-compose build api +docker-compose start api +``` ## Configuration -Block Atlas can run just fine without configuration. -By default, all coins offering public RPC/explorer APIs are enabled. +When any of Block Atlas services started they look up inside [default configuration](./config.yml). +Most coins offering public RPC/explorer APIs are enabled, thus Block Atlas can be started and used right away, no additional configuration needed. +By default starting any of the [services](#architecture) will enable all platforms -If you want to use custom RPC endpoints, or enable coins without public RPC (like Nimiq), -you can configure Block Atlas over `config.yml` or environment variables. +To run a specific service only by passing environmental variable, e.g: `ATLAS_PLATFORM=ethereum` : -#### Config File +```shell +ATLAS_PLATFORM=ethereum go run cmd/api/main.go + +ATLAS_PLATFORM=ethereum binance bitcoin go run cmd/api/main.go # for multiple platforms +``` + +or change in config file + +```yaml +# Single +platform: [ethereum] +# Multiple +platform: [ethereum, binance, bitcoin] +``` -Config is loaded from `config.yml` if it exists in the working directory. -The repository includes a [default config](./config.yml) for reference with all available config options. +This way you can one platform per binary, for scalability and sustainability. -Example (`config.yml`): +To enable use of private endpoint: ```yaml nimiq: api: http://localhost:8648 -#... ``` +It works the same for worker - you can run all observer at 1 binary or 30 coins per 30 binaries + #### Environment The rest gets loaded from environment variables. -Every config option is available under the `ATLAS_` prefix. -Nested keys are joined via `_` (Example `nimiq.api` => `NIMIQ_API`) +Every config option is available under the `ATLAS_` prefix. Nested keys are joined via `_`. Example: @@ -114,36 +166,50 @@ Example: ATLAS_NIMIQ_API=http://localhost:8648 ``` -## Docs +## Tests -Swagger API docs provided at path `/swagger/index.html` +### Unit tests -#### Updating Docs + make test -- After creating a new route, add comments to your API source code, [See Declarative Comments Format](https://swaggo.github.io/swaggo.io/declarative_comments_format/). -- Download Swag for Go by using: +### Mocked tests - `$ go get -u github.com/swaggo/swag/cmd/swag` +End-to-end tests with calls to external APIs has great value, but they are not suitable for regular CI verification, beacuse any external reason could break the tests. -- Run the Swag in your Go project root folder. + # Start API server with mocked config, at port 8437 ./ + go build -o api-bin cmd/api/main.go && ./api-bin -p 8437 -c configmock.yml - `$ swag init` +Therefore mocked API-level tests are used, whereby external APIs are replaced by mocks. -## Metrics +- External mocks are implemented as a simple, own, golang `mockserver`. It listens locally, and returns responses to specific API paths, taken from json data files. +- There is a file where API paths and corresponding data files are listed. +- Tests invoke into blockatlas through public APIs only, and are executed using _newman_ (Postman cli -- `make newman-mocked`). +- Product code, and even test code should not be aware whether it runs with mocks or the real external endpoints. +- See Makefile for targets with 'mock'; platform can be started locally with mocks using `make start-platform-api-mock`. +- The newman tests can be executed with unmocked external APIs as well, but verifications may fail, because some APIs return variable responses. Unmocked tests are not intended for regular CI execution, but as ad-hoc development tests. +- General steps for creating new mocked tests: replace endpoint to localhost:3347, observe incoming calls (visible in mockserver's output), obtain real response from external API (with exact same parameters), place response in a file, add path + file to data file list. Restart mock, and verify that blockatlas provides correct output. Also, add verifications of results to the tests. -The Blockatlas can collect and expose by `expvar's`, metrics about the application healthy and clients and server requests. -Prometheus or another service can collect metrics provided from the `/metrics` endpoint. +## Docs + +Swagger API docs provided at path `/swagger/index.html` -To protect the route, you can set the environment variables `METRICS_API_TOKEN`, and this route starts to require the auth bearer token. +or you can install `go-swagger` and render it locally (macOS example) -## Contributing +Install: -If you'd like to add support for a new blockchain, feel free to file a pull request. -Note that most tokens that run on top of other chains are already supported and -don't require code changes (e.g. ERC-20). +```shell +brew tap go-swagger/go-swagger +brew install go-swagger +``` + +Render: + +```shell +swagger serve docs/swagger.yaml +``` + +#### Updating Docs -The best way to submit feedback and report bugs is to open a GitHub issue. -Please be sure to include your operating system, version number, and -[steps](https://gist.github.com/nrollr/eb24336b8fb8e7ba5630) to reproduce reported bugs. +- After creating a new route, add comments to your API source code, [See Declarative Comments Format](https://swaggo.github.io/swaggo.io/declarative_comments_format/). -More resources for developers are in [CONTRIBUTING.md](CONTRIBUTING.md). +- Run `$ make go-gen-docs` in root folder. diff --git a/api/api.go b/api/api.go new file mode 100644 index 000000000..978d51fc1 --- /dev/null +++ b/api/api.go @@ -0,0 +1,39 @@ +package api + +import ( + "github.com/gin-gonic/gin" + "github.com/prometheus/client_golang/prometheus/promhttp" + ginSwagger "github.com/swaggo/gin-swagger" + "github.com/swaggo/gin-swagger/swaggerFiles" + "github.com/trustwallet/blockatlas/config" + _ "github.com/trustwallet/blockatlas/docs" + "github.com/trustwallet/blockatlas/platform" + "github.com/trustwallet/blockatlas/services/tokenindexer" +) + +func SetupPlatformAPI(router gin.IRouter) { + for _, api := range platform.Platforms { + RegisterTransactionsAPI(router, api) + RegisterTokensAPI(router, api) + RegisterStakeAPI(router, api) + RegisterBlockAPI(router, api) + } + for _, api := range platform.CollectionsAPIs { + RegisterCollectionsAPI(router, api) + } + + RegisterBatchAPI(router) + RegisterBasicAPI(router) +} + +func SetupTokensIndexAPI(router gin.IRouter, instance tokenindexer.Instance) { + RegisterTokensIndexAPI(router, instance) +} + +func SetupSwaggerAPI(router gin.IRouter) { + router.GET("swagger/*any", ginSwagger.WrapHandler(swaggerFiles.Handler)) +} + +func SetupMetrics(router gin.IRouter) { + router.GET(config.Default.Metrics.Path, gin.WrapH(promhttp.Handler())) +} diff --git a/api/batch.go b/api/batch.go deleted file mode 100644 index 6e4945ed2..000000000 --- a/api/batch.go +++ /dev/null @@ -1,177 +0,0 @@ -package api - -import ( - "github.com/gin-gonic/gin" - "github.com/trustwallet/blockatlas/coin" - "github.com/trustwallet/blockatlas/pkg/blockatlas" - "github.com/trustwallet/blockatlas/pkg/ginutils" - "github.com/trustwallet/blockatlas/platform" - "strconv" -) - -type AddressBatchRequest struct { - Address string `json:"address"` - CoinBatchRequest -} - -type CoinBatchRequest struct { - Coin uint `json:"coin"` -} - -type ENSBatchRequest struct { - Coins []uint64 `json:"coins"` - Name string `json:"name"` -} - -type AddressesRequest []AddressBatchRequest -type CoinsRequest []CoinBatchRequest - -// @Summary Get Multiple Stake Delegations -// @ID batch_delegations -// @Description Get Stake Delegations for multiple coins -// @Accept json -// @Produce json -// @Tags platform,staking -// @Param delegations body api.AddressesRequest true "Validators addresses and coins" -// @Success 200 {object} blockatlas.DelegationsBatchPage -// @Router /v2/staking/delegations [post] -func makeStakingDelegationsBatchRoute(router gin.IRouter) { - router.POST("/staking/delegations", func(c *gin.Context) { - var reqs AddressesRequest - if err := c.BindJSON(&reqs); err != nil { - ginutils.ErrorResponse(c).Message(err.Error()).Render() - return - } - - batch := make(blockatlas.DelegationsBatchPage, 0) - for _, r := range reqs { - c, ok := coin.Coins[r.Coin] - if !ok { - continue - } - p, ok := platform.StakeAPIs[c.Handle] - if !ok { - continue - } - delegation, err := getDelegationResponse(p, r.Address) - if err != nil { - continue - } - batch = append(batch, delegation) - } - ginutils.RenderSuccess(c, blockatlas.DocsResponse{Docs: batch}) - }) -} - -// @Summary Get Multiple Stake Delegations -// @ID batch_delegations -// @Description Get Stake Delegations for multiple coins -// @Accept json -// @Produce json -// @Tags platform,staking -// @Param delegations body api.AddressesRequest true "Validators addresses and coins" -// @Success 200 {object} blockatlas.DelegationsBatchPage -// @Router /v2/staking/list [post] -func makeStakingDelegationsSimpleBatchRoute(router gin.IRouter) { - router.POST("/staking/list", func(c *gin.Context) { - var reqs CoinsRequest - if err := c.BindJSON(&reqs); err != nil { - ginutils.ErrorResponse(c).Message(err.Error()).Render() - return - } - - batch := make(blockatlas.StakingBatchPage, 0) - for _, r := range reqs { - c, ok := coin.Coins[r.Coin] - if !ok { - continue - } - p, ok := platform.StakeAPIs[c.Handle] - if !ok { - continue - } - staking := getStakingResponse(p) - batch = append(batch, staking) - } - ginutils.RenderSuccess(c, blockatlas.DocsResponse{Docs: batch}) - }) -} - -// @Description Get collection categories -// @ID collection_categories_v2 -// @Summary Get list of collections from a specific coin and addresses -// @Accept json -// @Produce json -// @Tags Collectibles -// @Param data body string true "Payload" default({"60": ["0xb3624367b1ab37daef42e1a3a2ced012359659b0"]}) -// @Success 200 {object} blockatlas.DocsResponse -// @Router /v2/collectibles/categories [post] -//TODO: remove once most of the clients will be updated (deadline: March 17th) -func oldMakeCategoriesBatchRoute(router gin.IRouter) { - router.POST("/collectibles/categories", func(c *gin.Context) { - var reqs map[string][]string - if err := c.BindJSON(&reqs); err != nil { - ginutils.ErrorResponse(c).Message(err.Error()).Render() - return - } - - batch := make(blockatlas.CollectionPage, 0) - for key, addresses := range reqs { - coinId, err := strconv.Atoi(key) - if err != nil { - continue - } - p, ok := platform.CollectionAPIs[uint(coinId)] - if !ok { - continue - } - for _, address := range addresses { - collections, err := p.OldGetCollections(address) - if err != nil { - continue - } - batch = append(batch, collections...) - } - } - ginutils.RenderSuccess(c, batch) - }) -} - -// @Description Get collection categories -// @ID collection_categories_v3 -// @Summary Get list of collections from a specific coin and addresses -// @Accept json -// @Produce json -// @Tags Collectibles -// @Param data body string true "Payload" default({"60": ["0xb3624367b1ab37daef42e1a3a2ced012359659b0"]}) -// @Success 200 {object} blockatlas.DocsResponse -// @Router /v3/collectibles/categories [post] -func makeCategoriesBatchRoute(router gin.IRouter) { - router.POST("/collectibles/categories", func(c *gin.Context) { - var reqs map[string][]string - if err := c.BindJSON(&reqs); err != nil { - ginutils.ErrorResponse(c).Message(err.Error()).Render() - return - } - - batch := make(blockatlas.CollectionPage, 0) - for key, addresses := range reqs { - coinId, err := strconv.Atoi(key) - if err != nil { - continue - } - p, ok := platform.CollectionAPIs[uint(coinId)] - if !ok { - continue - } - for _, address := range addresses { - collections, err := p.GetCollections(address) - if err != nil { - continue - } - batch = append(batch, collections...) - } - } - ginutils.RenderSuccess(c, batch) - }) -} diff --git a/api/delegations.go b/api/delegations.go deleted file mode 100644 index 18277b0c1..000000000 --- a/api/delegations.go +++ /dev/null @@ -1,35 +0,0 @@ -package api - -import ( - "github.com/trustwallet/blockatlas/pkg/blockatlas" - "github.com/trustwallet/blockatlas/pkg/errors" -) - -func getDelegationResponse(p blockatlas.StakeAPI, address string) (blockatlas.DelegationResponse, error) { - delegations, err := p.GetDelegations(address) - if err != nil { - return blockatlas.DelegationResponse{ - StakingResponse: getStakingResponse(p), - }, errors.E("Unable to fetch delegations list", err) - } - balance, err := p.UndelegatedBalance(address) - if err != nil { - return blockatlas.DelegationResponse{ - StakingResponse: getStakingResponse(p), - }, errors.E("Unable to fetch undelegated balance", err) - } - return blockatlas.DelegationResponse{ - Balance: balance, - Delegations: delegations, - Address: address, - StakingResponse: getStakingResponse(p), - }, nil -} - -func getStakingResponse(p blockatlas.StakeAPI) blockatlas.StakingResponse { - c := p.Coin() - return blockatlas.StakingResponse{ - Coin: c.External(), - Details: p.GetDetails(), - } -} diff --git a/api/endpoint/basic.go b/api/endpoint/basic.go new file mode 100644 index 000000000..110b6b21d --- /dev/null +++ b/api/endpoint/basic.go @@ -0,0 +1,15 @@ +package endpoint + +import ( + "github.com/gin-gonic/gin" + "github.com/trustwallet/blockatlas/internal" + "net/http" +) + +func GetStatus(c *gin.Context) { + c.JSON(http.StatusOK, map[string]interface{}{ + "status": true, + "build": internal.Build, + "date": internal.Date, + }) +} diff --git a/api/endpoint/block.go b/api/endpoint/block.go new file mode 100644 index 000000000..50b0942d8 --- /dev/null +++ b/api/endpoint/block.go @@ -0,0 +1,39 @@ +package endpoint + +import ( + "errors" + "net/http" + "strconv" + + "github.com/gin-gonic/gin" + "github.com/trustwallet/blockatlas/pkg/blockatlas" +) + +// @Summary Get Block +// @ID block_v2 +// @Description Get Block information +// @Accept json +// @Produce json +// @Tags Transactions +// @Param coin path string true "the coin name" default(zilliqa) +// @Param address path string true "the query address" default(850321) +// @Failure 500 {object} ErrorResponse +// @Router /v2/{coin}/blocks/{block} [get] +func GetBlock(c *gin.Context, blockAPI blockatlas.BlockAPI) { + blockString := c.Param("block") + blockNumber, err := strconv.ParseUint(blockString, 10, 32) + + if err != nil || blockNumber < 1 { + c.AbortWithStatusJSON(http.StatusBadRequest, errorResponse(errors.New("invalid block number"))) + return + } + + block, err := blockAPI.GetBlockByNumber(int64(blockNumber)) + + if err != nil { + c.AbortWithStatusJSON(http.StatusNotFound, errorResponse(errors.New("block number not found"))) + return + } + + c.JSON(http.StatusOK, &block) +} diff --git a/api/endpoint/collection.go b/api/endpoint/collection.go new file mode 100644 index 000000000..a57313f0a --- /dev/null +++ b/api/endpoint/collection.go @@ -0,0 +1,83 @@ +package endpoint + +import ( + "net/http" + "strconv" + + "github.com/gin-gonic/gin" + "github.com/trustwallet/blockatlas/pkg/blockatlas" + "github.com/trustwallet/golibs/coin" + "github.com/trustwallet/golibs/types" +) + +// @Summary Get Collection +// @ID collection_v4 +// @Description Get a collection from the address +// @Accept json +// @Produce json +// @Tags Collections +// @Param coin path string true "the coin name" default(ethereum) +// @Param owner path string true "the query address" default(0x0875BCab22dE3d02402bc38aEe4104e1239374a7) +// @Param collection_id path string true "the query collection" default(0x06012c8cf97bead5deae237070f9587f8e7a266d) +// @Success 200 {object} types.CollectionPage +// @Failure 500 {object} ErrorResponse +// @Router /v4/{coin}/collections/{owner}/collection/{collection_id} [get] +func GetCollectiblesForSpecificCollectionAndOwner(c *gin.Context, api blockatlas.CollectionsAPI) { + collectibles, err := api.GetCollectibles(c.Param("owner"), c.Param("collection_id")) + if err != nil { + c.AbortWithStatusJSON(http.StatusInternalServerError, errorResponse(err)) + return + } + c.JSON(http.StatusOK, &collectibles) +} + +// @Description Get collection categories +// @ID collection_categories_v4 +// @Summary Get list of collections from a specific coin and addresses +// @Accept json +// @Produce json +// @Tags Collections +// @Param data body string true "Payload" default({"60": ["0xb3624367b1ab37daef42e1a3a2ced012359659b0"]}) +// @Success 200 {object} blockatlas.ResultsResponse +// @Router /v4/collectibles/categories [post] +func GetCollectionCategoriesFromList(c *gin.Context, apis blockatlas.CollectionsAPIs) { + var reqs map[string][]string + if err := c.BindJSON(&reqs); err != nil { + c.AbortWithStatusJSON(http.StatusBadRequest, errorResponse(err)) + return + } + + reqIds := []int{} + coinIds := []int{} + for k := range reqs { + coinId, err := strconv.Atoi(k) + if err != nil { + continue + } + reqIds = append(reqIds, coinId) + } + + // old iOS client requests all accounts + if len(reqIds) > 2 { + coinIds = append(coinIds, coin.ETHEREUM) + } else { + coinIds = reqIds + } + + batch := make(types.CollectionPage, 0) + for _, coinId := range coinIds { + p, ok := apis[uint(coinId)] + if !ok { + continue + } + addresses := reqs[strconv.Itoa(coinId)] + for _, address := range addresses { + collections, err := p.GetCollections(address) + if err != nil { + continue + } + batch = append(batch, collections...) + } + } + c.JSON(http.StatusOK, &batch) +} diff --git a/api/endpoint/errors.go b/api/endpoint/errors.go new file mode 100644 index 000000000..48f65578f --- /dev/null +++ b/api/endpoint/errors.go @@ -0,0 +1,22 @@ +package endpoint + +type ( + ErrorResponse struct { + Error ErrorDetails `json:"error"` + } + ErrorDetails struct { + Message string `json:"message"` + } + + ErrorCode int +) + +func errorResponse(err error) ErrorResponse { + var message string + if err != nil { + message = err.Error() + } + return ErrorResponse{Error: ErrorDetails{ + Message: message, + }} +} diff --git a/api/endpoint/staking.go b/api/endpoint/staking.go new file mode 100644 index 000000000..ec2b159c6 --- /dev/null +++ b/api/endpoint/staking.go @@ -0,0 +1,235 @@ +package endpoint + +import ( + "net/http" + "sort" + "strconv" + "strings" + + "github.com/trustwallet/golibs/numbers" + + "errors" + + "github.com/gin-gonic/gin" + "github.com/trustwallet/blockatlas/pkg/blockatlas" + "github.com/trustwallet/golibs/coin" +) + +type ( + AddressBatchRequest struct { + Address string `json:"address"` + CoinBatchRequest + } + + CoinBatchRequest struct { + Coin uint `json:"coin"` + } + + ENSBatchRequest struct { + Coins []uint64 `json:"coins"` + Name string `json:"name"` + } + + AddressesRequest []AddressBatchRequest + CoinsRequest []CoinBatchRequest +) + +// @Summary Get Multiple Stake Delegations +// @ID staking_v2_batch +// @Description Get Stake Delegations for multiple coins +// @Accept json +// @Produce json +// @Tags Staking +// @Param delegations body AddressesRequest true "Validators addresses and coins" +// @Success 200 {object} blockatlas.DelegationsBatchPage +// @Router /v2/staking/delegations [post] +func GetStakeDelegationsWithAllInfoForBatch(c *gin.Context, apis map[string]blockatlas.StakeAPI) { + var reqs AddressesRequest + if err := c.BindJSON(&reqs); err != nil { + c.AbortWithStatusJSON(http.StatusBadRequest, errorResponse(err)) + return + } + + batch := make(blockatlas.DelegationsBatchPage, 0) + for _, r := range reqs { + requestCoin, ok := coin.Coins[r.Coin] + if !ok { + continue + } + p, ok := apis[requestCoin.Handle] + if !ok { + continue + } + delegation, err := getDelegationResponse(p, r.Address) + if err != nil { + continue + } + delegation.Delegations = sortDelegations(delegation.Delegations) + batch = append(batch, delegation) + } + c.JSON(http.StatusOK, blockatlas.ResultsResponse{Results: &batch}) +} + +// @Summary Get Multiple Stake Delegations +// @ID staking_v2 +// @Description Get Stake Delegations for multiple coins +// @Accept json +// @Produce json +// @Tags Staking +// @Param delegations body AddressesRequest true "Validators addresses and coins" +// @Success 200 {object} blockatlas.DelegationsBatchPage +// @Router /v2/staking/list [post] +func GetStakeInfoForBatch(c *gin.Context, apis map[string]blockatlas.StakeAPI) { + var reqs CoinsRequest + if err := c.BindJSON(&reqs); err != nil { + c.AbortWithStatusJSON(http.StatusBadRequest, errorResponse(err)) + return + } + + batch := make(blockatlas.StakingBatchPage, 0) + for _, r := range reqs { + requestCoin, ok := coin.Coins[r.Coin] + if !ok { + continue + } + p, ok := apis[requestCoin.Handle] + if !ok { + continue + } + staking := getStakingResponse(p) + batch = append(batch, staking) + } + c.JSON(http.StatusOK, blockatlas.ResultsResponse{Results: &batch}) +} + +// @Summary Get staking info by coin ID +// @ID staking_v3 +// @Description Get staking info by coin ID +// @Produce json +// @Tags Staking +// @Param coins query string true "List of coins" +// @Success 200 {array} blockatlas.DelegationsBatchPage +// @Failure 400 {object} ErrorResponse +// @Router /v3/staking/list [get] +func GetStakeInfoForCoins(c *gin.Context, apis map[string]blockatlas.StakeAPI) { + coinsRequest := c.Query("coins") + if coinsRequest == "" { + c.AbortWithStatusJSON(http.StatusBadRequest, errorResponse(errors.New("empty coins list"))) + return + } + + coinsRaw := strings.Split(coinsRequest, ",") + + coins, err := numbers.SliceAtoi(coinsRaw) + if err != nil { + c.AbortWithStatusJSON(http.StatusBadRequest, errorResponse(err)) + return + } + + var reqs CoinsRequest + for _, c := range coins { + reqs = append(reqs, CoinBatchRequest{Coin: uint(c)}) + } + + batch := make(blockatlas.StakingBatchPage, 0) + for _, r := range reqs { + requestCoin, ok := coin.Coins[r.Coin] + if !ok { + continue + } + p, ok := apis[requestCoin.Handle] + if !ok { + continue + } + staking := getStakingResponse(p) + batch = append(batch, staking) + } + c.JSON(http.StatusOK, blockatlas.ResultsResponse{Results: &batch}) +} + +// @Summary Get Validators +// @ID validators_v2 +// @Description Get validators from the address +// @Accept json +// @Produce json +// @Tags Staking +// @Param coin path string true "the coin name" default(cosmos) +// @Success 200 {object} blockatlas.ResultsResponse +// @Failure 500 {object} ErrorResponse +// @Router /v2/{coin}/staking/validators [get] +func GetValidators(c *gin.Context, api blockatlas.StakeAPI) { + results, err := api.GetActiveValidators() + if err != nil { + c.AbortWithStatusJSON(http.StatusInternalServerError, errorResponse(err)) + return + } + c.JSON(http.StatusOK, blockatlas.ResultsResponse{Results: &results}) +} + +// @Summary Get Stake Delegations +// @ID delegations +// @Description Get stake delegations from the address +// @Accept json +// @Produce json +// @Tags Staking +// @Param coin path string true "the coin name" default(tron) +// @Param address path string true "the query address" default(TPJYCz8ppZNyvw7pTwmjajcx4Kk1MmEUhD) +// @Success 200 {object} blockatlas.DelegationResponse +// @Failure 500 {object} ErrorResponse +// @Router /v2/{coin}/staking/delegations/{address} [get] +func GetStakingDelegationsForSpecificCoin(c *gin.Context, api blockatlas.StakeAPI) { + result, err := getDelegationResponse(api, c.Param("address")) + if err != nil { + c.AbortWithStatusJSON(http.StatusInternalServerError, errorResponse(err)) + return + } + result.Delegations = sortDelegations(result.Delegations) + c.JSON(http.StatusOK, &result) +} + +func getDelegationResponse(api blockatlas.StakeAPI, address string) (blockatlas.DelegationResponse, error) { + delegations, err := api.GetDelegations(address) + if err != nil { + return blockatlas.DelegationResponse{ + StakingResponse: getStakingResponse(api), + Address: address, + }, err + } + balance, err := api.UndelegatedBalance(address) + if err != nil { + return blockatlas.DelegationResponse{ + Delegations: delegations, + Address: address, + StakingResponse: getStakingResponse(api), + }, err + } + return blockatlas.DelegationResponse{ + Balance: balance, + Delegations: delegations, + Address: address, + StakingResponse: getStakingResponse(api), + }, nil +} + +func getStakingResponse(api blockatlas.StakeAPI) blockatlas.StakingResponse { + stakingCoin := api.Coin() + return blockatlas.StakingResponse{ + Coin: stakingCoin.External(), + Details: api.GetDetails(), + } +} + +func sortDelegations(delegations blockatlas.DelegationsPage) blockatlas.DelegationsPage { + sort.Slice(delegations, func(i, j int) bool { + iA, err := strconv.Atoi(delegations[i].Value) + if err != nil { + return false + } + jA, err := strconv.Atoi(delegations[j].Value) + if err != nil { + return false + } + return iA > jA + }) + return delegations +} diff --git a/api/endpoint/token.go b/api/endpoint/token.go new file mode 100644 index 000000000..99a7011d4 --- /dev/null +++ b/api/endpoint/token.go @@ -0,0 +1,95 @@ +package endpoint + +import ( + "errors" + "net/http" + "strconv" + + "github.com/gin-gonic/gin" + "github.com/trustwallet/blockatlas/pkg/blockatlas" + "github.com/trustwallet/blockatlas/services/tokenindexer" + "github.com/trustwallet/golibs/types" +) + +// @Summary Get Tokens +// @ID tokens +// @Description Get tokens from the address +// @Accept json +// @Produce json +// @Tags Transactions +// @Param coin path string true "the coin name" default(ethereum) +// @Param address path string true "the query address" default(0x5574Cd97432cEd0D7Caf58ac3c4fEDB2061C98fB) +// @Success 200 {object} []string +// @Failure 500 {object} ErrorResponse +// @Router /v2/{coin}/tokens/{address} [get] +func GetTokensByAddress(c *gin.Context, tokenAPI blockatlas.TokensAPI) { + address := c.Param("address") + if address == "" { + c.JSON(http.StatusOK, []types.Token{}) + return + } + + result, err := tokenAPI.GetTokenListByAddress(address) + if err != nil { + c.AbortWithStatusJSON(http.StatusInternalServerError, errorResponse(err)) + return + } + c.JSON(http.StatusOK, result) +} + +func GetTokensIdsByAddress(c *gin.Context, tokenAPI blockatlas.TokensAPI) { + address := c.Param("address") + if address == "" { + c.JSON(http.StatusOK, []string{}) + return + } + + result, err := tokenAPI.GetTokenListIdsByAddress(address) + if err != nil { + c.AbortWithStatusJSON(http.StatusInternalServerError, errorResponse(err)) + return + } + c.JSON(http.StatusOK, result) +} + +func GetTokensByAddressV3(c *gin.Context, instance tokenindexer.Instance) { + var query tokenindexer.GetTokensByAddressRequest + if err := c.Bind(&query); err != nil { + c.AbortWithStatusJSON(http.StatusBadRequest, errorResponse(err)) + return + } + result, err := instance.GetTokensByAddress(query) + if err != nil { + c.AbortWithStatusJSON(http.StatusInternalServerError, errorResponse(err)) + return + } + c.JSON(http.StatusOK, result) +} + +// @Description Get new tokens +// @ID tokens_new_v3 +// @Summary Get list of new tokens by coin from specific unix timstamp +// @Accept json +// @Produce json +// @Tags Transactions +// @Param from query int true "unix timestamp" +// @Success 200 {object} tokenindexer.Response +// @Router /v3/tokens/new [get] +func GetNewTokens(c *gin.Context, instance tokenindexer.Instance) { + var request tokenindexer.Request + fromRaw := c.Query("from") + + from, err := strconv.Atoi(fromRaw) + if err != nil { + c.AbortWithStatusJSON(http.StatusBadRequest, errorResponse(errors.New("invalid from param"))) + return + } + request.From = int64(from) + + resp, err := instance.GetNewTokensRequest(request) + if err != nil { + c.AbortWithStatusJSON(http.StatusInternalServerError, errorResponse(err)) + return + } + c.JSON(http.StatusOK, resp) +} diff --git a/api/endpoint/transaction.go b/api/endpoint/transaction.go new file mode 100644 index 000000000..62fc938f7 --- /dev/null +++ b/api/endpoint/transaction.go @@ -0,0 +1,153 @@ +package endpoint + +import ( + "errors" + "net/http" + + "github.com/gin-gonic/gin" + "github.com/trustwallet/blockatlas/pkg/blockatlas" + "github.com/trustwallet/golibs/types" +) + +// @Summary Get Transactions +// @ID tx_v2 +// @Description Get transactions from the address +// @Accept json +// @Produce json +// @Tags Transactions +// @Param coin path string true "the coin name" default(tezos) +// @Param address path string true "the query address" default(tz1WCd2jm4uSt4vntk4vSuUWoZQGhLcDuR9q) +// @Failure 500 {object} ErrorResponse +// @Router /v1/{coin}/{address} [get] +// @Router /v2/{coin}/transactions/{address} [get] +func GetTransactionsHistory(c *gin.Context, txAPI blockatlas.TxAPI, tokenTxAPI blockatlas.TokenTxAPI) { + address := c.Param("address") + if address == "" { + c.AbortWithStatusJSON(http.StatusBadRequest, errorResponse(blockatlas.ErrInvalidAddr)) + return + } + token := c.Query("token") + + var ( + txs types.Txs + err error + ) + + switch { + case token == "" && txAPI != nil: + txs, err = txAPI.GetTxsByAddress(address) + case token != "" && tokenTxAPI != nil: + txs, err = tokenTxAPI.GetTokenTxsByAddress(address, token) + default: + c.AbortWithStatusJSON( + http.StatusInternalServerError, + errorResponse(errors.New("Failed to find api for that coin")), + ) + return + } + + if err != nil { + switch err { + case blockatlas.ErrInvalidAddr: + c.AbortWithStatusJSON( + http.StatusBadRequest, + errorResponse(blockatlas.ErrInvalidAddr), + ) + return + case blockatlas.ErrNotFound: + c.AbortWithStatusJSON( + http.StatusNotFound, + errorResponse(blockatlas.ErrNotFound), + ) + return + case blockatlas.ErrSourceConn: + c.AbortWithStatusJSON( + http.StatusServiceUnavailable, + errorResponse(blockatlas.ErrSourceConn), + ) + return + default: + c.AbortWithStatusJSON( + http.StatusInternalServerError, + errorResponse(err), + ) + return + } + } + + filteredTxs := txs.FilterUniqueID().SortByDate() + filteredTxs = filteredTxs.FilterTransactionsByMemo() + if token != "" { + filteredTxs = filteredTxs.FilterTransactionsByToken(token) + } + + if len(filteredTxs) > types.TxPerPage { + filteredTxs = filteredTxs[0:types.TxPerPage] + } + + // modify in loop + result := make(types.Txs, len(filteredTxs)) + for i, t := range filteredTxs { + result[i] = t + result[i].Direction = t.GetTransactionDirection(address) + } + c.JSON(http.StatusOK, types.NewTxPage(result)) +} + +// @Summary Get Transactions by XPUB +// @ID tx_xpub_v2 +// @Description Get transactions from XPUB address +// @Accept json +// @Produce json +// @Tags Transactions +// @Param coin path string true "the coin name" default(bitcoin) +// @Param xpub path string true "the xpub key" default(zpub6ruK9k6YGm8BRHWvTiQcrEPnFkuRDJhR7mPYzV2LDvjpLa5CuGgrhCYVZjMGcLcFqv9b2WvsFtY2Gb3xq8NVq8qhk9veozrA2W9QaWtihrC) +// @Failure 500 {object} ErrorResponse +// @Router /v1/{coin}/{address} [get] +// @Router /v2/{coin}/transactions/xpub/{xpub} [get] +func GetTransactionsByXpub(c *gin.Context, api blockatlas.TxUtxoAPI) { + xPubKey := c.Param("xpub") + if xPubKey == "" { + c.AbortWithStatusJSON(http.StatusBadRequest, errorResponse(blockatlas.ErrInvalidKey)) + return + } + + txs, err := api.GetTxsByXpub(xPubKey) + if err != nil { + switch err { + case blockatlas.ErrInvalidKey: + c.AbortWithStatusJSON( + http.StatusBadRequest, + errorResponse(blockatlas.ErrInvalidKey), + ) + return + case blockatlas.ErrNotFound: + c.AbortWithStatusJSON( + http.StatusNotFound, + errorResponse(blockatlas.ErrNotFound), + ) + return + case blockatlas.ErrSourceConn: + c.AbortWithStatusJSON( + http.StatusServiceUnavailable, + errorResponse(blockatlas.ErrSourceConn), + ) + return + default: + c.AbortWithStatusJSON( + http.StatusInternalServerError, + errorResponse(err), + ) + return + } + } + + filteredTxs := txs.FilterUniqueID().SortByDate() + filteredTxs = filteredTxs.FilterTransactionsByMemo() + + if len(filteredTxs) > types.TxPerPage { + filteredTxs = filteredTxs[0:types.TxPerPage] + } + + c.JSON(http.StatusOK, types.NewTxPage(filteredTxs)) +} diff --git a/api/handlers.go b/api/handlers.go deleted file mode 100644 index a33f25830..000000000 --- a/api/handlers.go +++ /dev/null @@ -1,346 +0,0 @@ -package api - -import ( - "net/http" - "time" - - "github.com/chenjiandongx/ginprom" - "github.com/gin-gonic/gin" - "github.com/prometheus/client_golang/prometheus/promhttp" - "github.com/spf13/viper" - "github.com/trustwallet/blockatlas/pkg/blockatlas" - "github.com/trustwallet/blockatlas/pkg/ginutils" - "github.com/trustwallet/blockatlas/pkg/ginutils/gincache" - "github.com/trustwallet/blockatlas/pkg/logger" - "github.com/trustwallet/blockatlas/pkg/metrics" - services "github.com/trustwallet/blockatlas/services/assets" -) - -// @Summary Get Transactions -// @ID tx_v1 -// @Description Get transactions from the address -// @Accept json -// @Produce json -// @Tags platform,tx -// @Param coin path string true "the coin name" default(tezos) -// @Param address path string true "the query address" default(tz1WCd2jm4uSt4vntk4vSuUWoZQGhLcDuR9q) -// @Failure 500 {object} ginutils.ApiError -// @Router /v1/{coin}/{address} [get] -func makeTxRouteV1(router gin.IRouter, api blockatlas.Platform) { - makeTxRoute(router, api, "/:address") -} - -// @Summary Get Transactions -// @ID tx_v2 -// @Description Get transactions from the address -// @Accept json -// @Produce json -// @Tags platform,tx -// @Param coin path string true "the coin name" default(tezos) -// @Param address path string true "the query address" default(tz1WCd2jm4uSt4vntk4vSuUWoZQGhLcDuR9q) -// @Success 200 {object} blockatlas.TxPage -// @Failure 500 {object} ginutils.ApiError -// @Router /v2/{coin}/transactions/{address} [get] -func makeTxRouteV2(router gin.IRouter, api blockatlas.Platform) { - makeTxRoute(router, api, "/transactions/:address") -} - -func makeTxRoute(router gin.IRouter, api blockatlas.Platform, path string) { - var txAPI blockatlas.TxAPI - var tokenTxAPI blockatlas.TokenTxAPI - txAPI, _ = api.(blockatlas.TxAPI) - tokenTxAPI, _ = api.(blockatlas.TokenTxAPI) - - if txAPI == nil && tokenTxAPI == nil { - return - } - - router.GET(path, func(c *gin.Context) { - address := c.Param("address") - if address == "" { - emptyPage(c) - return - } - token := c.Query("token") - - var txs []blockatlas.Tx - var err error - switch { - case token == "" && txAPI != nil: - txs, err = txAPI.GetTxsByAddress(address) - case token != "" && tokenTxAPI != nil: - txs, err = tokenTxAPI.GetTokenTxsByAddress(address, token) - default: - emptyPage(c) - return - } - - if err != nil { - errResp := ginutils.ErrorResponse(c) - switch { - case err == blockatlas.ErrInvalidAddr: - errResp.Params(http.StatusBadRequest, "Invalid address") - case err == blockatlas.ErrNotFound: - errResp.Params(http.StatusNotFound, "No such address") - case err == blockatlas.ErrSourceConn: - errResp.Params(http.StatusServiceUnavailable, "Lost connection to blockchain") - } - errResp.Render() - return - } - - page := make(blockatlas.TxPage, 0) - for _, tx := range txs { - if tx.Direction != "" { - goto AddTx - } - tx.Direction = blockatlas.DirectionOutgoing - if tx.To == address { - tx.Direction = blockatlas.DirectionIncoming - if tx.From == address { - tx.Direction = blockatlas.DirectionSelf - } - } - AddTx: - page = append(page, tx) - } - page.Sort() - ginutils.RenderSuccess(c, &page) - }) -} - -// @Summary Get Validators -// @ID validators -// @Description Get validators from the address -// @Accept json -// @Produce json -// @Tags platform,staking -// @Param coin path string true "the coin name" default(cosmos) -// @Success 200 {object} blockatlas.DocsResponse -// @Failure 500 {object} ginutils.ApiError -// @Router /v2/{coin}/staking/validators [get] -func makeStakingValidatorsRoute(router gin.IRouter, api blockatlas.Platform) { - var stakingAPI blockatlas.StakeAPI - stakingAPI, _ = api.(blockatlas.StakeAPI) - - if stakingAPI == nil { - return - } - - router.GET("/staking/validators", gincache.CacheMiddleware(time.Hour, func(c *gin.Context) { - results, err := services.GetValidators(stakingAPI) - if err != nil { - logger.Error(err) - ginutils.ErrorResponse(c).Message(err.Error()).Render() - return - } - ginutils.RenderSuccess(c, blockatlas.DocsResponse{Docs: results}) - })) -} - -// @Summary Get Stake Delegations -// @ID delegations -// @Description Get stake delegations from the address -// @Accept json -// @Produce json -// @Tags platform,staking -// @Param coin path string true "the coin name" default(tron) -// @Param address path string true "the query address" default(TPJYCz8ppZNyvw7pTwmjajcx4Kk1MmEUhD) -// @Success 200 {object} blockatlas.DelegationResponse -// @Failure 500 {object} ginutils.ApiError -// @Router /v2/{coin}/staking/delegations/{address} [get] -func makeStakingDelegationsRoute(router gin.IRouter, api blockatlas.Platform) { - var stakingAPI blockatlas.StakeAPI - stakingAPI, _ = api.(blockatlas.StakeAPI) - - if stakingAPI == nil { - return - } - - router.GET("/staking/delegations/:address", func(c *gin.Context) { - response, err := getDelegationResponse(stakingAPI, c.Param("address")) - if err != nil { - ginutils.ErrorResponse(c).Message(err.Error()).Render() - return - } - - ginutils.RenderSuccess(c, response) - }) -} - -// @Summary Get Collections -// @ID collections_v2 -// @Description Get all collections from the address -// @Accept json -// @Produce json -// @Tags platform,collection -// @Param coin path string true "the coin name" default(ethereum) -// @Param address path string true "the query address" default(0x5574Cd97432cEd0D7Caf58ac3c4fEDB2061C98fB) -// @Success 200 {object} blockatlas.CollectionPage -// @Failure 500 {object} ginutils.ApiError -// @Router /v2/{coin}/collections/{address} [get] -//TODO: remove once most of the clients will be updated (deadline: March 17th) -func oldMakeCollectionsRoute(router gin.IRouter, api blockatlas.Platform) { - var collectionAPI blockatlas.CollectionAPI - collectionAPI, _ = api.(blockatlas.CollectionAPI) - - if collectionAPI == nil { - return - } - - router.GET("/collections/:owner", func(c *gin.Context) { - collections, err := collectionAPI.OldGetCollections(c.Param("owner")) - if err != nil { - ginutils.ErrorResponse(c).Message(err.Error()).Render() - return - } - - ginutils.RenderSuccess(c, collections) - }) -} - -// @Summary Get Collections -// @ID collections_v3 -// @Description Get all collections from the address -// @Accept json -// @Produce json -// @Tags platform,collection -// @Param coin path string true "the coin name" default(ethereum) -// @Param address path string true "the query address" default(0x5574Cd97432cEd0D7Caf58ac3c4fEDB2061C98fB) -// @Success 200 {object} blockatlas.CollectionPage -// @Failure 500 {object} ginutils.ApiError -// @Router /v3/{coin}/collections/{address} [get] -func makeCollectionsRoute(router gin.IRouter, api blockatlas.Platform) { - var collectionAPI blockatlas.CollectionAPI - collectionAPI, _ = api.(blockatlas.CollectionAPI) - - if collectionAPI == nil { - return - } - - router.GET("/collections/:owner", func(c *gin.Context) { - collections, err := collectionAPI.GetCollections(c.Param("owner")) - if err != nil { - ginutils.ErrorResponse(c).Message(err.Error()).Render() - return - } - - ginutils.RenderSuccess(c, collections) - }) -} - -// @Summary Get Collection -// @ID collection_v2 -// @Description Get a collection from the address -// @Accept json -// @Produce json -// @Tags platform,collection -// @Param coin path string true "the coin name" default(ethereum) -// @Param owner path string true "the query address" default(0x0875BCab22dE3d02402bc38aEe4104e1239374a7) -// @Param collection_id path string true "the query collection" default(0x06012c8cf97bead5deae237070f9587f8e7a266d) -// @Success 200 {object} blockatlas.CollectionPage -// @Failure 500 {object} ginutils.ApiError -// @Router /v2/{coin}/collections/{owner}/collection/{collection_id} [get] -//TODO: remove once most of the clients will be updated (deadline: March 17th) -func oldMakeCollectionRoute(router gin.IRouter, api blockatlas.Platform) { - var collectionAPI blockatlas.CollectionAPI - collectionAPI, _ = api.(blockatlas.CollectionAPI) - - if collectionAPI == nil { - return - } - - router.GET("/collections/:owner/collection/:collection_id", func(c *gin.Context) { - collectibles, err := collectionAPI.OldGetCollectibles(c.Param("owner"), c.Param("collection_id")) - if err != nil { - ginutils.ErrorResponse(c).Message(err.Error()).Render() - return - } - - ginutils.RenderSuccess(c, collectibles) - }) -} - -// @Summary Get Collection -// @ID collection_v3 -// @Description Get a collection from the address -// @Accept json -// @Produce json -// @Tags platform,collection -// @Param coin path string true "the coin name" default(ethereum) -// @Param owner path string true "the query address" default(0x0875BCab22dE3d02402bc38aEe4104e1239374a7) -// @Param collection_id path string true "the query collection" default(0x06012c8cf97bead5deae237070f9587f8e7a266d) -// @Success 200 {object} blockatlas.CollectionPage -// @Failure 500 {object} ginutils.ApiError -// @Router /v3/{coin}/collections/{owner}/collection/{collection_id} [get] -func makeCollectionRoute(router gin.IRouter, api blockatlas.Platform) { - var collectionAPI blockatlas.CollectionAPI - collectionAPI, _ = api.(blockatlas.CollectionAPI) - - if collectionAPI == nil { - return - } - - router.GET("/collections/:owner/collection/:collection_id", func(c *gin.Context) { - collectibles, err := collectionAPI.GetCollectibles(c.Param("owner"), c.Param("collection_id")) - if err != nil { - ginutils.ErrorResponse(c).Message(err.Error()).Render() - return - } - - ginutils.RenderSuccess(c, collectibles) - }) -} - -// @Summary Get Tokens -// @ID tokens -// @Description Get tokens from the address -// @Accept json -// @Produce json -// @Tags platform,token -// @Param coin path string true "the coin name" default(ethereum) -// @Param address path string true "the query address" default(0x5574Cd97432cEd0D7Caf58ac3c4fEDB2061C98fB) -// @Success 200 {object} blockatlas.CollectionPage -// @Failure 500 {object} ginutils.ApiError -// @Router /v2/{coin}/tokens/{address} [get] -func makeTokenRoute(router gin.IRouter, api blockatlas.Platform) { - var tokenAPI blockatlas.TokenAPI - tokenAPI, _ = api.(blockatlas.TokenAPI) - - if tokenAPI == nil { - return - } - - router.GET("/tokens/:address", func(c *gin.Context) { - address := c.Param("address") - if address == "" { - emptyPage(c) - return - } - - tl, err := tokenAPI.GetTokenListByAddress(address) - if err != nil { - ginutils.ErrorResponse(c).Message(err.Error()).Render() - return - } - - ginutils.RenderSuccess(c, blockatlas.DocsResponse{Docs: tl}) - }) -} - -// @Summary Get Metrics -// @ID metrics -// @Description Get application metrics -// @Tags metrics -// @Router /metrics [get] -func MakeMetricsRoute(router gin.IRouter) { - router.Use(metrics.PromMiddleware()) - m := router.Group("/metrics") - m.Use(ginutils.TokenAuthMiddleware(viper.GetString("metrics.api_token"))) - m.GET("/", ginprom.PromHandler(promhttp.Handler())) -} - -func emptyPage(c *gin.Context) { - var page blockatlas.TxPage - ginutils.RenderSuccess(c, &page) -} diff --git a/api/maketdata.go b/api/maketdata.go deleted file mode 100644 index b4049f257..000000000 --- a/api/maketdata.go +++ /dev/null @@ -1,204 +0,0 @@ -package api - -import ( - "github.com/gin-gonic/gin" - "github.com/spf13/viper" - "github.com/trustwallet/blockatlas/coin" - "github.com/trustwallet/blockatlas/marketdata" - "github.com/trustwallet/blockatlas/pkg/blockatlas" - "github.com/trustwallet/blockatlas/pkg/ginutils" - "github.com/trustwallet/blockatlas/storage" - "net/http" - "strconv" - "strings" -) - -const ( - defaultMaxChartItems = 64 -) - -type TickerRequest struct { - Currency string `json:"currency"` - Assets []Coin `json:"assets"` -} - -type Coin struct { - Coin uint `json:"coin"` - CoinType blockatlas.CoinType `json:"type"` - TokenId string `json:"token_id,omitempty"` -} - -func SetupMarketAPI(router gin.IRouter, db storage.Market) { - router.Use(ginutils.TokenAuthMiddleware(viper.GetString("market.auth"))) - // Ticker - router.GET("/ticker", getTickerHandler(db)) - router.POST("/ticker", getTickersHandler(db)) - // Charts - router.GET("/charts", getChartsHandler()) - router.GET("/info", getCoinInfoHandler()) -} - -// @Summary Get ticker value for a specific market -// @Id get_ticker -// @Description Get the ticker value from an market and coin/token -// @Accept json -// @Produce json -// @Tags ticker -// @Param coin query int true "coin id" -// @Param token query string false "token id" -// @Param currency query string false "the currency to show the quote" default(USD) -// @Success 200 {object} blockatlas.Ticker -// @Router /v1/market/ticker [get] -func getTickerHandler(storage storage.Market) func(c *gin.Context) { - if storage == nil { - return nil - } - return func(c *gin.Context) { - coinQuery := c.Query("coin") - coinId, err := strconv.Atoi(coinQuery) - if err != nil { - ginutils.RenderError(c, http.StatusInternalServerError, "Invalid coin") - return - } - token := c.Query("token") - - currency := c.DefaultQuery("currency", blockatlas.DefaultCurrency) - rate, err := storage.GetRate(strings.ToUpper(currency)) - if err != nil { - ginutils.RenderError(c, http.StatusInternalServerError, "Invalid currency") - return - } - - coinObj := coin.Coins[uint(coinId)] - result, err := storage.GetTicker(coinObj.Symbol, strings.ToUpper(token)) - if err != nil { - ginutils.RenderError(c, http.StatusInternalServerError, err.Error()) - return - } - result.ApplyRate(currency, rate.Rate, rate.PercentChange24h) - ginutils.RenderSuccess(c, result) - } -} - -// @Summary Get ticker values for a specific markets -// @Id get_tickers -// @Description Get the ticker values from many markets and coin/token -// @Accept json -// @Produce json -// @Tags ticker -// @Param tickers body api.TickerRequest true "Ticker" -// @Success 200 {object} blockatlas.Tickers -// @Router /v1/market/ticker [post] -func getTickersHandler(storage storage.Market) func(c *gin.Context) { - if storage == nil { - return nil - } - return func(c *gin.Context) { - md := TickerRequest{Currency: blockatlas.DefaultCurrency} - if err := c.BindJSON(&md); err != nil { - ginutils.ErrorResponse(c).Message(err.Error()).Render() - return - } - rate, err := storage.GetRate(strings.ToUpper(md.Currency)) - if err != nil { - ginutils.RenderError(c, http.StatusInternalServerError, "Invalid currency") - return - } - - tickers := make(blockatlas.Tickers, 0) - for _, coinRequest := range md.Assets { - coinObj, ok := coin.Coins[coinRequest.Coin] - if !ok { - continue - } - r, err := storage.GetTicker(coinObj.Symbol, strings.ToUpper(coinRequest.TokenId)) - if err != nil { - continue - } - r.ApplyRate(md.Currency, rate.Rate, rate.PercentChange24h) - r.SetCoinId(coinRequest.Coin) - tickers = append(tickers, r) - } - - ginutils.RenderSuccess(c, blockatlas.TickerResponse{Currency: md.Currency, Docs: tickers}) - } -} - -// @Summary Get charts data for a specific coin -// @Id get_charts_data -// @Description Get the charts data from an market and coin/token -// @Accept json -// @Produce json -// @Tags charts -// @Param coin query int true "Coin ID" default(60) -// @Param token query string false "Token ID" -// @Param time_start query int false "Start timestamp" default(1574483028) -// @Param max_items query int false "Max number of items in result prices array" default(64) -// @Param currency query string false "The currency to show charts" default(USD) -// @Success 200 {object} blockatlas.ChartData -// @Router /v1/market/charts [get] -func getChartsHandler() func(c *gin.Context) { - var charts = marketdata.InitCharts() - return func(c *gin.Context) { - coinQuery := c.Query("coin") - coinId, err := strconv.Atoi(coinQuery) - if err != nil { - ginutils.RenderError(c, http.StatusInternalServerError, "Invalid coin") - return - } - token := c.Query("token") - - timeStart, err := strconv.ParseInt(c.Query("time_start"), 10, 64) - if err != nil { - ginutils.RenderError(c, http.StatusInternalServerError, "Invalid time_start") - return - } - maxItems, err := strconv.Atoi(c.Query("max_items")) - if err != nil || maxItems <= 0 { - maxItems = defaultMaxChartItems - } - - currency := c.DefaultQuery("currency", blockatlas.DefaultCurrency) - - chart, err := charts.GetChartData(uint(coinId), token, currency, timeStart, maxItems) - if err != nil { - ginutils.RenderError(c, http.StatusInternalServerError, err.Error()) - return - } - ginutils.RenderSuccess(c, chart) - } -} - -// @Summary Get charts coin info data for a specific coin -// @Id get_charts_coin_info -// @Description Get the charts coin info data from an market and coin/contract -// @Accept json -// @Produce json -// @Tags charts -// @Param coin query int true "Coin ID" default(60) -// @Param token query string false "Token ID" -// @Param time_start query int false "Start timestamp" default(1574483028) -// @Param currency query string false "The currency to show coin info in" default(USD) -// @Success 200 {object} blockatlas.ChartCoinInfo -// @Router /v1/market/info [get] -func getCoinInfoHandler() func(c *gin.Context) { - var charts = marketdata.InitCharts() - return func(c *gin.Context) { - coinQuery := c.Query("coin") - coinId, err := strconv.Atoi(coinQuery) - if err != nil { - ginutils.RenderError(c, http.StatusInternalServerError, "Invalid coin") - return - } - token := c.Query("token") - - currency := c.DefaultQuery("currency", blockatlas.DefaultCurrency) - - chart, err := charts.GetCoinInfo(uint(coinId), token, currency) - if err != nil { - ginutils.RenderError(c, http.StatusInternalServerError, err.Error()) - return - } - ginutils.RenderSuccess(c, chart) - } -} diff --git a/api/meta.go b/api/meta.go deleted file mode 100644 index 2d9a67843..000000000 --- a/api/meta.go +++ /dev/null @@ -1,30 +0,0 @@ -package api - -import ( - "github.com/gin-gonic/gin" - "github.com/trustwallet/blockatlas/pkg/ginutils" -) - -func GetRoot(c *gin.Context) { - ginutils.RenderSuccess(c, - `Welcome to the Block Atlas API! - -Don't know how you landed here? -Visit https://trustwallet.com to get back to the main page. - -If you know what you're doing: - - Visit /v1/ to list platforms - - Source: https://github.com/trustwallet/blockatlas - - Any questions? https://t.me/walletcore -`) -} - -func getEnabledEndpoints(c *gin.Context) { - var resp struct { - Endpoints []string `json:"endpoints,omitempty"` - } - for handle := range routers { - resp.Endpoints = append(resp.Endpoints, handle) - } - ginutils.RenderSuccess(c, &resp) -} diff --git a/api/naming_service.go b/api/naming_service.go deleted file mode 100644 index b54917306..000000000 --- a/api/naming_service.go +++ /dev/null @@ -1,120 +0,0 @@ -package api - -import ( - "github.com/trustwallet/blockatlas/pkg/errors" - "net/http" - "strconv" - "strings" - - "github.com/trustwallet/blockatlas/pkg/ginutils" - - "github.com/gin-gonic/gin" - CoinType "github.com/trustwallet/blockatlas/coin" - "github.com/trustwallet/blockatlas/pkg/blockatlas" - "github.com/trustwallet/blockatlas/platform" -) - -var TLDMapping = map[string]uint64{} - -type LookupBatchPage []blockatlas.Resolved - -// @Summary Lookup .eth / .zil addresses -// @ID lookup -// @Description Lookup ENS/ZNS to find registered addresses -// @Produce json -// @Tags ns -// @Param name query string empty "string name" -// @Param coin query string 60 "string coin" -// @Success 200 {object} blockatlas.Resolved -// @Failure 500 {object} ginutils.ApiError -// @Router /ns/lookup [get] -func MakeLookupRoute(router gin.IRouter) { - router.GET("/lookup", func(c *gin.Context) { - name := c.Query("name") - coinQuery := c.Query("coin") - coin, err := strconv.ParseUint(coinQuery, 10, 64) - if err != nil { - ginutils.RenderError(c, http.StatusBadRequest, "coin query is invalid") - return - } - - result, err := handleLookup(name, []uint64{coin}) - if err != nil { - ginutils.RenderError(c, http.StatusBadRequest, err.Error()) - return - } - if len(result) == 0 { - ginutils.RenderError(c, http.StatusBadRequest, errors.E("name not found", errors.Params{"coin": coin, "name": name}).Error()) - return - } - ginutils.RenderSuccess(c, result[0]) - }) - - TLDMapping[".eth"] = CoinType.ETH - TLDMapping[".xyz"] = CoinType.ETH - TLDMapping[".luxe"] = CoinType.ETH - TLDMapping[".zil"] = CoinType.ZIL - // it's on ethereum but same unstoppable api - TLDMapping[".crypto"] = CoinType.ZIL -} - -// @Summary Lookup .eth / .zil addresses -// @ID lookup -// @Description Lookup ENS/ZNS to find registered addresses for multiple coins -// @Produce json -// @Tags ns -// @Param name query string empty "string name" -// @Param coins query string true "List of coins" -// @Success 200 {array} blockatlas.Resolved -// @Failure 500 {object} ginutils.ApiError -// @Router /v2/ns/lookup [get] -func MakeLookupBatchRoute(router gin.IRouter) { - router.GET("/lookup", func(c *gin.Context) { - name := c.Query("name") - coinsRaw := strings.Split(c.Query("coins"), ",") - coins, err := sliceAtoi(coinsRaw) - - if err != nil { - ginutils.RenderError(c, http.StatusBadRequest, "coin query is invalid") - return - } - - result, err := handleLookup(name, coins) - if err != nil { - ginutils.RenderError(c, http.StatusBadRequest, err.Error()) - return - } - if len(result) == 0 { - ginutils.RenderError(c, http.StatusBadRequest, errors.E("name not found", errors.Params{"name": name}).Error()) - return - } - ginutils.RenderSuccess(c, result) - }) -} - -func sliceAtoi(sa []string) ([]uint64, error) { - si := make([]uint64, 0, len(sa)) - for _, a := range sa { - i, err := strconv.ParseUint(a, 10, 64) - if err != nil { - return si, err - } - si = append(si, i) - } - return si, nil -} - -func handleLookup(name string, coins []uint64) (result []blockatlas.Resolved, err error) { - name = strings.ToLower(name) - for tld, id := range TLDMapping { - if strings.HasSuffix(name, tld) { - api := platform.NamingAPIs[id] - result, err = api.Lookup(coins, name) - if err != nil { - return - } - return - } - } - return nil, errors.E("name not found", errors.Params{"name": name}) -} diff --git a/api/observer.go b/api/observer.go deleted file mode 100644 index 76ec28191..000000000 --- a/api/observer.go +++ /dev/null @@ -1,132 +0,0 @@ -package api - -import ( - "github.com/gin-gonic/gin" - "github.com/spf13/viper" - "github.com/trustwallet/blockatlas/pkg/blockatlas" - "github.com/trustwallet/blockatlas/pkg/ginutils" - "github.com/trustwallet/blockatlas/platform" - "github.com/trustwallet/blockatlas/storage" - "strconv" -) - -func SetupObserverAPI(router gin.IRouter, db *storage.Storage) { - router.Use(ginutils.TokenAuthMiddleware(viper.GetString("observer.auth"))) - router.POST("/webhook/register", addCall(db)) - router.DELETE("/webhook/register", deleteCall(db)) - router.GET("/status", statusCall(db)) -} - -// @Summary Create a webhook -// @ID create_webhook -// @Description Create a webhook for addresses transactions -// @Accept json -// @Produce json -// @Tags observer,subscriptions -// @Param subscriptions body blockatlas.Webhook true "Accounts subscriptions" -// @Param Authorization header string true "Bearer authorization header" default(Bearer test) -// @Header 200 {string} Authorization {token} -// @Success 200 {object} blockatlas.Observer -// @Router /observer/v1/webhook/register [post] -func addCall(storage storage.Addresses) func(c *gin.Context) { - if storage == nil { - return nil - } - return func(c *gin.Context) { - var req blockatlas.Webhook - if c.BindJSON(&req) != nil { - return - } - - if len(req.Subscriptions) == 0 { - ginutils.RenderSuccess(c, blockatlas.Observer{Message: "Added", Status: true}) - return - } - subs := parseSubscriptions(req.Subscriptions, req.Webhook) - go storage.AddSubscriptions(subs) - - ginutils.RenderSuccess(c, blockatlas.Observer{Message: "Added", Status: true}) - } -} - -// @Summary Delete a webhook -// @ID delete_webhook -// @Description Delete a webhook for addresses transactions -// @Accept json -// @Produce json -// @Tags observer,subscriptions -// @Param subscriptions body blockatlas.Webhook true "Accounts subscriptions" -// @Param Authorization header string true "Bearer authorization header" default(Bearer test) -// @Header 200 {string} Authorization {token} -// @Success 200 {object} blockatlas.Observer -// @Router /observer/v1/webhook/register [delete] -func deleteCall(storage storage.Addresses) func(c *gin.Context) { - if storage == nil { - return nil - } - return func(c *gin.Context) { - var req blockatlas.Webhook - if c.BindJSON(&req) != nil { - return - } - - if len(req.Subscriptions) == 0 { - ginutils.RenderSuccess(c, blockatlas.Observer{Message: "Deleted", Status: true}) - return - } - - subs := parseSubscriptions(req.Subscriptions, req.Webhook) - go storage.DeleteSubscriptions(subs) - ginutils.RenderSuccess(c, blockatlas.Observer{Message: "Deleted", Status: true}) - } -} - -// @Summary Get coin status -// @ID coin_status -// @Description Get coin status -// @Accept json -// @Produce json -// @Tags observer,subscriptions -// @Param Authorization header string true "Bearer authorization header" default(Bearer test) -// @Header 200 {string} Authorization {token} -// @Success 200 {object} blockatlas.CoinStatus -// @Router /observer/v1/status [get] -func statusCall(storage storage.Tracker) func(c *gin.Context) { - if storage == nil { - return nil - } - return func(c *gin.Context) { - result := make(map[string]blockatlas.CoinStatus) - for _, api := range platform.BlockAPIs { - coin := api.Coin() - num, err := storage.GetBlockNumber(coin.ID) - var status blockatlas.CoinStatus - if err != nil { - status = blockatlas.CoinStatus{Error: err.Error()} - } else if num == 0 { - status = blockatlas.CoinStatus{Error: "no blocks"} - } else { - status = blockatlas.CoinStatus{Height: num} - } - result[coin.Handle] = status - } - ginutils.RenderSuccess(c, result) - } -} - -func parseSubscriptions(subscriptions map[string][]string, webhook string) (subs []blockatlas.Subscription) { - for coinStr, perCoin := range subscriptions { - coin, err := strconv.Atoi(coinStr) - if err != nil { - continue - } - for _, addr := range perCoin { - subs = append(subs, blockatlas.Subscription{ - Coin: uint(coin), - Address: addr, - Webhook: webhook, - }) - } - } - return -} diff --git a/api/observer_test.go b/api/observer_test.go deleted file mode 100644 index d2e1e7831..000000000 --- a/api/observer_test.go +++ /dev/null @@ -1,71 +0,0 @@ -package api - -import ( - "github.com/stretchr/testify/assert" - "github.com/trustwallet/blockatlas/pkg/blockatlas" - "sort" - "testing" -) - -func Test_parseSubscriptions(t *testing.T) { - tests := []struct { - name string - subscriptions map[string][]string - webhook string - wantSubs []blockatlas.Subscription - }{ - { - name: "webhook with 2 coins", - subscriptions: map[string][]string{ - "2": {"zpub6rH4MwgyTmuexAX6HAraks5cKv5BbtmwdLirvnU5845ovUJb4abgjt9DtXK4ZEaToRrNj8dQznuLC6Nka4eMviGMinCVMUxKLpuyddcG9Vc"}, - "0": {"xpub6BpYi6J1GZzfY3yY7DbhLLccF3efQa18nQngM3jaehgtNSoEgk6UtPULpC3oK5oA3trczY8Ld34LFw1USMPfGHwTEizdD5QyGcMyuh2UoBA", "xpub6CYwPfnPJLPquufPkb98coSb3mdy1CgaZrWUtYWGJTJ4VWZUbzH9HLGy7nHpP7DG4UdTkYYpirkTWQSP7pWHsrk24Nos5oYNHpfr4BgPVTL"}, - }, - webhook: "http://127.0.0.1:8080", - wantSubs: []blockatlas.Subscription{ - { - Coin: 2, Webhook: "http://127.0.0.1:8080", - Address: "zpub6rH4MwgyTmuexAX6HAraks5cKv5BbtmwdLirvnU5845ovUJb4abgjt9DtXK4ZEaToRrNj8dQznuLC6Nka4eMviGMinCVMUxKLpuyddcG9Vc", - }, - { - Coin: 0, Webhook: "http://127.0.0.1:8080", - Address: "xpub6BpYi6J1GZzfY3yY7DbhLLccF3efQa18nQngM3jaehgtNSoEgk6UtPULpC3oK5oA3trczY8Ld34LFw1USMPfGHwTEizdD5QyGcMyuh2UoBA", - }, - { - Coin: 0, Webhook: "http://127.0.0.1:8080", - Address: "xpub6CYwPfnPJLPquufPkb98coSb3mdy1CgaZrWUtYWGJTJ4VWZUbzH9HLGy7nHpP7DG4UdTkYYpirkTWQSP7pWHsrk24Nos5oYNHpfr4BgPVTL", - }, - }, - }, { - name: "webhook with 1 coin", - subscriptions: map[string][]string{ - "0": {"xpub6BpYi6J1GZzfY3yY7DbhLLccF3efQa18nQngM3jaehgtNSoEgk6UtPULpC3oK5oA3trczY8Ld34LFw1USMPfGHwTEizdD5QyGcMyuh2UoBA", "xpub6CYwPfnPJLPquufPkb98coSb3mdy1CgaZrWUtYWGJTJ4VWZUbzH9HLGy7nHpP7DG4UdTkYYpirkTWQSP7pWHsrk24Nos5oYNHpfr4BgPVTL"}, - }, - webhook: "http://127.0.0.1:8080", - wantSubs: []blockatlas.Subscription{ - { - Coin: 0, Webhook: "http://127.0.0.1:8080", - Address: "xpub6BpYi6J1GZzfY3yY7DbhLLccF3efQa18nQngM3jaehgtNSoEgk6UtPULpC3oK5oA3trczY8Ld34LFw1USMPfGHwTEizdD5QyGcMyuh2UoBA", - }, - { - Coin: 0, Webhook: "http://127.0.0.1:8080", - Address: "xpub6CYwPfnPJLPquufPkb98coSb3mdy1CgaZrWUtYWGJTJ4VWZUbzH9HLGy7nHpP7DG4UdTkYYpirkTWQSP7pWHsrk24Nos5oYNHpfr4BgPVTL", - }, - }, - }, - } - - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - gotSubs := parseSubscriptions(tt.subscriptions, tt.webhook) - sort.Slice(gotSubs, func(i, j int) bool { - return gotSubs[i].Coin > gotSubs[j].Coin - }) - sort.Slice(tt.wantSubs, func(i, j int) bool { - return tt.wantSubs[i].Coin > tt.wantSubs[j].Coin - }) - if !assert.ObjectsAreEqualValues(tt.wantSubs, gotSubs) { - t.Errorf("parseSubscriptions() = %v, want %v", gotSubs, tt.wantSubs) - } - }) - } -} diff --git a/api/registry.go b/api/registry.go new file mode 100644 index 000000000..65345ec82 --- /dev/null +++ b/api/registry.go @@ -0,0 +1,111 @@ +package api + +import ( + "time" + + "github.com/gin-gonic/gin" + "github.com/trustwallet/blockatlas/api/endpoint" + "github.com/trustwallet/blockatlas/pkg/blockatlas" + "github.com/trustwallet/blockatlas/platform" + "github.com/trustwallet/blockatlas/services/tokenindexer" + "github.com/trustwallet/golibs/network/middleware" +) + +func RegisterTransactionsAPI(router gin.IRouter, api blockatlas.Platform) { + handle := api.Coin().Handle + txUtxoAPI, ok := api.(blockatlas.TxUtxoAPI) + if ok { + router.GET("/v1/"+handle+"/address/:address", func(c *gin.Context) { + endpoint.GetTransactionsHistory(c, txUtxoAPI, nil) + }) + router.GET("/v1/"+handle+"/xpub/:xpub", func(c *gin.Context) { + endpoint.GetTransactionsByXpub(c, txUtxoAPI) + }) + router.GET("/v2/"+handle+"/transactions/xpub/:xpub", func(c *gin.Context) { + endpoint.GetTransactionsByXpub(c, txUtxoAPI) + }) + return + } + txAPI, okTxApi := api.(blockatlas.TxAPI) + tokenTxAPI, okTokenTxApi := api.(blockatlas.TokenTxAPI) + if okTxApi || okTokenTxApi { + router.GET("/v1/"+handle+"/:address", func(c *gin.Context) { + endpoint.GetTransactionsHistory(c, txAPI, tokenTxAPI) + }) + router.GET("/v2/"+handle+"/transactions/:address", func(c *gin.Context) { + endpoint.GetTransactionsHistory(c, txAPI, tokenTxAPI) + }) + } +} + +func RegisterBlockAPI(router gin.IRouter, api blockatlas.Platform) { + handle := api.Coin().Handle + if blockAPI, ok := api.(blockatlas.BlockAPI); ok { + router.GET("/v2/"+handle+"/blocks/:block", func(c *gin.Context) { + endpoint.GetBlock(c, blockAPI) + }) + } +} + +func RegisterTokensAPI(router gin.IRouter, api blockatlas.Platform) { + tokenAPI, ok := api.(blockatlas.TokensAPI) + if !ok { + return + } + handle := tokenAPI.Coin().Handle + router.GET("/v2/"+handle+"/tokens/:address", func(c *gin.Context) { + endpoint.GetTokensByAddress(c, tokenAPI) + }) + router.GET("/v2/"+handle+"/tokens/:address/ids", func(c *gin.Context) { + endpoint.GetTokensIdsByAddress(c, tokenAPI) + }) +} + +func RegisterStakeAPI(router gin.IRouter, api blockatlas.Platform) { + stakeAPI, ok := api.(blockatlas.StakeAPI) + if !ok { + return + } + handle := api.Coin().Handle + router.GET("/v2/"+handle+"/staking/validators", middleware.CacheMiddleware(time.Hour, func(c *gin.Context) { + endpoint.GetValidators(c, stakeAPI) + })) + router.GET("/v2/"+handle+"/staking/delegations/:address", func(c *gin.Context) { + endpoint.GetStakingDelegationsForSpecificCoin(c, stakeAPI) + }) +} + +func RegisterCollectionsAPI(router gin.IRouter, api blockatlas.CollectionsAPI) { + handle := api.Coin().Handle + router.GET("/v4/"+handle+"/collections/:owner/collection/:collection_id", func(c *gin.Context) { + endpoint.GetCollectiblesForSpecificCollectionAndOwner(c, api) + }) +} + +func RegisterBatchAPI(router gin.IRouter) { + router.GET("/v3/staking/list", middleware.CacheMiddleware(time.Hour*10, func(c *gin.Context) { + endpoint.GetStakeInfoForCoins(c, platform.StakeAPIs) + })) + router.POST("/v2/staking/delegations", func(c *gin.Context) { + endpoint.GetStakeDelegationsWithAllInfoForBatch(c, platform.StakeAPIs) + }) + router.POST("/v2/staking/list", middleware.CacheMiddleware(time.Hour, func(c *gin.Context) { + endpoint.GetStakeInfoForBatch(c, platform.StakeAPIs) + })) + router.POST("/v4/collectibles/categories", func(c *gin.Context) { + endpoint.GetCollectionCategoriesFromList(c, platform.CollectionsAPIs) + }) +} + +func RegisterBasicAPI(router gin.IRouter) { + router.GET("/", endpoint.GetStatus) +} + +func RegisterTokensIndexAPI(router gin.IRouter, instance tokenindexer.Instance) { + router.GET("/v3/tokens/new", func(c *gin.Context) { + endpoint.GetNewTokens(c, instance) + }) + router.POST("/v1/assets/associations", func(c *gin.Context) { + endpoint.GetTokensByAddressV3(c, instance) + }) +} diff --git a/api/routes.go b/api/routes.go deleted file mode 100644 index 9105d6d97..000000000 --- a/api/routes.go +++ /dev/null @@ -1,82 +0,0 @@ -package api - -import ( - "fmt" - "github.com/gin-gonic/gin" - "github.com/trustwallet/blockatlas/pkg/logger" - "github.com/trustwallet/blockatlas/platform" -) - -var routers = make(map[string]gin.IRouter) - -func LoadPlatforms(root gin.IRouter) { - v1 := root.Group("/v1") - v2 := root.Group("/v2") - v3 := root.Group("/v3") - - for _, txAPI := range platform.Platforms { - router := getRouter(v1, txAPI.Coin().Handle) - makeTxRouteV1(router, txAPI) - - routerV2 := getRouter(v2, txAPI.Coin().Handle) - makeTxRouteV2(routerV2, txAPI) - } - - for _, tokenAPI := range platform.Platforms { - router := getRouter(v2, tokenAPI.Coin().Handle) - makeTokenRoute(router, tokenAPI) - } - - for _, stakeAPI := range platform.Platforms { - router := getRouter(v2, stakeAPI.Coin().Handle) - makeStakingValidatorsRoute(router, stakeAPI) - makeStakingDelegationsRoute(router, stakeAPI) - } - - for _, collectionAPI := range platform.Platforms { - routerv2 := getRouter(v2, collectionAPI.Coin().Handle) - routerv3 := getRouter(v3, collectionAPI.Coin().Handle) - - makeCollectionsRoute(routerv3, collectionAPI) - makeCollectionRoute(routerv3, collectionAPI) - - //TODO: remove once most of the clients will be updated (deadline: March 17th) - oldMakeCollectionRoute(routerv2, collectionAPI) - oldMakeCollectionsRoute(routerv2, collectionAPI) - } - - for _, customAPI := range platform.CustomAPIs { - router := getRouter(v1, customAPI.Coin().Handle) - customAPI.RegisterRoutes(router) - } - - { - ns := root.Group("/ns") - batchNs := v2.Group("/ns") - MakeLookupRoute(ns) - MakeLookupBatchRoute(batchNs) - } - - //TODO: remove once most of the clients will be updated (deadline: March 17th) - oldMakeCategoriesBatchRoute(v2) - makeCategoriesBatchRoute(v3) - makeStakingDelegationsBatchRoute(v2) - makeStakingDelegationsSimpleBatchRoute(v2) - - logger.Info("Routes set up", logger.Params{"routes": len(routers)}) - v1.GET("/", getEnabledEndpoints) -} - -// getRouter lazy loads routers -func getRouter(router *gin.RouterGroup, handle string) gin.IRouter { - key := fmt.Sprintf("%s/%s", router.BasePath(), handle) - if group, ok := routers[key]; ok { - return group - } else { - path := fmt.Sprintf("/%s", handle) - logger.Debug("Registering route", logger.Params{"path": len(path)}) - group := router.Group(path) - routers[key] = group - return group - } -} diff --git a/app.json b/app.json index af57abd51..a06ef2b75 100644 --- a/app.json +++ b/app.json @@ -1,22 +1,26 @@ { - "name": "Block Atlas", - "description": "Block Atlas blockchain API by Trust Wallet", - "keywords": [ - "blockatlas", - "trustwallet" + "name": "blockatlas", + "buildpacks":[ + { + "url":"heroku/go" + } + ], + "addons": [ + "heroku-postgresql:hobby-dev", + "cloudamqp" ], - "website": "https://github.com/trustwallet/blockatlas", - "repository": "https://github.com/trustwallet/blockatlas", - "logo": "https://avatars0.githubusercontent.com/u/32179889", - "success_url": "/v1/", - "formation": { - "web": { - "quantity": 1, - "size": "Free" - }, - "observer": { - "quantity": 1, - "size": "Free" + "environments": { + "review": { + "addons": [ + { + "plan":"heroku-postgresql:hobby-dev", + "as":"POSTGRES" + }, + { + "plan":"cloudamqp:lemur", + "as":"OBSERVER_RABBITMQ" + } + ] } } } diff --git a/azure-pipelines.yml b/azure-pipelines.yml deleted file mode 100644 index 8744d1279..000000000 --- a/azure-pipelines.yml +++ /dev/null @@ -1,52 +0,0 @@ -pool: - vmImage: 'Ubuntu 16.04' - -variables: - GOBIN: '$(GOPATH)/bin' # Go binaries path - GOROOT: '/usr/local/go1.13' # Go installation path - GOPATH: '$(system.defaultWorkingDirectory)/gopath' # Go workspace path - modulePath: '$(GOPATH)/src/github.com/trustwallet/blockatlas' # Path to the module's code - -steps: - - script: | - mkdir -p '$(GOBIN)' - mkdir -p '$(GOPATH)/pkg' - mkdir -p '$(modulePath)' - shopt -s extglob - shopt -s dotglob - mv !(gopath) '$(modulePath)' - echo '##vso[task.prependpath]$(GOBIN)' - echo '##vso[task.prependpath]$(GOROOT)/bin' - echo '$(go env)' - displayName: 'Set up the Go workspace' - - - task: CacheBeta@1 - inputs: - key: 'go | "$(Agent.OS)" | **/go.mod' - restoreKeys: | - go | "$(Agent.OS)" - go - path: | - $(GOPATH) - !$(modulePath) - displayName: 'Cache go packages' - - - script: | - go version - go get -v -t -d ./... - workingDirectory: '$(modulePath)' - displayName: 'Get dependencies' - - - script: make test - workingDirectory: '$(modulePath)' - displayName: 'Run unit tests' - - - script: | - go get github.com/gavv/httpexpect - make integration - workingDirectory: '$(modulePath)' - displayName: 'Run integration tests' - - - script: go build -v . - workingDirectory: '$(modulePath)' - displayName: 'Build' diff --git a/cmd/api.go b/cmd/api.go deleted file mode 100644 index 4a3dfb178..000000000 --- a/cmd/api.go +++ /dev/null @@ -1,79 +0,0 @@ -package cmd - -import ( - sentrygin "github.com/getsentry/sentry-go/gin" - "github.com/gin-gonic/gin" - "github.com/spf13/cobra" - "github.com/spf13/viper" - swaggerFiles "github.com/swaggo/files" - ginSwagger "github.com/swaggo/gin-swagger" - "github.com/trustwallet/blockatlas/api" - _ "github.com/trustwallet/blockatlas/docs" - "github.com/trustwallet/blockatlas/pkg/ginutils" - "github.com/trustwallet/blockatlas/pkg/logger" -) - -var apiCmd = &cobra.Command{ - Use: "api ", - Short: "API server", - Args: cobra.MaximumNArgs(1), - Run: runApi, -} - -func runApi(_ *cobra.Command, args []string) { - var bind string - if len(args) == 0 { - bind = ":8420" - } else { - bind = args[0] - } - RunApi(bind, nil) -} - -func RunApi(bind string, c chan *gin.Engine) { - gin.SetMode(viper.GetString("gin.mode")) - engine := gin.Default() - - sg := sentrygin.New(sentrygin.Options{}) - engine.Use(ginutils.CheckReverseProxy, sg) - - engine.Use(ginutils.CORSMiddleware()) - engine.OPTIONS("/*path", ginutils.CORSMiddleware()) - - engine.GET("swagger/*any", ginSwagger.WrapHandler(swaggerFiles.Handler)) - - engine.GET("/", api.GetRoot) - engine.GET("/status", func(c *gin.Context) { - ginutils.RenderSuccess(c, map[string]interface{}{ - "status": true, - }) - }) - - api.MakeMetricsRoute(engine) - api.LoadPlatforms(engine) - - if viper.GetBool("observer.enabled") { - logger.Info("Loading observer API") - observerAPI := engine.Group("/observer/v1") - api.SetupObserverAPI(observerAPI, Storage) - } - - if viper.GetBool("market.enabled") { - logger.Info("Loading market API") - marketAPI := engine.Group("/v1/market") - api.SetupMarketAPI(marketAPI, Storage) - } - - if c != nil { - c <- engine - } - - logger.Info("Running application", logger.Params{"bind": bind}) - if err := engine.Run(bind); err != nil { - logger.Fatal("Application failed", err) - } -} - -func init() { - rootCmd.AddCommand(apiCmd) -} diff --git a/cmd/api/main.go b/cmd/api/main.go new file mode 100644 index 000000000..303bd3ddf --- /dev/null +++ b/cmd/api/main.go @@ -0,0 +1,69 @@ +package main + +import ( + "context" + + "github.com/trustwallet/blockatlas/internal/metrics" + + golibsGin "github.com/trustwallet/golibs/network/gin" + + "github.com/trustwallet/golibs/network/middleware" + + "github.com/gin-gonic/gin" + log "github.com/sirupsen/logrus" + "github.com/trustwallet/blockatlas/api" + "github.com/trustwallet/blockatlas/config" + "github.com/trustwallet/blockatlas/db" + _ "github.com/trustwallet/blockatlas/docs" + "github.com/trustwallet/blockatlas/internal" + "github.com/trustwallet/blockatlas/platform" + "github.com/trustwallet/blockatlas/services/tokenindexer" +) + +const ( + defaultPort = "8420" + defaultConfigPath = "../../config.yml" +) + +var ( + ctx context.Context + cancel context.CancelFunc + port, confPath string + engine *gin.Engine + database *db.Instance + tokenIndexer tokenindexer.Instance +) + +func init() { + port, confPath = internal.ParseArgs(defaultPort, defaultConfigPath) + ctx, cancel = context.WithCancel(context.Background()) + var err error + + internal.InitConfig(confPath) + + if err := middleware.SetupSentry(config.Default.Sentry.DSN); err != nil { + log.Error(err) + } + + engine = internal.InitEngine(config.Default.Gin.Mode) + platform.Init(config.Default.Platform) + + database, err = db.New(config.Default.Postgres.URL, config.Default.Postgres.Log) + if err != nil { + log.Fatal(err) + } + + metrics.Setup(database) + + tokenIndexer = tokenindexer.Init(database) +} + +func main() { + api.SetupTokensIndexAPI(engine, tokenIndexer) + api.SetupSwaggerAPI(engine) + api.SetupPlatformAPI(engine) + api.SetupMetrics(engine) + + golibsGin.SetupGracefulShutdown(ctx, port, engine) + cancel() +} diff --git a/cmd/consumer/main.go b/cmd/consumer/main.go new file mode 100644 index 000000000..12dbb3c3d --- /dev/null +++ b/cmd/consumer/main.go @@ -0,0 +1,125 @@ +package main + +import ( + "context" + "time" + + "github.com/trustwallet/golibs/network/middleware" + + "github.com/trustwallet/blockatlas/platform" + + "github.com/trustwallet/golibs/network/mq" + + "github.com/trustwallet/blockatlas/services/tokenindexer" + + "github.com/trustwallet/blockatlas/services/notifier" + + "github.com/trustwallet/blockatlas/config" + "github.com/trustwallet/blockatlas/services/subscriber" + + log "github.com/sirupsen/logrus" + "github.com/trustwallet/blockatlas/db" + "github.com/trustwallet/blockatlas/internal" +) + +const ( + defaultConfigPath = "../../config.yml" +) + +var ( + ctx context.Context + cancel context.CancelFunc + database *db.Instance + + transactions = "transactions" + tokens = "tokens" + subscriptions = "subscriptions" + subscriptionsTokens = "subscriptions_tokens" +) + +func init() { + ctx, cancel = context.WithCancel(context.Background()) + _, confPath := internal.ParseArgs("", defaultConfigPath) + + internal.InitConfig(confPath) + + if err := middleware.SetupSentry(config.Default.Sentry.DSN); err != nil { + log.Error(err) + } + internal.InitMQ(config.Default.Observer.Rabbitmq.URL) + + var err error + database, err = db.New(config.Default.Postgres.URL, config.Default.Postgres.Log) + if err != nil { + log.Fatal("Postgres init: ", err) + } + + tokenindexer.Init(database) +} + +func main() { + defer mq.Close() + + // RunTokenIndexerSubscribe requires to fetch data from token apis. Improve later + platform.Init(config.Default.Platform) + + options := mq.InitDefaultConsumerOptions(config.Default.Consumer.Workers) + options.PrefetchLimit = config.Default.Consumer.Prefetch + // Special case options to avoid unknown deadlock on insert + subscriptionsOptions := mq.InitDefaultConsumerOptions(1) + + switch config.Default.Consumer.Service { + case transactions: + setupTransactionsConsumer(options, ctx) + case subscriptions: + setupSubscriptionsConsumer(subscriptionsOptions, ctx) + case subscriptionsTokens: + setupSubscriptionsTokensConsumer(options, ctx) + case tokens: + setupTokensConsumer(options, ctx) + default: + setupTransactionsConsumer(options, ctx) + setupSubscriptionsConsumer(subscriptionsOptions, ctx) + setupSubscriptionsTokensConsumer(options, ctx) + setupTokensConsumer(options, ctx) + } + + go mq.FatalWorker(time.Second * 10) + + middleware.SetupGracefulShutdown(time.Second * 5) + + cancel() +} + +func setupTransactionsConsumer(options mq.ConsumerOptions, ctx context.Context) { + go internal.RawTransactions.RunConsumer(internal.ConsumerDatabase{ + Database: database, + Delivery: notifier.RunNotifier, + Tag: transactions, + }, options, ctx) +} + +func setupSubscriptionsConsumer(options mq.ConsumerOptions, ctx context.Context) { + go internal.Subscriptions.RunConsumer(internal.ConsumerDatabase{ + Database: database, + Delivery: subscriber.RunSubscriber, + Tag: subscriptions, + }, options, ctx) +} + +func setupSubscriptionsTokensConsumer(options mq.ConsumerOptions, ctx context.Context) { + go internal.SubscriptionsTokens.RunConsumer(tokenindexer.ConsumerIndexer{ + Database: database, + TokensAPIs: platform.TokensAPIs, + Delivery: tokenindexer.RunTokenIndexerSubscribe, + Tag: subscriptionsTokens, + }, options, ctx) +} + +func setupTokensConsumer(options mq.ConsumerOptions, ctx context.Context) { + go internal.RawTokens.RunConsumer(internal.ConsumerDatabase{ + Database: database, + Delivery: tokenindexer.RunTokenIndexer, + Tag: tokens, + }, options, ctx) +} diff --git a/cmd/observer.go b/cmd/observer.go deleted file mode 100644 index 0d8b5aa48..000000000 --- a/cmd/observer.go +++ /dev/null @@ -1,87 +0,0 @@ -package cmd - -import ( - "context" - "github.com/spf13/cobra" - "github.com/spf13/viper" - "github.com/trustwallet/blockatlas/observer" - "github.com/trustwallet/blockatlas/pkg/logger" - "github.com/trustwallet/blockatlas/platform" - "sync" - "time" -) - -var observerCmd = &cobra.Command{ - Use: "observer", - Short: "Observer worker", - Args: cobra.NoArgs, - Run: runObserver, -} - -func runObserver(_ *cobra.Command, _ []string) { - if !viper.GetBool("observer.enabled") { - logger.Fatal("Observer is not enabled") - } - - if len(platform.BlockAPIs) == 0 { - logger.Fatal("No APIs to observe") - } - - minInterval := viper.GetDuration("observer.min_poll") - backlogTime := viper.GetDuration("observer.backlog") - - var wg sync.WaitGroup - wg.Add(len(platform.BlockAPIs)) - for _, api := range platform.BlockAPIs { - coin := api.Coin() - blockTime := time.Duration(coin.BlockTime) * time.Millisecond - pollInterval := blockTime / 4 - if pollInterval < minInterval { - pollInterval = minInterval - } - - // Stream incoming blocks - var backlogCount int - if coin.BlockTime == 0 { - backlogCount = 50 - logger.Warn("Unknown block time", logger.Params{"coin": coin.ID}) - } else { - backlogCount = int(backlogTime / blockTime) - } - stream := observer.Stream{ - BlockAPI: api, - Tracker: Storage, - PollInterval: pollInterval, - BacklogCount: backlogCount, - } - blocks := stream.Execute(context.Background()) - - // Check for transaction events - obs := observer.Observer{ - Storage: Storage, - Coin: coin.ID, - } - events := obs.Execute(blocks) - - // Dispatch events - dispatcher := observer.Dispatcher{} - go func() { - dispatcher.Run(events) - wg.Done() - }() - - logger.Info("Observing", logger.Params{ - "coin": coin, - "interval": pollInterval, - "backlog": backlogCount, - }) - } - - wg.Wait() - - logger.Info("Exiting cleanly") -} - -func init() { - rootCmd.AddCommand(observerCmd) -} diff --git a/cmd/parser/main.go b/cmd/parser/main.go new file mode 100644 index 000000000..b9eff7034 --- /dev/null +++ b/cmd/parser/main.go @@ -0,0 +1,120 @@ +package main + +import ( + "context" + "fmt" + "os" + "os/signal" + "sync" + "syscall" + "time" + + "github.com/trustwallet/golibs/network/middleware" + + "github.com/trustwallet/blockatlas/config" + + log "github.com/sirupsen/logrus" + "github.com/trustwallet/blockatlas/db" + "github.com/trustwallet/blockatlas/internal" + "github.com/trustwallet/blockatlas/platform" + "github.com/trustwallet/blockatlas/services/parser" + "github.com/trustwallet/golibs/network/mq" +) + +const ( + defaultConfigPath = "../../config.yml" +) + +var ( + ctx context.Context + cancel context.CancelFunc + database *db.Instance +) + +func init() { + ctx, cancel = context.WithCancel(context.Background()) + _, confPath := internal.ParseArgs("", defaultConfigPath) + + internal.InitConfig(confPath) + + if err := middleware.SetupSentry(config.Default.Sentry.DSN); err != nil { + log.Error(err) + } + + internal.InitMQ(config.Default.Observer.Rabbitmq.URL) + platform.Init(config.Default.Platform) + + if len(platform.BlockAPIs) == 0 { + log.Fatal("No APIs to observe") + } + + var err error + database, err = db.New(config.Default.Postgres.URL, config.Default.Postgres.Log) + if err != nil { + log.Fatal(err) + } +} + +func main() { + defer mq.Close() + var ( + wg sync.WaitGroup + coinCancel = make(map[string]context.CancelFunc) + stopChannel = make(chan<- struct{}, len(platform.BlockAPIs)) + ) + minInterval := config.Default.Observer.BlockPoll.Min + maxInterval := config.Default.Observer.BlockPoll.Max + fetchBlocksTimeout := config.Default.Observer.FetchBlocksInterval + maxBlocks := config.Default.Observer.BlockPoll.MaxBlocks + + go mq.FatalWorker(time.Second * 10) + + wg.Add(len(platform.BlockAPIs)) + for _, api := range platform.BlockAPIs { + coin := api.Coin() + pollInterval := parser.GetInterval(coin.BlockTime, minInterval, maxInterval) + + coinCancel[coin.Handle] = cancel + + params := parser.Params{ + Api: api, + TransactionsExchange: internal.RawTransactionsExchange, + ParsingBlocksInterval: pollInterval, + FetchBlocksTimeout: fetchBlocksTimeout, + MaxBlocks: maxBlocks, + StopChannel: stopChannel, + Database: database, + } + + go parser.RunParser(params, ctx) + + log.WithFields(log.Fields{ + "coin": api.Coin().Handle, + "interval": pollInterval, + "max blocks": maxBlocks, + "fetch blocks timeout": fetchBlocksTimeout, + }).Info("Parser params") + + wg.Done() + } + + wg.Wait() + + quit := make(chan os.Signal, 1) + signal.Notify(quit, syscall.SIGINT, syscall.SIGTERM) + <-quit + cancel() + log.Info("Shutdown parser ...") + for coin, cancel := range coinCancel { + log.Info(fmt.Sprintf("Starting to stop %s parser...", coin)) + cancel() + } + for { + if len(stopChannel) == len(platform.BlockAPIs) { + log.Info("All parsers are stopped") + break + } + } + + log.Info("Exiting gracefully") +} diff --git a/cmd/root.go b/cmd/root.go deleted file mode 100644 index cfacb17db..000000000 --- a/cmd/root.go +++ /dev/null @@ -1,60 +0,0 @@ -package cmd - -import ( - "github.com/spf13/cobra" - "github.com/spf13/viper" - "github.com/trustwallet/blockatlas/config" - "github.com/trustwallet/blockatlas/pkg/logger" - "github.com/trustwallet/blockatlas/platform" - "github.com/trustwallet/blockatlas/storage" - "os" - "os/signal" - "syscall" -) - -var ( - Storage = storage.New() - rootCmd = cobra.Command{ - Use: "blockatlas", - Short: "BlockAtlas by Trust Wallet", - PersistentPreRun: func(cmd *cobra.Command, args []string) { - // Load config - confPath, _ := cmd.Flags().GetString("config") - config.LoadConfig(confPath) - - // Init Logger - logger.InitLogger() - - // Load app components - platform.Init() - - // Init Storage - host := viper.GetString("storage.redis") - err := Storage.Init(host) - if err != nil { - logger.Fatal(err) - } - }, - } -) - -func init() { - rootCmd.PersistentFlags().StringP("config", "c", "", "Config file (optional)") -} - -// Execute adds all child commands to the root command and sets flags appropriately. -// This is called by main.main(). It only needs to happen once to the rootCmd. -func Execute() { - c := make(chan os.Signal, 1) - signal.Notify(c, syscall.SIGHUP, syscall.SIGINT, syscall.SIGTERM, syscall.SIGQUIT) - go func() { - sig := <-c - logger.Info("Got a signal. Aborting...", logger.Params{"code": sig}) - os.Exit(1) - }() - - if err := rootCmd.Execute(); err != nil { - logger.Error(err) - os.Exit(1) - } -} diff --git a/cmd/setup/main.go b/cmd/setup/main.go new file mode 100644 index 000000000..fb2da5a8e --- /dev/null +++ b/cmd/setup/main.go @@ -0,0 +1,69 @@ +package main + +import ( + "github.com/trustwallet/blockatlas/config" + "github.com/trustwallet/golibs/network/middleware" + "github.com/trustwallet/golibs/network/mq" + + log "github.com/sirupsen/logrus" + "github.com/trustwallet/blockatlas/db" + "github.com/trustwallet/blockatlas/internal" + "github.com/trustwallet/blockatlas/platform" +) + +const ( + defaultConfigPath = "../../config.yml" +) + +var ( + database *db.Instance +) + +func init() { + _, confPath := internal.ParseArgs("", defaultConfigPath) + + internal.InitConfig(confPath) + internal.InitMQ(config.Default.Observer.Rabbitmq.URL) + platform.Init(config.Default.Platform) + + var err error + database, err = db.New(config.Default.Postgres.URL, config.Default.Postgres.Log) + if err != nil { + log.Fatal(err) + } +} + +func main() { + log.Info("Start setup") + + if err := middleware.SetupSentry(config.Default.Sentry.DSN); err != nil { + log.Error(err) + } + + if err := db.Setup(database.Gorm); err != nil { + log.Fatal(err) + } + + if err := internal.RawTransactionsExchange.Declare("topic"); err != nil { + log.Fatal(err) + } + + queues := []mq.Queue{ + internal.TxNotifications, + internal.RawTransactions, + internal.Subscriptions, + internal.SubscriptionsTokens, + internal.RawTokens, + } + for _, queue := range queues { + if err := queue.Declare(); err != nil { + log.Fatal("Queue declare: ", queue, err) + } + } + + if err := internal.RawTransactionsExchange.Bind([]mq.Queue{internal.RawTokens, internal.RawTransactions}); err != nil { + log.Fatal("Transactions Exchange bind: ", err) + } + + log.Info("Finish setup") +} diff --git a/cmd/sync.go b/cmd/sync.go deleted file mode 100755 index 79729f16b..000000000 --- a/cmd/sync.go +++ /dev/null @@ -1,29 +0,0 @@ -package cmd - -import ( - "github.com/spf13/cobra" - "github.com/spf13/viper" - "github.com/trustwallet/blockatlas/marketdata" - "github.com/trustwallet/blockatlas/pkg/logger" -) - -var syncCmd = &cobra.Command{ - Use: "sync-markets", - Short: "Sync all markets prices and rates", - Args: cobra.NoArgs, - Run: syncMarketData, -} - -func syncMarketData(cmd *cobra.Command, args []string) { - if !viper.GetBool("market.enabled") { - logger.Fatal("Market is not enabled") - } - - marketdata.InitRates(Storage) - marketdata.InitMarkets(Storage) - <-make(chan bool) -} - -func init() { - rootCmd.AddCommand(syncCmd) -} diff --git a/coin/coins.go b/coin/coins.go deleted file mode 100644 index afb3bd298..000000000 --- a/coin/coins.go +++ /dev/null @@ -1,690 +0,0 @@ -// Code generated by go generate; DO NOT EDIT. -// This file was generated by robots at -// 2019-12-27 15:07:32.262554 +0800 CST m=+0.002000255 -// using data from coins.yml -package coin - -import ( - "fmt" -) - -// Coin is the native currency of a blockchain -type Coin struct { - ID uint - Handle string - Symbol string - Name string - Decimals uint - BlockTime int - MinConfirmations int64 - SampleAddr string -} - -func (c *Coin) String() string { - return fmt.Sprintf("[%s] %s (#%d)", c.Symbol, c.Name, c.ID) -} - -const ( - ETH = 60 - ETC = 61 - ICX = 74 - ATOM = 118 - XRP = 144 - XLM = 148 - POA = 178 - TRX = 195 - FIO = 235 - NIM = 242 - IOTX = 304 - ZIL = 313 - AION = 425 - AE = 457 - KAVA = 459 - THETA = 500 - BNB = 714 - VET = 818 - CLO = 820 - TOMO = 889 - TT = 1001 - ONT = 1024 - XTZ = 1729 - KIN = 2017 - NAS = 2718 - GO = 6060 - WAN = 5718350 - WAVES = 5741564 - SEM = 7562605 - BTC = 0 - LTC = 2 - DOGE = 3 - DASH = 5 - VIA = 14 - GRS = 17 - ZEC = 133 - XZC = 136 - BCH = 145 - RVN = 175 - QTUM = 2301 - ZEL = 19167 - DCR = 42 - ALGO = 283 - NANO = 165 - DGB = 20 - ONE = 1023 - KSM = 434 -) - -var Coins = map[uint]Coin{ - ETH: { - ID: 60, - Handle: "ethereum", - Symbol: "ETH", - Name: "Ethereum", - Decimals: 18, - BlockTime: 10000, - MinConfirmations: 0, - SampleAddr: "0xfc10cab6a50a1ab10c56983c80cc82afc6559cf1", - }, - ETC: { - ID: 61, - Handle: "classic", - Symbol: "ETC", - Name: "Ethereum Classic", - Decimals: 18, - BlockTime: 30000, - MinConfirmations: 0, - SampleAddr: "0xf3524415b6D873205B4c3Cda783527b2aC4daAA9", - }, - ICX: { - ID: 74, - Handle: "icon", - Symbol: "ICX", - Name: "ICON", - Decimals: 18, - BlockTime: 0, - MinConfirmations: 0, - SampleAddr: "hxee691e7bccc4eb11fee922896e9f51490e62b12e", - }, - ATOM: { - ID: 118, - Handle: "cosmos", - Symbol: "ATOM", - Name: "Cosmos", - Decimals: 6, - BlockTime: 5000, - MinConfirmations: 0, - SampleAddr: "cosmos1rw62phusuv9vzraezr55k0vsqssvz6ed52zyrl", - }, - XRP: { - ID: 144, - Handle: "ripple", - Symbol: "XRP", - Name: "Ripple", - Decimals: 6, - BlockTime: 5000, - MinConfirmations: 0, - SampleAddr: "rMQ98K56yXJbDGv49ZSmW51sLn94Xe1mu1", - }, - XLM: { - ID: 148, - Handle: "stellar", - Symbol: "XLM", - Name: "Stellar", - Decimals: 7, - BlockTime: 5000, - MinConfirmations: 0, - SampleAddr: "GDKIJJIKXLOM2NRMPNQZUUYK24ZPVFC6426GZAEP3KUK6KEJLACCWNMX", - }, - POA: { - ID: 178, - Handle: "poa", - Symbol: "POA", - Name: "Poa", - Decimals: 18, - BlockTime: 30000, - MinConfirmations: 0, - SampleAddr: "0x1fddEc96688e0538A316C64dcFd211c491ECf0d8", - }, - TRX: { - ID: 195, - Handle: "tron", - Symbol: "TRX", - Name: "Tron", - Decimals: 6, - BlockTime: 10000, - MinConfirmations: 0, - SampleAddr: "TMuA6YqfCeX8EhbfYEg5y7S4DqzSJireY9", - }, - FIO: { - ID: 235, - Handle: "fio", - Symbol: "FIO", - Name: "FIO", - Decimals: 9, - BlockTime: 0, - MinConfirmations: 0, - SampleAddr: "FIO5J2xdfWygeNdHZNZRzRws8YGbVxjUXtp4eP8KoGkGKoLFQ7CaU", - }, - NIM: { - ID: 242, - Handle: "nimiq", - Symbol: "NIM", - Name: "Nimiq", - Decimals: 5, - BlockTime: 60000, - MinConfirmations: 0, - SampleAddr: "NQ86 2H8F YGU5 RM77 QSN9 LYLH C56A CYYR 0MLA", - }, - IOTX: { - ID: 304, - Handle: "iotex", - Symbol: "IOTX", - Name: "IoTeX", - Decimals: 18, - BlockTime: 10000, - MinConfirmations: 0, - SampleAddr: "io1mwekae7qqwlr23220k5n9z3fmjxz72tuchra3m", - }, - ZIL: { - ID: 313, - Handle: "zilliqa", - Symbol: "ZIL", - Name: "Zilliqa", - Decimals: 12, - BlockTime: 30000, - MinConfirmations: 1, - SampleAddr: "zil1anrjcsj2ntklaa3arq4w3s6gw4l4hqrycs9egy", - }, - AION: { - ID: 425, - Handle: "aion", - Symbol: "AION", - Name: "Aion", - Decimals: 18, - BlockTime: 10000, - MinConfirmations: 0, - SampleAddr: "0xa07981da70ce919e1db5f051c3c386eb526e6ce8b9e2bfd56e3f3d754b0a17f3", - }, - AE: { - ID: 457, - Handle: "aeternity", - Symbol: "AE", - Name: "Aeternity", - Decimals: 18, - BlockTime: 6000, - MinConfirmations: 0, - SampleAddr: "ak_2p5878zbFhxnrm7meL7TmqwtvBaqcBddyp5eGzZbovZ5FeVfcw", - }, - KAVA: { - ID: 459, - Handle: "kava", - Symbol: "KAVA", - Name: "Kava", - Decimals: 6, - BlockTime: 5000, - MinConfirmations: 0, - SampleAddr: "kava13fxkk4730cqglgdv7w0mdelyx07myyq7h2nd3x", - }, - THETA: { - ID: 500, - Handle: "theta", - Symbol: "THETA", - Name: "Theta", - Decimals: 18, - BlockTime: 0, - MinConfirmations: 0, - SampleAddr: "0xac0eeb6ee3e32e2c74e14ac74155063e4f4f981f", - }, - BNB: { - ID: 714, - Handle: "binance", - Symbol: "BNB", - Name: "BNB", - Decimals: 8, - BlockTime: 4000, - MinConfirmations: 0, - SampleAddr: "tbnb1fhr04azuhcj0dulm7ka40y0cqjlafwae9k9gk2", - }, - VET: { - ID: 818, - Handle: "vechain", - Symbol: "VET", - Name: "VeChain Token", - Decimals: 18, - BlockTime: 20000, - MinConfirmations: 0, - SampleAddr: "0xB5e883349e68aB59307d1604555AC890fAC47128", - }, - CLO: { - ID: 820, - Handle: "callisto", - Symbol: "CLO", - Name: "Callisto", - Decimals: 18, - BlockTime: 10000, - MinConfirmations: 0, - SampleAddr: "0x39ec1c88a7a7c1a575e8c8f42eff7630d9278179", - }, - TOMO: { - ID: 889, - Handle: "tomochain", - Symbol: "TOMO", - Name: "TOMO", - Decimals: 18, - BlockTime: 4000, - MinConfirmations: 0, - SampleAddr: "0x7daa83030e3086477b79b6e757ca8608899fe783", - }, - TT: { - ID: 1001, - Handle: "thundertoken", - Symbol: "TT", - Name: "ThunderCore", - Decimals: 18, - BlockTime: 10000, - MinConfirmations: 0, - SampleAddr: "0x0ad80a408eac4f17ba0a9de8a12d8736f60700c3", - }, - ONT: { - ID: 1024, - Handle: "ontology", - Symbol: "ONT", - Name: "Ontology", - Decimals: 0, - BlockTime: 0, - MinConfirmations: 0, - SampleAddr: "AUyL4TZ1zFEcSKDJrjFnD7vsq5iFZMZqT7", - }, - XTZ: { - ID: 1729, - Handle: "tezos", - Symbol: "XTZ", - Name: "Tezos", - Decimals: 6, - BlockTime: 20000, - MinConfirmations: 0, - SampleAddr: "tz1WCd2jm4uSt4vntk4vSuUWoZQGhLcDuR9q", - }, - KIN: { - ID: 2017, - Handle: "kin", - Symbol: "KIN", - Name: "Kin", - Decimals: 5, - BlockTime: 5000, - MinConfirmations: 0, - SampleAddr: "GBHKUZ7C2SZ5N3X2S7O6TT6LNUWSEA2BXMSR5GTTSR6VZARSVAXIQNGH", - }, - NAS: { - ID: 2718, - Handle: "nebulas", - Symbol: "NAS", - Name: "Nebulas", - Decimals: 18, - BlockTime: 30000, - MinConfirmations: 0, - SampleAddr: "n1RCYwrpLMpSpUCQ8QUDzGRg6B2PnY8R94a", - }, - GO: { - ID: 6060, - Handle: "gochain", - Symbol: "GO", - Name: "GoChain GO", - Decimals: 18, - BlockTime: 20000, - MinConfirmations: 0, - SampleAddr: "0x76c2F81716A8D198a00502Ae9a59126418899FDe", - }, - WAN: { - ID: 5718350, - Handle: "wanchain", - Symbol: "WAN", - Name: "Wanchain", - Decimals: 18, - BlockTime: 30000, - MinConfirmations: 0, - SampleAddr: "0x36cEdc3A9d969306AF4F7CA2b83ABBf74095914d", - }, - WAVES: { - ID: 5741564, - Handle: "waves", - Symbol: "WAVES", - Name: "WAVES", - Decimals: 8, - BlockTime: 30000, - MinConfirmations: 1, - SampleAddr: "3P7wz6TXienpw3BHe8eHUEuZWb6WE58kgnQ", - }, - SEM: { - ID: 7562605, - Handle: "semux", - Symbol: "SEM", - Name: "Semux", - Decimals: 9, - BlockTime: 0, - MinConfirmations: 0, - SampleAddr: "0x8197987c401a3466ad678b2080b24838ebd95b41", - }, - BTC: { - ID: 0, - Handle: "bitcoin", - Symbol: "BTC", - Name: "Bitcoin", - Decimals: 8, - BlockTime: 600000, - MinConfirmations: 0, - SampleAddr: "bc1quvuarfksewfeuevuc6tn0kfyptgjvwsvrprk9d", - }, - LTC: { - ID: 2, - Handle: "litecoin", - Symbol: "LTC", - Name: "Litecoin", - Decimals: 8, - BlockTime: 150000, - MinConfirmations: 0, - SampleAddr: "ltc1qhd8fxxp2dx3vsmpac43z6ev0kllm4n53t5sk0u", - }, - DOGE: { - ID: 3, - Handle: "doge", - Symbol: "DOGE", - Name: "Dogecoin", - Decimals: 8, - BlockTime: 60000, - MinConfirmations: 0, - SampleAddr: "DJRFZNg8jkUtjcpo2zJd92FUAzwRjitw6f", - }, - DASH: { - ID: 5, - Handle: "dash", - Symbol: "DASH", - Name: "Dash", - Decimals: 8, - BlockTime: 180000, - MinConfirmations: 0, - SampleAddr: "XqHiz8EXYbTAtBEYs4pWTHh7ipEDQcNQeT", - }, - VIA: { - ID: 14, - Handle: "viacoin", - Symbol: "VIA", - Name: "Viacoin", - Decimals: 8, - BlockTime: 15000, - MinConfirmations: 0, - SampleAddr: "via1qnmsgjd6cvfprnszdgmyg9kewtjfgqflz67wwhc", - }, - GRS: { - ID: 17, - Handle: "groestlcoin", - Symbol: "GRS", - Name: "Groestlcoin", - Decimals: 8, - BlockTime: 60000, - MinConfirmations: 0, - SampleAddr: "grs1qexwmshts5pdpeqglkl39zyl6693tmfwp0cue4j", - }, - ZEC: { - ID: 133, - Handle: "zcash", - Symbol: "ZEC", - Name: "Zcash", - Decimals: 8, - BlockTime: 150000, - MinConfirmations: 0, - SampleAddr: "t1YYnByMzdGhQv3W3rnjHMrJs6HH4Y231gy", - }, - XZC: { - ID: 136, - Handle: "zcoin", - Symbol: "XZC", - Name: "Zcoin", - Decimals: 8, - BlockTime: 300000, - MinConfirmations: 0, - SampleAddr: "aEd5XFChyXobvEics2ppAqgK3Bgusjxtik", - }, - BCH: { - ID: 145, - Handle: "bitcoincash", - Symbol: "BCH", - Name: "Bitcoin Cash", - Decimals: 8, - BlockTime: 600000, - MinConfirmations: 0, - SampleAddr: "bitcoincash:qq07l6rr5lsdm3m80qxw80ku2ex0tj76vvsxpvmgme", - }, - RVN: { - ID: 175, - Handle: "ravencoin", - Symbol: "RVN", - Name: "Raven", - Decimals: 8, - BlockTime: 60000, - MinConfirmations: 0, - SampleAddr: "RHoCwPc2FCQqwToYnSiAb3SrCET4zEHsbS", - }, - QTUM: { - ID: 2301, - Handle: "qtum", - Symbol: "QTUM", - Name: "Qtum", - Decimals: 8, - BlockTime: 60000, - MinConfirmations: 0, - SampleAddr: "QhceuaTdeCZtcxmVc6yyEDEJ7Riu5gWFoF", - }, - ZEL: { - ID: 19167, - Handle: "zelcash", - Symbol: "ZEL", - Name: "Zelcash", - Decimals: 8, - BlockTime: 120000, - MinConfirmations: 0, - SampleAddr: "t1UKbRPzL4WN8Rs8aZ8RNiWoD2ftCMHKGUf", - }, - DCR: { - ID: 42, - Handle: "decred", - Symbol: "DCR", - Name: "Decred", - Decimals: 8, - BlockTime: 300000, - MinConfirmations: 0, - SampleAddr: "DsTxPUVFxXeNgu5fzozr4mTR4tqqMaKcvpY", - }, - ALGO: { - ID: 283, - Handle: "algorand", - Symbol: "ALGO", - Name: "Algorand", - Decimals: 6, - BlockTime: 20000, - MinConfirmations: 0, - SampleAddr: "4EZFQABCVQTHQCK3HQBIYGC4NV2VM42FZHEFTVH77ROG4ZGREC6Y7V5T2U", - }, - NANO: { - ID: 165, - Handle: "nano", - Symbol: "NANO", - Name: "Nano", - Decimals: 30, - BlockTime: 0, - MinConfirmations: 0, - SampleAddr: "nano_1trqphog5noig7z888asnjejcie8z1iopxyepcjdo1atps8whxiuwd51ehbw", - }, - DGB: { - ID: 20, - Handle: "digibyte", - Symbol: "DGB", - Name: "DigiByte", - Decimals: 8, - BlockTime: 15000, - MinConfirmations: 0, - SampleAddr: "D8NBg12kfW8uLjzCv7LYnPYCNhqvVtHaMQ", - }, - ONE: { - ID: 1023, - Handle: "harmony", - Symbol: "ONE", - Name: "Harmony", - Decimals: 18, - BlockTime: 5000, - MinConfirmations: 0, - SampleAddr: "one1syjs6cnfwd9fgrhng03dyzs07suwtywwreczmk", - }, - KSM: { - ID: 434, - Handle: "kusama", - Symbol: "KSM", - Name: "Kusama", - Decimals: 12, - BlockTime: 6000, - MinConfirmations: 0, - SampleAddr: "HewiDTQv92L2bVtkziZC8ASxrFUxr6ajQ62RXAnwQ8FDVmg", - }, -} -func Ethereum() Coin { - return Coins[ETH] -} -func Classic() Coin { - return Coins[ETC] -} -func Icon() Coin { - return Coins[ICX] -} -func Cosmos() Coin { - return Coins[ATOM] -} -func Ripple() Coin { - return Coins[XRP] -} -func Stellar() Coin { - return Coins[XLM] -} -func Poa() Coin { - return Coins[POA] -} -func Tron() Coin { - return Coins[TRX] -} -func Fio() Coin { - return Coins[FIO] -} -func Nimiq() Coin { - return Coins[NIM] -} -func Iotex() Coin { - return Coins[IOTX] -} -func Zilliqa() Coin { - return Coins[ZIL] -} -func Aion() Coin { - return Coins[AION] -} -func Aeternity() Coin { - return Coins[AE] -} -func Kava() Coin { - return Coins[KAVA] -} -func Theta() Coin { - return Coins[THETA] -} -func Binance() Coin { - return Coins[BNB] -} -func Vechain() Coin { - return Coins[VET] -} -func Callisto() Coin { - return Coins[CLO] -} -func Tomochain() Coin { - return Coins[TOMO] -} -func Thundertoken() Coin { - return Coins[TT] -} -func Ontology() Coin { - return Coins[ONT] -} -func Tezos() Coin { - return Coins[XTZ] -} -func Kin() Coin { - return Coins[KIN] -} -func Nebulas() Coin { - return Coins[NAS] -} -func Gochain() Coin { - return Coins[GO] -} -func Wanchain() Coin { - return Coins[WAN] -} -func Waves() Coin { - return Coins[WAVES] -} -func Semux() Coin { - return Coins[SEM] -} -func Bitcoin() Coin { - return Coins[BTC] -} -func Litecoin() Coin { - return Coins[LTC] -} -func Doge() Coin { - return Coins[DOGE] -} -func Dash() Coin { - return Coins[DASH] -} -func Viacoin() Coin { - return Coins[VIA] -} -func Groestlcoin() Coin { - return Coins[GRS] -} -func Zcash() Coin { - return Coins[ZEC] -} -func Zcoin() Coin { - return Coins[XZC] -} -func Bitcoincash() Coin { - return Coins[BCH] -} -func Ravencoin() Coin { - return Coins[RVN] -} -func Qtum() Coin { - return Coins[QTUM] -} -func Zelcash() Coin { - return Coins[ZEL] -} -func Decred() Coin { - return Coins[DCR] -} -func Algorand() Coin { - return Coins[ALGO] -} -func Nano() Coin { - return Coins[NANO] -} -func Digibyte() Coin { - return Coins[DGB] -} -func Harmony() Coin { - return Coins[ONE] -} -func Kusama() Coin { - return Coins[KSM] -} - diff --git a/coin/coins.yml b/coin/coins.yml deleted file mode 100644 index cd5e96630..000000000 --- a/coin/coins.yml +++ /dev/null @@ -1,371 +0,0 @@ -- id: 60 - symbol: ETH - handle: ethereum - name: Ethereum - decimals: 18 - blockTime: 10000 - sampleAddress: '0xfc10cab6a50a1ab10c56983c80cc82afc6559cf1' - -- id: 61 - symbol: ETC - handle: classic - name: Ethereum Classic - decimals: 18 - blockTime: 30000 - sampleAddress: '0xf3524415b6D873205B4c3Cda783527b2aC4daAA9' - -- id: 74 - symbol: ICX - handle: icon - name: ICON - decimals: 18 - sampleAddress: 'hxee691e7bccc4eb11fee922896e9f51490e62b12e' - -- id: 118 - symbol: ATOM - handle: cosmos - name: Cosmos - decimals: 6 - blockTime: 5000 - sampleAddress: 'cosmos1rw62phusuv9vzraezr55k0vsqssvz6ed52zyrl' - -- id: 144 - symbol: XRP - handle: ripple - name: Ripple - decimals: 6 - blockTime: 5000 - sampleAddress: 'rMQ98K56yXJbDGv49ZSmW51sLn94Xe1mu1' - -- id: 148 - symbol: XLM - handle: stellar - name: Stellar - decimals: 7 - blockTime: 5000 - sampleAddress: 'GDKIJJIKXLOM2NRMPNQZUUYK24ZPVFC6426GZAEP3KUK6KEJLACCWNMX' - -- id: 178 - symbol: POA - handle: poa - name: Poa - decimals: 18 - blockTime: 30000 - sampleAddress: '0x1fddEc96688e0538A316C64dcFd211c491ECf0d8' - -- id: 195 - symbol: TRX - handle: tron - name: Tron - decimals: 6 - blockTime: 10000 - sampleAddress: 'TMuA6YqfCeX8EhbfYEg5y7S4DqzSJireY9' - -- id: 235 - symbol: FIO - handle: fio - name: FIO - decimals: 9 - sampleAddress: 'FIO5J2xdfWygeNdHZNZRzRws8YGbVxjUXtp4eP8KoGkGKoLFQ7CaU' - -- id: 242 - symbol: NIM - handle: nimiq - name: Nimiq - decimals: 5 - blockTime: 60000 - sampleAddress: 'NQ86 2H8F YGU5 RM77 QSN9 LYLH C56A CYYR 0MLA' - -- id: 304 - symbol: IOTX - handle: iotex - name: IoTeX - decimals: 18 - blockTime: 10000 - sampleAddress: 'io1mwekae7qqwlr23220k5n9z3fmjxz72tuchra3m' - -- id: 313 - symbol: ZIL - handle: zilliqa - name: Zilliqa - decimals: 12 - blockTime: 30000 - minConfirmations: 1 - sampleAddress: 'zil1anrjcsj2ntklaa3arq4w3s6gw4l4hqrycs9egy' - -- id: 425 - symbol: AION - handle: aion - name: Aion - decimals: 18 - blockTime: 10000 - sampleAddress: '0xa07981da70ce919e1db5f051c3c386eb526e6ce8b9e2bfd56e3f3d754b0a17f3' - -- id: 457 - symbol: AE - handle: aeternity - name: Aeternity - decimals: 18 - blockTime: 6000 - sampleAddress: 'ak_2p5878zbFhxnrm7meL7TmqwtvBaqcBddyp5eGzZbovZ5FeVfcw' - -- id: 459 - symbol: KAVA - handle: kava - name: Kava - decimals: 6 - blockTime: 5000 - sampleAddress: 'kava13fxkk4730cqglgdv7w0mdelyx07myyq7h2nd3x' - -- id: 500 - symbol: THETA - handle: theta - name: Theta - decimals: 18 - sampleAddress: '0xac0eeb6ee3e32e2c74e14ac74155063e4f4f981f' - -- id: 714 - symbol: BNB - handle: binance - name: BNB - decimals: 8 - blockTime: 4000 - sampleAddress: 'tbnb1fhr04azuhcj0dulm7ka40y0cqjlafwae9k9gk2' - -- id: 818 - symbol: VET - handle: vechain - name: VeChain Token - decimals: 18 - blockTime: 20000 - sampleAddress: '0xB5e883349e68aB59307d1604555AC890fAC47128' - -- id: 820 - symbol: CLO - handle: callisto - name: Callisto - decimals: 18 - blockTime: 10000 - sampleAddress: '0x39ec1c88a7a7c1a575e8c8f42eff7630d9278179' - -- id: 889 - symbol: TOMO - handle: tomochain - name: TOMO - blockTime: 4000 - decimals: 18 - sampleAddress: '0x7daa83030e3086477b79b6e757ca8608899fe783' - -- id: 1001 - symbol: TT - handle: thundertoken - name: ThunderCore - decimals: 18 - blockTime: 10000 - sampleAddress: '0x0ad80a408eac4f17ba0a9de8a12d8736f60700c3' - -- id: 1024 - symbol: ONT - handle: ontology - name: Ontology - decimals: 0 - sampleAddress: 'AUyL4TZ1zFEcSKDJrjFnD7vsq5iFZMZqT7' - -- id: 1729 - symbol: XTZ - handle: tezos - name: Tezos - decimals: 6 - blockTime: 20000 - sampleAddress: 'tz1WCd2jm4uSt4vntk4vSuUWoZQGhLcDuR9q' - -- id: 2017 - symbol: KIN - handle: kin - name: Kin - decimals: 5 - blockTime: 5000 - sampleAddress: 'GBHKUZ7C2SZ5N3X2S7O6TT6LNUWSEA2BXMSR5GTTSR6VZARSVAXIQNGH' - -- id: 2718 - symbol: NAS - handle: nebulas - name: Nebulas - decimals: 18 - blockTime: 30000 - sampleAddress: 'n1RCYwrpLMpSpUCQ8QUDzGRg6B2PnY8R94a' - -- id: 6060 - symbol: GO - handle: gochain - name: GoChain GO - decimals: 18 - blockTime: 20000 - sampleAddress: '0x76c2F81716A8D198a00502Ae9a59126418899FDe' - -- id: 5718350 - symbol: WAN - handle: wanchain - name: Wanchain - decimals: 18 - blockTime: 30000 - sampleAddress: '0x36cEdc3A9d969306AF4F7CA2b83ABBf74095914d' - -- id: 5741564 - symbol: WAVES - handle: waves - name: WAVES - decimals: 8 - blockTime: 30000 - minConfirmations: 1 - sampleAddress: '3P7wz6TXienpw3BHe8eHUEuZWb6WE58kgnQ' - -- id: 7562605 - symbol: SEM - handle: semux - name: Semux - decimals: 9 - sampleAddress: '0x8197987c401a3466ad678b2080b24838ebd95b41' - -- id: 0 - symbol: BTC - handle: bitcoin - name: Bitcoin - decimals: 8 - blockTime: 600000 - sampleAddress: 'bc1quvuarfksewfeuevuc6tn0kfyptgjvwsvrprk9d' - -- id: 2 - symbol: LTC - handle: litecoin - name: Litecoin - decimals: 8 - blockTime: 150000 - sampleAddress: 'ltc1qhd8fxxp2dx3vsmpac43z6ev0kllm4n53t5sk0u' - -- id: 3 - symbol: DOGE - handle: doge - name: Dogecoin - decimals: 8 - blockTime: 60000 - sampleAddress: 'DJRFZNg8jkUtjcpo2zJd92FUAzwRjitw6f' - -- id: 5 - symbol: DASH - handle: dash - name: Dash - decimals: 8 - blockTime: 180000 - sampleAddress: 'XqHiz8EXYbTAtBEYs4pWTHh7ipEDQcNQeT' - -- id: 14 - symbol: VIA - handle: viacoin - name: Viacoin - decimals: 8 - blockTime: 15000 - sampleAddress: 'via1qnmsgjd6cvfprnszdgmyg9kewtjfgqflz67wwhc' - -- id: 17 - symbol: GRS - handle: groestlcoin - name: Groestlcoin - decimals: 8 - blockTime: 60000 - sampleAddress: 'grs1qexwmshts5pdpeqglkl39zyl6693tmfwp0cue4j' - -- id: 133 - symbol: ZEC - handle: zcash - name: Zcash - decimals: 8 - blockTime: 150000 - sampleAddress: 't1YYnByMzdGhQv3W3rnjHMrJs6HH4Y231gy' - -- id: 136 - symbol: XZC - handle: zcoin - name: Zcoin - decimals: 8 - blockTime: 300000 - sampleAddress: 'aEd5XFChyXobvEics2ppAqgK3Bgusjxtik' - -- id: 145 - symbol: BCH - handle: bitcoincash - name: Bitcoin Cash - decimals: 8 - blockTime: 600000 - sampleAddress: 'bitcoincash:qq07l6rr5lsdm3m80qxw80ku2ex0tj76vvsxpvmgme' - -- id: 175 - symbol: RVN - handle: ravencoin - name: Raven - decimals: 8 - blockTime: 60000 - sampleAddress: 'RHoCwPc2FCQqwToYnSiAb3SrCET4zEHsbS' - -- id: 2301 - symbol: QTUM - handle: qtum - name: Qtum - decimals: 8 - blockTime: 60000 - sampleAddress: 'QhceuaTdeCZtcxmVc6yyEDEJ7Riu5gWFoF' - -- id: 19167 - symbol: ZEL - handle: zelcash - name: Zelcash - decimals: 8 - blockTime: 120000 - sampleAddress: 't1UKbRPzL4WN8Rs8aZ8RNiWoD2ftCMHKGUf' - -- id: 42 - symbol: DCR - handle: decred - name: Decred - decimals: 8 - blockTime: 300000 - sampleAddress: 'DsTxPUVFxXeNgu5fzozr4mTR4tqqMaKcvpY' - -- id: 283 - symbol: ALGO - handle: algorand - name: Algorand - decimals: 6 - blockTime: 20000 - sampleAddress: '4EZFQABCVQTHQCK3HQBIYGC4NV2VM42FZHEFTVH77ROG4ZGREC6Y7V5T2U' - -- id: 165 - symbol: NANO - handle: nano - name: Nano - decimals: 30 - sampleAddress: 'nano_1trqphog5noig7z888asnjejcie8z1iopxyepcjdo1atps8whxiuwd51ehbw' - -- id: 20 - symbol: DGB - handle: digibyte - name: DigiByte - decimals: 8 - blockTime: 15000 - sampleAddress: 'D8NBg12kfW8uLjzCv7LYnPYCNhqvVtHaMQ' - -- id: 1023 - symbol: ONE - handle: harmony - name: Harmony - decimals: 18 - blockTime: 5000 - sampleAddress: 'one1syjs6cnfwd9fgrhng03dyzs07suwtywwreczmk' - -- id: 434 - symbol: KSM - handle: kusama - name: Kusama - decimals: 12 - blockTime: 6000 - sampleAddress: 'HewiDTQv92L2bVtkziZC8ASxrFUxr6ajQ62RXAnwQ8FDVmg' diff --git a/coin/gen.go b/coin/gen.go deleted file mode 100644 index ee65f3bad..000000000 --- a/coin/gen.go +++ /dev/null @@ -1,127 +0,0 @@ -// +build coins - -//go:generate rm -f coins.go -//go:generate go run gen.go - -package main - -import ( - "gopkg.in/yaml.v2" - "html/template" - "log" - "os" - "strings" - "time" -) - -const ( - coinFile = "coins.yml" - filename = "coins.go" - templateFile = `// Code generated by go generate; DO NOT EDIT. -// This file was generated by robots at -// {{ .Timestamp }} -// using data from coins.yml -package coin - -import ( - "fmt" -) - -// Coin is the native currency of a blockchain -type Coin struct { - ID uint - Handle string - Symbol string - Name string - Decimals uint - BlockTime int - MinConfirmations int64 - SampleAddr string -} - -func (c *Coin) String() string { - return fmt.Sprintf("[%s] %s (#%d)", c.Symbol, c.Name, c.ID) -} - -const ( -{{- range .Coins }} - {{ .Symbol }} = {{ .ID }} -{{- end }} -) - -var Coins = map[uint]Coin{ -{{- range .Coins }} - {{ .Symbol }}: { - ID: {{.ID}}, - Handle: "{{.Handle}}", - Symbol: "{{.Symbol}}", - Name: "{{.Name}}", - Decimals: {{.Decimals}}, - BlockTime: {{.BlockTime}}, - MinConfirmations: {{.MinConfirmations}}, - SampleAddr: "{{.SampleAddr}}", - }, -{{- end }} -} - -{{- range .Coins }} -func {{ .Handle.Upper }}() Coin { - return Coins[{{ .Symbol }}] -} - -{{- end }} - -` -) - -type Handle string - -func (h Handle) Upper() string { - return strings.Title(string(h)) -} - -type Coin struct { - ID uint `yaml:"id"` - Handle Handle `yaml:"handle"` - Symbol string `yaml:"symbol"` - Name string `yaml:"name"` - Decimals uint `yaml:"decimals"` - BlockTime int `yaml:"blockTime"` - MinConfirmations int64 `yaml:"minConfirmations"` - SampleAddr string `yaml:"sampleAddress"` -} - -func main() { - coinFile := getValidParameter("COIN_FILE", coinFile) - var coinList []Coin - coin, err := os.Open(coinFile) - dec := yaml.NewDecoder(coin) - err = dec.Decode(&coinList) - if err != nil { - log.Panic(err) - } - - goFile := getValidParameter("COIN_GO_FILE", filename) - f, err := os.Create(goFile) - if err != nil { - log.Panic(err) - } - defer f.Close() - - coinsTemplate := template.Must(template.New("").Parse(templateFile)) - err = coinsTemplate.Execute(f, map[string]interface{}{ - "Timestamp": time.Now(), - "Coins": coinList, - }) - if err != nil { - log.Panic(err) - } -} - -func getValidParameter(env, variable string) string { - e, ok := os.LookupEnv(env) - if ok { - return e - } - return variable -} diff --git a/coin/gen_test.go b/coin/gen_test.go deleted file mode 100644 index d86c9dd43..000000000 --- a/coin/gen_test.go +++ /dev/null @@ -1,85 +0,0 @@ -package coin - -import ( - "fmt" - "github.com/stretchr/testify/assert" - "gopkg.in/yaml.v2" - "io/ioutil" - "os" - "strings" - "testing" -) - -const ( - coinFile = "coins.yml" - filename = "coins.go" -) - -type TestCoin struct { - ID uint `yaml:"id"` - Handle string `yaml:"handle"` - Symbol string `yaml:"symbol"` - Name string `yaml:"name"` - Decimals uint `yaml:"decimals"` - BlockTime int `yaml:"blockTime"` - MinConfirmations int64 `yaml:"minConfirmations"` - SampleAddr string `yaml:"sampleAddress"` -} - -func TestFilesExists(t *testing.T) { - assert.True(t, assert.FileExists(t, coinFile)) - assert.True(t, assert.FileExists(t, filename)) -} - -func TestCoinFile(t *testing.T) { - var coinList []TestCoin - coin, err := os.Open(coinFile) - dec := yaml.NewDecoder(coin) - err = dec.Decode(&coinList) - if err != nil { - t.Error(err) - } - - f, err := os.Open(filename) - if err != nil { - t.Error(err) - } - defer f.Close() - b, err := ioutil.ReadAll(f) - if err != nil{ - t.Error(err) - } - code := string(b) - - for _, want := range coinList { - got, ok := Coins[want.ID] - assert.True(t, ok) - assert.Equal(t, got.ID, want.ID) - assert.Equal(t, got.Handle, want.Handle) - assert.Equal(t, got.Symbol, want.Symbol) - assert.Equal(t, got.Name, want.Name) - assert.Equal(t, got.Decimals, want.Decimals) - assert.Equal(t, got.BlockTime, want.BlockTime) - assert.Equal(t, got.MinConfirmations, want.MinConfirmations) - assert.Equal(t, got.SampleAddr, want.SampleAddr) - - s := strings.Title(want.Handle) - method := fmt.Sprintf("func %s() Coin", s) - assert.True(t, strings.Contains(code, method), "Coin method not found") - enum := fmt.Sprintf("%s = %d", want.Symbol, want.ID) - assert.True(t, strings.Contains(code, enum), "Coin enum not found") - } -} - -func TestEthereum(t *testing.T) { - - c := Ethereum() - - assert.Equal(t, uint(60), c.ID) - assert.Equal(t, "ethereum", c.Handle) - assert.Equal(t, "ETH", c.Symbol) - assert.Equal(t, "Ethereum", c.Name) - assert.Equal(t, uint(18), c.Decimals) - assert.Equal(t, 10000, c.BlockTime) - assert.Equal(t, int64(0), c.MinConfirmations) -} diff --git a/coin/models.go b/coin/models.go deleted file mode 100644 index 06429cfe4..000000000 --- a/coin/models.go +++ /dev/null @@ -1,17 +0,0 @@ -package coin - -type ExternalCoin struct { - Coin uint `json:"coin"` - Symbol string `json:"symbol"` - Name string `json:"name"` - Decimals uint `json:"decimals"` -} - -func (c *Coin) External() *ExternalCoin { - return &ExternalCoin{ - Coin: c.ID, - Name: c.Name, - Symbol: c.Symbol, - Decimals: c.Decimals, - } -} diff --git a/config.yml b/config.yml index 6230fe504..5d10c7a89 100644 --- a/config.yml +++ b/config.yml @@ -2,68 +2,43 @@ gin: # Possible values: "debug", "release" mode: release - # App running behind a reverse proxy? - # If set, HTTP Forwarded headers will be respected - reverse_proxy: false -#metrics: -# api_token: xxxxxx - -# Sentry error tracking -#sentry: -# dsn: https://xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx@sentry.io/xxxxxxx +# If all - run all platforms in one binary. You can pick specific coin handle to run binary only with specific coin +# Example: ethereum +# You can see all the coin handles at coins/coins.yml file +platform: [ all ] # The transaction watcher observer: - enabled: false - # TODO : Add description - auth: test - # Redis Subscription Database - redis: redis://localhost:6379 - # Smallest possible block polling interval - min_poll: 250ms - # Don't request blocks older than this - backlog: 3h - # Don't request more than N blocks at once - backlog_max_blocks: 200 - # Max connections to open to API - stream_conns: 16 - -# The market watcher -market: - enabled: false - quote_update_time: 20m - rate_update_time: 20m - dex: - quote_update_time: 5m - api: https://dex.binance.org/api - cmc: - api: https://pro-api.coinmarketcap.com - webapi: https://web-api.coinmarketcap.com - widgetapi: https://widgets.coinmarketcap.com - api_key: - map_url: https://raw.githubusercontent.com/trustwallet/assets/master/pricing/coinmarketcap - fixer: - rate_update_time: 1h - api: https://data.fixer.io/api - api_key: - compound: - api: https://api.compound.finance/api - coingecko: - api: https://api.coingecko.com/api - -storage: - redis: redis://localhost:6379 - -# [BNB] Binance DEX: https://wallet.binance.org -# Binance Chain: https://explorer.binance.org + # Amount of time between fetching blocks concurrently + fetch_blocks_interval: 1ms + # Block polling interval + block_poll: + min: 3s + max: 30s + # Don't request more than N blocks at once + max_blocks: 15 + rabbitmq: + url: amqp://localhost:5672 + +postgres: + url: postgresql://user:pass@localhost/blockatlas?sslmode=disable + log: false + +consumer: + service: "" + prefetch: 8 + workers: 8 + +# [BNB] Binance DEX: https://www.binance.org/ binance: - api: https://explorer.binance.org/api/v1 - dex: https://dex.binance.org/api + api: https://dex.binance.org + key: "" + staking_api: "https://api.binance.org" # [NIM] Nimiq: https://nimiq.com -#nimiq: -# api: http://localhost:8648 +nimiq: + api: http://localhost:8648 # [XRP] Ripple: https://ripple.com ripple: @@ -73,49 +48,45 @@ ripple: stellar: api: https://horizon.stellar.org -# [KIN] Kin: https://www.kin.org -kin: - api: https://horizon-block-explorer.kininfrastructure.com - # [XTZ] Tezos: https://tezos.com tezos: - api: https://api.tzstats.com/explorer - rpc: https://mainnet.tezos.org.ua + api: https://api.tzstats.com/explorer # https://tzstats.com/docs/api/index.html#introduction + rpc: https://mainnet-tezos.giganode.io + baker: https://api.baking-bad.org -# [ETH] Ethereum: https://ethereum.org (Trust-Ray API) -# ethereum: -# api: https://localhost:4567 -# collections_api: https://api.opensea.io -# collections_api_key: [opensea_api_key] -# rpc: [ethereum rpc] +# [ETH] Ethereum: https://ethereum.org +ethereum: + api: https://eth1.trezor.io + collections_api: https://api.opensea.io + # collections_api_key: [opensea_api_key] # [ETC] Ethereum Classic: https://ethereumclassic.org (Trust-Ray API) -# classic: -# api: https://localhost:4567 +classic: + api: https://localhost:4567 -# [POA] POA Network: https://poa.network (Trust-Ray API) -# poa: -# api: https://localhost:4567 +# [POA] POA Network: https://poa.network +poa: + api: https://localhost:4567 -# [CLO] Callisto Network: https://callisto.network (Trust-Ray API) -# callisto: -# api: https://localhost:4567 +# [CLO] Callisto Network: https://callisto.network +callisto: + api: https://localhost:4567 -# [GO] GoChain: https://gochain.io (Trust-Ray API) -# gochain: -# api: https://localhost:4567 +# [GO] GoChain: https://gochain.io +gochain: + api: https://localhost:4567 -# [WAN] Wanchain: https://wanchain.org (Trust-Ray API) -# wanchain: -# api: https://localhost:4567 +# [WAN] Wanchain: https://wanchain.org +wanchain: + api: https://localhost:4567 -# [TOMO] TomoChain: https://tomochain.com (Trust-Ray API) -# tomochain: -# api: https://localhost:4567 +# [TOMO] TomoChain: https://tomochain.com +tomochain: + api: https://localhost:4567 -# [TT] ThunderCore: https://www.thundercore.com (Trust-Ray API) -# thundertoken: -# api: https://localhost:4567 +# [TT] ThunderCore: https://www.thundercore.com +thundertoken: + api: https://localhost:4567 # [AION] Aion: https://aion.network aion: @@ -128,6 +99,7 @@ icon: # [TRX] Tron: https://tron.network/ tron: api: https://api.trongrid.io + key: "" # [VET] VeChain: https://www.vechain.org vechain: @@ -135,34 +107,30 @@ vechain: # [THETA] THETA: https://www.thetatoken.org/ theta: - api: https://explorer.thetatoken.org:9000/api + api: https://explorer.thetatoken.org:9000/api + key: "" # [ATOM] Cosmos: https://cosmos.network/ cosmos: - api: https://stargate.cosmos.network - -# [SEMUX] SEMUX: https://semux.org/ -semux: - api: https://sempy.online/api + api: https://api.cosmos.network # [ONTOLOGY] ONT: https://ont.io/ ontology: - api: https://explorer.ont.io/api/v1/explorer + api: https://explorer.ont.io # [ZIL] Zilliqa: https://zilliqa.com zilliqa: -# api: https://api.viewblock.io/v1/zilliqa -# key: YOUR_API_KEY + api: https://api.viewblock.io/v1/zilliqa + # key: YOUR_API_KEY rpc: https://api.zilliqa.com - lookup: https://unstoppabledomains.com/api/v1 #[IoTeX] IoTeX: https://iotex.io iotex: - api: https://pharos.iotex.io/v1 + api: https://pharos.iotex.io/v1 # [WAVES] Waves: http://wavesplatform.com waves: - api: https://nodes.wavesnodes.com + api: https://nodes.wavesnodes.com # [AE] Aeternity: https://aeternity.com aeternity: @@ -172,64 +140,91 @@ aeternity: nebulas: api: https://explorer-backend.nebulas.io/api +# [FIO] FIO: https://fioprotocol.io fio: - api: https://addresses.fio.foundation + api: https://fio.greymass.com # [BTC] Bitcoin: https://bitcoin.org/ (Blockbook API https://github.com/trezor/blockbook) bitcoin: - api: https://btc1.trezor.io/api + api: https://btc1.trezor.io litecoin: - api: https://ltc1.trezor.io/api + api: https://ltc1.trezor.io bitcoincash: - api: https://bch1.trezor.io/api + api: https://bch1.trezor.io doge: - api: https://doge1.trezor.io/api + api: https://doge1.trezor.io dash: - api: https://dash1.trezor.io/api + api: https://dash1.trezor.io zcoin: - api: https://blockbook.zcoin.io/api + api: https://blockbook.zcoin.io zcash: - api: https://zec1.trezor.io/api + api: https://zec1.trezor.io zelcash: - api: https://blockbook.zel.network/api + api: https://blockbook.zel.network viacoin: - api: https://blockbook.viacoin.org/api + api: https://blockbook.viacoin.org qtum: - api: https://blockv3.qtum.info/api + api: https://blockv3.qtum.info groestlcoin: - api: https://blockbook.groestlcoin.org/api + api: https://blockbook.groestlcoin.org ravencoin: - api: https://blockbook.ravencoin.org/api + api: https://blockbook.ravencoin.org decred: - api: https://blockbook.decred.org:9161/api + api: https://blockbook.decred.org:9161 algorand: - api: https://mainnet-algorand.api.purestake.io/ps1 -# key: YOUR_API_KEY + api: https://api.algoexplorer.io/idx2 + key: "" nano: api: https://nanoverse.io/api/node digibyte: - api: https://dgb1.trezor.io/api + api: https://dgb1.trezor.io harmony: api: https://api.s0.t.hmny.io kava: - api: https://data.kava.io + api: https://api.kava.io + +polkadot: + api: https://polkadot.subscan.io/api + +solana: + api: https://api.mainnet-beta.solana.com + +near: + api: https://staging-rpc.nearprotocol.com + +elrond: + api: https://gateway.elrond.com + +filecoin: + api: https://api.filscan.io:8700/rpc/v1 + explorer: https://filfox.info + +oasis: + api: https://oasis.atlas.zondax.ch + +smartchain: + api: "" + collections_api: https://nftview.bounce.finance + +sentry: + dsn: "" -kusama: - api: https://kusama.subscan.io/api +metrics: + path: metrics diff --git a/config/config.go b/config/config.go deleted file mode 100644 index 56c11e623..000000000 --- a/config/config.go +++ /dev/null @@ -1,39 +0,0 @@ -package config - -import ( - "github.com/spf13/viper" - "github.com/trustwallet/blockatlas/pkg/logger" - "strings" -) - -func LoadConfig(confPath string) { - // Load config from environment - viper.SetEnvPrefix("atlas") // will be uppercased automatically => ATLAS - viper.SetEnvKeyReplacer(strings.NewReplacer(".", "_")) - viper.AutomaticEnv() - - viper.AddConfigPath(".") - viper.SetConfigName("config") - viper.SetConfigType("yml") - - // Load config file - if confPath == "" { - if err := viper.ReadInConfig(); err != nil { - if _, ok := err.(viper.ConfigFileNotFoundError); ok { - logger.Info("Config file was not supplied") - } else { - logger.Fatal("Issue reading config", err) - } - } - logger.Info("Viper config", logger.Params{"config_file": viper.ConfigFileUsed()}) - } else { - viper.SetConfigFile(confPath) - err := viper.ReadInConfig() - if err != nil { - logger.Error("Failed to read config", err, - logger.Params{"config_file": confPath}) - } else { - logger.Info("Using config file", logger.Params{"config_file": confPath}) - } - } -} diff --git a/config/configuration.go b/config/configuration.go new file mode 100755 index 000000000..a094c1837 --- /dev/null +++ b/config/configuration.go @@ -0,0 +1,277 @@ +package config + +import ( + "reflect" + "strings" + "time" + + log "github.com/sirupsen/logrus" + "github.com/spf13/viper" +) + +type Configuration struct { + Gin struct { + Mode string `mapstructure:"mode"` + } `mapstructure:"gin"` + Platform []string `mapstructure:"platform"` + RestAPI string `mapstructure:"rest_api"` + Observer struct { + FetchBlocksInterval time.Duration `mapstructure:"fetch_blocks_interval"` + BlockPoll struct { + Min time.Duration `mapstructure:"min"` + Max time.Duration `mapstructure:"max"` + MaxBlocks int64 `mapstructure:"max_blocks"` + } `mapstructure:"block_poll"` + Rabbitmq struct { + URL string `mapstructure:"url"` + } `mapstructure:"rabbitmq"` + } `mapstructure:"observer"` + Postgres struct { + URL string `mapstructure:"url"` + Log bool `mapstructure:"log"` + } `mapstructure:"postgres"` + Ethereum struct { + API string `mapstructure:"api"` + CollectionsAPI string `mapstructure:"collections_api"` + CollectionsKey string `mapstructure:"collections_api_key"` + } `mapstructure:"ethereum"` + Binance struct { + API string `mapstructure:"api"` + Key string `mapstructure:"key"` + StakingAPI string `mapstructure:"staking_api"` + } `mapstructure:"binance"` + Ripple struct { + API string `mapstructure:"api"` + } `mapstructure:"ripple"` + Stellar struct { + API string `mapstructure:"api"` + } `mapstructure:"stellar"` + Nimiq struct { + API string `mapstructure:"api"` + } `mapstructure:"nimiq"` + Tezos struct { + API string `mapstructure:"api"` + RPC string `mapstructure:"rpc"` + Baker string `mapstructure:"baker"` + } `mapstructure:"tezos"` + Thundertoken struct { + API string `mapstructure:"api"` + RPC string `mapstructure:"rpc"` + } `mapstructure:"thundertoken"` + Gochain struct { + API string `mapstructure:"api"` + RPC string `mapstructure:"rpc"` + } `mapstructure:"gochain"` + Classic struct { + API string `mapstructure:"api"` + RPC string `mapstructure:"rpc"` + } `mapstructure:"classic"` + Smartchain struct { + API string `mapstructure:"api"` + CollectionsAPI string `mapstructure:"collections_api"` + } `mapstructure:"smartchain"` + Poa struct { + API string `mapstructure:"api"` + RPC string `mapstructure:"rpc"` + } `mapstructure:"poa"` + Callisto struct { + API string `mapstructure:"api"` + RPC string `mapstructure:"rpc"` + } `mapstructure:"callisto"` + Wanchain struct { + API string `mapstructure:"api"` + RPC string `mapstructure:"rpc"` + } `mapstructure:"wanchain"` + Tomochain struct { + API string `mapstructure:"api"` + RPC string `mapstructure:"rpc"` + } `mapstructure:"tomochain"` + Aion struct { + API string `mapstructure:"api"` + } `mapstructure:"aion"` + Icon struct { + API string `mapstructure:"api"` + } `mapstructure:"icon"` + Tron struct { + API string `mapstructure:"api"` + Key string `mapstructure:"key"` + } `mapstructure:"tron"` + Vechain struct { + API string `mapstructure:"api"` + } `mapstructure:"vechain"` + Theta struct { + API string `mapstructure:"api"` + Key string `mapstructure:"key"` + } `mapstructure:"theta"` + Cosmos struct { + API string `mapstructure:"api"` + } `mapstructure:"cosmos"` + Ontology struct { + API string `mapstructure:"api"` + } `mapstructure:"ontology"` + Zilliqa struct { + API string `mapstructure:"api"` + RPC string `mapstructure:"rpc"` + Key string `mapstructure:"key"` + } `mapstructure:"zilliqa"` + Iotex struct { + API string `mapstructure:"api"` + } `mapstructure:"iotex"` + Waves struct { + API string `mapstructure:"api"` + } `mapstructure:"waves"` + Aeternity struct { + API string `mapstructure:"api"` + } `mapstructure:"aeternity"` + Nebulas struct { + API string `mapstructure:"api"` + } `mapstructure:"nebulas"` + Fio struct { + API string `mapstructure:"api"` + } `mapstructure:"fio"` + Bitcoin struct { + API string `mapstructure:"api"` + } `mapstructure:"bitcoin"` + Litecoin struct { + API string `mapstructure:"api"` + } `mapstructure:"litecoin"` + Bitcoincash struct { + API string `mapstructure:"api"` + } `mapstructure:"bitcoincash"` + Doge struct { + API string `mapstructure:"api"` + } `mapstructure:"doge"` + Dash struct { + API string `mapstructure:"api"` + } `mapstructure:"dash"` + Zcoin struct { + API string `mapstructure:"api"` + } `mapstructure:"zcoin"` + Zcash struct { + API string `mapstructure:"api"` + } `mapstructure:"zcash"` + Zelcash struct { + API string `mapstructure:"api"` + } `mapstructure:"zelcash"` + Viacoin struct { + API string `mapstructure:"api"` + } `mapstructure:"viacoin"` + Qtum struct { + API string `mapstructure:"api"` + } `mapstructure:"qtum"` + Groestlcoin struct { + API string `mapstructure:"api"` + } `mapstructure:"groestlcoin"` + Ravencoin struct { + API string `mapstructure:"api"` + } `mapstructure:"ravencoin"` + Decred struct { + API string `mapstructure:"api"` + } `mapstructure:"decred"` + Algorand struct { + API string `mapstructure:"api"` + Key string `mapstructure:"key"` + } `mapstructure:"algorand"` + Nano struct { + API string `mapstructure:"api"` + } `mapstructure:"nano"` + Digibyte struct { + API string `mapstructure:"api"` + } `mapstructure:"digibyte"` + Harmony struct { + API string `mapstructure:"api"` + } `mapstructure:"harmony"` + Kava struct { + API string `mapstructure:"api"` + } `mapstructure:"kava"` + Kusama struct { + API string `mapstructure:"api"` + } `mapstructure:"kusama"` + Polkadot struct { + API string `mapstructure:"api"` + } `mapstructure:"polkadot"` + Solana struct { + API string `mapstructure:"api"` + } `mapstructure:"solana"` + Near struct { + API string `mapstructure:"api"` + } `mapstructure:"near"` + Elrond struct { + API string `mapstructure:"api"` + } `mapstructure:"elrond"` + Filecoin struct { + API string `mapstructure:"api"` + Explorer string `mapstructure:"explorer"` + } `mapstructure:"filecoin"` + Oasis struct { + API string `mapstructure:"api"` + } `mapstructure:"oasis"` + Sentry struct { + DSN string `mapstructure:"dsn"` + } `mapstructure:"sentry"` + Metrics struct { + Path string `mapstructure:"path"` + } `mapstructure:"metrics"` + Consumer struct { + Service string `mapstructure:"service"` + Prefetch int `mapstructure:"prefetch"` + Workers int `mapstructure:"workers"` + } `mapstructure:"consumer"` +} + +var Default Configuration + +func Init(confPath string) { + c := Configuration{} + + viper.AutomaticEnv() + viper.SetEnvKeyReplacer(strings.NewReplacer(".", "_")) + + viper.AddConfigPath(".") + viper.SetConfigName("config") + viper.SetConfigType("yml") + + if confPath == "" { + err := viper.ReadInConfig() + if err != nil { + log.Panic(err, "Fatal error reading default config") + } else { + log.WithFields(log.Fields{"config": viper.ConfigFileUsed()}).Info("Viper using default config") + } + } else { + viper.SetConfigFile(confPath) + err := viper.ReadInConfig() + if err != nil { + log.Panic(err, "Fatal error reading supplied config") + } else { + log.WithFields(log.Fields{"config": viper.ConfigFileUsed()}).Info("Viper using supplied config") + } + } + + bindEnvs(c) + if err := viper.Unmarshal(&c); err != nil { + log.Panic(err, "Error Unmarshal Viper Config File") + } + Default = c +} + +func bindEnvs(iface interface{}, parts ...string) { + ifv := reflect.ValueOf(iface) + ift := reflect.TypeOf(iface) + for i := 0; i < ift.NumField(); i++ { + v := ifv.Field(i) + t := ift.Field(i) + tv, ok := t.Tag.Lookup("mapstructure") + if !ok { + continue + } + switch v.Kind() { + case reflect.Struct: + bindEnvs(v.Interface(), append(parts, tv)...) + default: + if err := viper.BindEnv(strings.Join(append(parts, tv), ".")); err != nil { + log.Fatal(err) + } + } + } +} diff --git a/configmock.yml b/configmock.yml new file mode 100644 index 000000000..7a3d9477c --- /dev/null +++ b/configmock.yml @@ -0,0 +1,199 @@ +# Gin is the web framework +gin: + mode: release + +# If all - run all platforms in one binary. You can pick specific coin handle to run binary only with specific coin +# Example: ethereum +# You can see all the coin handles at coins/coins.yml file +platform: all + +# The transaction watcher +observer: + # Block polling interval + block_poll: + min: 3s + max: 30s + max_blocks: 15 + rabbitmq: + uri: amqp://rabbit:5672 + consumer: + prefetch_count: 10 + +postgres: + uri: postgresql://user:pass@localhost/blockatlas?sslmode=disable + read_uri: postgresql://user:pass@localhost/blockatlas?sslmode=disable + log: false + +# [BNB] Binance DEX: https://wallet.binance.org +# Binance Chain: https://explorer.binance.org +binance: + api: http://localhost:3347/mock/binance-api + explorer: http://localhost:3347/mock/binance-explorer + +# [NIM] Nimiq: https://nimiq.com +nimiq: + api: http://localhost:3347/mock/nimiq-rpc + +# [XRP] Ripple: https://ripple.com +ripple: + api: http://localhost:3347/mock/ripple-api + +# [XLM] Stellar Lumen: https://www.stellar.org +stellar: + api: http://localhost:3347/mock/stellar-api + +# [KIN] Kin: https://www.kin.org +kin: + api: http://localhost:3347/mock/kin-api + +# [XTZ] Tezos: https://tezos.com +tezos: + api: http://localhost:3347/mock/tezos-api + rpc: https://mainnet.tezos.org.ua + +# [ETH] Ethereum: https://ethereum.org +ethereum: + api: http://localhost:3347/mock/eth-api + blockbook_api: http://localhost:3347/mock/eth-blockbook-api + collections_api: http://localhost:3347/mock/opensea-api + collections_api_key: opensea_api_key + rpc: http://localhost:3347/mock/eth-rpc + +# [ETC] Ethereum Classic: https://ethereumclassic.org (Trust-Ray API) +classic: + api: http://localhost:3347/mock/ethclassic-api + +# [POA] POA Network: https://poa.network (Trust-Ray API) +poa: + api: http://localhost:3347/mock/poa-api + +# [CLO] Callisto Network: https://callisto.network (Trust-Ray API) +callisto: + api: http://localhost:3347/mock/callisto-api + +# [GO] GoChain: https://gochain.io (Trust-Ray API) +gochain: + api: http://localhost:3347/mock/gochain-api + +# [WAN] Wanchain: https://wanchain.org (Trust-Ray API) +# wanchain: +# api: https://localhost:4567 + +# [TOMO] TomoChain: https://tomochain.com (Trust-Ray API) +tomochain: + api: http://localhost:3347/mock/tomochain-api + +# [TT] ThunderCore: https://www.thundercore.com (Trust-Ray API) +thundertoken: + api: http://localhost:3347/mock/thundertoken-api + +# [AION] Aion: https://aion.network +aion: + api: http://localhost:3347/mock/aion-api + +# [ICX] ICON: https://icon.foundation +icon: + api: http://localhost:3347/mock/icon-api + +# [TRX] Tron: https://tron.network/ +tron: + api: http://localhost:3347/mock/tron-api + +# [VET] VeChain: https://www.vechain.org +vechain: + api: http://localhost:3347/mock/vechain-api + +# [THETA] THETA: https://www.thetatoken.org/ +theta: + api: http://localhost:3347/mock/theta-api + +# [ATOM] Cosmos: https://cosmos.network/ +cosmos: + api: http://localhost:3347/mock/cosmos-api + +# [ONTOLOGY] ONT: https://ont.io/ +ontology: + api: http://localhost:3347/mock/ontology-api + +# [ZIL] Zilliqa: https://zilliqa.com +zilliqa: + api: http://localhost:3347/mock/zilliqa-api + # key: YOUR_API_KEY + rpc: https://api.zilliqa.com + +#[IoTeX] IoTeX: https://iotex.io +iotex: + api: http://localhost:3347/mock/iotex-api + +# [WAVES] Waves: http://wavesplatform.com +waves: + api: http://localhost:3347/mock/waves-api + +# [AE] Aeternity: https://aeternity.com +aeternity: + api: http://localhost:3347/mock/aeternity-api + +# [NAS] Nebulas: https://nebulas.io +nebulas: + api: http://localhost:3347/mock/nebulas-api + +fio: + api: http://localhost:3347/mock/fio-api + +# [BTC] Bitcoin: https://bitcoin.org/ (Blockbook API https://github.com/trezor/blockbook) +bitcoin: + api: http://localhost:3347/mock/bitcoin-api + +litecoin: + api: http://localhost:3347/mock/litecoin-api + +bitcoincash: + api: http://localhost:3347/mock/bitcoincash-api + +doge: + api: http://localhost:3347/mock/doge-api + +dash: + api: http://localhost:3347/mock/dash-api + +zcoin: + api: http://localhost:3347/mock/zcoin-api + +zcash: + api: http://localhost:3347/mock/zcash-api + +zelcash: + api: http://localhost:3347/mock/zelcash-api + +viacoin: + api: http://localhost:3347/mock/viacoin-api + +qtum: + api: http://localhost:3347/mock/qtum-api + +groestlcoin: + api: http://localhost:3347/mock/groestlcoin-api + +ravencoin: + api: http://localhost:3347/mock/ravencoin-api + +decred: + api: http://localhost:3347/mock/decred-api + +algorand: + api: http://localhost:3347/mock/algorand-api + +nano: + api: http://localhost:3347/mock/nano-api + +digibyte: + api: http://localhost:3347/mock/digibyte-api + +harmony: + api: http://localhost:3347/mock/harmony-api + +kava: + api: http://localhost:3347/mock/kava-api + +kusama: + api: http://localhost:3347/mock/kusama-rpc diff --git a/db/asset.go b/db/asset.go new file mode 100644 index 000000000..9ac1dd63d --- /dev/null +++ b/db/asset.go @@ -0,0 +1,136 @@ +package db + +import ( + "encoding/json" + "time" + + "gorm.io/gorm/clause" + + gocache "github.com/patrickmn/go-cache" + + "github.com/trustwallet/blockatlas/db/models" +) + +func (i *Instance) GetAsset(assetId string) (models.Asset, error) { + var asset models.Asset + err := i.Gorm.First(&asset, "asset = ?", assetId).Error + if err != nil { + return asset, err + } + return asset, nil +} + +func (i *Instance) GetAssetsByIDs(ids []string) ([]models.Asset, error) { + //TODO: look why nil and len 0 make db calls rn + if len(ids) == 0 { + return nil, nil + } + + var dbAssets []models.Asset + if err := i.Gorm. + Where("asset in (?)", ids). + Find(&dbAssets).Error; err != nil { + return nil, err + } + return dbAssets, nil +} + +func (i *Instance) GetSubscriptionsByAddressIDs(ids []string, from time.Time) ([]models.SubscriptionsAssetAssociation, error) { + var associations []models.SubscriptionsAssetAssociation + if err := i.Gorm. + Joins("join subscriptions on subscriptions.id = subscriptions_asset_associations.subscription_id", ids). + Preload("Subscription"). + Preload("Asset"). + Where("subscriptions.address in (?)", ids). + Where("subscriptions_asset_associations.updated_at > ?", from). + Find(&associations).Error; err != nil { + return nil, err + } + return associations, nil +} + +func (i *Instance) AddNewAssets(assets []models.Asset) error { + if len(assets) == 0 { + return nil + } + + uniqueAssets := getUniqueAssets(assets) + + var notInMemoryAssets []models.Asset + for _, a := range uniqueAssets { + _, err := i.MemoryGet(a.Asset) + if err != nil { + notInMemoryAssets = append(notInMemoryAssets, a) + } + } + if len(notInMemoryAssets) == 0 { + return nil + } + + existingAssets, err := i.GetAssetsByIDs(models.AssetIDs(notInMemoryAssets)) + if err != nil { + return err + } + if len(existingAssets) == 0 { + i.addToMemory(notInMemoryAssets) + return i.Gorm.Clauses(clause.OnConflict{DoNothing: true}).Create(¬InMemoryAssets).Error + } + allAssetsMap := make(map[string]models.Asset) + for _, ua := range notInMemoryAssets { + allAssetsMap[ua.Asset] = ua + } + existingAssetsMap := make(map[string]models.Asset) + for _, ea := range existingAssets { + existingAssetsMap[ea.Asset] = ea + } + var newAssets []models.Asset + for k, v := range allAssetsMap { + _, ok := existingAssetsMap[k] + if !ok && v.Asset != "" { + newAssets = append(newAssets, v) + } + } + if len(newAssets) == 0 { + return nil + } + i.addToMemory(newAssets) + + return i.Gorm.Clauses(clause.OnConflict{DoNothing: true}).Create(&newAssets).Error +} + +func (i *Instance) addToMemory(newAssets []models.Asset) { + for _, a := range newAssets { + raw, err := json.Marshal(a) + if err != nil { + continue + } + err = i.MemorySet(a.Asset, raw, gocache.NoExpiration) + if err != nil { + continue + } + } +} + +func (i *Instance) GetAssetsFrom(from time.Time) ([]models.Asset, error) { + var dbAssets []models.Asset + if err := i.Gorm. + Where("created_at > ?", from). + Order("created_at desc"). + Limit(1000). + Find(&dbAssets).Error; err != nil { + return nil, err + } + return dbAssets, nil +} + +func getUniqueAssets(values []models.Asset) []models.Asset { + keys := make(map[string]bool) + var list []models.Asset + for _, entry := range values { + if _, value := keys[entry.Asset]; !value { + keys[entry.Asset] = true + list = append(list, entry) + } + } + return list +} diff --git a/db/db.go b/db/db.go new file mode 100644 index 000000000..c26c719d5 --- /dev/null +++ b/db/db.go @@ -0,0 +1,60 @@ +package db + +import ( + "errors" + "time" + + "github.com/trustwallet/blockatlas/db/models" + + "gorm.io/gorm/logger" + + gocache "github.com/patrickmn/go-cache" + "gorm.io/driver/postgres" + "gorm.io/gorm" +) + +type Instance struct { + Gorm *gorm.DB + MemoryCache *gocache.Cache +} + +func New(url string, log bool) (*Instance, error) { + var logMode logger.LogLevel + if log { + logMode = logger.Info + } + + cfg := &gorm.Config{Logger: logger.Default.LogMode(logMode), SkipDefaultTransaction: true} + + db, err := gorm.Open(postgres.Open(url), cfg) + if err != nil { + return nil, err + } + + mc := gocache.New(gocache.NoExpiration, gocache.NoExpiration) + i := &Instance{Gorm: db, MemoryCache: mc} + + return i, nil +} + +func Setup(db *gorm.DB) error { + return db.AutoMigrate( + &models.Tracker{}, + &models.Asset{}, + &models.Subscription{}, + &models.SubscriptionsAssetAssociation{}, + ) +} + +func (i *Instance) MemorySet(key string, data []byte, exp time.Duration) error { + i.MemoryCache.Set(key, data, exp) + return nil +} + +func (i *Instance) MemoryGet(key string) ([]byte, error) { + res, ok := i.MemoryCache.Get(key) + if !ok { + return nil, errors.New("not found") + } + return res.([]byte), nil +} diff --git a/db/models/asset.go b/db/models/asset.go new file mode 100644 index 000000000..3fd039efe --- /dev/null +++ b/db/models/asset.go @@ -0,0 +1,118 @@ +package models + +import ( + "errors" + "time" + "unicode/utf8" + + "github.com/trustwallet/golibs/asset" + "github.com/trustwallet/golibs/types" +) + +type Asset struct { + CreatedAt time.Time `gorm:"index:,"` + ID uint `gorm:"primary_key; uniqueIndex"` + Asset string `gorm:"type:varchar(128); uniqueIndex"` + + Decimals uint `gorm:"int(4)"` + Name string `gorm:"type:varchar(128)"` + Symbol string `gorm:"type:varchar(128)"` + Type string `gorm:"type:varchar(12)"` + Coin uint +} + +func AssetsFrom(t types.Tx) (assets []Asset) { + switch t.Meta.(type) { + case types.TokenTransfer: + transfer := t.Meta.(types.TokenTransfer) + if asset, ok := AssetFromTokenTransfer(&t, transfer); ok { + assets = append(assets, asset) + } + case *types.TokenTransfer: + transfer := t.Meta.(*types.TokenTransfer) + if asset, ok := AssetFromTokenTransfer(&t, *transfer); ok { + assets = append(assets, asset) + } + case types.NativeTokenTransfer: + transfer := t.Meta.(types.NativeTokenTransfer) + if asset, ok := AssetFromNativeTokenTransfer(&t, &transfer); ok { + assets = append(assets, asset) + } + case *types.NativeTokenTransfer: + transfer := t.Meta.(*types.NativeTokenTransfer) + if asset, ok := AssetFromNativeTokenTransfer(&t, transfer); ok { + assets = append(assets, asset) + } + default: + break + } + + for _, transfer := range t.TokenTransfers { + //Improve this later. Making cure we only include assets associated with current addresses + for _, address := range t.GetAddresses() { + if address == transfer.To || address == transfer.From { + if asset, ok := AssetFromTokenTransfer(&t, transfer); ok { + assets = append(assets, asset) + } + } + } + } + + return +} + +func AssetFromTokenTransfer(t *types.Tx, transfer types.TokenTransfer) (a Asset, ok bool) { + tp, ok := types.GetTokenType(t.Coin, transfer.TokenID) + if !ok { + return a, ok + } + a.Asset = asset.BuildID(t.Coin, transfer.TokenID) + a.Decimals = transfer.Decimals + a.Name = transfer.Name + a.Symbol = transfer.Symbol + a.Type = tp + a.Coin = t.Coin + return a, a.IsValid() == nil +} + +func AssetFromNativeTokenTransfer(t *types.Tx, transfer *types.NativeTokenTransfer) (a Asset, ok bool) { + tp, ok := types.GetTokenType(t.Coin, transfer.TokenID) + if !ok { + return + } + a.Asset = asset.BuildID(t.Coin, transfer.TokenID) + a.Decimals = transfer.Decimals + a.Name = transfer.Name + a.Symbol = transfer.Symbol + a.Type = tp + a.Coin = t.Coin + return a, a.IsValid() == nil +} + +func (asset *Asset) IsValid() error { + if len(asset.Name) >= 32 { + return errors.New("name should be less than 32") + } + if len(asset.Symbol) >= 32 { + return errors.New("name should be less than 32") + } + stringValues := []string{asset.Asset, asset.Type, asset.Symbol, asset.Name} + + for _, value := range stringValues { + if value == "" { + return errors.New("empty value for asset: " + asset.Asset) + } + if !utf8.ValidString(value) { + return errors.New("not valid utf8 string: " + value) + } + } + return nil +} + +func AssetIDs(assets []Asset) []string { + result := make([]string, 0, len(assets)) + for _, a := range assets { + result = append(result, a.Asset) + } + return result +} diff --git a/db/models/asset_test.go b/db/models/asset_test.go new file mode 100644 index 000000000..0f5cd60b9 --- /dev/null +++ b/db/models/asset_test.go @@ -0,0 +1,133 @@ +package models + +import ( + "reflect" + "testing" + "time" + + "github.com/trustwallet/golibs/types" +) + +func TestAsset_isValid1(t *testing.T) { + type fields struct { + CreatedAt time.Time + ID uint + Asset string + Decimals uint + Name string + Symbol string + Type string + Coin uint + } + tests := []struct { + name string + fields fields + wantErr bool + }{ + { + "Valid asset", + fields{ + Asset: "c60", + Decimals: 18, + Name: "Ethereum", + Symbol: "ETH", + Type: "coin", + Coin: 60, + }, + false, + }, + { + "Bytes32 name", + fields{ + Asset: "c60_t0xfFED56a180f23fD32Bc6A1d8d3c09c283aB594A8", + Decimals: 0, + Name: "\\u0000\\u0000\\u0000\\u0000\\u0000\\u0000\\u0000\\u0000\\u0000\\u0000\\u0000\\u0000\\u0000\\u0000\\u0000\\u0000\\u0000\\u0000\\u0000\\u0000\\u0000\\u0000\\u0000\\u0000\\u0000\\u0000\\u0000\\u0000\\u0000\\u0000\\u0000\\u0000", + Symbol: "FL", + Type: "ERC20", + Coin: 60, + }, + true, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + asset := &Asset{ + CreatedAt: tt.fields.CreatedAt, + ID: tt.fields.ID, + Asset: tt.fields.Asset, + Decimals: tt.fields.Decimals, + Name: tt.fields.Name, + Symbol: tt.fields.Symbol, + Type: tt.fields.Type, + Coin: tt.fields.Coin, + } + if err := asset.IsValid(); (err != nil) != tt.wantErr { + t.Errorf("isValid() error = %v, wantErr %v", err, tt.wantErr) + } + }) + } +} + +func TestAssetsFrom(t *testing.T) { + type args struct { + t types.Tx + } + tests := []struct { + name string + args args + wantAssets []Asset + }{ + { + "Token Transfer", + args{t: types.Tx{ + Coin: 60, + Type: types.TxTokenTransfer, + TokenTransfers: []types.TokenTransfer{ + { + Name: "Trust Wallet", + Symbol: "TWT", + TokenID: "TWT-123", + Decimals: 8, + Value: "1", + From: "0x1", + To: "0x2", + }, + }, + Meta: types.TokenTransfer{ + Name: "TW 2", + Symbol: "TWT2", + TokenID: "TWT2-123", + Decimals: 18, + Value: "0", + From: "0x2", + To: "0x123", + }, + }}, + []Asset{ + { + Asset: "c60_tTWT2-123", + Decimals: 18, + Name: "TW 2", + Symbol: "TWT2", + Type: "ERC20", + Coin: 60, + }, + { + Asset: "c60_tTWT-123", + Decimals: 8, + Name: "Trust Wallet", + Symbol: "TWT", + Type: "ERC20", + Coin: 60, + }, + }, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + if gotAssets := AssetsFrom(tt.args.t); !reflect.DeepEqual(gotAssets, tt.wantAssets) { + t.Errorf("AssetsFrom() = %v, want %v", gotAssets, tt.wantAssets) + } + }) + } +} diff --git a/db/models/subscriptions.go b/db/models/subscriptions.go new file mode 100644 index 000000000..28b608b11 --- /dev/null +++ b/db/models/subscriptions.go @@ -0,0 +1,22 @@ +package models + +import ( + "time" +) + +type ( + Subscription struct { + ID uint `gorm:"primaryKey;"` + Address string `gorm:"uniqueIndex; type:varchar(256); not null;"` + } + + SubscriptionsAssetAssociation struct { + CreatedAt time.Time `gorm:"index;"` + UpdatedAt time.Time `gorm:"index;"` + Subscription Subscription `gorm:"ForeignKey:SubscriptionId; not null"` + SubscriptionId uint `gorm:"primary_key; autoIncrement:false; index"` + + Asset Asset `gorm:"ForeignKey:AssetId; not null"` + AssetId uint `gorm:"primary_key; autoIncrement:false; index"` + } +) diff --git a/db/models/tracker.go b/db/models/tracker.go new file mode 100644 index 000000000..87b471fa3 --- /dev/null +++ b/db/models/tracker.go @@ -0,0 +1,11 @@ +package models + +import "time" + +type Tracker struct { + UpdatedAt time.Time + Coin string `gorm:"primary_key:true; type:varchar(64)"` + Priority string `gorm:"default:normal"` + Height int64 + Enabled bool `gorm:"default:true" sql:"index"` +} diff --git a/db/subscription.go b/db/subscription.go new file mode 100644 index 000000000..922acd3c7 --- /dev/null +++ b/db/subscription.go @@ -0,0 +1,66 @@ +package db + +import ( + "github.com/trustwallet/blockatlas/db/models" + "github.com/trustwallet/golibs/types" + "gorm.io/gorm/clause" +) + +func (i *Instance) CreateSubscriptions(addresses []types.Subscription) error { + if len(addresses) == 0 { + return nil + } + // remove duplicates + addressIds := make(map[string]bool) + for _, address := range addresses { + addressIds[address.AddressID()] = true + } + result := make([]models.Subscription, 0) + for addressId := range addressIds { + result = append(result, models.Subscription{Address: addressId}) + } + + return i.Gorm.Clauses(clause.OnConflict{DoNothing: true}).Create(&result).Error +} + +func (i *Instance) GetSubscriptions(addresses []string) ([]models.Subscription, error) { + var subscriptions []models.Subscription + err := i.Gorm.Find(&subscriptions, "address in ?", addresses).Error + if err != nil { + return nil, err + } + return subscriptions, nil +} + +func (i *Instance) DeleteSubscriptions(addresses []string) error { + subscriptions, err := i.GetSubscriptions(addresses) + if err != nil { + return err + } + if len(subscriptions) == 0 { + return nil + } + subscriptionsIds := make([]uint, 0) + for _, subscription := range subscriptions { + subscriptionsIds = append(subscriptionsIds, subscription.ID) + } + if err = i.Gorm. + Where("subscription_id in (?)", subscriptionsIds). + Delete(&models.SubscriptionsAssetAssociation{}).Error; err != nil { + return err + } + return i.Gorm. + Where("id in (?)", subscriptionsIds). + Delete(&models.Subscription{}).Error +} + +func (i *Instance) CreateSubscriptionsAssets(associations []models.SubscriptionsAssetAssociation) error { + if len(associations) == 0 { + return nil + } + return i.Gorm.Clauses( + clause.OnConflict{ + OnConstraint: "subscriptions_asset_associations_pkey", + DoUpdates: clause.AssignmentColumns([]string{"updated_at"})}, + ).Create(&associations).Error +} diff --git a/db/tracker.go b/db/tracker.go new file mode 100644 index 000000000..0cf6dbc65 --- /dev/null +++ b/db/tracker.go @@ -0,0 +1,39 @@ +package db + +import ( + "github.com/trustwallet/blockatlas/db/models" + "gorm.io/gorm/clause" +) + +func (i *Instance) GetLastParsedBlockNumbers() ([]models.Tracker, error) { + var trackers []models.Tracker + if err := i.Gorm. + Find(&trackers).Error; err != nil { + return trackers, nil + } + return trackers, nil +} + +func (i *Instance) GetLastParsedBlockNumber(coin string) (models.Tracker, error) { + var tracker models.Tracker + if err := i.Gorm. + Find(&tracker, "coin = ?", coin).Error; err != nil { + return tracker, err + } + return tracker, nil +} + +func (i *Instance) SetLastParsedBlockNumber(coin string, num int64) error { + tracker := models.Tracker{ + Coin: coin, + Height: num, + } + return i.Gorm.Clauses(clause.OnConflict{ + Columns: []clause.Column{ + { + Name: "coin", + }, + }, + DoUpdates: clause.AssignmentColumns([]string{"height", "updated_at"}), + }).Create(&tracker).Error +} diff --git a/deployment/Procfile-consumer b/deployment/Procfile-consumer new file mode 100644 index 000000000..e0b19f1b2 --- /dev/null +++ b/deployment/Procfile-consumer @@ -0,0 +1,5 @@ +release: bin/setup -c $HOME/config.yml +transactions: CONSUMER_SERVICE=transactions bin/consumer -c $HOME/config.yml +subscriptions: CONSUMER_SERVICE=subscriptions bin/consumer -c $HOME/config.yml +subscriptions_tokens: CONSUMER_SERVICE=subscriptions_tokens bin/consumer -c $HOME/config.yml +tokens: CONSUMER_SERVICE=tokens bin/consumer -c $HOME/config.yml diff --git a/deployment/Procfile-parser b/deployment/Procfile-parser new file mode 100644 index 000000000..16ddc5fb8 --- /dev/null +++ b/deployment/Procfile-parser @@ -0,0 +1,2 @@ +release: bin/setup -c $HOME/config.yml +parser: bin/parser -c $HOME/config.yml diff --git a/deployment/Procfile-web b/deployment/Procfile-web new file mode 100644 index 000000000..b91d503df --- /dev/null +++ b/deployment/Procfile-web @@ -0,0 +1,2 @@ +release: bin/setup -c $HOME/config.yml +web: bin/api -c $HOME/config.yml -p $PORT diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 000000000..88028cb3e --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,68 @@ +version: '3.7' +services: + api: + container_name: api + environment: + - POSTGRES_URL=postgresql://user:pass@postgres/blockatlas?sslmode=disable + - POSTGRES_READ_URL=postgresql://user:pass@postgres/blockatlas?sslmode=disable + - OBSERVER_RABBITMQ_URL=amqp://rabbit:5672 + build: + context: . + args: + - SERVICE=api + ports: + - 8420:8420 + + consumer: + build: + context: . + args: + - SERVICE=consumer + environment: + - POSTGRES_URL=postgresql://user:pass@postgres/blockatlas?sslmode=disable + - POSTGRES_READ_URL=postgresql://user:pass@postgres/blockatlas?sslmode=disable + - OBSERVER_RABBITMQ_URL=amqp://rabbit:5672 + links: + - rabbit + - postgres + restart: on-failure + + parser: + build: + context: . + args: + - SERVICE=parser + environment: + - POSTGRES_URL=postgresql://user:pass@postgres/blockatlas?sslmode=disable + - POSTGRES_READ_URL=postgresql://user:pass@postgres/blockatlas?sslmode=disable + - OBSERVER_RABBITMQ_URL=amqp://rabbit:5672 + links: + - rabbit + - postgres + restart: on-failure + + rabbit: + container_name: rabbit + image: rabbitmq + ports: + - 5672:5672 + healthcheck: + test: [ "CMD", "curl", "-f", "http://localhost:5672" ] + interval: 30s + timeout: 10s + retries: 5 + + postgres: + container_name: postgres + image: postgres + environment: + - POSTGRES_USER=user + - POSTGRES_PASSWORD=pass + - POSTGRES_DB=blockatlas + ports: + - 5432:5432 + healthcheck: + test: [ "CMD", "curl", "-f", "http://localhost:5432" ] + interval: 30s + timeout: 10s + retries: 5 diff --git a/docs/docs.go b/docs/docs.go index b0fff90d4..ec99327d8 100644 --- a/docs/docs.go +++ b/docs/docs.go @@ -1,6 +1,5 @@ // GENERATED BY THE COMMAND ABOVE; DO NOT EDIT -// This file was generated by swaggo/swag at -// 2020-01-21 15:34:39.376593 -0300 -03 m=+0.082727839 +// This file was generated by swaggo/swag package docs @@ -26,60 +25,44 @@ var doc = `{ "host": "{{.Host}}", "basePath": "{{.BasePath}}", "paths": { - "/metrics": { - "get": { - "description": "Get application metrics", - "tags": [ - "metrics" + "/v2/staking/delegations": { + "post": { + "description": "Get Stake Delegations for multiple coins", + "consumes": [ + "application/json" ], - "summary": "Get Metrics", - "operationId": "metrics" - } - }, - "/ns/lookup": { - "get": { - "description": "Lookup ENS/ZNS to find registered addresses", "produces": [ "application/json" ], "tags": [ - "ns" + "Staking" ], - "summary": "Lookup .eth / .zil addresses", - "operationId": "lookup", + "summary": "Get Multiple Stake Delegations", + "operationId": "staking_v2_batch", "parameters": [ { - "type": "string", - "description": "string name", - "name": "name", - "in": "query" - }, - { - "type": "string", - "description": "string coin", - "name": "coin", - "in": "query" + "description": "Validators addresses and coins", + "name": "delegations", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/endpoint.AddressesRequest" + } } ], "responses": { "200": { "description": "OK", "schema": { - "$ref": "#/definitions/blockatlas.Resolved" - } - }, - "500": { - "description": "Internal Server Error", - "schema": { - "$ref": "#/definitions/ginutils.ApiError" + "$ref": "#/definitions/blockatlas.DelegationsBatchPage" } } } } }, - "/observer/v1/status": { - "get": { - "description": "Get coin status", + "/v2/staking/list": { + "post": { + "description": "Get Stake Delegations for multiple coins", "consumes": [ "application/json" ], @@ -87,34 +70,34 @@ var doc = `{ "application/json" ], "tags": [ - "observer", - "subscriptions" + "Staking" ], - "summary": "Get coin status", - "operationId": "coin_status", + "summary": "Get Multiple Stake Delegations", + "operationId": "staking_v2", "parameters": [ { - "type": "string", - "default": "Bearer test", - "description": "Bearer authorization header", - "name": "Authorization", - "in": "header", - "required": true + "description": "Validators addresses and coins", + "name": "delegations", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/endpoint.AddressesRequest" + } } ], "responses": { "200": { "description": "OK", "schema": { - "$ref": "#/definitions/blockatlas.CoinStatus" + "$ref": "#/definitions/blockatlas.DelegationsBatchPage" } } } } }, - "/observer/v1/webhook/register": { + "/v2/tokens": { "post": { - "description": "Create a webhook for addresses transactions", + "description": "Get tokens", "consumes": [ "application/json" ], @@ -122,41 +105,35 @@ var doc = `{ "application/json" ], "tags": [ - "observer", - "subscriptions" + "Transactions" ], - "summary": "Create a webhook", - "operationId": "create_webhook", + "summary": "Get list of tokens by map: coin -\u003e [addresses]", + "operationId": "tokens_v3", "parameters": [ { - "description": "Accounts subscriptions", - "name": "subscriptions", + "default": "{\"60\": [\"0xb3624367b1ab37daef42e1a3a2ced012359659b0\"]}", + "description": "Payload", + "name": "data", "in": "body", "required": true, "schema": { - "$ref": "#/definitions/blockatlas.Webhook" + "type": "string" } - }, - { - "type": "string", - "default": "Bearer test", - "description": "Bearer authorization header", - "name": "Authorization", - "in": "header", - "required": true } ], "responses": { "200": { "description": "OK", "schema": { - "$ref": "#/definitions/blockatlas.Observer" + "$ref": "#/definitions/blockatlas.ResultsResponse" } } } - }, - "delete": { - "description": "Delete a webhook for addresses transactions", + } + }, + "/v2/{coin}/blocks/{block}": { + "get": { + "description": "Get Block information", "consumes": [ "application/json" ], @@ -164,43 +141,41 @@ var doc = `{ "application/json" ], "tags": [ - "observer", - "subscriptions" + "Transactions" ], - "summary": "Delete a webhook", - "operationId": "delete_webhook", + "summary": "Get Block", + "operationId": "block_v2", "parameters": [ { - "description": "Accounts subscriptions", - "name": "subscriptions", - "in": "body", - "required": true, - "schema": { - "$ref": "#/definitions/blockatlas.Webhook" - } + "type": "string", + "default": "zilliqa", + "description": "the coin name", + "name": "coin", + "in": "path", + "required": true }, { "type": "string", - "default": "Bearer test", - "description": "Bearer authorization header", - "name": "Authorization", - "in": "header", + "default": "850321", + "description": "the query address", + "name": "address", + "in": "path", "required": true } ], "responses": { - "200": { - "description": "OK", + "500": { + "description": "Internal Server Error", "schema": { - "$ref": "#/definitions/blockatlas.Observer" + "$ref": "#/definitions/endpoint.ErrorResponse" } } } } }, - "/v1/market/charts": { + "/v2/{coin}/staking/delegations/{address}": { "get": { - "description": "Get the charts data from an market and coin/token", + "description": "Get stake delegations from the address", "consumes": [ "application/json" ], @@ -208,60 +183,47 @@ var doc = `{ "application/json" ], "tags": [ - "charts" + "Staking" ], - "summary": "Get charts data for a specific coin", - "operationId": "get_charts_data", + "summary": "Get Stake Delegations", + "operationId": "delegations", "parameters": [ { - "type": "integer", - "default": 60, - "description": "Coin ID", + "type": "string", + "default": "tron", + "description": "the coin name", "name": "coin", - "in": "query", + "in": "path", "required": true }, { "type": "string", - "description": "Token ID", - "name": "token", - "in": "query" - }, - { - "type": "integer", - "default": 1574483028, - "description": "Start timestamp", - "name": "time_start", - "in": "query" - }, - { - "type": "integer", - "default": 64, - "description": "Max number of items in result prices array", - "name": "max_items", - "in": "query" - }, - { - "type": "string", - "default": "USD", - "description": "The currency to show charts", - "name": "currency", - "in": "query" + "default": "TPJYCz8ppZNyvw7pTwmjajcx4Kk1MmEUhD", + "description": "the query address", + "name": "address", + "in": "path", + "required": true } ], "responses": { "200": { "description": "OK", "schema": { - "$ref": "#/definitions/blockatlas.ChartData" + "$ref": "#/definitions/blockatlas.DelegationResponse" + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/endpoint.ErrorResponse" } } } } }, - "/v1/market/info": { + "/v2/{coin}/staking/validators": { "get": { - "description": "Get the charts coin info data from an market and coin/contract", + "description": "Get validators from the address", "consumes": [ "application/json" ], @@ -269,53 +231,39 @@ var doc = `{ "application/json" ], "tags": [ - "charts" + "Staking" ], - "summary": "Get charts coin info data for a specific coin", - "operationId": "get_charts_coin_info", + "summary": "Get Validators", + "operationId": "validators_v2", "parameters": [ { - "type": "integer", - "default": 60, - "description": "Coin ID", + "type": "string", + "default": "cosmos", + "description": "the coin name", "name": "coin", - "in": "query", + "in": "path", "required": true - }, - { - "type": "string", - "description": "Token ID", - "name": "token", - "in": "query" - }, - { - "type": "integer", - "default": 1574483028, - "description": "Start timestamp", - "name": "time_start", - "in": "query" - }, - { - "type": "string", - "default": "USD", - "description": "The currency to show coin info in", - "name": "currency", - "in": "query" } ], "responses": { "200": { "description": "OK", "schema": { - "$ref": "#/definitions/blockatlas.ChartCoinInfo" + "$ref": "#/definitions/blockatlas.DocsResponse" + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/endpoint.ErrorResponse" } } } } }, - "/v1/market/ticker": { + "/v2/{coin}/tokens/{address}": { "get": { - "description": "Get the ticker value from an market and coin/token", + "description": "Get tokens from the address", "consumes": [ "application/json" ], @@ -323,78 +271,47 @@ var doc = `{ "application/json" ], "tags": [ - "ticker" + "Transactions" ], - "summary": "Get ticker value for a specific market", - "operationId": "get_ticker", + "summary": "Get Tokens", + "operationId": "tokens", "parameters": [ { - "type": "integer", - "description": "coin id", + "type": "string", + "default": "ethereum", + "description": "the coin name", "name": "coin", - "in": "query", + "in": "path", "required": true }, { "type": "string", - "description": "token id", - "name": "token", - "in": "query" - }, - { - "type": "string", - "default": "USD", - "description": "the currency to show the quote", - "name": "currency", - "in": "query" + "default": "0x5574Cd97432cEd0D7Caf58ac3c4fEDB2061C98fB", + "description": "the query address", + "name": "address", + "in": "path", + "required": true } ], "responses": { "200": { "description": "OK", "schema": { - "$ref": "#/definitions/blockatlas.Ticker" - } - } - } - }, - "post": { - "description": "Get the ticker values from many markets and coin/token", - "consumes": [ - "application/json" - ], - "produces": [ - "application/json" - ], - "tags": [ - "ticker" - ], - "summary": "Get ticker values for a specific markets", - "operationId": "get_tickers", - "parameters": [ - { - "description": "Ticker", - "name": "tickers", - "in": "body", - "required": true, - "schema": { - "$ref": "#/definitions/api.TickerRequest" + "$ref": "#/definitions/types.CollectionPage" } - } - ], - "responses": { - "200": { - "description": "OK", + }, + "500": { + "description": "Internal Server Error", "schema": { - "$ref": "#/definitions/blockatlas.Tickers" + "$ref": "#/definitions/endpoint.ErrorResponse" } } } } }, - "/v1/{coin}/xpub/{xpub}": { + "/v2/{coin}/transactions/xpub/{xpub}": { "get": { - "description": "Get transactions from xpub address", + "description": "Get transactions from XPUB address", "consumes": [ "application/json" ], @@ -402,11 +319,10 @@ var doc = `{ "application/json" ], "tags": [ - "platform", - "tx" + "Transactions" ], - "summary": "Get xpub transactions", - "operationId": "xpub", + "summary": "Get Transactions by XPUB", + "operationId": "tx_xpub_v2", "parameters": [ { "type": "string", @@ -419,23 +335,23 @@ var doc = `{ { "type": "string", "default": "zpub6ruK9k6YGm8BRHWvTiQcrEPnFkuRDJhR7mPYzV2LDvjpLa5CuGgrhCYVZjMGcLcFqv9b2WvsFtY2Gb3xq8NVq8qhk9veozrA2W9QaWtihrC", - "description": "the xpub address", + "description": "the xpub key", "name": "xpub", "in": "path", "required": true } ], "responses": { - "200": { - "description": "OK", + "500": { + "description": "Internal Server Error", "schema": { - "$ref": "#/definitions/blockatlas.TxPage" + "$ref": "#/definitions/endpoint.ErrorResponse" } } } } }, - "/v1/{coin}/{address}": { + "/v2/{coin}/transactions/{address}": { "get": { "description": "Get transactions from the address", "consumes": [ @@ -445,11 +361,10 @@ var doc = `{ "application/json" ], "tags": [ - "platform", - "tx" + "Transactions" ], "summary": "Get Transactions", - "operationId": "tx_v1", + "operationId": "tx_v2", "parameters": [ { "type": "string", @@ -472,66 +387,24 @@ var doc = `{ "500": { "description": "Internal Server Error", "schema": { - "$ref": "#/definitions/ginutils.ApiError" - } - } - } - } - }, - "/v2/collectibles/categories": { - "post": { - "description": "Get collection categories", - "consumes": [ - "application/json" - ], - "produces": [ - "application/json" - ], - "tags": [ - "Collectibles" - ], - "summary": "Get list of collections from a specific coin and addresses", - "operationId": "collection_categories_v2", - "parameters": [ - { - "default": "{\"60\": [\"0xb3624367b1ab37daef42e1a3a2ced012359659b0\"]}", - "description": "Payload", - "name": "data", - "in": "body", - "required": true, - "schema": { - "type": "string" - } - } - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "$ref": "#/definitions/blockatlas.DocsResponse" + "$ref": "#/definitions/endpoint.ErrorResponse" } } } } }, - "/v2/ns/lookup": { + "/v3/staking/list": { "get": { - "description": "Lookup ENS/ZNS to find registered addresses for multiple coins", + "description": "Get staking info by coin ID", "produces": [ "application/json" ], "tags": [ - "ns" + "Staking" ], - "summary": "Lookup .eth / .zil addresses", - "operationId": "lookup", + "summary": "Get staking info by coin ID", + "operationId": "staking_v3", "parameters": [ - { - "type": "string", - "description": "string name", - "name": "name", - "in": "query" - }, { "type": "string", "description": "List of coins", @@ -546,22 +419,22 @@ var doc = `{ "schema": { "type": "array", "items": { - "$ref": "#/definitions/blockatlas.Resolved" + "$ref": "#/definitions/blockatlas.DelegationsBatchPage" } } }, - "500": { - "description": "Internal Server Error", + "400": { + "description": "Bad Request", "schema": { - "$ref": "#/definitions/ginutils.ApiError" + "$ref": "#/definitions/endpoint.ErrorResponse" } } } } }, - "/v2/staking/delegations": { - "post": { - "description": "Get Stake Delegations for multiple coins", + "/v3/tokens/new": { + "get": { + "description": "Get new tokens", "consumes": [ "application/json" ], @@ -569,35 +442,38 @@ var doc = `{ "application/json" ], "tags": [ - "platform", - "staking" + "Transactions" ], - "summary": "Get Multiple Stake Delegations", - "operationId": "batch_delegations", + "summary": "Get list of new tokens by coin from specific unix timstamp", + "operationId": "tokens_new_v3", "parameters": [ { - "description": "Validators addresses and coins", - "name": "delegations", - "in": "body", - "required": true, - "schema": { - "$ref": "#/definitions/api.AddressesRequest" - } + "type": "integer", + "description": "unix timestamp", + "name": "from", + "in": "query", + "required": true + }, + { + "type": "integer", + "description": "coin like 60", + "name": "coin", + "in": "query" } ], "responses": { "200": { "description": "OK", "schema": { - "$ref": "#/definitions/blockatlas.DelegationsBatchPage" + "$ref": "#/definitions/tokenindexer.Response" } } } } }, - "/v2/staking/list": { + "/v4/collectibles/categories": { "post": { - "description": "Get Stake Delegations for multiple coins", + "description": "Get collection categories", "consumes": [ "application/json" ], @@ -605,19 +481,19 @@ var doc = `{ "application/json" ], "tags": [ - "platform", - "staking" + "Collections" ], - "summary": "Get Multiple Stake Delegations", - "operationId": "batch_delegations", + "summary": "Get list of collections from a specific coin and addresses", + "operationId": "collection_categories_v4", "parameters": [ { - "description": "Validators addresses and coins", - "name": "delegations", + "default": "{\"60\": [\"0xb3624367b1ab37daef42e1a3a2ced012359659b0\"]}", + "description": "Payload", + "name": "data", "in": "body", "required": true, "schema": { - "$ref": "#/definitions/api.AddressesRequest" + "type": "string" } } ], @@ -625,15 +501,15 @@ var doc = `{ "200": { "description": "OK", "schema": { - "$ref": "#/definitions/blockatlas.DelegationsBatchPage" + "$ref": "#/definitions/blockatlas.DocsResponse" } } } } }, - "/v2/{coin}/collections/{address}": { + "/v4/{coin}/collections/{owner}/collection/{collection_id}": { "get": { - "description": "Get all collections from the address", + "description": "Get a collection from the address", "consumes": [ "application/json" ], @@ -641,390 +517,10 @@ var doc = `{ "application/json" ], "tags": [ - "platform", - "collection" - ], - "summary": "Get Collections", - "operationId": "collections_v2", - "parameters": [ - { - "type": "string", - "default": "ethereum", - "description": "the coin name", - "name": "coin", - "in": "path", - "required": true - }, - { - "type": "string", - "default": "0x5574Cd97432cEd0D7Caf58ac3c4fEDB2061C98fB", - "description": "the query address", - "name": "address", - "in": "path", - "required": true - } - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "$ref": "#/definitions/blockatlas.CollectionPage" - } - }, - "500": { - "description": "Internal Server Error", - "schema": { - "$ref": "#/definitions/ginutils.ApiError" - } - } - } - } - }, - "/v2/{coin}/collections/{owner}/collection/{collection_id}": { - "get": { - "description": "Get a collection from the address", - "consumes": [ - "application/json" - ], - "produces": [ - "application/json" - ], - "tags": [ - "platform", - "collection" - ], - "summary": "Get Collection", - "operationId": "collection_v2", - "parameters": [ - { - "type": "string", - "default": "ethereum", - "description": "the coin name", - "name": "coin", - "in": "path", - "required": true - }, - { - "type": "string", - "default": "0x0875BCab22dE3d02402bc38aEe4104e1239374a7", - "description": "the query address", - "name": "owner", - "in": "path", - "required": true - }, - { - "type": "string", - "default": "0x06012c8cf97bead5deae237070f9587f8e7a266d", - "description": "the query collection", - "name": "collection_id", - "in": "path", - "required": true - } - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "$ref": "#/definitions/blockatlas.CollectionPage" - } - }, - "500": { - "description": "Internal Server Error", - "schema": { - "$ref": "#/definitions/ginutils.ApiError" - } - } - } - } - }, - "/v2/{coin}/staking/delegations/{address}": { - "get": { - "description": "Get stake delegations from the address", - "consumes": [ - "application/json" - ], - "produces": [ - "application/json" - ], - "tags": [ - "platform", - "staking" - ], - "summary": "Get Stake Delegations", - "operationId": "delegations", - "parameters": [ - { - "type": "string", - "default": "tron", - "description": "the coin name", - "name": "coin", - "in": "path", - "required": true - }, - { - "type": "string", - "default": "TPJYCz8ppZNyvw7pTwmjajcx4Kk1MmEUhD", - "description": "the query address", - "name": "address", - "in": "path", - "required": true - } - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "$ref": "#/definitions/blockatlas.DelegationResponse" - } - }, - "500": { - "description": "Internal Server Error", - "schema": { - "$ref": "#/definitions/ginutils.ApiError" - } - } - } - } - }, - "/v2/{coin}/staking/validators": { - "get": { - "description": "Get validators from the address", - "consumes": [ - "application/json" - ], - "produces": [ - "application/json" - ], - "tags": [ - "platform", - "staking" - ], - "summary": "Get Validators", - "operationId": "validators", - "parameters": [ - { - "type": "string", - "default": "cosmos", - "description": "the coin name", - "name": "coin", - "in": "path", - "required": true - } - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "$ref": "#/definitions/blockatlas.DocsResponse" - } - }, - "500": { - "description": "Internal Server Error", - "schema": { - "$ref": "#/definitions/ginutils.ApiError" - } - } - } - } - }, - "/v2/{coin}/tokens/{address}": { - "get": { - "description": "Get tokens from the address", - "consumes": [ - "application/json" - ], - "produces": [ - "application/json" - ], - "tags": [ - "platform", - "token" - ], - "summary": "Get Tokens", - "operationId": "tokens", - "parameters": [ - { - "type": "string", - "default": "ethereum", - "description": "the coin name", - "name": "coin", - "in": "path", - "required": true - }, - { - "type": "string", - "default": "0x5574Cd97432cEd0D7Caf58ac3c4fEDB2061C98fB", - "description": "the query address", - "name": "address", - "in": "path", - "required": true - } - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "$ref": "#/definitions/blockatlas.CollectionPage" - } - }, - "500": { - "description": "Internal Server Error", - "schema": { - "$ref": "#/definitions/ginutils.ApiError" - } - } - } - } - }, - "/v2/{coin}/transactions/{address}": { - "get": { - "description": "Get transactions from the address", - "consumes": [ - "application/json" - ], - "produces": [ - "application/json" - ], - "tags": [ - "platform", - "tx" - ], - "summary": "Get Transactions", - "operationId": "tx_v2", - "parameters": [ - { - "type": "string", - "default": "tezos", - "description": "the coin name", - "name": "coin", - "in": "path", - "required": true - }, - { - "type": "string", - "default": "tz1WCd2jm4uSt4vntk4vSuUWoZQGhLcDuR9q", - "description": "the query address", - "name": "address", - "in": "path", - "required": true - } - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "$ref": "#/definitions/blockatlas.TxPage" - } - }, - "500": { - "description": "Internal Server Error", - "schema": { - "$ref": "#/definitions/ginutils.ApiError" - } - } - } - } - }, - "/v3/collectibles/categories": { - "post": { - "description": "Get collection categories", - "consumes": [ - "application/json" - ], - "produces": [ - "application/json" - ], - "tags": [ - "Collectibles" - ], - "summary": "Get list of collections from a specific coin and addresses", - "operationId": "collection_categories_v3", - "parameters": [ - { - "default": "{\"60\": [\"0xb3624367b1ab37daef42e1a3a2ced012359659b0\"]}", - "description": "Payload", - "name": "data", - "in": "body", - "required": true, - "schema": { - "type": "string" - } - } - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "$ref": "#/definitions/blockatlas.DocsResponse" - } - } - } - } - }, - "/v3/{coin}/collections/{address}": { - "get": { - "description": "Get all collections from the address", - "consumes": [ - "application/json" - ], - "produces": [ - "application/json" - ], - "tags": [ - "platform", - "collection" - ], - "summary": "Get Collections", - "operationId": "collections_v3", - "parameters": [ - { - "type": "string", - "default": "ethereum", - "description": "the coin name", - "name": "coin", - "in": "path", - "required": true - }, - { - "type": "string", - "default": "0x5574Cd97432cEd0D7Caf58ac3c4fEDB2061C98fB", - "description": "the query address", - "name": "address", - "in": "path", - "required": true - } - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "$ref": "#/definitions/blockatlas.CollectionPage" - } - }, - "500": { - "description": "Internal Server Error", - "schema": { - "$ref": "#/definitions/ginutils.ApiError" - } - } - } - } - }, - "/v3/{coin}/collections/{owner}/collection/{collection_id}": { - "get": { - "description": "Get a collection from the address", - "consumes": [ - "application/json" - ], - "produces": [ - "application/json" - ], - "tags": [ - "platform", - "collection" + "Collections" ], "summary": "Get Collection", - "operationId": "collection_v3", + "operationId": "collection_v4", "parameters": [ { "type": "string", @@ -1055,13 +551,13 @@ var doc = `{ "200": { "description": "OK", "schema": { - "$ref": "#/definitions/blockatlas.CollectionPage" + "$ref": "#/definitions/types.CollectionPage" } }, "500": { "description": "Internal Server Error", "schema": { - "$ref": "#/definitions/ginutils.ApiError" + "$ref": "#/definitions/endpoint.ErrorResponse" } } } @@ -1069,113 +565,12 @@ var doc = `{ } }, "definitions": { - "api.AddressBatchRequest": { - "type": "object", - "properties": { - "address": { - "type": "string" - }, - "coin": { - "type": "integer" - } - } - }, - "api.AddressesRequest": { - "type": "array", - "items": { - "$ref": "#/definitions/api.AddressBatchRequest" - } - }, - "api.Coin": { - "type": "object", - "properties": { - "coin": { - "type": "integer" - }, - "token_id": { - "type": "string" - }, - "type": { - "type": "string" - } - } - }, - "api.TickerRequest": { - "type": "object", - "properties": { - "assets": { - "type": "array", - "items": { - "$ref": "#/definitions/api.Coin" - } - }, - "currency": { - "type": "string" - } - } - }, - "blockatlas.ChartCoinInfo": { - "type": "object", - "properties": { - "circulating_supply": { - "type": "number" - }, - "market_cap": { - "type": "number" - }, - "total_supply": { - "type": "number" - }, - "volume_24": { - "type": "number" - } - } - }, - "blockatlas.ChartData": { - "type": "object", - "properties": { - "error": { - "type": "string" - }, - "prices": { - "type": "array", - "items": { - "$ref": "#/definitions/blockatlas.ChartPrice" - } - } - } - }, - "blockatlas.ChartPrice": { - "type": "object", - "properties": { - "date": { - "type": "integer" - }, - "price": { - "type": "number" - } - } - }, - "blockatlas.CoinStatus": { - "type": "object", - "properties": { - "error": { - "type": "string" - }, - "height": { - "type": "integer" - } - } - }, "blockatlas.Collection": { "type": "object", "properties": { "address": { "type": "string" }, - "category_address": { - "type": "string" - }, "coin": { "type": "integer" }, @@ -1194,24 +589,12 @@ var doc = `{ "name": { "type": "string" }, - "nft_version": { - "type": "string" - }, - "slug": { - "type": "string" - }, - "symbol": { - "type": "string" - }, "total": { "type": "integer" - }, - "type": { - "type": "string" } } }, - "blockatlas.CollectionPage": { + "types.CollectionPage": { "type": "array", "items": { "$ref": "#/definitions/blockatlas.Collection" @@ -1278,25 +661,14 @@ var doc = `{ } } }, - "blockatlas.Observer": { + "blockatlas.ResultsResponse": { "type": "object", "properties": { - "message": { - "type": "string" + "docs": { + "type": "object" }, - "status": { - "type": "boolean" - } - } - }, - "blockatlas.Resolved": { - "type": "object", - "properties": { - "coin": { + "total": { "type": "integer" - }, - "result": { - "type": "string" } } }, @@ -1362,178 +734,62 @@ var doc = `{ } } }, - "blockatlas.Ticker": { + "coin.ExternalCoin": { "type": "object", "properties": { "coin": { "type": "integer" }, - "coin_name": { - "type": "string" - }, - "error": { - "type": "string" - }, - "last_update": { - "type": "string" - }, - "price": { - "type": "object", - "$ref": "#/definitions/blockatlas.TickerPrice" + "decimals": { + "type": "integer" }, - "token_id": { + "name": { "type": "string" }, - "type": { + "symbol": { "type": "string" } } }, - "blockatlas.TickerPrice": { + "endpoint.AddressBatchRequest": { "type": "object", "properties": { - "change_24h": { - "type": "number" - }, - "currency": { - "type": "string" - }, - "provider": { + "address": { "type": "string" }, - "value": { - "type": "number" + "coin": { + "type": "integer" } } }, - "blockatlas.Tickers": { + "endpoint.AddressesRequest": { "type": "array", "items": { - "$ref": "#/definitions/blockatlas.Ticker" - } - }, - "blockatlas.Tx": { - "type": "object", - "properties": { - "block": { - "description": "Height of the block the transaction was included in", - "type": "integer" - }, - "coin": { - "description": "SLIP-44 coin index of the platform", - "type": "integer" - }, - "date": { - "description": "Unix timestamp of the block the transaction was included in", - "type": "integer" - }, - "direction": { - "description": "Transaction Direction", - "type": "string" - }, - "error": { - "description": "Empty if the transaction was successful,\nelse error explaining why the transaction failed (optional)", - "type": "string" - }, - "fee": { - "description": "Transaction fee (native currency)", - "type": "string" - }, - "from": { - "description": "Address of the transaction sender", - "type": "string" - }, - "id": { - "description": "Unique identifier", - "type": "string" - }, - "inputs": { - "description": "Input addresses", - "type": "array", - "items": { - "$ref": "#/definitions/blockatlas.TxOutput" - } - }, - "memo": { - "description": "Meta data object", - "type": "string" - }, - "metadata": { - "type": "object" - }, - "outputs": { - "description": "Output addresses", - "type": "array", - "items": { - "$ref": "#/definitions/blockatlas.TxOutput" - } - }, - "sequence": { - "description": "Transaction nonce or sequence", - "type": "integer" - }, - "status": { - "description": "Status of the transaction", - "type": "string" - }, - "to": { - "description": "Address of the transaction recipient", - "type": "string" - }, - "type": { - "description": "Type of metadata", - "type": "string" - } + "$ref": "#/definitions/endpoint.AddressBatchRequest" } }, - "blockatlas.TxOutput": { + "endpoint.ErrorDetails": { "type": "object", "properties": { - "address": { - "type": "string" - }, - "value": { + "message": { "type": "string" } } }, - "blockatlas.TxPage": { - "type": "array", - "items": { - "$ref": "#/definitions/blockatlas.Tx" - } - }, - "blockatlas.Webhook": { + "endpoint.ErrorResponse": { "type": "object", "properties": { - "subscriptions": { - "type": "object", - "additionalProperties": { - "type": "array", - "items": { - "type": "string" - } - } - }, - "webhook": { - "type": "string" - }, - "xpub_subscriptions": { + "error": { "type": "object", - "additionalProperties": { - "type": "array", - "items": { - "type": "string" - } - } + "$ref": "#/definitions/endpoint.ErrorDetails" } } }, - "coin.ExternalCoin": { + "tokenindexer.Asset": { "type": "object", "properties": { - "coin": { - "type": "integer" + "asset": { + "type": "string" }, "decimals": { "type": "integer" @@ -1543,17 +799,20 @@ var doc = `{ }, "symbol": { "type": "string" + }, + "type": { + "type": "string" } } }, - "ginutils.ApiError": { + "tokenindexer.Response": { "type": "object", "properties": { - "status_code": { - "type": "integer" - }, - "status_message": { - "type": "string" + "assets": { + "type": "array", + "items": { + "$ref": "#/definitions/tokenindexer.Asset" + } } } } diff --git a/docs/features.csv b/docs/features.csv new file mode 100644 index 000000000..b9a04d4e7 --- /dev/null +++ b/docs/features.csv @@ -0,0 +1,29 @@ +Chain\API,Transaction list,Block parsing,Staking ,Token list,Collectiable +Bitcoin,✅,✅,N/A,N/A,N/A +Ethereum,✅,✅,,✅,✅ +ICON,✅,,N/A,N/A,N/A +Cosmos,✅,✅,✅,, +XRP,✅,✅,N/A,N/A,N/A +Stellar,✅,✅,N/A,,N/A +Nano,✅,,N/A,N/A,N/A +Tron,✅,✅,✅,✅, +FIO,✅,,N/A,N/A,N/A +Nimiq,✅,✅,N/A,N/A,N/A +Algorand,✅,✅,✅,,N/A +IoTeX,✅,✅,✅,N/A,N/A +Zilliqa,✅,✅,,N/A,N/A +Polkadot,✅,✅,,,N/A +Aion,✅,,,N/A,N/A +Aeternity,✅,,N/A,N/A,N/A +Kava,✅,✅,✅,, +Filecoin,,✅,N/A,N/A,N/A +Theta,✅,,N/A,N/A,N/A +Solana,,,✅,,N/A +Elrond,✅,✅,,N/A,N/A +BNB,✅,✅,,✅, +VeChain,✅,✅,N/A,N/A,N/A +Harmony,✅,✅,✅,N/A,N/A +Ontology,✅,✅,N/A,N/A,N/A +Tezos,✅,✅,✅,,N/A +Nebulas,✅,✅,N/A,N/A,N/A +Waves,✅,✅,,N/A,N/A diff --git a/docs/swagger.json b/docs/swagger.json index c4fda60fb..4fcea199b 100644 --- a/docs/swagger.json +++ b/docs/swagger.json @@ -5,60 +5,44 @@ "license": {} }, "paths": { - "/metrics": { - "get": { - "description": "Get application metrics", - "tags": [ - "metrics" + "/v2/staking/delegations": { + "post": { + "description": "Get Stake Delegations for multiple coins", + "consumes": [ + "application/json" ], - "summary": "Get Metrics", - "operationId": "metrics" - } - }, - "/ns/lookup": { - "get": { - "description": "Lookup ENS/ZNS to find registered addresses", "produces": [ "application/json" ], "tags": [ - "ns" + "Staking" ], - "summary": "Lookup .eth / .zil addresses", - "operationId": "lookup", + "summary": "Get Multiple Stake Delegations", + "operationId": "staking_v2_batch", "parameters": [ { - "type": "string", - "description": "string name", - "name": "name", - "in": "query" - }, - { - "type": "string", - "description": "string coin", - "name": "coin", - "in": "query" + "description": "Validators addresses and coins", + "name": "delegations", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/endpoint.AddressesRequest" + } } ], "responses": { "200": { "description": "OK", "schema": { - "$ref": "#/definitions/blockatlas.Resolved" - } - }, - "500": { - "description": "Internal Server Error", - "schema": { - "$ref": "#/definitions/ginutils.ApiError" + "$ref": "#/definitions/blockatlas.DelegationsBatchPage" } } } } }, - "/observer/v1/status": { - "get": { - "description": "Get coin status", + "/v2/staking/list": { + "post": { + "description": "Get Stake Delegations for multiple coins", "consumes": [ "application/json" ], @@ -66,34 +50,34 @@ "application/json" ], "tags": [ - "observer", - "subscriptions" + "Staking" ], - "summary": "Get coin status", - "operationId": "coin_status", + "summary": "Get Multiple Stake Delegations", + "operationId": "staking_v2", "parameters": [ { - "type": "string", - "default": "Bearer test", - "description": "Bearer authorization header", - "name": "Authorization", - "in": "header", - "required": true + "description": "Validators addresses and coins", + "name": "delegations", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/endpoint.AddressesRequest" + } } ], "responses": { "200": { "description": "OK", "schema": { - "$ref": "#/definitions/blockatlas.CoinStatus" + "$ref": "#/definitions/blockatlas.DelegationsBatchPage" } } } } }, - "/observer/v1/webhook/register": { + "/v2/tokens": { "post": { - "description": "Create a webhook for addresses transactions", + "description": "Get tokens", "consumes": [ "application/json" ], @@ -101,41 +85,35 @@ "application/json" ], "tags": [ - "observer", - "subscriptions" + "Transactions" ], - "summary": "Create a webhook", - "operationId": "create_webhook", + "summary": "Get list of tokens by map: coin -\u003e [addresses]", + "operationId": "tokens_v3", "parameters": [ { - "description": "Accounts subscriptions", - "name": "subscriptions", + "default": "{\"60\": [\"0xb3624367b1ab37daef42e1a3a2ced012359659b0\"]}", + "description": "Payload", + "name": "data", "in": "body", "required": true, "schema": { - "$ref": "#/definitions/blockatlas.Webhook" + "type": "string" } - }, - { - "type": "string", - "default": "Bearer test", - "description": "Bearer authorization header", - "name": "Authorization", - "in": "header", - "required": true } ], "responses": { "200": { "description": "OK", "schema": { - "$ref": "#/definitions/blockatlas.Observer" + "$ref": "#/definitions/blockatlas.ResultsResponse" } } } - }, - "delete": { - "description": "Delete a webhook for addresses transactions", + } + }, + "/v2/{coin}/blocks/{block}": { + "get": { + "description": "Get Block information", "consumes": [ "application/json" ], @@ -143,43 +121,41 @@ "application/json" ], "tags": [ - "observer", - "subscriptions" + "Transactions" ], - "summary": "Delete a webhook", - "operationId": "delete_webhook", + "summary": "Get Block", + "operationId": "block_v2", "parameters": [ { - "description": "Accounts subscriptions", - "name": "subscriptions", - "in": "body", - "required": true, - "schema": { - "$ref": "#/definitions/blockatlas.Webhook" - } + "type": "string", + "default": "zilliqa", + "description": "the coin name", + "name": "coin", + "in": "path", + "required": true }, { "type": "string", - "default": "Bearer test", - "description": "Bearer authorization header", - "name": "Authorization", - "in": "header", + "default": "850321", + "description": "the query address", + "name": "address", + "in": "path", "required": true } ], "responses": { - "200": { - "description": "OK", + "500": { + "description": "Internal Server Error", "schema": { - "$ref": "#/definitions/blockatlas.Observer" + "$ref": "#/definitions/endpoint.ErrorResponse" } } } } }, - "/v1/market/charts": { + "/v2/{coin}/staking/delegations/{address}": { "get": { - "description": "Get the charts data from an market and coin/token", + "description": "Get stake delegations from the address", "consumes": [ "application/json" ], @@ -187,60 +163,47 @@ "application/json" ], "tags": [ - "charts" + "Staking" ], - "summary": "Get charts data for a specific coin", - "operationId": "get_charts_data", + "summary": "Get Stake Delegations", + "operationId": "delegations", "parameters": [ { - "type": "integer", - "default": 60, - "description": "Coin ID", + "type": "string", + "default": "tron", + "description": "the coin name", "name": "coin", - "in": "query", + "in": "path", "required": true }, { "type": "string", - "description": "Token ID", - "name": "token", - "in": "query" - }, - { - "type": "integer", - "default": 1574483028, - "description": "Start timestamp", - "name": "time_start", - "in": "query" - }, - { - "type": "integer", - "default": 64, - "description": "Max number of items in result prices array", - "name": "max_items", - "in": "query" - }, - { - "type": "string", - "default": "USD", - "description": "The currency to show charts", - "name": "currency", - "in": "query" + "default": "TPJYCz8ppZNyvw7pTwmjajcx4Kk1MmEUhD", + "description": "the query address", + "name": "address", + "in": "path", + "required": true } ], "responses": { "200": { "description": "OK", "schema": { - "$ref": "#/definitions/blockatlas.ChartData" + "$ref": "#/definitions/blockatlas.DelegationResponse" + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/endpoint.ErrorResponse" } } } } }, - "/v1/market/info": { + "/v2/{coin}/staking/validators": { "get": { - "description": "Get the charts coin info data from an market and coin/contract", + "description": "Get validators from the address", "consumes": [ "application/json" ], @@ -248,53 +211,39 @@ "application/json" ], "tags": [ - "charts" + "Staking" ], - "summary": "Get charts coin info data for a specific coin", - "operationId": "get_charts_coin_info", + "summary": "Get Validators", + "operationId": "validators_v2", "parameters": [ { - "type": "integer", - "default": 60, - "description": "Coin ID", + "type": "string", + "default": "cosmos", + "description": "the coin name", "name": "coin", - "in": "query", + "in": "path", "required": true - }, - { - "type": "string", - "description": "Token ID", - "name": "token", - "in": "query" - }, - { - "type": "integer", - "default": 1574483028, - "description": "Start timestamp", - "name": "time_start", - "in": "query" - }, - { - "type": "string", - "default": "USD", - "description": "The currency to show coin info in", - "name": "currency", - "in": "query" } ], "responses": { "200": { "description": "OK", "schema": { - "$ref": "#/definitions/blockatlas.ChartCoinInfo" + "$ref": "#/definitions/blockatlas.DocsResponse" + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/endpoint.ErrorResponse" } } } } }, - "/v1/market/ticker": { + "/v2/{coin}/tokens/{address}": { "get": { - "description": "Get the ticker value from an market and coin/token", + "description": "Get tokens from the address", "consumes": [ "application/json" ], @@ -302,78 +251,47 @@ "application/json" ], "tags": [ - "ticker" + "Transactions" ], - "summary": "Get ticker value for a specific market", - "operationId": "get_ticker", + "summary": "Get Tokens", + "operationId": "tokens", "parameters": [ { - "type": "integer", - "description": "coin id", + "type": "string", + "default": "ethereum", + "description": "the coin name", "name": "coin", - "in": "query", + "in": "path", "required": true }, { "type": "string", - "description": "token id", - "name": "token", - "in": "query" - }, - { - "type": "string", - "default": "USD", - "description": "the currency to show the quote", - "name": "currency", - "in": "query" + "default": "0x5574Cd97432cEd0D7Caf58ac3c4fEDB2061C98fB", + "description": "the query address", + "name": "address", + "in": "path", + "required": true } ], "responses": { "200": { "description": "OK", "schema": { - "$ref": "#/definitions/blockatlas.Ticker" - } - } - } - }, - "post": { - "description": "Get the ticker values from many markets and coin/token", - "consumes": [ - "application/json" - ], - "produces": [ - "application/json" - ], - "tags": [ - "ticker" - ], - "summary": "Get ticker values for a specific markets", - "operationId": "get_tickers", - "parameters": [ - { - "description": "Ticker", - "name": "tickers", - "in": "body", - "required": true, - "schema": { - "$ref": "#/definitions/api.TickerRequest" + "$ref": "#/definitions/types.CollectionPage" } - } - ], - "responses": { - "200": { - "description": "OK", + }, + "500": { + "description": "Internal Server Error", "schema": { - "$ref": "#/definitions/blockatlas.Tickers" + "$ref": "#/definitions/endpoint.ErrorResponse" } } } } }, - "/v1/{coin}/xpub/{xpub}": { + "/v2/{coin}/transactions/xpub/{xpub}": { "get": { - "description": "Get transactions from xpub address", + "description": "Get transactions from XPUB address", "consumes": [ "application/json" ], @@ -381,11 +299,10 @@ "application/json" ], "tags": [ - "platform", - "tx" + "Transactions" ], - "summary": "Get xpub transactions", - "operationId": "xpub", + "summary": "Get Transactions by XPUB", + "operationId": "tx_xpub_v2", "parameters": [ { "type": "string", @@ -398,23 +315,23 @@ { "type": "string", "default": "zpub6ruK9k6YGm8BRHWvTiQcrEPnFkuRDJhR7mPYzV2LDvjpLa5CuGgrhCYVZjMGcLcFqv9b2WvsFtY2Gb3xq8NVq8qhk9veozrA2W9QaWtihrC", - "description": "the xpub address", + "description": "the xpub key", "name": "xpub", "in": "path", "required": true } ], "responses": { - "200": { - "description": "OK", + "500": { + "description": "Internal Server Error", "schema": { - "$ref": "#/definitions/blockatlas.TxPage" + "$ref": "#/definitions/endpoint.ErrorResponse" } } } } }, - "/v1/{coin}/{address}": { + "/v2/{coin}/transactions/{address}": { "get": { "description": "Get transactions from the address", "consumes": [ @@ -424,11 +341,10 @@ "application/json" ], "tags": [ - "platform", - "tx" + "Transactions" ], "summary": "Get Transactions", - "operationId": "tx_v1", + "operationId": "tx_v2", "parameters": [ { "type": "string", @@ -451,66 +367,24 @@ "500": { "description": "Internal Server Error", "schema": { - "$ref": "#/definitions/ginutils.ApiError" - } - } - } - } - }, - "/v2/collectibles/categories": { - "post": { - "description": "Get collection categories", - "consumes": [ - "application/json" - ], - "produces": [ - "application/json" - ], - "tags": [ - "Collectibles" - ], - "summary": "Get list of collections from a specific coin and addresses", - "operationId": "collection_categories_v2", - "parameters": [ - { - "default": "{\"60\": [\"0xb3624367b1ab37daef42e1a3a2ced012359659b0\"]}", - "description": "Payload", - "name": "data", - "in": "body", - "required": true, - "schema": { - "type": "string" - } - } - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "$ref": "#/definitions/blockatlas.DocsResponse" + "$ref": "#/definitions/endpoint.ErrorResponse" } } } } }, - "/v2/ns/lookup": { + "/v3/staking/list": { "get": { - "description": "Lookup ENS/ZNS to find registered addresses for multiple coins", + "description": "Get staking info by coin ID", "produces": [ "application/json" ], "tags": [ - "ns" + "Staking" ], - "summary": "Lookup .eth / .zil addresses", - "operationId": "lookup", + "summary": "Get staking info by coin ID", + "operationId": "staking_v3", "parameters": [ - { - "type": "string", - "description": "string name", - "name": "name", - "in": "query" - }, { "type": "string", "description": "List of coins", @@ -525,22 +399,22 @@ "schema": { "type": "array", "items": { - "$ref": "#/definitions/blockatlas.Resolved" + "$ref": "#/definitions/blockatlas.DelegationsBatchPage" } } }, - "500": { - "description": "Internal Server Error", + "400": { + "description": "Bad Request", "schema": { - "$ref": "#/definitions/ginutils.ApiError" + "$ref": "#/definitions/endpoint.ErrorResponse" } } } } }, - "/v2/staking/delegations": { - "post": { - "description": "Get Stake Delegations for multiple coins", + "/v3/tokens/new": { + "get": { + "description": "Get new tokens", "consumes": [ "application/json" ], @@ -548,35 +422,38 @@ "application/json" ], "tags": [ - "platform", - "staking" + "Transactions" ], - "summary": "Get Multiple Stake Delegations", - "operationId": "batch_delegations", + "summary": "Get list of new tokens by coin from specific unix timstamp", + "operationId": "tokens_new_v3", "parameters": [ { - "description": "Validators addresses and coins", - "name": "delegations", - "in": "body", - "required": true, - "schema": { - "$ref": "#/definitions/api.AddressesRequest" - } + "type": "integer", + "description": "unix timestamp", + "name": "from", + "in": "query", + "required": true + }, + { + "type": "integer", + "description": "coin like 60", + "name": "coin", + "in": "query" } ], "responses": { "200": { "description": "OK", "schema": { - "$ref": "#/definitions/blockatlas.DelegationsBatchPage" + "$ref": "#/definitions/tokenindexer.Response" } } } } }, - "/v2/staking/list": { + "/v4/collectibles/categories": { "post": { - "description": "Get Stake Delegations for multiple coins", + "description": "Get collection categories", "consumes": [ "application/json" ], @@ -584,19 +461,19 @@ "application/json" ], "tags": [ - "platform", - "staking" + "Collections" ], - "summary": "Get Multiple Stake Delegations", - "operationId": "batch_delegations", + "summary": "Get list of collections from a specific coin and addresses", + "operationId": "collection_categories_v4", "parameters": [ { - "description": "Validators addresses and coins", - "name": "delegations", + "default": "{\"60\": [\"0xb3624367b1ab37daef42e1a3a2ced012359659b0\"]}", + "description": "Payload", + "name": "data", "in": "body", "required": true, "schema": { - "$ref": "#/definitions/api.AddressesRequest" + "type": "string" } } ], @@ -604,15 +481,15 @@ "200": { "description": "OK", "schema": { - "$ref": "#/definitions/blockatlas.DelegationsBatchPage" + "$ref": "#/definitions/blockatlas.DocsResponse" } } } } }, - "/v2/{coin}/collections/{address}": { + "/v4/{coin}/collections/{owner}/collection/{collection_id}": { "get": { - "description": "Get all collections from the address", + "description": "Get a collection from the address", "consumes": [ "application/json" ], @@ -620,390 +497,10 @@ "application/json" ], "tags": [ - "platform", - "collection" - ], - "summary": "Get Collections", - "operationId": "collections_v2", - "parameters": [ - { - "type": "string", - "default": "ethereum", - "description": "the coin name", - "name": "coin", - "in": "path", - "required": true - }, - { - "type": "string", - "default": "0x5574Cd97432cEd0D7Caf58ac3c4fEDB2061C98fB", - "description": "the query address", - "name": "address", - "in": "path", - "required": true - } - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "$ref": "#/definitions/blockatlas.CollectionPage" - } - }, - "500": { - "description": "Internal Server Error", - "schema": { - "$ref": "#/definitions/ginutils.ApiError" - } - } - } - } - }, - "/v2/{coin}/collections/{owner}/collection/{collection_id}": { - "get": { - "description": "Get a collection from the address", - "consumes": [ - "application/json" - ], - "produces": [ - "application/json" - ], - "tags": [ - "platform", - "collection" - ], - "summary": "Get Collection", - "operationId": "collection_v2", - "parameters": [ - { - "type": "string", - "default": "ethereum", - "description": "the coin name", - "name": "coin", - "in": "path", - "required": true - }, - { - "type": "string", - "default": "0x0875BCab22dE3d02402bc38aEe4104e1239374a7", - "description": "the query address", - "name": "owner", - "in": "path", - "required": true - }, - { - "type": "string", - "default": "0x06012c8cf97bead5deae237070f9587f8e7a266d", - "description": "the query collection", - "name": "collection_id", - "in": "path", - "required": true - } - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "$ref": "#/definitions/blockatlas.CollectionPage" - } - }, - "500": { - "description": "Internal Server Error", - "schema": { - "$ref": "#/definitions/ginutils.ApiError" - } - } - } - } - }, - "/v2/{coin}/staking/delegations/{address}": { - "get": { - "description": "Get stake delegations from the address", - "consumes": [ - "application/json" - ], - "produces": [ - "application/json" - ], - "tags": [ - "platform", - "staking" - ], - "summary": "Get Stake Delegations", - "operationId": "delegations", - "parameters": [ - { - "type": "string", - "default": "tron", - "description": "the coin name", - "name": "coin", - "in": "path", - "required": true - }, - { - "type": "string", - "default": "TPJYCz8ppZNyvw7pTwmjajcx4Kk1MmEUhD", - "description": "the query address", - "name": "address", - "in": "path", - "required": true - } - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "$ref": "#/definitions/blockatlas.DelegationResponse" - } - }, - "500": { - "description": "Internal Server Error", - "schema": { - "$ref": "#/definitions/ginutils.ApiError" - } - } - } - } - }, - "/v2/{coin}/staking/validators": { - "get": { - "description": "Get validators from the address", - "consumes": [ - "application/json" - ], - "produces": [ - "application/json" - ], - "tags": [ - "platform", - "staking" - ], - "summary": "Get Validators", - "operationId": "validators", - "parameters": [ - { - "type": "string", - "default": "cosmos", - "description": "the coin name", - "name": "coin", - "in": "path", - "required": true - } - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "$ref": "#/definitions/blockatlas.DocsResponse" - } - }, - "500": { - "description": "Internal Server Error", - "schema": { - "$ref": "#/definitions/ginutils.ApiError" - } - } - } - } - }, - "/v2/{coin}/tokens/{address}": { - "get": { - "description": "Get tokens from the address", - "consumes": [ - "application/json" - ], - "produces": [ - "application/json" - ], - "tags": [ - "platform", - "token" - ], - "summary": "Get Tokens", - "operationId": "tokens", - "parameters": [ - { - "type": "string", - "default": "ethereum", - "description": "the coin name", - "name": "coin", - "in": "path", - "required": true - }, - { - "type": "string", - "default": "0x5574Cd97432cEd0D7Caf58ac3c4fEDB2061C98fB", - "description": "the query address", - "name": "address", - "in": "path", - "required": true - } - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "$ref": "#/definitions/blockatlas.CollectionPage" - } - }, - "500": { - "description": "Internal Server Error", - "schema": { - "$ref": "#/definitions/ginutils.ApiError" - } - } - } - } - }, - "/v2/{coin}/transactions/{address}": { - "get": { - "description": "Get transactions from the address", - "consumes": [ - "application/json" - ], - "produces": [ - "application/json" - ], - "tags": [ - "platform", - "tx" - ], - "summary": "Get Transactions", - "operationId": "tx_v2", - "parameters": [ - { - "type": "string", - "default": "tezos", - "description": "the coin name", - "name": "coin", - "in": "path", - "required": true - }, - { - "type": "string", - "default": "tz1WCd2jm4uSt4vntk4vSuUWoZQGhLcDuR9q", - "description": "the query address", - "name": "address", - "in": "path", - "required": true - } - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "$ref": "#/definitions/blockatlas.TxPage" - } - }, - "500": { - "description": "Internal Server Error", - "schema": { - "$ref": "#/definitions/ginutils.ApiError" - } - } - } - } - }, - "/v3/collectibles/categories": { - "post": { - "description": "Get collection categories", - "consumes": [ - "application/json" - ], - "produces": [ - "application/json" - ], - "tags": [ - "Collectibles" - ], - "summary": "Get list of collections from a specific coin and addresses", - "operationId": "collection_categories_v3", - "parameters": [ - { - "default": "{\"60\": [\"0xb3624367b1ab37daef42e1a3a2ced012359659b0\"]}", - "description": "Payload", - "name": "data", - "in": "body", - "required": true, - "schema": { - "type": "string" - } - } - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "$ref": "#/definitions/blockatlas.DocsResponse" - } - } - } - } - }, - "/v3/{coin}/collections/{address}": { - "get": { - "description": "Get all collections from the address", - "consumes": [ - "application/json" - ], - "produces": [ - "application/json" - ], - "tags": [ - "platform", - "collection" - ], - "summary": "Get Collections", - "operationId": "collections_v3", - "parameters": [ - { - "type": "string", - "default": "ethereum", - "description": "the coin name", - "name": "coin", - "in": "path", - "required": true - }, - { - "type": "string", - "default": "0x5574Cd97432cEd0D7Caf58ac3c4fEDB2061C98fB", - "description": "the query address", - "name": "address", - "in": "path", - "required": true - } - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "$ref": "#/definitions/blockatlas.CollectionPage" - } - }, - "500": { - "description": "Internal Server Error", - "schema": { - "$ref": "#/definitions/ginutils.ApiError" - } - } - } - } - }, - "/v3/{coin}/collections/{owner}/collection/{collection_id}": { - "get": { - "description": "Get a collection from the address", - "consumes": [ - "application/json" - ], - "produces": [ - "application/json" - ], - "tags": [ - "platform", - "collection" + "Collections" ], "summary": "Get Collection", - "operationId": "collection_v3", + "operationId": "collection_v4", "parameters": [ { "type": "string", @@ -1034,13 +531,13 @@ "200": { "description": "OK", "schema": { - "$ref": "#/definitions/blockatlas.CollectionPage" + "$ref": "#/definitions/types.CollectionPage" } }, "500": { "description": "Internal Server Error", "schema": { - "$ref": "#/definitions/ginutils.ApiError" + "$ref": "#/definitions/endpoint.ErrorResponse" } } } @@ -1048,113 +545,12 @@ } }, "definitions": { - "api.AddressBatchRequest": { - "type": "object", - "properties": { - "address": { - "type": "string" - }, - "coin": { - "type": "integer" - } - } - }, - "api.AddressesRequest": { - "type": "array", - "items": { - "$ref": "#/definitions/api.AddressBatchRequest" - } - }, - "api.Coin": { - "type": "object", - "properties": { - "coin": { - "type": "integer" - }, - "token_id": { - "type": "string" - }, - "type": { - "type": "string" - } - } - }, - "api.TickerRequest": { - "type": "object", - "properties": { - "assets": { - "type": "array", - "items": { - "$ref": "#/definitions/api.Coin" - } - }, - "currency": { - "type": "string" - } - } - }, - "blockatlas.ChartCoinInfo": { - "type": "object", - "properties": { - "circulating_supply": { - "type": "number" - }, - "market_cap": { - "type": "number" - }, - "total_supply": { - "type": "number" - }, - "volume_24": { - "type": "number" - } - } - }, - "blockatlas.ChartData": { - "type": "object", - "properties": { - "error": { - "type": "string" - }, - "prices": { - "type": "array", - "items": { - "$ref": "#/definitions/blockatlas.ChartPrice" - } - } - } - }, - "blockatlas.ChartPrice": { - "type": "object", - "properties": { - "date": { - "type": "integer" - }, - "price": { - "type": "number" - } - } - }, - "blockatlas.CoinStatus": { - "type": "object", - "properties": { - "error": { - "type": "string" - }, - "height": { - "type": "integer" - } - } - }, "blockatlas.Collection": { "type": "object", "properties": { "address": { "type": "string" }, - "category_address": { - "type": "string" - }, "coin": { "type": "integer" }, @@ -1173,24 +569,12 @@ "name": { "type": "string" }, - "nft_version": { - "type": "string" - }, - "slug": { - "type": "string" - }, - "symbol": { - "type": "string" - }, "total": { "type": "integer" - }, - "type": { - "type": "string" } } }, - "blockatlas.CollectionPage": { + "types.CollectionPage": { "type": "array", "items": { "$ref": "#/definitions/blockatlas.Collection" @@ -1257,25 +641,14 @@ } } }, - "blockatlas.Observer": { + "blockatlas.ResultsResponse": { "type": "object", "properties": { - "message": { - "type": "string" + "docs": { + "type": "object" }, - "status": { - "type": "boolean" - } - } - }, - "blockatlas.Resolved": { - "type": "object", - "properties": { - "coin": { + "total": { "type": "integer" - }, - "result": { - "type": "string" } } }, @@ -1341,178 +714,62 @@ } } }, - "blockatlas.Ticker": { + "coin.ExternalCoin": { "type": "object", "properties": { "coin": { "type": "integer" }, - "coin_name": { - "type": "string" - }, - "error": { - "type": "string" - }, - "last_update": { - "type": "string" - }, - "price": { - "type": "object", - "$ref": "#/definitions/blockatlas.TickerPrice" + "decimals": { + "type": "integer" }, - "token_id": { + "name": { "type": "string" }, - "type": { + "symbol": { "type": "string" } } }, - "blockatlas.TickerPrice": { + "endpoint.AddressBatchRequest": { "type": "object", "properties": { - "change_24h": { - "type": "number" - }, - "currency": { - "type": "string" - }, - "provider": { + "address": { "type": "string" }, - "value": { - "type": "number" + "coin": { + "type": "integer" } } }, - "blockatlas.Tickers": { + "endpoint.AddressesRequest": { "type": "array", "items": { - "$ref": "#/definitions/blockatlas.Ticker" - } - }, - "blockatlas.Tx": { - "type": "object", - "properties": { - "block": { - "description": "Height of the block the transaction was included in", - "type": "integer" - }, - "coin": { - "description": "SLIP-44 coin index of the platform", - "type": "integer" - }, - "date": { - "description": "Unix timestamp of the block the transaction was included in", - "type": "integer" - }, - "direction": { - "description": "Transaction Direction", - "type": "string" - }, - "error": { - "description": "Empty if the transaction was successful,\nelse error explaining why the transaction failed (optional)", - "type": "string" - }, - "fee": { - "description": "Transaction fee (native currency)", - "type": "string" - }, - "from": { - "description": "Address of the transaction sender", - "type": "string" - }, - "id": { - "description": "Unique identifier", - "type": "string" - }, - "inputs": { - "description": "Input addresses", - "type": "array", - "items": { - "$ref": "#/definitions/blockatlas.TxOutput" - } - }, - "memo": { - "description": "Meta data object", - "type": "string" - }, - "metadata": { - "type": "object" - }, - "outputs": { - "description": "Output addresses", - "type": "array", - "items": { - "$ref": "#/definitions/blockatlas.TxOutput" - } - }, - "sequence": { - "description": "Transaction nonce or sequence", - "type": "integer" - }, - "status": { - "description": "Status of the transaction", - "type": "string" - }, - "to": { - "description": "Address of the transaction recipient", - "type": "string" - }, - "type": { - "description": "Type of metadata", - "type": "string" - } + "$ref": "#/definitions/endpoint.AddressBatchRequest" } }, - "blockatlas.TxOutput": { + "endpoint.ErrorDetails": { "type": "object", "properties": { - "address": { - "type": "string" - }, - "value": { + "message": { "type": "string" } } }, - "blockatlas.TxPage": { - "type": "array", - "items": { - "$ref": "#/definitions/blockatlas.Tx" - } - }, - "blockatlas.Webhook": { + "endpoint.ErrorResponse": { "type": "object", "properties": { - "subscriptions": { - "type": "object", - "additionalProperties": { - "type": "array", - "items": { - "type": "string" - } - } - }, - "webhook": { - "type": "string" - }, - "xpub_subscriptions": { + "error": { "type": "object", - "additionalProperties": { - "type": "array", - "items": { - "type": "string" - } - } + "$ref": "#/definitions/endpoint.ErrorDetails" } } }, - "coin.ExternalCoin": { + "tokenindexer.Asset": { "type": "object", "properties": { - "coin": { - "type": "integer" + "asset": { + "type": "string" }, "decimals": { "type": "integer" @@ -1522,17 +779,20 @@ }, "symbol": { "type": "string" + }, + "type": { + "type": "string" } } }, - "ginutils.ApiError": { + "tokenindexer.Response": { "type": "object", "properties": { - "status_code": { - "type": "integer" - }, - "status_message": { - "type": "string" + "assets": { + "type": "array", + "items": { + "$ref": "#/definitions/tokenindexer.Asset" + } } } } diff --git a/docs/swagger.yaml b/docs/swagger.yaml index cd7c129ef..c0c29c495 100644 --- a/docs/swagger.yaml +++ b/docs/swagger.yaml @@ -1,73 +1,8 @@ definitions: - api.AddressBatchRequest: - properties: - address: - type: string - coin: - type: integer - type: object - api.AddressesRequest: - items: - $ref: '#/definitions/api.AddressBatchRequest' - type: array - api.Coin: - properties: - coin: - type: integer - token_id: - type: string - type: - type: string - type: object - api.TickerRequest: - properties: - assets: - items: - $ref: '#/definitions/api.Coin' - type: array - currency: - type: string - type: object - blockatlas.ChartCoinInfo: - properties: - circulating_supply: - type: number - market_cap: - type: number - total_supply: - type: number - volume_24: - type: number - type: object - blockatlas.ChartData: - properties: - error: - type: string - prices: - items: - $ref: '#/definitions/blockatlas.ChartPrice' - type: array - type: object - blockatlas.ChartPrice: - properties: - date: - type: integer - price: - type: number - type: object - blockatlas.CoinStatus: - properties: - error: - type: string - height: - type: integer - type: object blockatlas.Collection: properties: address: type: string - category_address: - type: string coin: type: integer description: @@ -80,18 +15,10 @@ definitions: type: string name: type: string - nft_version: - type: string - slug: - type: string - symbol: - type: string total: type: integer - type: - type: string type: object - blockatlas.CollectionPage: + types.CollectionPage: items: $ref: '#/definitions/blockatlas.Collection' type: array @@ -136,19 +63,12 @@ definitions: docs: type: object type: object - blockatlas.Observer: - properties: - message: - type: string - status: - type: boolean - type: object - blockatlas.Resolved: + blockatlas.ResultsResponse: properties: - coin: + docs: + type: object + total: type: integer - result: - type: string type: object blockatlas.StakeValidator: properties: @@ -191,276 +111,77 @@ definitions: annual: type: number type: object - blockatlas.Ticker: - properties: - coin: - type: integer - coin_name: - type: string - error: - type: string - last_update: - type: string - price: - $ref: '#/definitions/blockatlas.TickerPrice' - type: object - token_id: - type: string - type: - type: string - type: object - blockatlas.TickerPrice: - properties: - change_24h: - type: number - currency: - type: string - provider: - type: string - value: - type: number - type: object - blockatlas.Tickers: - items: - $ref: '#/definitions/blockatlas.Ticker' - type: array - blockatlas.Tx: + coin.ExternalCoin: properties: - block: - description: Height of the block the transaction was included in - type: integer coin: - description: SLIP-44 coin index of the platform type: integer - date: - description: Unix timestamp of the block the transaction was included in - type: integer - direction: - description: Transaction Direction - type: string - error: - description: |- - Empty if the transaction was successful, - else error explaining why the transaction failed (optional) - type: string - fee: - description: Transaction fee (native currency) - type: string - from: - description: Address of the transaction sender - type: string - id: - description: Unique identifier - type: string - inputs: - description: Input addresses - items: - $ref: '#/definitions/blockatlas.TxOutput' - type: array - memo: - description: Meta data object - type: string - metadata: - type: object - outputs: - description: Output addresses - items: - $ref: '#/definitions/blockatlas.TxOutput' - type: array - sequence: - description: Transaction nonce or sequence + decimals: type: integer - status: - description: Status of the transaction - type: string - to: - description: Address of the transaction recipient + name: type: string - type: - description: Type of metadata + symbol: type: string type: object - blockatlas.TxOutput: + endpoint.AddressBatchRequest: properties: address: type: string - value: - type: string + coin: + type: integer type: object - blockatlas.TxPage: + endpoint.AddressesRequest: items: - $ref: '#/definitions/blockatlas.Tx' + $ref: '#/definitions/endpoint.AddressBatchRequest' type: array - blockatlas.Webhook: + endpoint.ErrorDetails: properties: - subscriptions: - additionalProperties: - items: - type: string - type: array - type: object - webhook: + message: type: string - xpub_subscriptions: - additionalProperties: - items: - type: string - type: array + type: object + endpoint.ErrorResponse: + properties: + error: + $ref: '#/definitions/endpoint.ErrorDetails' type: object type: object - coin.ExternalCoin: + tokenindexer.Asset: properties: - coin: - type: integer + asset: + type: string decimals: type: integer name: type: string symbol: type: string + type: + type: string type: object - ginutils.ApiError: + tokenindexer.Response: properties: - status_code: - type: integer - status_message: - type: string + assets: + items: + $ref: '#/definitions/tokenindexer.Asset' + type: array type: object info: contact: {} license: {} paths: - /metrics: - get: - description: Get application metrics - operationId: metrics - summary: Get Metrics - tags: - - metrics - /ns/lookup: - get: - description: Lookup ENS/ZNS to find registered addresses - operationId: lookup - parameters: - - description: string name - in: query - name: name - type: string - - description: string coin - in: query - name: coin - type: string - produces: - - application/json - responses: - "200": - description: OK - schema: - $ref: '#/definitions/blockatlas.Resolved' - "500": - description: Internal Server Error - schema: - $ref: '#/definitions/ginutils.ApiError' - summary: Lookup .eth / .zil addresses - tags: - - ns - /observer/v1/status: - get: - consumes: - - application/json - description: Get coin status - operationId: coin_status - parameters: - - default: Bearer test - description: Bearer authorization header - in: header - name: Authorization - required: true - type: string - produces: - - application/json - responses: - "200": - description: OK - schema: - $ref: '#/definitions/blockatlas.CoinStatus' - summary: Get coin status - tags: - - observer - - subscriptions - /observer/v1/webhook/register: - delete: - consumes: - - application/json - description: Delete a webhook for addresses transactions - operationId: delete_webhook - parameters: - - description: Accounts subscriptions - in: body - name: subscriptions - required: true - schema: - $ref: '#/definitions/blockatlas.Webhook' - - default: Bearer test - description: Bearer authorization header - in: header - name: Authorization - required: true - type: string - produces: - - application/json - responses: - "200": - description: OK - schema: - $ref: '#/definitions/blockatlas.Observer' - summary: Delete a webhook - tags: - - observer - - subscriptions - post: - consumes: - - application/json - description: Create a webhook for addresses transactions - operationId: create_webhook - parameters: - - description: Accounts subscriptions - in: body - name: subscriptions - required: true - schema: - $ref: '#/definitions/blockatlas.Webhook' - - default: Bearer test - description: Bearer authorization header - in: header - name: Authorization - required: true - type: string - produces: - - application/json - responses: - "200": - description: OK - schema: - $ref: '#/definitions/blockatlas.Observer' - summary: Create a webhook - tags: - - observer - - subscriptions - /v1/{coin}/{address}: + /v2/{coin}/blocks/{block}: get: consumes: - application/json - description: Get transactions from the address - operationId: tx_v1 + description: Get Block information + operationId: block_v2 parameters: - - default: tezos + - default: zilliqa description: the coin name in: path name: coin required: true type: string - - default: tz1WCd2jm4uSt4vntk4vSuUWoZQGhLcDuR9q + - default: "850321" description: the query address in: path name: address @@ -472,247 +193,10 @@ paths: "500": description: Internal Server Error schema: - $ref: '#/definitions/ginutils.ApiError' - summary: Get Transactions + $ref: '#/definitions/endpoint.ErrorResponse' + summary: Get Block tags: - - platform - - tx - /v1/{coin}/xpub/{xpub}: - get: - consumes: - - application/json - description: Get transactions from xpub address - operationId: xpub - parameters: - - default: bitcoin - description: the coin name - in: path - name: coin - required: true - type: string - - default: zpub6ruK9k6YGm8BRHWvTiQcrEPnFkuRDJhR7mPYzV2LDvjpLa5CuGgrhCYVZjMGcLcFqv9b2WvsFtY2Gb3xq8NVq8qhk9veozrA2W9QaWtihrC - description: the xpub address - in: path - name: xpub - required: true - type: string - produces: - - application/json - responses: - "200": - description: OK - schema: - $ref: '#/definitions/blockatlas.TxPage' - summary: Get xpub transactions - tags: - - platform - - tx - /v1/market/charts: - get: - consumes: - - application/json - description: Get the charts data from an market and coin/token - operationId: get_charts_data - parameters: - - default: 60 - description: Coin ID - in: query - name: coin - required: true - type: integer - - description: Token ID - in: query - name: token - type: string - - default: 1574483028 - description: Start timestamp - in: query - name: time_start - type: integer - - default: 64 - description: Max number of items in result prices array - in: query - name: max_items - type: integer - - default: USD - description: The currency to show charts - in: query - name: currency - type: string - produces: - - application/json - responses: - "200": - description: OK - schema: - $ref: '#/definitions/blockatlas.ChartData' - summary: Get charts data for a specific coin - tags: - - charts - /v1/market/info: - get: - consumes: - - application/json - description: Get the charts coin info data from an market and coin/contract - operationId: get_charts_coin_info - parameters: - - default: 60 - description: Coin ID - in: query - name: coin - required: true - type: integer - - description: Token ID - in: query - name: token - type: string - - default: 1574483028 - description: Start timestamp - in: query - name: time_start - type: integer - - default: USD - description: The currency to show coin info in - in: query - name: currency - type: string - produces: - - application/json - responses: - "200": - description: OK - schema: - $ref: '#/definitions/blockatlas.ChartCoinInfo' - summary: Get charts coin info data for a specific coin - tags: - - charts - /v1/market/ticker: - get: - consumes: - - application/json - description: Get the ticker value from an market and coin/token - operationId: get_ticker - parameters: - - description: coin id - in: query - name: coin - required: true - type: integer - - description: token id - in: query - name: token - type: string - - default: USD - description: the currency to show the quote - in: query - name: currency - type: string - produces: - - application/json - responses: - "200": - description: OK - schema: - $ref: '#/definitions/blockatlas.Ticker' - summary: Get ticker value for a specific market - tags: - - ticker - post: - consumes: - - application/json - description: Get the ticker values from many markets and coin/token - operationId: get_tickers - parameters: - - description: Ticker - in: body - name: tickers - required: true - schema: - $ref: '#/definitions/api.TickerRequest' - produces: - - application/json - responses: - "200": - description: OK - schema: - $ref: '#/definitions/blockatlas.Tickers' - summary: Get ticker values for a specific markets - tags: - - ticker - /v2/{coin}/collections/{address}: - get: - consumes: - - application/json - description: Get all collections from the address - operationId: collections_v2 - parameters: - - default: ethereum - description: the coin name - in: path - name: coin - required: true - type: string - - default: 0x5574Cd97432cEd0D7Caf58ac3c4fEDB2061C98fB - description: the query address - in: path - name: address - required: true - type: string - produces: - - application/json - responses: - "200": - description: OK - schema: - $ref: '#/definitions/blockatlas.CollectionPage' - "500": - description: Internal Server Error - schema: - $ref: '#/definitions/ginutils.ApiError' - summary: Get Collections - tags: - - platform - - collection - /v2/{coin}/collections/{owner}/collection/{collection_id}: - get: - consumes: - - application/json - description: Get a collection from the address - operationId: collection_v2 - parameters: - - default: ethereum - description: the coin name - in: path - name: coin - required: true - type: string - - default: 0x0875BCab22dE3d02402bc38aEe4104e1239374a7 - description: the query address - in: path - name: owner - required: true - type: string - - default: 0x06012c8cf97bead5deae237070f9587f8e7a266d - description: the query collection - in: path - name: collection_id - required: true - type: string - produces: - - application/json - responses: - "200": - description: OK - schema: - $ref: '#/definitions/blockatlas.CollectionPage' - "500": - description: Internal Server Error - schema: - $ref: '#/definitions/ginutils.ApiError' - summary: Get Collection - tags: - - platform - - collection + - Transactions /v2/{coin}/staking/delegations/{address}: get: consumes: @@ -742,17 +226,16 @@ paths: "500": description: Internal Server Error schema: - $ref: '#/definitions/ginutils.ApiError' + $ref: '#/definitions/endpoint.ErrorResponse' summary: Get Stake Delegations tags: - - platform - - staking + - Staking /v2/{coin}/staking/validators: get: consumes: - application/json description: Get validators from the address - operationId: validators + operationId: validators_v2 parameters: - default: cosmos description: the coin name @@ -770,11 +253,10 @@ paths: "500": description: Internal Server Error schema: - $ref: '#/definitions/ginutils.ApiError' + $ref: '#/definitions/endpoint.ErrorResponse' summary: Get Validators tags: - - platform - - staking + - Staking /v2/{coin}/tokens/{address}: get: consumes: @@ -800,15 +282,14 @@ paths: "200": description: OK schema: - $ref: '#/definitions/blockatlas.CollectionPage' + $ref: '#/definitions/types.CollectionPage' "500": description: Internal Server Error schema: - $ref: '#/definitions/ginutils.ApiError' + $ref: '#/definitions/endpoint.ErrorResponse' summary: Get Tokens tags: - - platform - - token + - Transactions /v2/{coin}/transactions/{address}: get: consumes: @@ -831,85 +312,55 @@ paths: produces: - application/json responses: - "200": - description: OK - schema: - $ref: '#/definitions/blockatlas.TxPage' "500": description: Internal Server Error schema: - $ref: '#/definitions/ginutils.ApiError' + $ref: '#/definitions/endpoint.ErrorResponse' summary: Get Transactions tags: - - platform - - tx - /v2/collectibles/categories: - post: + - Transactions + /v2/{coin}/transactions/xpub/{xpub}: + get: consumes: - application/json - description: Get collection categories - operationId: collection_categories_v2 + description: Get transactions from XPUB address + operationId: tx_xpub_v2 parameters: - - default: '{"60": ["0xb3624367b1ab37daef42e1a3a2ced012359659b0"]}' - description: Payload - in: body - name: data + - default: bitcoin + description: the coin name + in: path + name: coin required: true - schema: - type: string - produces: - - application/json - responses: - "200": - description: OK - schema: - $ref: '#/definitions/blockatlas.DocsResponse' - summary: Get list of collections from a specific coin and addresses - tags: - - Collectibles - /v2/ns/lookup: - get: - description: Lookup ENS/ZNS to find registered addresses for multiple coins - operationId: lookup - parameters: - - description: string name - in: query - name: name type: string - - description: List of coins - in: query - name: coins + - default: zpub6ruK9k6YGm8BRHWvTiQcrEPnFkuRDJhR7mPYzV2LDvjpLa5CuGgrhCYVZjMGcLcFqv9b2WvsFtY2Gb3xq8NVq8qhk9veozrA2W9QaWtihrC + description: the xpub key + in: path + name: xpub required: true type: string produces: - application/json responses: - "200": - description: OK - schema: - items: - $ref: '#/definitions/blockatlas.Resolved' - type: array "500": description: Internal Server Error schema: - $ref: '#/definitions/ginutils.ApiError' - summary: Lookup .eth / .zil addresses + $ref: '#/definitions/endpoint.ErrorResponse' + summary: Get Transactions by XPUB tags: - - ns + - Transactions /v2/staking/delegations: post: consumes: - application/json description: Get Stake Delegations for multiple coins - operationId: batch_delegations + operationId: staking_v2_batch parameters: - description: Validators addresses and coins in: body name: delegations required: true schema: - $ref: '#/definitions/api.AddressesRequest' + $ref: '#/definitions/endpoint.AddressesRequest' produces: - application/json responses: @@ -919,21 +370,20 @@ paths: $ref: '#/definitions/blockatlas.DelegationsBatchPage' summary: Get Multiple Stake Delegations tags: - - platform - - staking + - Staking /v2/staking/list: post: consumes: - application/json description: Get Stake Delegations for multiple coins - operationId: batch_delegations + operationId: staking_v2 parameters: - description: Validators addresses and coins in: body name: delegations required: true schema: - $ref: '#/definitions/api.AddressesRequest' + $ref: '#/definitions/endpoint.AddressesRequest' produces: - application/json responses: @@ -943,25 +393,39 @@ paths: $ref: '#/definitions/blockatlas.DelegationsBatchPage' summary: Get Multiple Stake Delegations tags: - - platform - - staking - /v3/{coin}/collections/{address}: - get: + - Staking + /v2/tokens: + post: consumes: - application/json - description: Get all collections from the address - operationId: collections_v3 + description: Get tokens + operationId: tokens_v3 parameters: - - default: ethereum - description: the coin name - in: path - name: coin + - default: '{"60": ["0xb3624367b1ab37daef42e1a3a2ced012359659b0"]}' + description: Payload + in: body + name: data required: true - type: string - - default: 0x5574Cd97432cEd0D7Caf58ac3c4fEDB2061C98fB - description: the query address - in: path - name: address + schema: + type: string + produces: + - application/json + responses: + "200": + description: OK + schema: + $ref: '#/definitions/blockatlas.ResultsResponse' + summary: 'Get list of tokens by map: coin -> [addresses]' + tags: + - Transactions + /v3/staking/list: + get: + description: Get staking info by coin ID + operationId: staking_v3 + parameters: + - description: List of coins + in: query + name: coins required: true type: string produces: @@ -970,21 +434,48 @@ paths: "200": description: OK schema: - $ref: '#/definitions/blockatlas.CollectionPage' - "500": - description: Internal Server Error + items: + $ref: '#/definitions/blockatlas.DelegationsBatchPage' + type: array + "400": + description: Bad Request + schema: + $ref: '#/definitions/endpoint.ErrorResponse' + summary: Get staking info by coin ID + tags: + - Staking + /v3/tokens/new: + get: + consumes: + - application/json + description: Get new tokens + operationId: tokens_new_v3 + parameters: + - description: unix timestamp + in: query + name: from + required: true + type: integer + - description: coin like 60 + in: query + name: coin + type: integer + produces: + - application/json + responses: + "200": + description: OK schema: - $ref: '#/definitions/ginutils.ApiError' - summary: Get Collections + $ref: '#/definitions/tokenindexer.Response' + summary: Get list of new tokens by coin from specific unix timstamp tags: - - platform - - collection - /v3/{coin}/collections/{owner}/collection/{collection_id}: + - Transactions + /v4/{coin}/collections/{owner}/collection/{collection_id}: get: consumes: - application/json description: Get a collection from the address - operationId: collection_v3 + operationId: collection_v4 parameters: - default: ethereum description: the coin name @@ -1010,21 +501,20 @@ paths: "200": description: OK schema: - $ref: '#/definitions/blockatlas.CollectionPage' + $ref: '#/definitions/types.CollectionPage' "500": description: Internal Server Error schema: - $ref: '#/definitions/ginutils.ApiError' + $ref: '#/definitions/endpoint.ErrorResponse' summary: Get Collection tags: - - platform - - collection - /v3/collectibles/categories: + - Collections + /v4/collectibles/categories: post: consumes: - application/json description: Get collection categories - operationId: collection_categories_v3 + operationId: collection_categories_v4 parameters: - default: '{"60": ["0xb3624367b1ab37daef42e1a3a2ced012359659b0"]}' description: Payload @@ -1042,5 +532,5 @@ paths: $ref: '#/definitions/blockatlas.DocsResponse' summary: Get list of collections from a specific coin and addresses tags: - - Collectibles + - Collections swagger: "2.0" diff --git a/go.mod b/go.mod index 30695b6be..edd84eca0 100644 --- a/go.mod +++ b/go.mod @@ -1,66 +1,38 @@ module github.com/trustwallet/blockatlas -// +heroku goVersion go1.13 -go 1.13.3 +go 1.15 + +// +heroku goVersion go1.15 +// +heroku install ./cmd/... require ( - github.com/Pantani/httpexpect v2.0.0+incompatible + github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1 // indirect + github.com/Microsoft/go-winio v0.5.2 // indirect github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751 - github.com/allegro/bigcache v1.2.1 // indirect - github.com/aristanetworks/goarista v0.0.0-20191106175434-873d404c7f40 // indirect - github.com/btcsuite/btcutil v0.0.0-20190425235716-9e5f4b9a998d - github.com/cenkalti/backoff v2.2.1+incompatible - github.com/cespare/xxhash/v2 v2.1.1 // indirect - github.com/chenjiandongx/ginprom v0.0.0-20191022035802-6f3da3c84986 + github.com/btcsuite/btcutil v1.0.2 + github.com/containerd/continuity v0.1.0 // indirect github.com/deckarep/golang-set v1.7.1 - github.com/elastic/gosigar v0.10.5 // indirect - github.com/ethereum/go-ethereum v1.9.2 - github.com/gballet/go-libpcsclite v0.0.0-20191108122812-4678299bea08 // indirect - github.com/getsentry/sentry-go v0.3.1 - github.com/gin-gonic/gin v1.4.0 - github.com/go-openapi/jsonreference v0.19.3 // indirect - github.com/go-openapi/spec v0.19.4 // indirect - github.com/go-redis/redis v6.15.6+incompatible - github.com/google/uuid v1.1.1 // indirect - github.com/hashicorp/golang-lru v0.5.3 // indirect - github.com/hewigovens/go-coincodec v1.0.4 - github.com/jackpal/go-nat-pmp v1.0.2 // indirect - github.com/jinzhu/gorm v1.9.11 - github.com/json-iterator/go v1.1.8 // indirect - github.com/karalabe/usb v0.0.0-20191104083709-911d15fe12a9 // indirect - github.com/konsorten/go-windows-terminal-sequences v1.0.2 // indirect - github.com/mailru/easyjson v0.7.0 // indirect - github.com/mattn/go-isatty v0.0.10 // indirect - github.com/mattn/go-runewidth v0.0.6 // indirect - github.com/minio/sha256-simd v0.1.1 // indirect - github.com/mr-tron/base58 v1.1.2 - github.com/multiformats/go-multihash v0.0.9 // indirect - github.com/olekukonko/tablewriter v0.0.2 // indirect + github.com/getsentry/raven-go v0.2.0 + github.com/gin-contrib/cors v1.3.1 + github.com/gin-gonic/gin v1.7.7 + github.com/itchyny/timefmt-go v0.1.2 + github.com/mitchellh/mapstructure v1.4.1 + github.com/mr-tron/base58 v1.2.0 + github.com/opencontainers/runc v1.1.0 // indirect + github.com/ory/dockertest v3.3.5+incompatible github.com/patrickmn/go-cache v2.1.0+incompatible - github.com/pelletier/go-toml v1.6.0 // indirect - github.com/prometheus/client_golang v1.2.1 - github.com/prometheus/procfs v0.0.7 // indirect - github.com/robfig/cron/v3 v3.0.0 - github.com/rs/cors v1.7.0 // indirect - github.com/shopspring/decimal v0.0.0-20200105231215-408a2507e114 - github.com/sirupsen/logrus v1.4.2 - github.com/spf13/afero v1.2.2 // indirect - github.com/spf13/cast v1.3.0 - github.com/spf13/cobra v0.0.5 - github.com/spf13/jwalterweatherman v1.1.0 // indirect - github.com/spf13/pflag v1.0.5 // indirect - github.com/spf13/viper v1.5.0 - github.com/status-im/keycard-go v0.0.0-20191114114615-9d48af884d5b // indirect - github.com/stretchr/testify v1.4.0 - github.com/swaggo/files v0.0.0-20190704085106-630677cd5c14 - github.com/swaggo/gin-swagger v1.2.0 - github.com/swaggo/swag v1.6.3 - github.com/ugorji/go v1.1.7 // indirect - github.com/wealdtech/go-ens/v3 v3.0.9 - github.com/xeipuuv/gojsonpointer v0.0.0-20190809123943-df4f5c81cb3b // indirect - golang.org/x/crypto v0.0.0-20191117063200-497ca9f6d64f - golang.org/x/net v0.0.0-20191118183410-d06c31c94cae // indirect - golang.org/x/sys v0.0.0-20191118133127-cf1e2d577169 // indirect - golang.org/x/tools v0.0.0-20191118222007-07fc4c7f2b98 // indirect - gopkg.in/yaml.v2 v2.2.5 + github.com/prometheus/client_golang v0.9.4 + github.com/sirupsen/logrus v1.8.1 + github.com/spf13/viper v1.7.1 + github.com/streadway/amqp v1.0.0 + github.com/stretchr/testify v1.7.0 + github.com/swaggo/gin-swagger v1.3.0 + github.com/swaggo/swag v1.7.0 + github.com/trustwallet/golibs v0.1.8 + github.com/trustwallet/golibs/network v0.0.0-20210302024139-c340cb937103 + golang.org/x/crypto v0.0.0-20220315160706-3147a52a75dd + golang.org/x/tools v0.0.0-20210106214847-113979e3529a // indirect + gopkg.in/yaml.v2 v2.4.0 + gorm.io/driver/postgres v1.0.8 + gorm.io/gorm v1.20.12 ) diff --git a/go.sum b/go.sum index 522779a79..13cd10500 100644 --- a/go.sum +++ b/go.sum @@ -1,63 +1,55 @@ +bazil.org/fuse v0.0.0-20160811212531-371fbbdaa898/go.mod h1:Xbm+BRKSBEpa4q4hTSxohYNQpsxXPbPry4JJWOB3LB8= cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= -cloud.google.com/go v0.37.4 h1:glPeL3BQJsbF6aIIYfZizMwc5LTYz250bDMjttbBGAU= -cloud.google.com/go v0.37.4/go.mod h1:NHPJ89PdicEuT9hdPXMROBD91xc5uRDxsMtSB16k7hw= -github.com/AndreasBriese/bbloom v0.0.0-20190306092124-e2d15f34fcf9/go.mod h1:bOvUY6CB00SOBii9/FifXqc0awNKxLFCL/+pkDPuyl8= +cloud.google.com/go v0.38.0/go.mod h1:990N+gfupTy94rShfmMCWGDn0LpTmnzTp2qbd1dvSRU= +cloud.google.com/go v0.44.1/go.mod h1:iSa0KzasP4Uvy3f1mN/7PiObzGgflwredwwASm/v6AU= +cloud.google.com/go v0.44.2/go.mod h1:60680Gw3Yr4ikxnPRS/oxxkBccT6SA1yMk63TGekxKY= +cloud.google.com/go v0.45.1/go.mod h1:RpBamKRgapWJb87xiFSdk4g1CME7QZg3uwTez+TSTjc= +cloud.google.com/go v0.46.3/go.mod h1:a6bKKbmY7er1mI7TEI4lsAkts/mkhTSZK8w33B4RAg0= +cloud.google.com/go/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbfbpx4poX+o= +cloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7TKLgZqpHYE= +cloud.google.com/go/firestore v1.1.0/go.mod h1:ulACoGHTpvq5r8rxGJ4ddJZBZqakUQqClKRT5SZwBmk= +cloud.google.com/go/pubsub v1.0.1/go.mod h1:R0Gpsv3s54REJCy4fxDixWD93lHJMoZTyQ2kNxGRt3I= +cloud.google.com/go/storage v1.0.0/go.mod h1:IhtSnM/ZTZV8YYJWCY8RULGVqBDmpoyjwiyrjsg+URw= +dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= +github.com/Azure/go-ansiterm v0.0.0-20170929234023-d6e3b3328b78/go.mod h1:LmzpDX56iTiv29bbRTIsUNlaFfuhWRQBWjQdVyAevI8= +github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1 h1:UQHMgLO+TxOElx5B5HZ4hJQsoJ/PvUvKRhJHDQXO8P8= +github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1/go.mod h1:xomTg63KZ2rFqZQzSB4Vz2SUXa1BpHTVz9L5PTmPC4E= github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= -github.com/CloudyKit/fastprinter v0.0.0-20170127035650-74b38d55f37a/go.mod h1:EFZQ978U7x8IRnstaskI3IysnWY5Ao3QgZUKOXlsAdw= -github.com/CloudyKit/jet v2.1.3-0.20180809161101-62edd43e4f88+incompatible/go.mod h1:HPYO+50pSWkPoj9Q/eq0aRGByCL6ScRlUmiEX5Zgm+w= -github.com/DataDog/zstd v1.3.6-0.20190409195224-796139022798/go.mod h1:1jcaCB/ufaK+sKp1NBhlGmpz41jOoPQ35bpF36t7BBo= -github.com/Joker/hpp v1.0.0/go.mod h1:8x5n+M1Hp5hC0g8okX3sR3vFQwynaX/UgSOM9MeBKzY= -github.com/Joker/jade v1.0.1-0.20190614124447-d475f43051e7/go.mod h1:6E6s8o2AE4KhCrqr6GRJjdC/gNfTdxkIXvuGZZda2VM= +github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= github.com/KyleBanks/depth v1.2.1 h1:5h8fQADFrWtarTdtDudMmGsC7GPbOAu6RVB3ffsVFHc= github.com/KyleBanks/depth v1.2.1/go.mod h1:jzSb9d0L43HxTQfT+oSA1EEp2q+ne2uh6XgeJcm8brE= +github.com/Microsoft/go-winio v0.4.16/go.mod h1:XB6nPKklQyQ7GC9LdcBEcBl8PF76WugXOPRXwdLnMv0= +github.com/Microsoft/go-winio v0.5.2 h1:a9IhgEQBCUEk6QCdml9CiJGhAws+YwffDHEMp1VMrpA= +github.com/Microsoft/go-winio v0.5.2/go.mod h1:WpS1mjBmmwHBEWmogvA2mj8546UReBk4v8QkMxJ6pZY= +github.com/Nvveen/Gotty v0.0.0-20120604004816-cd527374f1e5 h1:TngWCqHvy9oXAN6lEVMRuU21PR1EtLVZJmdB18Gu3Rw= +github.com/Nvveen/Gotty v0.0.0-20120604004816-cd527374f1e5/go.mod h1:lmUJ/7eu/Q8D7ML55dXQrVaamCz2vxCfdQBasLZfHKk= github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU= -github.com/Pantani/httpexpect v2.0.0+incompatible h1:P658jo0d3gej0D67KBcSUgpZY76CH1TdxvOfQAmyNu0= -github.com/Pantani/httpexpect v2.0.0+incompatible/go.mod h1:+8VdK+EZPV0YorWMMNyakEIYKcDl9OHtde3DdkPqbwQ= github.com/PuerkitoBio/purell v1.1.0/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0= github.com/PuerkitoBio/purell v1.1.1 h1:WEQqlqaGbrPkxLJWfBwQmfEAE1Z7ONdDLqrN38tNFfI= github.com/PuerkitoBio/purell v1.1.1/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0= github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578 h1:d+Bc7a5rLufV/sSk/8dngufqelfh6jnri85riMAaF/M= github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578/go.mod h1:uGdkoq3SwY9Y+13GIhn11/XLaGBb4BfwItxLd5jeuXE= -github.com/Shopify/goreferrer v0.0.0-20181106222321-ec9c9a553398/go.mod h1:a1uqRtAwp2Xwc6WNPJEufxJ7fx3npB4UV/JOLmbu5I0= -github.com/Shopify/sarama v1.19.0/go.mod h1:FVkBWblsNy7DGZRfXLU0O9RCGt5g3g3yEuWXgklEdEo= -github.com/Shopify/sarama v1.23.1/go.mod h1:XLH1GYJnLVE0XCr6KdJGVJRTwY30moWNJ4sERjXX6fs= -github.com/Shopify/toxiproxy v2.1.4+incompatible/go.mod h1:OXgGpZ6Cli1/URJOF1DMxUHB2q5Ap20/P/eIdh4G0pI= github.com/aead/siphash v1.0.1/go.mod h1:Nywa3cDsYNNK3gaciGTWPwHt0wlpNV15vwmswBAUSII= -github.com/ajg/form v1.5.1 h1:t9c7v8JUKu/XxOGBU0yjNpaMloxGEJhUkqFRq0ibGeU= -github.com/ajg/form v1.5.1/go.mod h1:uL1WgH+h2mgNtvBq0339dVnzXdBETtL2LeUXaIv25UY= github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751 h1:JYp7IbQjafoB+tBA3gMyHYHrpOtNuDiK/uB5uXxq5wM= github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= -github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= -github.com/allegro/bigcache v1.2.0/go.mod h1:Cb/ax3seSYIx7SuZdm2G2xzfwmv3TPSk2ucNfQESPXM= -github.com/allegro/bigcache v1.2.1 h1:hg1sY1raCwic3Vnsvje6TT7/pnZba83LeFck5NrFKSc= -github.com/allegro/bigcache v1.2.1/go.mod h1:Cb/ax3seSYIx7SuZdm2G2xzfwmv3TPSk2ucNfQESPXM= -github.com/apache/thrift v0.12.0/go.mod h1:cp2SuWMxlEZw2r+iP2GNCdIi4C1qmUzdZFSVb+bacwQ= -github.com/apilayer/freegeoip v3.5.0+incompatible h1:z1u2gv0/rsSi/HqMDB436AiUROXXim7st5DOg4Ikl4A= -github.com/apilayer/freegeoip v3.5.0+incompatible/go.mod h1:CUfFqErhFhXneJendyQ/rRcuA8kH8JxHvYnbOozmlCU= -github.com/aristanetworks/fsnotify v1.4.2/go.mod h1:D/rtu7LpjYM8tRJphJ0hUBYpjai8SfX+aSNsWDTq/Ks= -github.com/aristanetworks/glog v0.0.0-20180419172825-c15b03b3054f/go.mod h1:KASm+qXFKs/xjSoWn30NrWBBvdTTQq+UjkhjEJHfSFA= -github.com/aristanetworks/goarista v0.0.0-20190219163901-728bce664cf5/go.mod h1:D/tb0zPVXnP7fmsLZjtdUhSsumbK/ij54UXjjVgMGxQ= -github.com/aristanetworks/goarista v0.0.0-20191106175434-873d404c7f40 h1:ZdRuixFqR3mfx4FHzclG3COrRgWrYq0VhNgIoYoObcM= -github.com/aristanetworks/goarista v0.0.0-20191106175434-873d404c7f40/go.mod h1:Z4RTxGAuYhPzcq8+EdRM+R8M48Ssle2TsWtwRKa+vns= -github.com/aristanetworks/splunk-hec-go v0.3.3/go.mod h1:1VHO9r17b0K7WmOlLb9nTk/2YanvOEnLMUgsFrxBROc= +github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e/go.mod h1:3U/XgcO3hCbHZ8TKRvWD2dDTCfh9M9ya+I9JpbB7O8o= github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8= -github.com/aymerick/raymond v2.0.3-0.20180322193309-b565731e1464+incompatible/go.mod h1:osfaiScAUVup+UC9Nfq76eWqDhXlp+4UYaA8uhTBO6g= +github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da/go.mod h1:Q73ZrmVTwzkszR9V5SSuryQ31EELlFMUz1kKyl939pY= +github.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8= github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= +github.com/beorn7/perks v1.0.0 h1:HWo1m869IqiPhD389kmkxeTalrjNbbJTC8LXupb+sl0= github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8= -github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= -github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= -github.com/btcsuite/btcd v0.0.0-20190418232430-6867ff32788a/go.mod h1:DrZx5ec/dmnfpw9KyYoQyYo7d0KEvTkk/5M/vbZjAr8= -github.com/btcsuite/btcd v0.20.1-beta h1:Ik4hyJqN8Jfyv3S4AGBOmyouMsYE3EdYODkMbQjwPGw= +github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs= +github.com/bketelsen/crypt v0.0.3-0.20200106085610-5cbc8cc4026c/go.mod h1:MKsuJmJgSg28kpZDP6UIiPt0e0Oz0kqKNGyRaWEPv84= github.com/btcsuite/btcd v0.20.1-beta/go.mod h1:wVuoA8VJLEcwgqHBwHmzLRazpKxTv13Px/pDuV7OomQ= -github.com/btcsuite/btclog v0.0.0-20170628155309-84c8d2346e9f h1:bAs4lUbRJpnnkd9VhRV3jjAVU7DJVjMaK+IsvSeZvFo= github.com/btcsuite/btclog v0.0.0-20170628155309-84c8d2346e9f/go.mod h1:TdznJufoqS23FtqVCzL0ZqgP5MqXbb4fg/WgDys70nA= -github.com/btcsuite/btcutil v0.0.0-20190207003914-4c204d697803/go.mod h1:+5NJ2+qvTyV9exUAL/rxXi3DcLg2Ts+ymUAY5y4NvMg= -github.com/btcsuite/btcutil v0.0.0-20190425235716-9e5f4b9a998d h1:yJzD/yFppdVCf6ApMkVy8cUxV0XrxdP9rVf6D87/Mng= github.com/btcsuite/btcutil v0.0.0-20190425235716-9e5f4b9a998d/go.mod h1:+5NJ2+qvTyV9exUAL/rxXi3DcLg2Ts+ymUAY5y4NvMg= +github.com/btcsuite/btcutil v1.0.2 h1:9iZ1Terx9fMIOtq1VrwdqfsATL9MC2l8ZrUY6YZ2uts= +github.com/btcsuite/btcutil v1.0.2/go.mod h1:j9HUFwoQRsZL3V4n+qG+CUnEGHOarIxfC3Le2Yhbcts= github.com/btcsuite/go-socks v0.0.0-20170105172521-4720035b7bfd/go.mod h1:HHNXQzUsZCxOoE+CPiyCTO6x34Zs86zZUiwtpXoGdtg= github.com/btcsuite/goleveldb v0.0.0-20160330041536-7834afc9e8cd/go.mod h1:F+uVaaLLH7j4eDXPRvw78tMflu7Ie2bzYOH4Y8rRKBY= github.com/btcsuite/snappy-go v0.0.0-20151229074030-0bdef8d06723/go.mod h1:8woku9dyThutzjeg+3xrA5iCpBRH8XEEg3lh6TiUghc= @@ -65,72 +57,55 @@ github.com/btcsuite/websocket v0.0.0-20150119174127-31079b680792/go.mod h1:ghJtE github.com/btcsuite/winsvc v1.0.0/go.mod h1:jsenWakMcC0zFBFurPLEAyrnc/teJEM1O46fmI40EZs= github.com/cenkalti/backoff v2.2.1+incompatible h1:tNowT99t7UNflLxfYYSlKYsBpXdEet03Pg2g16Swow4= github.com/cenkalti/backoff v2.2.1+incompatible/go.mod h1:90ReRw6GdpyfrHakVjL/QHaoyV4aDUVVkXQJJJ3NXXM= -github.com/cespare/cp v1.1.1 h1:nCb6ZLdB7NRaqsm91JtQTAme2SKJzXVsdPIPkyJr1MU= -github.com/cespare/cp v1.1.1/go.mod h1:SOGHArjBr4JWaSDEVpWpo/hNg6RoKrls6Oh40hiwW+s= -github.com/cespare/xxhash v1.1.0 h1:a6HrQnmkObjyL+Gs60czilIUGqrzKutQD6XZog3p+ko= +github.com/certifi/gocertifi v0.0.0-20200922220541-2c3bb06c6054 h1:uH66TXeswKn5PW5zdZ39xEwfS9an067BirqA+P4QaLI= +github.com/certifi/gocertifi v0.0.0-20200922220541-2c3bb06c6054/go.mod h1:sGbDF6GwGcLpkNXPUTkMRoywsNa/ol15pxFe6ERfguA= github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc= -github.com/cespare/xxhash/v2 v2.1.0/go.mod h1:dgIUBU3pDso/gPgZ1osOZ0iQf77oPR28Tjxl5dIMyVM= -github.com/cespare/xxhash/v2 v2.1.1 h1:6MnRN8NT7+YBpUIWxHtefFZOKTAPgGjpQSxqLNn0+qY= -github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= -github.com/chenjiandongx/ginprom v0.0.0-20191022035802-6f3da3c84986 h1:6r9/zDxh+oMzqLWol3ByjfoZN85AaCTnXNvEfvc316U= -github.com/chenjiandongx/ginprom v0.0.0-20191022035802-6f3da3c84986/go.mod h1:lINNCb1ZH3c0uL/9ApaQ8muR4QILsi0STj8Ojt8ZmwU= +github.com/checkpoint-restore/go-criu/v5 v5.3.0/go.mod h1:E/eQpaFtUKGOOSEBZgmKAcn+zUUwWxqcaKZlF54wK8E= +github.com/cilium/ebpf v0.7.0/go.mod h1:/oI2+1shJiTGAMgl6/RgJr36Eo1jzrRcAWbcXO2usCA= github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= -github.com/codegangsta/inject v0.0.0-20150114235600-33e0aa1cb7c0/go.mod h1:4Zcjuz89kmFXt9morQgcfYZAYZ5n8WHjt81YYWIwtTM= +github.com/cockroachdb/apd v1.1.0 h1:3LFP3629v+1aKXU5Q37mxmRxX/pIu1nijXydLShEq5I= +github.com/cockroachdb/apd v1.1.0/go.mod h1:8Sl8LxpKi29FqWXR16WEFZRNSz3SoPzUzeMeY4+DwBQ= +github.com/containerd/console v1.0.3/go.mod h1:7LqA/THxQ86k76b8c/EMSiaJ3h1eZkMkXar0TQ1gf3U= +github.com/containerd/continuity v0.0.0-20201208142359-180525291bb7/go.mod h1:kR3BEg7bDFaEddKm54WSmrol1fKWDU1nKYkgrcgZT7Y= +github.com/containerd/continuity v0.1.0 h1:UFRRY5JemiAhPZrr/uE0n8fMTLcZsUvySPr1+D7pgr8= +github.com/containerd/continuity v0.1.0/go.mod h1:ICJu0PwR54nI0yPEnJ6jcS+J7CZAUXrLh8lPo2knzsM= github.com/coreos/bbolt v1.3.2/go.mod h1:iRUV2dpdMOn7Bo10OQBFzIJO9kkE559Wcmn+qkEiiKk= github.com/coreos/etcd v3.3.10+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE= -github.com/coreos/go-etcd v2.0.0+incompatible/go.mod h1:Jez6KQU2B/sWsbdaef3ED8NzMklzPG4d5KIOhIy30Tk= +github.com/coreos/etcd v3.3.13+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE= github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= +github.com/coreos/go-semver v0.3.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= +github.com/coreos/go-systemd v0.0.0-20190719114852-fd7a80b32e1f/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= +github.com/coreos/go-systemd/v22 v22.3.2/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc= github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA= -github.com/cpacia/bchutil v0.0.0-20181003130114-b126f6a35b6c h1:4e6Zsb6LFd3kadoMiut2zcd3hCb4zywpJnQa8+NV2Cs= -github.com/cpacia/bchutil v0.0.0-20181003130114-b126f6a35b6c/go.mod h1:k5D13LCXSsMrQyfdW0yGYs4GWUvirqoxHht8qwtqyRY= -github.com/cpuguy83/go-md2man v1.0.10/go.mod h1:SmD6nW6nTyfqj6ABTjUi3V3JVMnlJmwcJI5acqYI6dE= +github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= +github.com/cpuguy83/go-md2man/v2 v2.0.0/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= +github.com/creack/pty v1.1.7/go.mod h1:lj5s0c3V2DBrqTV7llrYr5NG6My20zk30Fl46Y7DoTY= +github.com/cyphar/filepath-securejoin v0.2.3/go.mod h1:aPGpWjXOXUn2NCNjFvBE6aRxGGx79pTxQpKOJNYHHl4= github.com/davecgh/go-spew v0.0.0-20171005155431-ecdeabc65495/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/deckarep/golang-set v1.7.1 h1:SCQV0S6gTtp6itiFrTqI+pfmJ4LN85S1YzhDf9rTHJQ= github.com/deckarep/golang-set v1.7.1/go.mod h1:93vsz/8Wt4joVM7c2AVqh+YRMiUSc14yDtF28KmMOgQ= -github.com/denisenkom/go-mssqldb v0.0.0-20190515213511-eb9f6a1743f3 h1:tkum0XDgfR0jcVVXuTsYv/erY2NnEDqwRojbxR1rBYA= -github.com/denisenkom/go-mssqldb v0.0.0-20190515213511-eb9f6a1743f3/go.mod h1:zAg7JM8CkOJ43xKXIj7eRO9kmWm/TW578qo+oDO6tuM= -github.com/dgraph-io/badger v1.6.0/go.mod h1:zwt7syl517jmP8s94KqSxTlM6IMsdhYy6psNgSztDR4= github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ= -github.com/dgryski/go-farm v0.0.0-20190423205320-6a90982ecee2/go.mod h1:SqUrOPUnsFjfmXRMNPybcSiG0BgUW2AuFH8PAnS2iTw= github.com/dgryski/go-sip13 v0.0.0-20181026042036-e10d5fee7954/go.mod h1:vAd38F8PWV+bWy6jNmig1y/TA+kYO4g3RSRF0IAv0no= -github.com/docker/docker v1.13.1 h1:IkZjBSIc8hBjLpqeAbeE5mca5mNgeatLHBy3GO78BWo= -github.com/docker/docker v1.13.1/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= +github.com/docker/go-connections v0.4.0 h1:El9xVISelRB7BuFusrZozjnkIM5YnzCViNKohAFqRJQ= +github.com/docker/go-connections v0.4.0/go.mod h1:Gbd7IOopHjR8Iph03tsViu4nIes5XhDvyHbTtUxmeec= +github.com/docker/go-units v0.4.0 h1:3uh0PgVws3nIA0Q+MwDC8yjEPf9zjRfZZWXZYDct3Tw= +github.com/docker/go-units v0.4.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk= github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk= -github.com/eapache/go-resiliency v1.1.0/go.mod h1:kFI+JgMyC7bLPUVY133qvEBtVayf5mFgVsvEsIPBvNs= -github.com/eapache/go-xerial-snappy v0.0.0-20180814174437-776d5712da21/go.mod h1:+020luEh2TKB4/GOp8oxxtq0Daoen/Cii55CzbTV6DU= -github.com/eapache/queue v1.1.0/go.mod h1:6eCeP0CKFpHLu8blIFXhExK/dRa7WDZfr6jVFPTqq+I= -github.com/edsrzf/mmap-go v1.0.0 h1:CEBF7HpRnUCSJgGUb5h1Gm7e3VkmVDrR8lvWVLtrOFw= -github.com/edsrzf/mmap-go v1.0.0/go.mod h1:YO35OhQPt3KJa3ryjFM5Bs14WD66h8eGKpfaBNrHW5M= -github.com/eknkc/amber v0.0.0-20171010120322-cdade1c07385/go.mod h1:0vRUJqYpeSZifjYj7uP3BG/gKcuzL9xWVV/Y+cK33KM= -github.com/elastic/gosigar v0.10.4/go.mod h1:cdorVVzy1fhmEqmtgqkoE3bYtCfSCkVyjTyCIo22xvs= -github.com/elastic/gosigar v0.10.5 h1:GzPQ+78RaAb4J63unidA/JavQRKrB6s8IOzN6Ib59jo= -github.com/elastic/gosigar v0.10.5/go.mod h1:cdorVVzy1fhmEqmtgqkoE3bYtCfSCkVyjTyCIo22xvs= -github.com/erikstmartin/go-testdb v0.0.0-20160219214506-8d10e4a1bae5 h1:Yzb9+7DPaBjB8zlTR87/ElzFsnQfuHnVUVqpZZIcV5Y= -github.com/erikstmartin/go-testdb v0.0.0-20160219214506-8d10e4a1bae5/go.mod h1:a2zkGnVExMxdzMo3M0Hi/3sEU+cWnZpSni0O6/Yb/P0= -github.com/etcd-io/bbolt v1.3.3/go.mod h1:ZF2nL25h33cCyBtcyWeZ2/I3HQOfTP+0PIEvHjkjCrw= -github.com/ethereum/go-ethereum v1.9.2 h1:RMIHDO/diqXEgORSVzYx8xW9x2+S32PoAX5lQwya0Lw= -github.com/ethereum/go-ethereum v1.9.2/go.mod h1:PwpWDrCLZrV+tfrhqqF6kPknbISMHaJv9Ln3kPCZLwY= -github.com/fasthttp-contrib/websocket v0.0.0-20160511215533-1f3b11f56072 h1:DddqAaWDpywytcG8w/qoQ5sAN8X12d3Z3koB0C3Rxsc= -github.com/fasthttp-contrib/websocket v0.0.0-20160511215533-1f3b11f56072/go.mod h1:duJ4Jxv5lDcvg4QuQr0oowTf7dz4/CR8NtyCooz9HL8= -github.com/fatih/structs v1.1.0 h1:Q7juDM0QtcnhCpeyLGQKyg4TOIghuNXrkL32pHAUMxo= -github.com/fatih/structs v1.1.0/go.mod h1:9NiDSp5zOcgEDl+j00MP/WkGVPOlPRLejGD8Ga6PJ7M= -github.com/fjl/memsize v0.0.0-20180929194037-2a09253e352a h1:1znxn4+q2MrEdTk1eCk6KIV3muTYVclBIB6CTVR/zBc= -github.com/fjl/memsize v0.0.0-20180929194037-2a09253e352a/go.mod h1:VvhXpOYNQvB+uIk2RvXzuaQtkQJzzIx6lSBe1xv7hi0= -github.com/flosch/pongo2 v0.0.0-20190707114632-bbf5a6c351f4/go.mod h1:T9YF2M40nIgbVgp3rreNmTged+9HrbNTIQf1PsaIiTA= +github.com/evalphobia/logrus_sentry v0.8.2 h1:dotxHq+YLZsT1Bb45bB5UQbfCh3gM/nFFetyN46VoDQ= +github.com/evalphobia/logrus_sentry v0.8.2/go.mod h1:pKcp+vriitUqu9KiWj/VRFbRfFNUwz95/UkgG8a6MNc= +github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= +github.com/frankban/quicktest v1.11.3/go.mod h1:wRf/ReqHper53s+kmmSZizM8NamnL3IM0I9ntUbOk+k= github.com/fsnotify/fsnotify v1.4.7 h1:IXs+QLmnXW2CcXuY+8Mzv/fWEsPGWxqefPtCP5CnV9I= github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= -github.com/garyburd/redigo v1.6.0/go.mod h1:NR3MbYisc3/PwhQ00EMzDiPmrwpPxAn5GI05/YaO1SY= -github.com/gavv/httpexpect v2.0.0+incompatible/go.mod h1:x+9tiU1YnrOvnB725RkpoLv1M62hOWzwo5OXotisrKc= -github.com/gballet/go-libpcsclite v0.0.0-20190607065134-2772fd86a8ff/go.mod h1:x7DCsMOv1taUwEWCzT4cmDeAkigA5/QCwUodaVOe8Ww= -github.com/gballet/go-libpcsclite v0.0.0-20191108122812-4678299bea08 h1:f6D9Hr8xV8uYKlyuj8XIruxlh9WjVjdh1gIicAS7ays= -github.com/gballet/go-libpcsclite v0.0.0-20191108122812-4678299bea08/go.mod h1:x7DCsMOv1taUwEWCzT4cmDeAkigA5/QCwUodaVOe8Ww= -github.com/getsentry/sentry-go v0.3.1 h1:yTTEl5wqb8mECvTujvyqSi/WjKQnUQL9F921EIDuVqs= -github.com/getsentry/sentry-go v0.3.1/go.mod h1:rnN2T5/zgkxv1oOpRVzfRqvjCw7XM6cjbDGmGyY/+8E= +github.com/getsentry/raven-go v0.2.0 h1:no+xWJRb5ZI7eE8TWgIq1jLulQiIoLG0IfYxv5JYMGs= +github.com/getsentry/raven-go v0.2.0/go.mod h1:KungGk8q33+aIAZUIVWZDr2OfAEBsO49PX4NzFV5kcQ= github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= +github.com/gin-contrib/cors v1.3.1 h1:doAsuITavI4IOcd0Y19U4B+O0dNWihRyX//nn4sEmgA= +github.com/gin-contrib/cors v1.3.1/go.mod h1:jjEJ4268OPZUcU7k9Pm653S7lXUGcqMADzFA61xsmDk= github.com/gin-contrib/gzip v0.0.1 h1:ezvKOL6jH+jlzdHNE4h9h8q8uMpDQjyl0NN0Jd7jozc= github.com/gin-contrib/gzip v0.0.1/go.mod h1:fGBJBCdt6qCZuCAOwWuFhBB4OOq9EFqlo5dEaFhhu5w= github.com/gin-contrib/sse v0.0.0-20170109093832-22d885f9ecc7/go.mod h1:VJ0WA2NBN22VlZ2dKZQPAPnyWw5XTlK1KymzLKsr59s= @@ -138,565 +113,596 @@ github.com/gin-contrib/sse v0.0.0-20190301062529-5545eab6dad3/go.mod h1:VJ0WA2NB github.com/gin-contrib/sse v0.1.0 h1:Y/yl/+YNO8GZSjAhjMsSuLt29uWRFHdHYUb5lYOV9qE= github.com/gin-contrib/sse v0.1.0/go.mod h1:RHrZQHXnP2xjPF+u1gW/2HnVO7nvIa9PG3Gm+fLHvGI= github.com/gin-gonic/gin v1.3.0/go.mod h1:7cKuhb5qV2ggCFctp2fJQ+ErvciLZrIeoOSOm6mUr7Y= -github.com/gin-gonic/gin v1.4.0 h1:3tMoCCfM7ppqsR0ptz/wi1impNpT7/9wQtMZ8lr1mCQ= github.com/gin-gonic/gin v1.4.0/go.mod h1:OW2EZn3DO8Ln9oIKOvM++LBO+5UPHJJDH72/q/3rZdM= -github.com/go-check/check v0.0.0-20180628173108-788fd7840127/go.mod h1:9ES+weclKsC9YodN5RgxqK/VD9HM9JsCSh7rNhMZE98= -github.com/go-errors/errors v1.0.1 h1:LUHzmkK3GUKUrL/1gfBUxAHzcev3apQlezX/+O7ma6w= -github.com/go-errors/errors v1.0.1/go.mod h1:f4zRHt4oKfwPJE5k8C9vpYG+aDHdBFUsgrm6/TyX73Q= +github.com/gin-gonic/gin v1.5.0/go.mod h1:Nd6IXA8m5kNZdNEHMBd93KT+mdY3+bewLgRvmCsR2Do= +github.com/gin-gonic/gin v1.6.3/go.mod h1:75u5sXoLsGZoRN5Sgbi1eraJ4GU3++wFwWzhwvtwp4M= +github.com/gin-gonic/gin v1.7.7 h1:3DoBmSbJbZAWqXJC3SLjAPfutPJJRN1U5pALB7EeTTs= +github.com/gin-gonic/gin v1.7.7/go.mod h1:axIBovoeJpVj8S3BwE0uPMTeReE4+AfFtqpqaZ1qq1U= +github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU= github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= -github.com/go-kit/kit v0.9.0 h1:wDJmvq38kDhkVxi50ni9ykkdUr1PKgqKOoi01fa0Mdk= -github.com/go-kit/kit v0.9.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE= -github.com/go-logfmt/logfmt v0.4.0 h1:MP4Eh7ZCb31lleYCFuwm0oe4/YGak+5l1vA2NOE80nA= github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk= -github.com/go-martini/martini v0.0.0-20170121215854-22fa46961aab/go.mod h1:/P9AEU963A2AYjv4d1V5eVL1CQbEJq6aCNHDDjibzu8= github.com/go-openapi/jsonpointer v0.17.0/go.mod h1:cOnomiV+CVVwFLk0A/MExoFMjwdsUdVpsRhURCKh+3M= -github.com/go-openapi/jsonpointer v0.19.2/go.mod h1:3akKfEdA7DF1sugOqz1dVQHBcuDBPKZGEoHC/NkiQRg= github.com/go-openapi/jsonpointer v0.19.3 h1:gihV7YNZK1iK6Tgwwsxo2rJbD1GTbdm72325Bq8FI3w= github.com/go-openapi/jsonpointer v0.19.3/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg= github.com/go-openapi/jsonreference v0.17.0/go.mod h1:g4xxGn04lDIRh0GJb5QlpE3HfopLOL6uZrK/VgnsK9I= github.com/go-openapi/jsonreference v0.19.0/go.mod h1:g4xxGn04lDIRh0GJb5QlpE3HfopLOL6uZrK/VgnsK9I= -github.com/go-openapi/jsonreference v0.19.2/go.mod h1:jMjeRr2HHw6nAVajTXJ4eiUwohSTlpa0o73RUL1owJc= -github.com/go-openapi/jsonreference v0.19.3 h1:5cxNfTy0UVC3X8JL5ymxzyoUZmo8iZb+jeTWn7tUa8o= -github.com/go-openapi/jsonreference v0.19.3/go.mod h1:rjx6GuL8TTa9VaixXglHmQmIL98+wF9xc8zWvFonSJ8= +github.com/go-openapi/jsonreference v0.19.4 h1:3Vw+rh13uq2JFNxgnMTGE1rnoieU9FmyE1gvnyylsYg= +github.com/go-openapi/jsonreference v0.19.4/go.mod h1:RdybgQwPxbL4UEjuAruzK1x3nE69AqPYEJeo/TWfEeg= github.com/go-openapi/spec v0.19.0/go.mod h1:XkF/MOi14NmjsfZ8VtAKf8pIlbZzyoTvZsdfssdxcBI= -github.com/go-openapi/spec v0.19.4 h1:ixzUSnHTd6hCemgtAJgluaTSGYpLNpJY4mA2DIkdOAo= -github.com/go-openapi/spec v0.19.4/go.mod h1:FpwSN1ksY1eteniUU7X0N/BgJ7a4WvBFVA8Lj9mJglo= +github.com/go-openapi/spec v0.19.14 h1:r4fbYFo6N4ZelmSX8G6p+cv/hZRXzcuqQIADGT1iNKM= +github.com/go-openapi/spec v0.19.14/go.mod h1:gwrgJS15eCUgjLpMjBJmbZezCsw88LmgeEip0M63doA= github.com/go-openapi/swag v0.17.0/go.mod h1:AByQ+nYG6gQg71GINrmuDXCPWdL640yX49/kXLo40Tg= -github.com/go-openapi/swag v0.19.2/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk= -github.com/go-openapi/swag v0.19.5 h1:lTz6Ys4CmqqCQmZPBlbQENR1/GucA2bzYTE12Pw4tFY= github.com/go-openapi/swag v0.19.5/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk= -github.com/go-redis/redis v6.15.6+incompatible h1:H9evprGPLI8+ci7fxQx6WNZHJSb7be8FqJQRhdQZ5Sg= -github.com/go-redis/redis v6.15.6+incompatible/go.mod h1:NAIEuMOZ/fxfXJIrKDQDz8wamY7mA7PouImQ2Jvg6kA= -github.com/go-sql-driver/mysql v1.4.1 h1:g24URVg0OFbNUTx9qqY1IRZ9D9z3iPyi5zKhQZpNwpA= -github.com/go-sql-driver/mysql v1.4.1/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w= -github.com/go-stack/stack v1.8.0 h1:5SgMzNM5HxrEjV0ww2lTmX6E2Izsfxas4+YHWRs3Lsk= +github.com/go-openapi/swag v0.19.11 h1:RFTu/dlFySpyVvJDfp/7674JY4SDglYWKztbiIGFpmc= +github.com/go-openapi/swag v0.19.11/go.mod h1:Uc0gKkdR+ojzsEpjh39QChyu92vPgIr72POcgHMAgSY= +github.com/go-playground/assert/v2 v2.0.1 h1:MsBgLAaY856+nPRTKrp3/OZK38U/wa0CcBYNjji3q3A= +github.com/go-playground/assert/v2 v2.0.1/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4= +github.com/go-playground/locales v0.12.1/go.mod h1:IUMDtCfWo/w/mtMfIE/IG2K+Ey3ygWanZIBtBW0W2TM= +github.com/go-playground/locales v0.13.0 h1:HyWk6mgj5qFqCT5fjGBuRArbVDfE4hi8+e8ceBS/t7Q= +github.com/go-playground/locales v0.13.0/go.mod h1:taPMhCMXrRLJO55olJkUXHZBHCxTMfnGwq/HNwmWNS8= +github.com/go-playground/universal-translator v0.16.0/go.mod h1:1AnU7NaIRDWWzGEKwgtJRd2xk99HeFyHw3yid4rvQIY= +github.com/go-playground/universal-translator v0.17.0 h1:icxd5fm+REJzpZx7ZfpaD876Lmtgy7VtROAbHHXk8no= +github.com/go-playground/universal-translator v0.17.0/go.mod h1:UkSxE5sNxxRwHyU+Scu5vgOQjsIJAF8j9muTVoKLVtA= +github.com/go-playground/validator/v10 v10.2.0/go.mod h1:uOYAAleCW8F/7oMFd6aG0GOhaH6EGOAJShg8Id5JGkI= +github.com/go-playground/validator/v10 v10.4.1 h1:pH2c5ADXtd66mxoE0Zm9SUhxE20r7aM3F26W0hOn+GE= +github.com/go-playground/validator/v10 v10.4.1/go.mod h1:nlOn6nFhuKACm19sB/8EGNn9GlaMV7XkbRSipzJ0Ii4= github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= -github.com/gobwas/httphead v0.0.0-20180130184737-2c6c146eadee/go.mod h1:L0fX3K22YWvt/FAX9NnzrNzcI4wNYi9Yku4O0LKYflo= -github.com/gobwas/pool v0.2.0/go.mod h1:q8bcK0KcYlCgd9e7WYLm9LpyS+YeLd8JVDW6WezmKEw= -github.com/gobwas/ws v1.0.2/go.mod h1:szmBTxLgaFppYjEmNtny/v3w89xOydFnnZMcgRRu/EM= +github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= +github.com/godbus/dbus/v5 v5.0.6/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= +github.com/gofrs/uuid v3.2.0+incompatible h1:y12jRkkFxsd7GpqdSZ+/KCs/fJbqpEXSGd4+jfEaewE= +github.com/gofrs/uuid v3.2.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM= github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= -github.com/gogo/protobuf v1.2.0/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= github.com/golang/groupcache v0.0.0-20190129154638-5b532d6fd5ef/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= +github.com/golang/mock v1.3.1/go.mod h1:sBzyDLLjw3U8JLTeZvSv8jJB+tU5PVekmnlKIyFUx0Y= github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= -github.com/golang/protobuf v1.3.2 h1:6nsPYzhq5kReh6QImI3k5qWzO4PEbvbIW2cwSfR/6xs= github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= -github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= -github.com/golang/snappy v0.0.1 h1:Qgr9rKW7uDUkrbSmQeiDsGa8SjGyCOGtuasMWwvp2P4= -github.com/golang/snappy v0.0.1/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= -github.com/gomodule/redigo v1.7.1-0.20190724094224-574c33c3df38/go.mod h1:B4C85qUVwatsJoIUNIfCRsp7qO0iAmpGFZ4EELWSbC4= +github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= +github.com/golang/protobuf v1.3.5/go.mod h1:6O5/vntMXwX2lRkT1hjjk0nAC1IDOTvTlVgjlRvqsdk= +github.com/golang/protobuf v1.5.0 h1:LUVKkCeviFUMKqHa4tXIIij/lbhnMbP7Fn5wKdKkRh4= +github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= -github.com/google/go-cmp v0.3.1 h1:Xye71clBPdm5HgqGwUkwhbynsUJZhDbS20FvLhQ2izg= -github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= -github.com/google/go-querystring v1.0.0 h1:Xkwi/a1rcvNg1PPYe5vI8GbeBY/jrVuDX5ASuANWTrk= -github.com/google/go-querystring v1.0.0/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO6wN/zVPAxq5ck= +github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.5 h1:Khx7svrCpmxxtHBq5j2mp/xVjsi8hQMfNLvJFAlrGgU= +github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs= github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= -github.com/google/uuid v1.0.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/google/uuid v1.1.1 h1:Gkbcsh/GbpXz7lPftLA3P6TYMwjCLYm83jiFQZF/3gY= -github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/google/pprof v0.0.0-20190515194954-54271f7e092f/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= +github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg= +github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk= github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1 h1:EGx4pi6eqNxGaHF6qqu48+N2wcFQ5qg5FXgOdqsJ5d8= github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= -github.com/gorilla/context v1.1.1/go.mod h1:kBGZzfjB9CEq2AlWe17Uuf7NDRt0dE0s8S51q0aT7Yg= -github.com/gorilla/mux v1.6.2/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs= github.com/gorilla/websocket v1.4.0/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ= -github.com/gorilla/websocket v1.4.1 h1:q7AeDBpnBk8AogcD4DSag/Ukw/KV+YhzLj2bP5HvKCM= -github.com/gorilla/websocket v1.4.1/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= -github.com/graph-gophers/graphql-go v0.0.0-20190724201507-010347b5f9e6 h1:9WiNlI9Cds5S5YITwRpRs8edNaq0nxTEymhDW20A1QE= -github.com/graph-gophers/graphql-go v0.0.0-20190724201507-010347b5f9e6/go.mod h1:Au3iQ8DvDis8hZ4q2OzRcaKYlAsPt+fYvib5q4nIqu4= +github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= +github.com/gotestyourself/gotestyourself v2.2.0+incompatible h1:AQwinXlbQR2HvPjQZOmDhRqsv5mZf+Jb1RnSLxcqZcI= +github.com/gotestyourself/gotestyourself v2.2.0+incompatible/go.mod h1:zZKM6oeNM8k+FRljX1mnzVYeS8wiGgQyvST1/GafPbY= github.com/grpc-ecosystem/go-grpc-middleware v1.0.0/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs= github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk= github.com/grpc-ecosystem/grpc-gateway v1.9.0/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY= +github.com/hashicorp/consul/api v1.1.0/go.mod h1:VmuI/Lkw1nC05EYQWNKwWGbkg+FbDBtguAZLlVdkD9Q= +github.com/hashicorp/consul/sdk v0.1.1/go.mod h1:VKf9jXwCTEY1QZP2MOLRhb5i/I/ssyNV1vwHyQBF0x8= +github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= +github.com/hashicorp/go-cleanhttp v0.5.1/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80= +github.com/hashicorp/go-immutable-radix v1.0.0/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60= +github.com/hashicorp/go-msgpack v0.5.3/go.mod h1:ahLV/dePpqEmjfWmKiqvPkv/twdG7iPBM1vqhUKIvfM= +github.com/hashicorp/go-multierror v1.0.0/go.mod h1:dHtQlpGsu+cZNNAkkCN/P3hoUDHhCYQXV3UM06sGGrk= +github.com/hashicorp/go-rootcerts v1.0.0/go.mod h1:K6zTfqpRlCUIjkwsN4Z+hiSfzSTQa6eBIzfwKfwNnHU= +github.com/hashicorp/go-sockaddr v1.0.0/go.mod h1:7Xibr9yA9JjQq1JpNB2Vw7kxv8xerXegt+ozgdvDeDU= +github.com/hashicorp/go-syslog v1.0.0/go.mod h1:qPfqrKkXGihmCqbJM2mZgkZGvKG1dFdvsLplgctolz4= +github.com/hashicorp/go-uuid v1.0.0/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= github.com/hashicorp/go-uuid v1.0.1/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= -github.com/hashicorp/go-version v1.2.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= +github.com/hashicorp/go.net v0.0.1/go.mod h1:hjKkEWcCURg++eb33jQU7oqQcI9XDCnUzHA0oac0k90= github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= -github.com/hashicorp/golang-lru v0.5.3 h1:YPkqC67at8FYaadspW/6uE0COsBxS2656RLEr8Bppgk= -github.com/hashicorp/golang-lru v0.5.3/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4= github.com/hashicorp/hcl v1.0.0 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4= github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= -github.com/hewigovens/go-coincodec v1.0.4 h1:asF02q8WfDwVQjU1O0VZYbOBer0cPJUmTiZKfAgqBYM= -github.com/hewigovens/go-coincodec v1.0.4/go.mod h1:+LTdzScnu782gMt0J3ZccPY9S2uyrGe0R1LUYGWecfc= -github.com/howeyc/fsnotify v0.9.0 h1:0gtV5JmOKH4A8SsFxG2BczSeXWWPvcMT0euZt5gDAxY= -github.com/howeyc/fsnotify v0.9.0/go.mod h1:41HzSPxBGeFRQKEEwgh49TRw/nKBsYZ2cF1OzPjSJsA= -github.com/hpcloud/tail v1.0.0 h1:nfCOvKYfkgYP8hkirhJocXT2+zOD8yUNjXaWfTlyFKI= +github.com/hashicorp/logutils v1.0.0/go.mod h1:QIAnNjmIWmVIIkWDTG1z5v++HQmx9WQRO+LraFDTW64= +github.com/hashicorp/mdns v1.0.0/go.mod h1:tL+uN++7HEJ6SQLQ2/p+z2pH24WQKWjBPkE0mNTz8vQ= +github.com/hashicorp/memberlist v0.1.3/go.mod h1:ajVTdAv/9Im8oMAAj5G31PhhMCZJV2pPBoIllUwCN7I= +github.com/hashicorp/serf v0.8.2/go.mod h1:6hOLApaqBFA1NXqRQAsxw9QxuDEvNxSQRwA/JwenrHc= github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= -github.com/huin/goupnp v1.0.0 h1:wg75sLpL6DZqwHQN6E1Cfk6mtfzS45z8OV+ic+DtHRo= -github.com/huin/goupnp v1.0.0/go.mod h1:n9v9KO1tAxYH82qOn+UTIFQDmx5n1Zxd/ClZDMX7Bnc= -github.com/huin/goutil v0.0.0-20170803182201-1ca381bf3150/go.mod h1:PpLOETDnJ0o3iZrZfqZzyLl6l7F3c6L1oWn7OICBi6o= -github.com/imkira/go-interpol v1.1.0 h1:KIiKr0VSG2CUW1hl1jpiyuzuJeKUUpC8iM1AIE7N1Vk= -github.com/imkira/go-interpol v1.1.0/go.mod h1:z0h2/2T3XF8kyEPpRgJ3kmNv+C43p+I/CoI+jC3w2iA= -github.com/inconshreveable/mousetrap v1.0.0 h1:Z8tu5sraLXCXIcARxBp/8cbvlwVa7Z1NHg9XEKhtSvM= github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= -github.com/influxdata/influxdb v1.7.7 h1:UvNzAPfBrKMENVbQ4mr4ccA9sW+W1Ihl0Yh1s0BiVAg= -github.com/influxdata/influxdb v1.7.7/go.mod h1:qZna6X/4elxqT3yI9iZYdZrWWdeFOOprn86kgg4+IzY= -github.com/influxdata/influxdb1-client v0.0.0-20190809212627-fc22c7df067e/go.mod h1:qj24IKcXYK6Iy9ceXlo3Tc+vtHo9lIhSX5JddghvEPo= -github.com/iris-contrib/blackfriday v2.0.0+incompatible/go.mod h1:UzZ2bDEoaSGPbkg6SAB4att1aAwTmVIx/5gCVqeyUdI= -github.com/iris-contrib/go.uuid v2.0.0+incompatible/go.mod h1:iz2lgM/1UnEf1kP0L/+fafWORmlnuysV2EMP8MW+qe0= -github.com/iris-contrib/i18n v0.0.0-20171121225848-987a633949d0/go.mod h1:pMCz62A0xJL6I+umB2YTlFRwWXaDFA0jy+5HzGiJjqI= -github.com/iris-contrib/schema v0.0.1/go.mod h1:urYA3uvUNG1TIIjOSCzHr9/LmbQo8LrOcOqfqxa4hXw= -github.com/jackpal/go-nat-pmp v1.0.1/go.mod h1:QPH045xvCAeXUZOxsnwmrtiCoxIr9eob+4orBN1SBKc= -github.com/jackpal/go-nat-pmp v1.0.2 h1:KzKSgb7qkJvOUTqYl9/Hg/me3pWgBmERKrTGD7BdWus= -github.com/jackpal/go-nat-pmp v1.0.2/go.mod h1:QPH045xvCAeXUZOxsnwmrtiCoxIr9eob+4orBN1SBKc= -github.com/jcmturner/gofork v0.0.0-20190328161633-dc7c13fece03/go.mod h1:MK8+TM0La+2rjBD4jE12Kj1pCCxK7d2LK/UM3ncEo0o= +github.com/itchyny/timefmt-go v0.1.2 h1:q0Xa4P5it6K6D7ISsbLAMwx1PnWlixDcJL6/sFs93Hs= +github.com/itchyny/timefmt-go v0.1.2/go.mod h1:0osSSCQSASBJMsIZnhAaF1C2fCBTJZXrnj37mG8/c+A= +github.com/jackc/chunkreader v1.0.0 h1:4s39bBR8ByfqH+DKm8rQA3E1LHZWB9XWcrz8fqaZbe0= +github.com/jackc/chunkreader v1.0.0/go.mod h1:RT6O25fNZIuasFJRyZ4R/Y2BbhasbmZXF9QQ7T3kePo= +github.com/jackc/chunkreader/v2 v2.0.0/go.mod h1:odVSm741yZoC3dpHEUXIqA9tQRhFrgOHwnPIn9lDKlk= +github.com/jackc/chunkreader/v2 v2.0.1 h1:i+RDz65UE+mmpjTfyz0MoVTnzeYxroil2G82ki7MGG8= +github.com/jackc/chunkreader/v2 v2.0.1/go.mod h1:odVSm741yZoC3dpHEUXIqA9tQRhFrgOHwnPIn9lDKlk= +github.com/jackc/pgconn v0.0.0-20190420214824-7e0022ef6ba3/go.mod h1:jkELnwuX+w9qN5YIfX0fl88Ehu4XC3keFuOJJk9pcnA= +github.com/jackc/pgconn v0.0.0-20190824142844-760dd75542eb/go.mod h1:lLjNuW/+OfW9/pnVKPazfWOgNfH2aPem8YQ7ilXGvJE= +github.com/jackc/pgconn v0.0.0-20190831204454-2fabfa3c18b7/go.mod h1:ZJKsE/KZfsUgOEh9hBm+xYTstcNHg7UPMVJqRfQxq4s= +github.com/jackc/pgconn v1.4.0/go.mod h1:Y2O3ZDF0q4mMacyWV3AstPJpeHXWGEetiFttmq5lahk= +github.com/jackc/pgconn v1.5.0/go.mod h1:QeD3lBfpTFe8WUnPZWN5KY/mB8FGMIYRdd8P8Jr0fAI= +github.com/jackc/pgconn v1.5.1-0.20200601181101-fa742c524853/go.mod h1:QeD3lBfpTFe8WUnPZWN5KY/mB8FGMIYRdd8P8Jr0fAI= +github.com/jackc/pgconn v1.8.0 h1:FmjZ0rOyXTr1wfWs45i4a9vjnjWUAGpMuQLD9OSs+lw= +github.com/jackc/pgconn v1.8.0/go.mod h1:1C2Pb36bGIP9QHGBYCjnyhqu7Rv3sGshaQUvmfGIB/o= +github.com/jackc/pgio v1.0.0 h1:g12B9UwVnzGhueNavwioyEEpAmqMe1E/BN9ES+8ovkE= +github.com/jackc/pgio v1.0.0/go.mod h1:oP+2QK2wFfUWgr+gxjoBH9KGBb31Eio69xUb0w5bYf8= +github.com/jackc/pgmock v0.0.0-20190831213851-13a1b77aafa2 h1:JVX6jT/XfzNqIjye4717ITLaNwV9mWbJx0dLCpcRzdA= +github.com/jackc/pgmock v0.0.0-20190831213851-13a1b77aafa2/go.mod h1:fGZlG77KXmcq05nJLRkk0+p82V8B8Dw8KN2/V9c/OAE= +github.com/jackc/pgpassfile v1.0.0 h1:/6Hmqy13Ss2zCq62VdNG8tM1wchn8zjSGOBJ6icpsIM= +github.com/jackc/pgpassfile v1.0.0/go.mod h1:CEx0iS5ambNFdcRtxPj5JhEz+xB6uRky5eyVu/W2HEg= +github.com/jackc/pgproto3 v1.1.0 h1:FYYE4yRw+AgI8wXIinMlNjBbp/UitDJwfj5LqqewP1A= +github.com/jackc/pgproto3 v1.1.0/go.mod h1:eR5FA3leWg7p9aeAqi37XOTgTIbkABlvcPB3E5rlc78= +github.com/jackc/pgproto3/v2 v2.0.0-alpha1.0.20190420180111-c116219b62db/go.mod h1:bhq50y+xrl9n5mRYyCBFKkpRVTLYJVWeCc+mEAI3yXA= +github.com/jackc/pgproto3/v2 v2.0.0-alpha1.0.20190609003834-432c2951c711/go.mod h1:uH0AWtUmuShn0bcesswc4aBTWGvw0cAxIJp+6OB//Wg= +github.com/jackc/pgproto3/v2 v2.0.0-rc3/go.mod h1:ryONWYqW6dqSg1Lw6vXNMXoBJhpzvWKnT95C46ckYeM= +github.com/jackc/pgproto3/v2 v2.0.0-rc3.0.20190831210041-4c03ce451f29/go.mod h1:ryONWYqW6dqSg1Lw6vXNMXoBJhpzvWKnT95C46ckYeM= +github.com/jackc/pgproto3/v2 v2.0.1/go.mod h1:WfJCnwN3HIg9Ish/j3sgWXnAfK8A9Y0bwXYU5xKaEdA= +github.com/jackc/pgproto3/v2 v2.0.6 h1:b1105ZGEMFe7aCvrT1Cca3VoVb4ZFMaFJLJcg/3zD+8= +github.com/jackc/pgproto3/v2 v2.0.6/go.mod h1:WfJCnwN3HIg9Ish/j3sgWXnAfK8A9Y0bwXYU5xKaEdA= +github.com/jackc/pgservicefile v0.0.0-20200307190119-3430c5407db8/go.mod h1:vsD4gTJCa9TptPL8sPkXrLZ+hDuNrZCnj29CQpr4X1E= +github.com/jackc/pgservicefile v0.0.0-20200714003250-2b9c44734f2b h1:C8S2+VttkHFdOOCXJe+YGfa4vHYwlt4Zx+IVXQ97jYg= +github.com/jackc/pgservicefile v0.0.0-20200714003250-2b9c44734f2b/go.mod h1:vsD4gTJCa9TptPL8sPkXrLZ+hDuNrZCnj29CQpr4X1E= +github.com/jackc/pgtype v0.0.0-20190421001408-4ed0de4755e0/go.mod h1:hdSHsc1V01CGwFsrv11mJRHWJ6aifDLfdV3aVjFF0zg= +github.com/jackc/pgtype v0.0.0-20190824184912-ab885b375b90/go.mod h1:KcahbBH1nCMSo2DXpzsoWOAfFkdEtEJpPbVLq8eE+mc= +github.com/jackc/pgtype v0.0.0-20190828014616-a8802b16cc59/go.mod h1:MWlu30kVJrUS8lot6TQqcg7mtthZ9T0EoIBFiJcmcyw= +github.com/jackc/pgtype v1.2.0/go.mod h1:5m2OfMh1wTK7x+Fk952IDmI4nw3nPrvtQdM0ZT4WpC0= +github.com/jackc/pgtype v1.3.1-0.20200510190516-8cd94a14c75a/go.mod h1:vaogEUkALtxZMCH411K+tKzNpwzCKU+AnPzBKZ+I+Po= +github.com/jackc/pgtype v1.3.1-0.20200606141011-f6355165a91c/go.mod h1:cvk9Bgu/VzJ9/lxTO5R5sf80p0DiucVtN7ZxvaC4GmQ= +github.com/jackc/pgtype v1.6.2 h1:b3pDeuhbbzBYcg5kwNmNDun4pFUD/0AAr1kLXZLeNt8= +github.com/jackc/pgtype v1.6.2/go.mod h1:JCULISAZBFGrHaOXIIFiyfzW5VY0GRitRr8NeJsrdig= +github.com/jackc/pgx/v4 v4.0.0-20190420224344-cc3461e65d96/go.mod h1:mdxmSJJuR08CZQyj1PVQBHy9XOp5p8/SHH6a0psbY9Y= +github.com/jackc/pgx/v4 v4.0.0-20190421002000-1b8f0016e912/go.mod h1:no/Y67Jkk/9WuGR0JG/JseM9irFbnEPbuWV2EELPNuM= +github.com/jackc/pgx/v4 v4.0.0-pre1.0.20190824185557-6972a5742186/go.mod h1:X+GQnOEnf1dqHGpw7JmHqHc1NxDoalibchSk9/RWuDc= +github.com/jackc/pgx/v4 v4.5.0/go.mod h1:EpAKPLdnTorwmPUUsqrPxy5fphV18j9q3wrfRXgo+kA= +github.com/jackc/pgx/v4 v4.6.1-0.20200510190926-94ba730bb1e9/go.mod h1:t3/cdRQl6fOLDxqtlyhe9UWgfIi9R8+8v8GKV5TRA/o= +github.com/jackc/pgx/v4 v4.6.1-0.20200606145419-4e5062306904/go.mod h1:ZDaNWkt9sW1JMiNn0kdYBaLelIhw7Pg4qd+Vk6tw7Hg= +github.com/jackc/pgx/v4 v4.10.1 h1:/6Q3ye4myIj6AaplUm+eRcz4OhK9HAvFf4ePsG40LJY= +github.com/jackc/pgx/v4 v4.10.1/go.mod h1:QlrWebbs3kqEZPHCTGyxecvzG6tvIsYu+A5b1raylkA= +github.com/jackc/puddle v0.0.0-20190413234325-e4ced69a3a2b/go.mod h1:m4B5Dj62Y0fbyuIc15OsIqK0+JU8nkqQjsgx7dvjSWk= +github.com/jackc/puddle v0.0.0-20190608224051-11cab39313c9/go.mod h1:m4B5Dj62Y0fbyuIc15OsIqK0+JU8nkqQjsgx7dvjSWk= +github.com/jackc/puddle v1.1.0/go.mod h1:m4B5Dj62Y0fbyuIc15OsIqK0+JU8nkqQjsgx7dvjSWk= +github.com/jackc/puddle v1.1.1/go.mod h1:m4B5Dj62Y0fbyuIc15OsIqK0+JU8nkqQjsgx7dvjSWk= +github.com/jackc/puddle v1.1.3/go.mod h1:m4B5Dj62Y0fbyuIc15OsIqK0+JU8nkqQjsgx7dvjSWk= github.com/jessevdk/go-flags v0.0.0-20141203071132-1679536dcc89/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= -github.com/jinzhu/gorm v1.9.11 h1:gaHGvE+UnWGlbWG4Y3FUwY1EcZ5n6S9WtqBA/uySMLE= -github.com/jinzhu/gorm v1.9.11/go.mod h1:bu/pK8szGZ2puuErfU0RwyeNdsf3e6nCX/noXaVxkfw= github.com/jinzhu/inflection v1.0.0 h1:K317FqzuhWc8YvSVlFMCCUb36O/S9MCKRDI7QkRKD/E= github.com/jinzhu/inflection v1.0.0/go.mod h1:h+uFLlag+Qp1Va5pdKtLDYj+kHp5pxUVkryuEj+Srlc= -github.com/jinzhu/now v1.0.1 h1:HjfetcXq097iXP0uoPCdnM4Efp5/9MsM0/M+XOTeR3M= -github.com/jinzhu/now v1.0.1/go.mod h1:d3SSVoowX0Lcu0IBviAWJpolVfI5UJVZZ7cO71lE/z8= +github.com/jinzhu/now v1.1.1 h1:g39TucaRWyV3dwDO++eEc6qf8TVIQ/Da48WmqjZ3i7E= +github.com/jinzhu/now v1.1.1/go.mod h1:d3SSVoowX0Lcu0IBviAWJpolVfI5UJVZZ7cO71lE/z8= github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo= github.com/jrick/logrotate v1.0.0/go.mod h1:LNinyqDIJnpAur+b8yyulnQw/wDuN1+BYKlTRt3OuAQ= github.com/json-iterator/go v1.1.5/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= github.com/json-iterator/go v1.1.7/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= -github.com/json-iterator/go v1.1.8 h1:QiWkFLKq0T7mpzwOTu6BzNDbfTE8OLrYhVKYMLF46Ok= -github.com/json-iterator/go v1.1.8/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= +github.com/json-iterator/go v1.1.9 h1:9yzud/Ht36ygwatGx56VwCZtlI/2AD15T1X2sjSuGns= +github.com/json-iterator/go v1.1.9/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU= github.com/jtolds/gls v4.20.0+incompatible h1:xdiiI2gbIgH/gLH7ADydsJ1uDOEzR8yvV7C0MuV77Wo= github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU= -github.com/juju/errors v0.0.0-20181118221551-089d3ea4e4d5/go.mod h1:W54LbzXuIE0boCoNJfwqpmkKJ1O4TCTZMetAt6jGk7Q= -github.com/juju/loggo v0.0.0-20180524022052-584905176618/go.mod h1:vgyd7OREkbtVEN/8IXZe5Ooef3LQePvuBm9UWj6ZL8U= -github.com/juju/testing v0.0.0-20180920084828-472a3e8b2073/go.mod h1:63prj8cnj0tU0S9OHjGJn+b1h0ZghCndfnbQolrYTwA= -github.com/julienschmidt/httprouter v1.2.0 h1:TDTW5Yz1mjftljbcKqRcrYhd4XeOoI98t+9HbQbYf7g= github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w= -github.com/k0kubun/colorstring v0.0.0-20150214042306-9440f1994b88 h1:uC1QfSlInpQF+M0ao65imhwqKnz3Q2z/d8PWZRMQvDM= -github.com/k0kubun/colorstring v0.0.0-20150214042306-9440f1994b88/go.mod h1:3w7q1U84EfirKl04SVQ/s7nPm1ZPhiXd34z40TNz36k= -github.com/karalabe/usb v0.0.0-20190819132248-550797b1cad8/go.mod h1:Od972xHfMJowv7NGVDiWVxk2zxnWgjLlJzE+F4F7AGU= -github.com/karalabe/usb v0.0.0-20191104083709-911d15fe12a9 h1:ZHuwnjpP8LsVsUYqTqeVAI+GfDfJ6UNPrExZF+vX/DQ= -github.com/karalabe/usb v0.0.0-20191104083709-911d15fe12a9/go.mod h1:Od972xHfMJowv7NGVDiWVxk2zxnWgjLlJzE+F4F7AGU= -github.com/kataras/golog v0.0.9/go.mod h1:12HJgwBIZFNGL0EJnMRhmvGA0PQGx8VFwrZtM4CqbAk= -github.com/kataras/iris/v12 v12.0.1/go.mod h1:udK4vLQKkdDqMGJJVd/msuMtN6hpYJhg/lSzuxjhO+U= -github.com/kataras/neffos v0.0.10/go.mod h1:ZYmJC07hQPW67eKuzlfY7SO3bC0mw83A3j6im82hfqw= -github.com/kataras/pio v0.0.0-20190103105442-ea782b38602d/go.mod h1:NV88laa9UiiDuX9AhMbDPkGYSPugBOV6yTZB1l2K9Z0= github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= github.com/kkdai/bstream v0.0.0-20161212061736-f391b8402d23/go.mod h1:J+Gs4SYgM6CZQHDETBtE9HaSEkGmuNXF86RwHhHUvq4= -github.com/klauspost/compress v1.8.2/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0guNDohfE1A= -github.com/klauspost/compress v1.9.0 h1:GhthINjveNZAdFUD8QoQYfjxnOONZgztK/Yr6M23UTY= -github.com/klauspost/compress v1.9.0/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0guNDohfE1A= -github.com/klauspost/cpuid v1.2.1/go.mod h1:Pj4uuM528wm8OyEC2QMXAi2YiTZ96dNQPGgoMS4s3ek= -github.com/klauspost/reedsolomon v1.9.2/go.mod h1:CwCi+NUr9pqSVktrkN+Ondf06rkhYZ/pcNv7fu+8Un4= github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= -github.com/konsorten/go-windows-terminal-sequences v1.0.2 h1:DB17ag19krx9CFsz4o3enTrPXyIXCl+2iCXH/aMAp9s= github.com/konsorten/go-windows-terminal-sequences v1.0.2/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= -github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515 h1:T+h1c/A9Gawja4Y9mFVWj2vyii2bbUNDw3kt9VxK2EY= +github.com/konsorten/go-windows-terminal-sequences v1.0.3/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc= -github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= +github.com/kr/pretty v0.2.1 h1:Fmg33tUaq4/8ym9TJN1x7sLJnHVwhP33CNkpYV/7rwI= +github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= -github.com/kr/pty v1.1.5/go.mod h1:9r2w37qlBe7rQ6e1fg1S/9xpWHSnaqNdHD3WcMdbPDA= +github.com/kr/pty v1.1.8/go.mod h1:O1sed60cT9XZ5uDucP5qwvh+TE3NnUj51EiZO/lmSfw= github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= -github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw= -github.com/labstack/echo/v4 v4.1.11/go.mod h1:i541M3Fj6f76NZtHSj7TXnyM8n2gaodfvfxNnFqi74g= -github.com/labstack/gommon v0.3.0/go.mod h1:MULnywXg0yavhxWKc+lOruYdAhDwPK9wf0OL7NoOu+k= -github.com/lib/pq v1.1.1 h1:sJZmqHoEaY7f+NPP8pgLB/WxulyR3fewgCM2qaSlBb4= -github.com/lib/pq v1.1.1/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= +github.com/leodido/go-urn v1.1.0/go.mod h1:+cyI34gQWZcE1eQU7NVgKkkzdXDQHr1dBMtdAPozLkw= +github.com/leodido/go-urn v1.2.0 h1:hpXL4XnriNwQ/ABnpepYM/1vCLWNDfUNts8dX3xTG6Y= +github.com/leodido/go-urn v1.2.0/go.mod h1:+8+nEpDfqqsY+g338gtMEUOtuK+4dEMhiQEgxpxOKII= +github.com/lib/pq v1.0.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= +github.com/lib/pq v1.1.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= +github.com/lib/pq v1.2.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= +github.com/lib/pq v1.3.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= +github.com/lib/pq v1.9.0 h1:L8nSXQQzAYByakOFMTwpjRoHsMJklur4Gi59b6VivR8= +github.com/lib/pq v1.9.0/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o= github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= github.com/magiconair/properties v1.8.1 h1:ZC2Vc7/ZFkGmsVC9KvOjumD+G5lXy2RtTKyzRKO2BQ4= github.com/magiconair/properties v1.8.1/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= github.com/mailru/easyjson v0.0.0-20180823135443-60711f1a8329/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= github.com/mailru/easyjson v0.0.0-20190614124828-94de47d64c63/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= +github.com/mailru/easyjson v0.0.0-20190626092158-b2ccc519800e h1:hB2xlXdHp/pmPZq0y3QnmWAArdw9PqbmotexnWx/FU8= github.com/mailru/easyjson v0.0.0-20190626092158-b2ccc519800e/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= -github.com/mailru/easyjson v0.7.0 h1:aizVhC/NAAcKWb+5QsU1iNOZb4Yws5UO2I+aIprQITM= -github.com/mailru/easyjson v0.7.0/go.mod h1:KAzv3t3aY1NaHWoQz1+4F1ccyAH66Jk7yos7ldAVICs= +github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU= github.com/mattn/go-colorable v0.1.1/go.mod h1:FuOcm+DKB9mbwrcAfNl7/TZVBZ6rcnceauSikq3lYCQ= -github.com/mattn/go-colorable v0.1.2 h1:/bC9yWikZXAL9uJdulbSfyVNIR3n3trXl+v8+1sx8mU= github.com/mattn/go-colorable v0.1.2/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE= +github.com/mattn/go-colorable v0.1.6/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= +github.com/mattn/go-isatty v0.0.3/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4= github.com/mattn/go-isatty v0.0.4/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4= github.com/mattn/go-isatty v0.0.5/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= github.com/mattn/go-isatty v0.0.7/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= github.com/mattn/go-isatty v0.0.9/go.mod h1:YNRxwqDuOph6SZLI9vUUz6OYw3QyUt7WiY2yME+cCiQ= -github.com/mattn/go-isatty v0.0.10 h1:qxFzApOv4WsAL965uUPIsXzAKCZxN2p9UqdhFS4ZW10= -github.com/mattn/go-isatty v0.0.10/go.mod h1:qgIWMr58cqv1PHHyhnkY9lrL7etaEgOFcMEpPG5Rm84= -github.com/mattn/go-runewidth v0.0.4/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU= -github.com/mattn/go-runewidth v0.0.6 h1:V2iyH+aX9C5fsYCpK60U8BYIvmhqxuOL3JZcqc1NB7k= -github.com/mattn/go-runewidth v0.0.6/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI= -github.com/mattn/go-sqlite3 v1.11.0 h1:LDdKkqtYlom37fkvqs8rMPFKAMe8+SgjbwZ6ex1/A/Q= -github.com/mattn/go-sqlite3 v1.11.0/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc= -github.com/mattn/goveralls v0.0.2/go.mod h1:8d1ZMHsd7fW6IRPKQh46F2WRpyib5/X4FOpevwGNQEw= +github.com/mattn/go-isatty v0.0.12 h1:wuysRhFDzyxgEmMf5xjvJ2M9dZoWAXNNr5LSBS7uHXY= +github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= github.com/matttproud/golang_protobuf_extensions v1.0.1 h1:4hp9jkHxhMHkqkrB3Ix0jegS5sx/RkqARlsWZ6pIwiU= github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= -github.com/mediocregopher/mediocre-go-lib v0.0.0-20181029021733-cb65787f37ed/go.mod h1:dSsfyI2zABAdhcbvkXqgxOxrCsbYeHCPgrZkku60dSg= -github.com/mediocregopher/radix/v3 v3.3.0/go.mod h1:EmfVyvspXz1uZEyPBMyGK+kjWiKQGvsUt6O3Pj+LDCQ= -github.com/microcosm-cc/bluemonday v1.0.2/go.mod h1:iVP4YcDBq+n/5fb23BhYFvIMq/leAFZyRl6bYmGDlGc= -github.com/minio/blake2b-simd v0.0.0-20160723061019-3f5f724cb5b1 h1:lYpkrQH5ajf0OXOcUbGjvZxxijuBwbbmlSxLiuofa+g= -github.com/minio/blake2b-simd v0.0.0-20160723061019-3f5f724cb5b1/go.mod h1:pD8RvIylQ358TN4wwqatJ8rNavkEINozVn9DtGI3dfQ= -github.com/minio/sha256-simd v0.0.0-20190328051042-05b4dd3047e5/go.mod h1:2FMWW+8GMoPweT6+pI63m9YE3Lmw4J71hV56Chs1E/U= -github.com/minio/sha256-simd v0.1.1-0.20190913151208-6de447530771/go.mod h1:B5e1o+1/KgNmWrSQK08Y6Z1Vb5pwIktudl0J58iy0KM= -github.com/minio/sha256-simd v0.1.1 h1:5QHSlgo3nt5yKOJrC7W8w7X+NFl8cMPZm96iu8kKUJU= -github.com/minio/sha256-simd v0.1.1/go.mod h1:B5e1o+1/KgNmWrSQK08Y6Z1Vb5pwIktudl0J58iy0KM= +github.com/miekg/dns v1.0.14/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg= +github.com/mitchellh/cli v1.0.0/go.mod h1:hNIlj7HEI86fIcpObd7a0FcrxTWetlwJDGcceTlRvqc= +github.com/mitchellh/go-homedir v1.0.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= -github.com/mitchellh/mapstructure v1.1.2 h1:fmNYVwqnSfB9mZU6OS2O6GsXM+wcskZDuKQzvN1EDeE= +github.com/mitchellh/go-testing-interface v1.0.0/go.mod h1:kRemZodwjscx+RGhAo8eIhFbs2+BFgRtFPeD/KE+zxI= +github.com/mitchellh/gox v0.4.0/go.mod h1:Sd9lOJ0+aimLBi73mGofS1ycjY8lL3uZM3JPS42BGNg= +github.com/mitchellh/iochan v1.0.0/go.mod h1:JwYml1nuB7xOzsp52dPpHFffvOCDupsG0QubkSMEySY= +github.com/mitchellh/mapstructure v0.0.0-20160808181253-ca63d7c062ee/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= +github.com/mitchellh/mapstructure v1.4.1 h1:CpVNEelQCZBooIPDn+AR3NpivK/TIKU8bDxdASFVQag= +github.com/mitchellh/mapstructure v1.4.1/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= +github.com/moby/sys/mountinfo v0.5.0/go.mod h1:3bMD3Rg+zkqx8MRYPi7Pyb0Ie97QEBmdxbhnCLlSvSU= github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= github.com/modern-go/reflect2 v1.0.1 h1:9f412s+6RmYXLWZSEzVVgPGK7C2PphHj5RJrvfx9AWI= github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= -github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826 h1:RWengNIwukTxcDr9M+97sNutRR1RKhG96O6jWumTTnw= -github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826/go.mod h1:TaXosZuwdSHYgviHp1DAtfrULt5eUgsSMsZf+YrPgl8= -github.com/moul/http2curl v1.0.0 h1:dRMWoAtb+ePxMlLkrCbAqh4TlPHXvoGUSQ323/9Zahs= -github.com/moul/http2curl v1.0.0/go.mod h1:8UbvGypXm98wA/IqH45anm5Y2Z6ep6O31QGOAZ3H0fQ= -github.com/mr-tron/base58 v1.1.2 h1:ZEw4I2EgPKDJ2iEw0cNmLB3ROrEmkOtXIkaG7wZg+78= -github.com/mr-tron/base58 v1.1.2/go.mod h1:BinMc/sQntlIE1frQmRFPUoPA1Zkr8VRgBdjWI2mNwc= -github.com/multiformats/go-multihash v0.0.5/go.mod h1:lt/HCbqlQwlPBz7lv0sQCdtfcMtlJvakRUn/0Ual8po= -github.com/multiformats/go-multihash v0.0.9 h1:aoijQXYYl7Xtb2pUUP68R+ys1TlnlR3eX6wmozr0Hp4= -github.com/multiformats/go-multihash v0.0.9/go.mod h1:YSLudS+Pi8NHE7o6tb3D8vrpKa63epEDmG8nTduyAew= +github.com/mr-tron/base58 v1.2.0 h1:T/HDJBh4ZCPbU39/+c3rRvE0uKBQlU27+QI8LJ4t64o= +github.com/mr-tron/base58 v1.2.0/go.mod h1:BinMc/sQntlIE1frQmRFPUoPA1Zkr8VRgBdjWI2mNwc= +github.com/mrunalp/fileutils v0.5.0/go.mod h1:M1WthSahJixYnrXQl/DFQuteStB1weuxD2QJNHXfbSQ= github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= -github.com/nats-io/nats.go v1.8.1/go.mod h1:BrFz9vVn0fU3AcH9Vn4Kd7W0NpJ651tD5omQ3M8LwxM= -github.com/nats-io/nkeys v0.0.2/go.mod h1:dab7URMsZm6Z/jp9Z5UGa87Uutgc2mVpXLC4B7TDb/4= -github.com/nats-io/nuid v1.0.1/go.mod h1:19wcPz3Ph3q0Jbyiqsd0kePYG7A95tJPxeL+1OSON2c= github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U= -github.com/olekukonko/tablewriter v0.0.1/go.mod h1:vsDQFd/mU46D+Z4whnwzcISnGGzXWMclvtLoiIKAKIo= -github.com/olekukonko/tablewriter v0.0.2 h1:sq53g+DWf0J6/ceFUHpQ0nAEb6WgM++fq16MZ91cS6o= -github.com/olekukonko/tablewriter v0.0.2/go.mod h1:rSAaSIOAGT9odnlyGlUfAJaoc5w2fSBUmeGDbRWPxyQ= github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= -github.com/onsi/ginkgo v1.10.1/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= -github.com/onsi/ginkgo v1.10.3 h1:OoxbjfXVZyod1fmWYhI7SEyaD8B00ynP3T+D5GiyHOY= -github.com/onsi/ginkgo v1.10.3/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= -github.com/onsi/gomega v1.7.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= -github.com/onsi/gomega v1.7.1 h1:K0jcRCwNQM3vFGh1ppMtDh/+7ApJrjldlX8fA0jDTLQ= -github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY= -github.com/openconfig/gnmi v0.0.0-20190823184014-89b2bf29312c/go.mod h1:t+O9It+LKzfOAhKTT5O0ehDix+MTqbtT0T9t+7zzOvc= -github.com/openconfig/reference v0.0.0-20190727015836-8dfd928c9696/go.mod h1:ym2A+zigScwkSEb/cVQB0/ZMpU3rqiH6X7WRRsxgOGw= -github.com/opentracing/opentracing-go v1.1.0 h1:pWlfV3Bxv7k65HYwkikxat0+s3pV4bsqf19k25Ur8rU= -github.com/opentracing/opentracing-go v1.1.0/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o= -github.com/openzipkin/zipkin-go v0.1.6/go.mod h1:QgAqvLzwWbR/WpD4A3cGpPtJrZXNIiJc5AZX7/PBEpw= -github.com/oschwald/maxminddb-golang v1.3.1 h1:kPc5+ieL5CC/Zn0IaXJPxDFlUxKTQEU8QBTtmfQDAIo= -github.com/oschwald/maxminddb-golang v1.3.1/go.mod h1:3jhIUymTJ5VREKyIhWm66LJiQt04F0UCDdodShpjWsY= +github.com/opencontainers/go-digest v1.0.0 h1:apOUWs51W5PlhuyGyz9FCeeBIOUDA/6nW8Oi/yOhh5U= +github.com/opencontainers/go-digest v1.0.0/go.mod h1:0JzlMkj0TRzQZfJkVvzbP0HBR3IKzErnv2BNG4W4MAM= +github.com/opencontainers/image-spec v1.0.1 h1:JMemWkRwHx4Zj+fVxWoMCFm/8sYGGrUVojFA6h/TRcI= +github.com/opencontainers/image-spec v1.0.1/go.mod h1:BtxoFyWECRxE4U/7sNtV5W15zMzWCbyJoFRP3s7yZA0= +github.com/opencontainers/runc v0.1.1/go.mod h1:qT5XzbpPznkRYVz/mWwUaVBUv2rmF59PVA73FjuZG0U= +github.com/opencontainers/runc v1.1.0 h1:O9+X96OcDjkmmZyfaG996kV7yq8HsoU2h1XRRQcefG8= +github.com/opencontainers/runc v1.1.0/go.mod h1:Tj1hFw6eFWp/o33uxGf5yF2BX5yz2Z6iptFpuvbbKqc= +github.com/opencontainers/runtime-spec v1.0.3-0.20210326190908-1c3f411f0417/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0= +github.com/opencontainers/selinux v1.10.0/go.mod h1:2i0OySw99QjzBBQByd1Gr9gSjvuho1lHsJxIJ3gGbJI= +github.com/ory/dockertest v3.3.5+incompatible h1:iLLK6SQwIhcbrG783Dghaaa3WPzGc+4Emza6EbVUUGA= +github.com/ory/dockertest v3.3.5+incompatible/go.mod h1:1vX4m9wsvi00u5bseYwXaSnhNrne+V0E6LAcBILJdPs= +github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc= github.com/patrickmn/go-cache v2.1.0+incompatible h1:HRMgzkcYKYpi3C8ajMPV8OFXaaRUnok+kx1WdO15EQc= github.com/patrickmn/go-cache v2.1.0+incompatible/go.mod h1:3Qf8kWWT7OJRJbdiICTKqZju1ZixQ/KpMGzzAfe6+WQ= -github.com/pborman/uuid v1.2.0 h1:J7Q5mO4ysT1dv8hyrUGHb9+ooztCXu1D8MY8DZYsu3g= -github.com/pborman/uuid v1.2.0/go.mod h1:X/NO0urCmaxf9VXbdlT7C2Yzkj2IKimNn4k+gtPdI/k= +github.com/pelletier/go-toml v1.2.0 h1:T5zMGML61Wp+FlcbWjRDT7yAxhJNAiPPLOFECq181zc= github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic= -github.com/pelletier/go-toml v1.6.0 h1:aetoXYr0Tv7xRU/V4B4IZJ2QcbtMUFoNb3ORp7TzIK4= -github.com/pelletier/go-toml v1.6.0/go.mod h1:5N711Q9dKgbdkxHL+MEfF31hpT7l0S0s/t2kKREewys= -github.com/pierrec/lz4 v0.0.0-20190327172049-315a67e90e41/go.mod h1:3/3N9NVKO0jef7pBehbT1qWhCMrIgbYNnFAZCqQ5LRc= -github.com/pierrec/lz4 v2.0.5+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY= -github.com/pingcap/errors v0.11.4 h1:lFuQV/oaUMGcD2tqt+01ROSmJs75VG1ToEOkZIZ4nE4= -github.com/pingcap/errors v0.11.4/go.mod h1:Oi8TUi2kEtXXLMJk9l1cGmz20kV3TaQ0usTwv5KuLY8= github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= -github.com/pkg/errors v0.8.1 h1:iURUrRGxPUNPdy5/HRSm+Yj6okJ6UtLINN0Q9M4+h3I= github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= -github.com/pkg/profile v1.2.1/go.mod h1:hJw3o1OdXxsrSjjVksARp5W95eeEaEfptyVZyv6JUPA= +github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= +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/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/posener/complete v1.1.1/go.mod h1:em0nMJCgc9GFtwrmVmEMR/ZL6WyhyjMBndrE9hABlRI= github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw= -github.com/prometheus/client_golang v0.9.3-0.20190127221311-3c4408c8b829/go.mod h1:p2iRAGwDERtqlqzRXnrOVns+ignqQo//hLXqYxZYVNs= github.com/prometheus/client_golang v0.9.3/go.mod h1:/TN21ttK/J9q6uSwhBd54HahCDft0ttaMvbicHlPoso= -github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo= -github.com/prometheus/client_golang v1.1.0/go.mod h1:I1FGZT9+L76gKKOs5djB6ezCbFQP1xR9D75/vuwEF3g= -github.com/prometheus/client_golang v1.2.1 h1:JnMpQc6ppsNgw9QPAGF6Dod479itz7lvlsMzzNayLOI= -github.com/prometheus/client_golang v1.2.1/go.mod h1:XMU6Z2MjaRKVu/dC1qupJI9SiNkDYzz3xecMgSW/F+U= +github.com/prometheus/client_golang v0.9.4 h1:Y8E/JaaPbmFSW2V81Ab/d8yZFYQQGbni1b1jPcG9Y6A= +github.com/prometheus/client_golang v0.9.4/go.mod h1:oCXIBxdI62A4cR6aTRJCgetEjecSIYzOEaeAn4iYEpM= github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= -github.com/prometheus/client_model v0.0.0-20190115171406-56726106282f/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= +github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90 h1:S/YWwWx/RA8rT8tKFRuGUZhuA90OyIBpPCXkcbwU8DE= github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= -github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4 h1:gQz4mCbXsO+nc9n1hCxHcGA3Zx3Eo+UHZoInFGUIXNM= -github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/prometheus/common v0.0.0-20181113130724-41aa239b4cce/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro= -github.com/prometheus/common v0.2.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= github.com/prometheus/common v0.4.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= +github.com/prometheus/common v0.4.1 h1:K0MGApIoQvMw27RTdJkPbr3JZ7DNbtxQNyi5STVM6Kw= github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= -github.com/prometheus/common v0.6.0/go.mod h1:eBmuwkDJBwy6iBfxCBob6t6dR6ENT/y+J+Zk0j9GMYc= -github.com/prometheus/common v0.7.0 h1:L+1lyG48J1zAQXA3RBX/nG/B3gjlHq0zTt2tlbJLyCY= -github.com/prometheus/common v0.7.0/go.mod h1:DjGbpBbp5NYNiECxcL/VnbXCCaQpKd3tt26CguLLsqA= github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= -github.com/prometheus/procfs v0.0.0-20190117184657-bf6a532e95b1/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= github.com/prometheus/procfs v0.0.0-20190507164030-5867b95ac084/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= +github.com/prometheus/procfs v0.0.2 h1:6LJUbpNm42llc4HRCuvApCSWB/WfhuNo9K98Q9sNGfs= github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= -github.com/prometheus/procfs v0.0.3/go.mod h1:4A/X28fw3Fc593LaREMrKMqOKvUAntwMDaekg4FpcdQ= -github.com/prometheus/procfs v0.0.5/go.mod h1:4A/X28fw3Fc593LaREMrKMqOKvUAntwMDaekg4FpcdQ= -github.com/prometheus/procfs v0.0.7 h1:RS5GAlMbnkWkhs4+bPocMTmGjYkuCY5djjqEDdXOhcQ= -github.com/prometheus/procfs v0.0.7/go.mod h1:7Qr8sr6344vo1JqZ6HhLceV9o3AJ1Ff+GxbHq6oeK9A= github.com/prometheus/tsdb v0.7.1/go.mod h1:qhTCs0VvXwvX/y3TZrWD7rabWM+ijKTux40TwIPHuXU= -github.com/prometheus/tsdb v0.10.0 h1:If5rVCMTp6W2SiRAQFlbpJNgVlgMEd+U2GZckwK38ic= -github.com/prometheus/tsdb v0.10.0/go.mod h1:oi49uRhEe9dPUTlS3JRZOwJuVi6tmh10QSgwXEyGCt4= -github.com/rcrowley/go-metrics v0.0.0-20181016184325-3113b8401b8a/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4= -github.com/rjeczalik/notify v0.9.2 h1:MiTWrPj55mNDHEiIX5YUSKefw/+lCQVoAFmD6oQm5w8= -github.com/rjeczalik/notify v0.9.2/go.mod h1:aErll2f0sUX9PXZnVNyeiObbmTlk5jnMoCa4QEjJeqM= -github.com/robfig/cron/v3 v3.0.0 h1:kQ6Cb7aHOHTSzNVNEhmp8EcWKLb4CbiMW9h9VyIhO4E= -github.com/robfig/cron/v3 v3.0.0/go.mod h1:eQICP3HwyT7UooqI/z+Ov+PtYAWygg1TEWWzGIFLtro= github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg= -github.com/rs/cors v1.6.0/go.mod h1:gFx+x8UowdsKA9AchylcLynDq+nNFfI8FkUZdN/jGCU= -github.com/rs/cors v1.7.0 h1:+88SsELBHx5r+hZ8TCkggzSstaWNbDvThkVK8H6f9ik= -github.com/rs/cors v1.7.0/go.mod h1:gFx+x8UowdsKA9AchylcLynDq+nNFfI8FkUZdN/jGCU= -github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g= -github.com/ryanuber/columnize v2.1.0+incompatible/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts= +github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= +github.com/rs/xid v1.2.1/go.mod h1:+uKXf+4Djp6Md1KODXJxgGQPKngRmWyn10oCKFzNHOQ= +github.com/rs/zerolog v1.13.0/go.mod h1:YbFCdg8HfsridGWAh22vktObvhZbQsZXe4/zB0OKkWU= +github.com/rs/zerolog v1.15.0/go.mod h1:xYTKnLHcpfU2225ny5qZjxnj9NvkumZYjJHlAThCjNc= +github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= +github.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts= github.com/satori/go.uuid v1.2.0/go.mod h1:dA0hQrYB0VpLJoorglMZABFdXlWrHn1NEOzdhQKdks0= -github.com/sergi/go-diff v1.0.0 h1:Kpca3qRNrduNnOQeazBd0ysaKrUJiIuISHxogkT9RPQ= -github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo= -github.com/shopspring/decimal v0.0.0-20200105231215-408a2507e114 h1:Pm6R878vxWWWR+Sa3ppsLce/Zq+JNTs6aVvRu13jv9A= -github.com/shopspring/decimal v0.0.0-20200105231215-408a2507e114/go.mod h1:DKyhrW/HYNuLGql+MJL6WCR6knT2jwCFRcu2hWCYk4o= +github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc= +github.com/seccomp/libseccomp-golang v0.9.2-0.20210429002308-3879420cc921/go.mod h1:JA8cRccbGaA1s33RQf7Y1+q9gHmZX1yB/z9WDN1C6fg= +github.com/shopspring/decimal v0.0.0-20180709203117-cd690d0c9e24/go.mod h1:M+9NzErvs504Cn4c5DxATwIqPbtswREoFCre64PpcG4= +github.com/shopspring/decimal v0.0.0-20200227202807-02e2044944cc/go.mod h1:DKyhrW/HYNuLGql+MJL6WCR6knT2jwCFRcu2hWCYk4o= +github.com/shopspring/decimal v1.2.0 h1:abSATXmQEYyShuxI4/vyW3tV1MrKAJzCZ/0zLUXYbsQ= +github.com/shopspring/decimal v1.2.0/go.mod h1:DKyhrW/HYNuLGql+MJL6WCR6knT2jwCFRcu2hWCYk4o= github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc= github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= -github.com/sirupsen/logrus v1.4.2 h1:SPIRibHv4MatM3XXNO2BJeFLZwZ2LvZgfQ5+UNI2im4= +github.com/sirupsen/logrus v1.4.1/go.mod h1:ni0Sbl8bgC9z8RoU9G6nDWqqs/fq4eDPysMBDgk/93Q= github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE= +github.com/sirupsen/logrus v1.6.0/go.mod h1:7uNnSEd1DgxDLC74fIahvMZmmYsHGZGEOFrfsX/uA88= +github.com/sirupsen/logrus v1.7.0/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0= +github.com/sirupsen/logrus v1.8.1 h1:dJKuHgqk1NNQlqoA6BTlM1Wf9DOH3NBjQyu0h9+AZZE= +github.com/sirupsen/logrus v1.8.1/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0= github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d h1:zE9ykElWQ6/NYmHa3jpm/yHnI4xSofP+UP6SpjHcSeM= github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc= github.com/smartystreets/goconvey v1.6.4 h1:fv0U8FUIMPNf1L9lnHLvLhgicrIVChEkdzIKYqbNC9s= github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA= github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM= github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= -github.com/spaolacci/murmur3 v1.1.0 h1:7c1g84S4BPRrfL5Xrdp6fOJ206sU9y293DDHaoy0bLI= -github.com/spaolacci/murmur3 v1.1.0/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= +github.com/spf13/afero v1.1.2 h1:m8/z1t7/fwjysjQRYbP0RD+bUIF/8tJwPdEZsI83ACI= github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ= -github.com/spf13/afero v1.2.2 h1:5jhuqJyZCZf2JRofRvN/nIFgIWNzPa3/Vz8mYylgbWc= -github.com/spf13/afero v1.2.2/go.mod h1:9ZxEEn6pIJ8Rxe320qSDBk6AsU0r9pR7Q4OcevTdifk= github.com/spf13/cast v1.3.0 h1:oget//CVOEoFewqQxwr0Ej5yjygnqGkvggSE/gB35Q8= github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE= -github.com/spf13/cobra v0.0.5 h1:f0B+LkLX6DtmRH1isoNA9VTtNUK9K8xYd28JNNfOv/s= -github.com/spf13/cobra v0.0.5/go.mod h1:3K3wKZymM7VvHMDS9+Akkh4K60UwM26emMESw8tLCHU= +github.com/spf13/cobra v0.0.2-0.20171109065643-2da4a54c5cee/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ= +github.com/spf13/cobra v1.0.0/go.mod h1:/6GTrnGXV9HjY+aR4k0oJ5tcvakLuG6EuKReYlHNrgE= +github.com/spf13/jwalterweatherman v1.0.0 h1:XHEdyB+EcvlqZamSM4ZOMGlc93t6AcsBEu9Gc1vn7yk= github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo= -github.com/spf13/jwalterweatherman v1.1.0 h1:ue6voC5bR5F8YxI5S67j9i582FU4Qvo2bmqnqMYADFk= -github.com/spf13/jwalterweatherman v1.1.0/go.mod h1:aNWZUN0dPAAO/Ljvb5BEdw96iTZ0EXowPYD95IqWIGo= +github.com/spf13/pflag v1.0.1-0.20171106142849-4c012f6dcd95/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= +github.com/spf13/pflag v1.0.3 h1:zPAT6CGy6wXeQ7NtTnaTerfKOsV6V6F8agHXFiazDkg= github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= -github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= -github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= -github.com/spf13/viper v1.3.2/go.mod h1:ZiWeW+zYFKm7srdB9IoDzzZXaJaI5eL9QjNiN/DMA2s= -github.com/spf13/viper v1.5.0 h1:GpsTwfsQ27oS/Aha/6d1oD7tpKIqWnOA6tgOX9HHkt4= -github.com/spf13/viper v1.5.0/go.mod h1:AkYRkVJF8TkSG/xet6PzXX+l39KhhXa2pdqVSxnTcn4= -github.com/status-im/keycard-go v0.0.0-20190424133014-d95853db0f48/go.mod h1:RZLeN1LMWmRsyYjvAu+I6Dm9QmlDaIIt+Y+4Kd7Tp+Q= -github.com/status-im/keycard-go v0.0.0-20191114114615-9d48af884d5b h1:yRRMsW8U/sYfVxNPuI9KtNxunG3Pzq0cr9VBY42W+rA= -github.com/status-im/keycard-go v0.0.0-20191114114615-9d48af884d5b/go.mod h1:RZLeN1LMWmRsyYjvAu+I6Dm9QmlDaIIt+Y+4Kd7Tp+Q= -github.com/steakknife/bloomfilter v0.0.0-20180922174646-6819c0d2a570 h1:gIlAHnH1vJb5vwEjIp5kBj/eu99p/bl0Ay2goiPe5xE= -github.com/steakknife/bloomfilter v0.0.0-20180922174646-6819c0d2a570/go.mod h1:8OR4w3TdeIHIh1g6EMY5p0gVNOovcWC+1vpc7naMuAw= -github.com/steakknife/hamming v0.0.0-20180906055917-c99c65617cd3 h1:njlZPzLwU639dk2kqnCPPv+wNjq7Xb6EfUxe/oX0/NM= -github.com/steakknife/hamming v0.0.0-20180906055917-c99c65617cd3/go.mod h1:hpGUWaI9xL8pRQCTXQgocU38Qw1g0Us7n5PxxTwTCYU= +github.com/spf13/viper v1.4.0/go.mod h1:PTJ7Z/lr49W6bUbkmS1V3by4uWynFiR9p7+dSq/yZzE= +github.com/spf13/viper v1.7.1 h1:pM5oEahlgWv/WnHXpgbKz7iLIxRf65tye2Ci+XFK5sk= +github.com/spf13/viper v1.7.1/go.mod h1:8WkrPz2fc9jxqZNCJI/76HCieCp4Q8HaLFoCha5qpdg= +github.com/streadway/amqp v1.0.0 h1:kuuDrUJFZL1QYL9hUNuCxNObNzB0bV/ZG5jV3RWAQgo= +github.com/streadway/amqp v1.0.0/go.mod h1:AZpEONHx3DKn8O/DFsRAY58/XVQiIPMTMB1SddzLXVw= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.2.0/go.mod h1:qt09Ya8vawLte6SNmTgCsAVtYtaKzEcn8ATUoHMkEqE= github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= -github.com/stretchr/testify v1.4.0 h1:2E4SXV/wtOkTonXsotYi4li6zVWxYlZuYNCXe9XRJyk= github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= +github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= +github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY= +github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/subosito/gotenv v1.2.0 h1:Slr1R9HxAlEKefgq5jn9U+DnETlIUa6HfgEzj0g5d7s= github.com/subosito/gotenv v1.2.0/go.mod h1:N0PQaV/YGNqwC0u51sEeR/aUtSLEXKX9iv69rRypqCw= -github.com/swaggo/files v0.0.0-20190704085106-630677cd5c14 h1:PyYN9JH5jY9j6av01SpfRMb+1DWg/i3MbGOKPxJ2wjM= github.com/swaggo/files v0.0.0-20190704085106-630677cd5c14/go.mod h1:gxQT6pBGRuIGunNf/+tSOB5OHvguWi8Tbt82WOkf35E= -github.com/swaggo/gin-swagger v1.2.0 h1:YskZXEiv51fjOMTsXrOetAjrMDfFaXD79PEoQBOe2W0= -github.com/swaggo/gin-swagger v1.2.0/go.mod h1:qlH2+W7zXGZkczuL+r2nEBR2JTT+/lX05Nn6vPhc7OI= +github.com/swaggo/gin-swagger v1.3.0 h1:eOmp7r57oUgZPw2dJOjcGNMse9cvXcI4tTqBcnZtPsI= +github.com/swaggo/gin-swagger v1.3.0/go.mod h1:oy1BRA6WvgtCp848lhxce7BnWH4C8Bxa0m5SkWx+cS0= github.com/swaggo/swag v1.5.1/go.mod h1:1Bl9F/ZBpVWh22nY0zmYyASPO1lI/zIwRDrpZU+tv8Y= -github.com/swaggo/swag v1.6.3 h1:N+uVPGP4H2hXoss2pt5dctoSUPKKRInr6qcTMOm0usI= -github.com/swaggo/swag v1.6.3/go.mod h1:wcc83tB4Mb2aNiL/HP4MFeQdpHUrca+Rp/DRNgWAUio= -github.com/syndtr/goleveldb v1.0.0 h1:fBdIW9lB4Iz0n9khmH8w27SJ3QEJ7+IgjPEwGSZiFdE= -github.com/syndtr/goleveldb v1.0.0/go.mod h1:ZVVdQEZoIme9iO1Ch2Jdy24qqXrMMOU6lpPAyBWyWuQ= -github.com/templexxx/cpufeat v0.0.0-20180724012125-cef66df7f161/go.mod h1:wM7WEvslTq+iOEAMDLSzhVuOt5BRZ05WirO+b09GHQU= -github.com/templexxx/xor v0.0.0-20181023030647-4e92f724b73b/go.mod h1:5XA7W9S6mni3h5uvOC75dA3m9CCCaS83lltmc0ukdi4= -github.com/tjfoc/gmsm v1.0.1/go.mod h1:XxO4hdhhrzAd+G4CjDqaOkd0hUzmtPR/d3EiBBMn/wc= +github.com/swaggo/swag v1.7.0 h1:5bCA/MTLQoIqDXXyHfOpMeDvL9j68OY/udlK4pQoo4E= +github.com/swaggo/swag v1.7.0/go.mod h1:BdPIL73gvS9NBsdi7M1JOxLvlbfvNRaBP8m6WT6Aajo= +github.com/syndtr/gocapability v0.0.0-20200815063812-42c35b437635/go.mod h1:hkRG7XYTFWNJGYcbNJQlaLq0fg1yr4J4t/NcTQtrfww= github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= -github.com/tyler-smith/go-bip39 v1.0.2 h1:+t3w+KwLXO6154GNJY+qUtIxLTmFjfUmpguQT1OlOT8= -github.com/tyler-smith/go-bip39 v1.0.2/go.mod h1:sJ5fKU0s6JVwZjjcUEX2zFOnvq0ASQ2K9Zr6cf67kNs= +github.com/trustwallet/golibs v0.0.35/go.mod h1:VI0APImKAYxvJ8MnMD6aHSKvnArXUd3NgNEghX5P+K8= +github.com/trustwallet/golibs v0.1.8 h1:g/c2RY8XZxOjoT8ZaXUS1X7zeaXvYuy3IJScqZcwMeA= +github.com/trustwallet/golibs v0.1.8/go.mod h1:SQ3mijAuOTX9GRyaqph3NY2ox04JD5WQ6PkWqX2NB8w= +github.com/trustwallet/golibs/network v0.0.0-20210302024139-c340cb937103 h1:RQVyaTFRRu37c+1kj+O2Z18doNAHOElMh8Q+/DrQi0I= +github.com/trustwallet/golibs/network v0.0.0-20210302024139-c340cb937103/go.mod h1:LDMLFnOnwmC30WuCCIJ56TWeXxwCVcrMFJYeC6GEnxY= github.com/ugorji/go v1.1.4/go.mod h1:uQMGLiO92mf5W77hV/PUCpI3pbzQx3CRekS0kk+RGrc= -github.com/ugorji/go v1.1.5-pre/go.mod h1:FwP/aQVg39TXzItUBMwnWp9T9gPQnXw4Poh4/oBQZ/0= -github.com/ugorji/go v1.1.7 h1:/68gy2h+1mWMrwZFeD1kQialdSzAb432dtpeJ42ovdo= github.com/ugorji/go v1.1.7/go.mod h1:kZn38zHttfInRq0xu/PH0az30d+z6vm202qpg1oXVMw= +github.com/ugorji/go v1.1.13 h1:nB3O5kBSQGjEQAcfe1aLUYuxmXdFKmYgBZhY32rQb6Q= +github.com/ugorji/go v1.1.13/go.mod h1:jxau1n+/wyTGLQoCkjok9r5zFa/FxT6eI5HiHKQszjc= github.com/ugorji/go/codec v0.0.0-20181022190402-e5e69e061d4f/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0= -github.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0= -github.com/ugorji/go/codec v1.1.5-pre/go.mod h1:tULtS6Gy1AE1yCENaw4Vb//HLH5njI2tfCQDUqRd8fI= -github.com/ugorji/go/codec v1.1.7 h1:2SvQaVZ1ouYrrKKwoSk2pzd4A9evlKJb9oTL+OaLUSs= github.com/ugorji/go/codec v1.1.7/go.mod h1:Ax+UKWsSmolVDwsd+7N3ZtXu+yMGCf907BLYF3GoBXY= +github.com/ugorji/go/codec v1.1.13 h1:013LbFhocBoIqgHeIHKlV4JWYhqogATYWZhIcH0WHn4= +github.com/ugorji/go/codec v1.1.13/go.mod h1:oNVt3Dq+FO91WNQ/9JnHKQP2QJxTzoN7wCBFCq1OeuU= github.com/urfave/cli v1.20.0/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijbERA= -github.com/urfave/negroni v1.0.0/go.mod h1:Meg73S6kFm/4PpbYdq35yYWoCZ9mS/YSx+lKnmiohz4= -github.com/valyala/bytebufferpool v1.0.0 h1:GqA5TC/0021Y/b9FG4Oi9Mr3q7XYx6KllzawFIhcdPw= -github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc= -github.com/valyala/fasthttp v1.6.0 h1:uWF8lgKmeaIewWVPwi4GRq2P6+R46IgYZdxWtM+GtEY= -github.com/valyala/fasthttp v1.6.0/go.mod h1:FstJa9V+Pj9vQ7OJie2qMHdwemEDaDiSdBnvPM1Su9w= -github.com/valyala/fasttemplate v1.0.1/go.mod h1:UQGH1tvbgY+Nz5t2n7tXsz52dQxojPUpymEIMZ47gx8= -github.com/valyala/tcplisten v0.0.0-20161114210144-ceec8f93295a/go.mod h1:v3UYOV9WzVtRmSR+PDvWpU/qWl4Wa5LApYYX4ZtKbio= -github.com/wealdtech/go-ens/v3 v3.0.9 h1:gXMBNXikJ/XV9k6ybPOZMXIMPjBGSCC9N10dxe8Y2Xk= -github.com/wealdtech/go-ens/v3 v3.0.9/go.mod h1:P2OEBvgkhXLrPzPN+eR5z2/wFIGwHyijTDvpuC1xLlo= -github.com/wealdtech/go-multicodec v1.2.0 h1:9AHSxcSE9F9r6ZvQLAO0EXCdM08QfYohaXmW3k6sSh4= -github.com/wealdtech/go-multicodec v1.2.0/go.mod h1:aedGMaTeYkIqi/KCPre1ho5rTb3hGpu/snBOS3GQLw4= -github.com/wealdtech/go-slip44 v1.0.0 h1:g0Wi5EufdD/ULZ4hcZKQ3TGlA6FZhGTCkmVzYmf+7Is= -github.com/wealdtech/go-slip44 v1.0.0/go.mod h1://S3V9M6iN1cCflLXMjJYciRPakCDubG9YpWVyW1AvM= -github.com/wealdtech/go-string2eth v1.0.0 h1:jY6b1MVqU6k2Uw/kvcU1Y9/3dDyXfPzZrOFspt82UJs= -github.com/wealdtech/go-string2eth v1.0.0/go.mod h1:UZA/snEybGcD6n+Pl+yoDjmexlEJ6dtoS9myfM83Ol4= -github.com/wsddn/go-ecdh v0.0.0-20161211032359-48726bab9208 h1:1cngl9mPEoITZG8s8cVcUy5CeIBYhEESkOB7m6Gmkrk= -github.com/wsddn/go-ecdh v0.0.0-20161211032359-48726bab9208/go.mod h1:IotVbo4F+mw0EzQ08zFqg7pK3FebNXpaMsRy2RT+Ees= -github.com/xdg/scram v0.0.0-20180814205039-7eeb5667e42c/go.mod h1:lB8K/P019DLNhemzwFU4jHLhdvlE6uDZjXFejJXr49I= -github.com/xdg/stringprep v1.0.0/go.mod h1:Jhud4/sHMO4oL310DaZAKk9ZaJ08SJfe+sJh0HrGL1Y= -github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU= -github.com/xeipuuv/gojsonpointer v0.0.0-20190809123943-df4f5c81cb3b h1:6cLsL+2FW6dRAdl5iMtHgRogVCff0QpRi9653YmdcJA= -github.com/xeipuuv/gojsonpointer v0.0.0-20190809123943-df4f5c81cb3b/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU= -github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 h1:EzJWgHovont7NscjpAxXsDA8S8BMYve8Y5+7cuRE7R0= -github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415/go.mod h1:GwrjFmJcFw6At/Gs6z4yjiIwzuJ1/+UwLxMQDVQXShQ= -github.com/xeipuuv/gojsonschema v1.2.0 h1:LhYJRs+L4fBtjZUfuSZIKGeVu0QRy8e5Xi7D17UxZ74= -github.com/xeipuuv/gojsonschema v1.2.0/go.mod h1:anYRn/JVcOK2ZgGU+IjEV4nwlhoK5sQluxsYJ78Id3Y= +github.com/urfave/cli v1.22.1/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0= +github.com/urfave/cli/v2 v2.3.0/go.mod h1:LJmUH05zAU44vOAcrfzZQKsZbVcdbOG8rtL3/XcUArI= +github.com/vishvananda/netlink v1.1.0/go.mod h1:cTgwzPIzzgDAYoQrMm0EdrjRUBkTqKYppBueQtXaqoE= +github.com/vishvananda/netns v0.0.0-20191106174202-0a2b9b5464df/go.mod h1:JP3t17pCcGlemwknint6hfoeCVQrEMVwxRLRjXpq+BU= github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU= github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q= -github.com/xtaci/kcp-go v5.4.5+incompatible/go.mod h1:bN6vIwHQbfHaHtFpEssmWsN45a+AZwO7eyRCmEIbtvE= -github.com/xtaci/lossyconn v0.0.0-20190602105132-8df528c0c9ae/go.mod h1:gXtu8J62kEgmN++bm9BVICuT/e8yiLI2KFobd/TRFsE= -github.com/yalp/jsonpath v0.0.0-20180802001716-5cc68e5049a0 h1:6fRhSjgLCkTD3JnJxvaJ4Sj+TYblw757bqYgZaOq5ZY= -github.com/yalp/jsonpath v0.0.0-20180802001716-5cc68e5049a0/go.mod h1:/LWChgwKmvncFJFHJ7Gvn9wZArjbV5/FppcK2fKk/tI= -github.com/yudai/gojsondiff v1.0.0 h1:27cbfqXLVEJ1o8I6v3y9lg8Ydm53EKqHXAOMxEGlCOA= -github.com/yudai/gojsondiff v1.0.0/go.mod h1:AY32+k2cwILAkW1fbgxQ5mUmMiZFgLIV+FBNExI05xg= -github.com/yudai/golcs v0.0.0-20170316035057-ecda9a501e82 h1:BHyfKlQyqbsFN5p3IfnEUduWvb9is428/nNb5L3U01M= -github.com/yudai/golcs v0.0.0-20170316035057-ecda9a501e82/go.mod h1:lgjkn3NuSvDfVJdfcVVdX+jpBxNmX4rDAzaS45IcYoM= -github.com/yudai/pp v2.0.1+incompatible h1:Q4//iY4pNF6yPLZIigmvcl7k/bPgrcTPIFIcmawg5bI= -github.com/yudai/pp v2.0.1+incompatible/go.mod h1:PuxR/8QJ7cyCkFp/aUDS+JY727OFEZkTdatxwunjIkc= +github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +github.com/zenazn/goji v0.9.0/go.mod h1:7S9M489iMyHBNxwZnk9/EHS098H4/F6TATF2mIxtB1Q= go.etcd.io/bbolt v1.3.2/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU= -go.opencensus.io v0.20.1/go.mod h1:6WKK9ahsWS3RSO+PY9ZHZUfv2irvY6gN279GOPZjmmk= +go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU= +go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8= +go.uber.org/atomic v1.3.2/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= +go.uber.org/atomic v1.6.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ= +go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc= go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0= +go.uber.org/multierr v1.5.0/go.mod h1:FeouvMocqHpRaaGuG9EjoKcStLC43Zu/fmqdUMPcKYU= +go.uber.org/tools v0.0.0-20190618225709-2cfd321de3ee/go.mod h1:vJERXedbb3MVM5f9Ejo0C68/HhF8uaILCdgjnY+goOA= +go.uber.org/zap v1.9.1/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= golang.org/x/crypto v0.0.0-20170930174604-9419663f5a44/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= -golang.org/x/crypto v0.0.0-20181203042331-505ab145d0a9/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= +golang.org/x/crypto v0.0.0-20181029021203-45a5f77698d3/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= -golang.org/x/crypto v0.0.0-20190325154230-a5d413f7728c/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= -golang.org/x/crypto v0.0.0-20190404164418-38d8ce5564a5/go.mod h1:WFFai1msRO1wXaEeE5yQxYXgSfI8pQAWXbQop6sCtWE= -golang.org/x/crypto v0.0.0-20190426145343-a29dc8fdc734/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/crypto v0.0.0-20190611184440-5c40567a22f8/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/crypto v0.0.0-20190701094942-4def268fd1a4/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/crypto v0.0.0-20191112222119-e1110fd1c708/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= -golang.org/x/crypto v0.0.0-20191117063200-497ca9f6d64f h1:kz4KIr+xcPUsI3VMoqWfPMvtnJ6MGfiVwsWSVzphMO4= -golang.org/x/crypto v0.0.0-20191117063200-497ca9f6d64f/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/crypto v0.0.0-20190411191339-88737f569e3a/go.mod h1:WFFai1msRO1wXaEeE5yQxYXgSfI8pQAWXbQop6sCtWE= +golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20190820162420-60c769a6c586/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20190911031432-227b76d455e7/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20200115085410-6d4e4cb37c7d/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/crypto v0.0.0-20200323165209-0ec3e9974c59/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/crypto v0.0.0-20201016220609-9e8e0b390897/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/crypto v0.0.0-20220315160706-3147a52a75dd h1:XcWmESyNjXJMLahc3mqVQJcgSTDxFxhETVlfk9uGc38= +golang.org/x/crypto v0.0.0-20220315160706-3147a52a75dd/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= +golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= +golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= +golang.org/x/exp v0.0.0-20190829153037-c13cbed26979/go.mod h1:86+5VVa7VpoJ4kLfm080zCjGlMRFzhUhsZKEZO7MGek= +golang.org/x/exp v0.0.0-20191030013958-a1ab85dbe136/go.mod h1:JXzH8nQsPlswgeRAPE3MuO9GYsAcnJvJ4vnMwN/5qkY= +golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= +golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/lint v0.0.0-20190409202823-959b441ac422/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/lint v0.0.0-20190909230951-414d861bb4ac/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE= +golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028/go.mod h1:E/iHnbuqvinMTCcRqshq8CkpyQDoeVncDDYHnLhea+o= +golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc= +golang.org/x/mod v0.1.0/go.mod h1:0QHyrYULN0/3qlju5TqG8bIK38QM8yzMo5ekMj3DlcY= +golang.org/x/mod v0.3.0 h1:RM4zey1++hCTbCVQfnWeKs9/IEsaBLA8vTkd0WVtmH4= +golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20181005035420-146acd28ed58/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20181011144130-49bb7cea24b1/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20181023162649-9b4f9f5ad519/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20181201002055-351d144fa1fc/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20181220203305-927f97764cc3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20190125091013-d26f9f9a57f3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= -golang.org/x/net v0.0.0-20190327091125-710a502c58a2/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190501004415-9ce7a6920f09/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190522155817-f3200d17e092/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= +golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= golang.org/x/net v0.0.0-20190611141213-3f473d35a33a/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20190813141303-74dc4d7220e7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190827160401-ba9fcec4b297/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20190912160710-24e19bdeb0f2/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20191118183410-d06c31c94cae h1:AzDIJnLFoW3GaQvpbMRKk+SptYRYtnhYdyuX+S/dTbc= -golang.org/x/net v0.0.0-20191118183410-d06c31c94cae/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= +golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= +golang.org/x/net v0.0.0-20201216054612-986b41b23924/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= +golang.org/x/net v0.0.0-20201224014010-6772e930b67b/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= +golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2 h1:CIJ76btIcR3eFI5EgSo6k1qKw9KJexJuRLI9G7Hp5wE= +golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= +golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e h1:vcxGaoTs7kV8m5Np9uUNQin4BrLOthgV7252N8V+FwY= -golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20180926160741-c2ed4eda69e7/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20181026203630-95b1ffbd15a5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20181107165924-66b7b1311ac8/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20181122145206-62eef0e2fa9b/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20181205085412-a5c9d58dba9a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20181228144115-9a3f9b0469bb/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190403152447-81d4e9dc473e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190606203320-7fc4e5ec1444/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190610200419-93c9922d18ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190616124812-15dcb6c0061f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190626221950-04f50cda93cb/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190801041406-cbf593c0f2f3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190813064441-fde4db37ae7a/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190912141932-bc967efca4b8/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20191008105621-543471e840be/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20191010194322-b09406accb47/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20191118133127-cf1e2d577169 h1:LPLFLulk2vyM7yI3CwNW64O6e8AxBmr9opfv14yI7HI= -golang.org/x/sys v0.0.0-20191118133127-cf1e2d577169/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190826190057-c7b8b68b1456/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190916202348-b4ddaad3f8a3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191115151921-52ab43148777/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200615200032-f1bc736245b1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20201201145000-ef89a241ccb3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210616094352-59db8d763f22/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210906170528-6f6e22806c34/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20211025201205-69cdffdb9359/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20211116061358-0a5406a5449c h1:DHcbWVXeY+0Y8HHKR+rbLwnoh2F4tNCY7rTiHJ30RmA= +golang.org/x/sys v0.0.0-20211116061358-0a5406a5449c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= -golang.org/x/text v0.3.2 h1:tW2bmiBqwgJj/UpqtC8EpXEZVYOwU0yG4iWbprSVAcs= golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= +golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.6 h1:aRYxNxv6iGQlyVaZmk6ZgYEDa+Jg18DxebPSrd6bg1M= +golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= -golang.org/x/tools v0.0.0-20180828015842-6cd1fcedba52/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= -golang.org/x/tools v0.0.0-20181221001348-537d06c36207/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190312151545-0bb0c0a6e846/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= -golang.org/x/tools v0.0.0-20190327201419-c70d86f8b7cf/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190328211700-ab21143f2384/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= -golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= +golang.org/x/tools v0.0.0-20190425150028-36563e24a262/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= +golang.org/x/tools v0.0.0-20190425163242-31fd60d6bfdc/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= +golang.org/x/tools v0.0.0-20190506145303-2d16b83fe98c/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= golang.org/x/tools v0.0.0-20190606050223-4d9ae51c2468/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= +golang.org/x/tools v0.0.0-20190606124116-d0a3d012864b/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= golang.org/x/tools v0.0.0-20190611222205-d73e1c7e250b/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= -golang.org/x/tools v0.0.0-20190614205625-5aca471b1d59/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= -golang.org/x/tools v0.0.0-20190912185636-87d9f09c5d89/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20191118222007-07fc4c7f2b98 h1:tZwpOHmF1OEL9wJGSgBALnhFg/8VKjQTtctCX51GLNI= -golang.org/x/tools v0.0.0-20191118222007-07fc4c7f2b98/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= +golang.org/x/tools v0.0.0-20190628153133-6cdbf07be9d0/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= +golang.org/x/tools v0.0.0-20190816200558-6889da9d5479/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20190823170909-c4a336ef6a2f/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20190911174233-4f2ddba30aff/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191012152004-8de300cfc20a/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191029041327-9cc4af7d6b2c/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191029190741-b9c20aec41a5/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191112195655-aa38f8e97acc/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20201120155355-20be4ac4bd6e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/tools v0.0.0-20210106214847-113979e3529a h1:CB3a9Nez8M13wwlr/E2YtwoU+qYHKfC+JrDa45RXXoQ= +golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/xerrors v0.0.0-20190410155217-1f06c39b4373/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20190513163551-3ee3066db522/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -google.golang.org/api v0.3.1/go.mod h1:6wY9I6uQWHQ8EM57III9mq/AjF+i8G65rmVagqKMtkk= +golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE= +golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE= +google.golang.org/api v0.7.0/go.mod h1:WtwebWUNSVBH/HAw79HIFXZNqEvBhG+Ra+ax0hx3E3M= +google.golang.org/api v0.8.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg= +google.golang.org/api v0.9.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg= +google.golang.org/api v0.13.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= -google.golang.org/appengine v1.4.0 h1:/wp5JvzpHIxhs/dumFmF7BXTf3Z+dd4uXta4kVyO508= google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= +google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= +google.golang.org/appengine v1.6.1/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0= google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= -google.golang.org/genproto v0.0.0-20190404172233-64821d5d2107/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= -google.golang.org/grpc v1.17.0/go.mod h1:6QZJwpn2B+Zp71q/5VxRsJ6NXXVCE5NRUHRo+f3cWCs= +google.golang.org/genproto v0.0.0-20190418145605-e7d98fc518a7/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= +google.golang.org/genproto v0.0.0-20190425155659-357c62f0e4bb/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= +google.golang.org/genproto v0.0.0-20190502173448-54afdca5d873/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= +google.golang.org/genproto v0.0.0-20190801165951-fa694d86fc64/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= +google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= +google.golang.org/genproto v0.0.0-20190911173649-1774047e7e51/go.mod h1:IbNlFCBrqXvoKpeg0TB2l7cyZUmoaFKYIwrEpbDKLA8= +google.golang.org/genproto v0.0.0-20191108220845-16a3f7862a1a/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= +google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38= google.golang.org/grpc v1.21.0/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= -google.golang.org/grpc v1.23.1/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= +google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= +google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= +google.golang.org/protobuf v1.27.1 h1:SnqbnDw1V7RiZcXPx5MEeqPv2s79L9i7BJUlG/+RurQ= +google.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= -gopkg.in/bsm/ratelimit.v1 v1.0.0-20160220154919-db14e161995a/go.mod h1:KF9sEfUPAXdG8Oev9e99iLGnl2uJMjc5B+4y3O7x610= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/fsnotify.v1 v1.4.7 h1:xOHLXZwVvI9hhs+cLKq5+I5onOuwQLhQwiu63xxlHs4= +gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 h1:YR8cESwS4TdDjEe65xsg0ogRM/Nc3DYOhEAlW+xobZo= +gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= -gopkg.in/go-playground/assert.v1 v1.2.1 h1:xoYuJVE7KT85PYWrN730RguIQO0ePzVRfFMXadIrXTM= gopkg.in/go-playground/assert.v1 v1.2.1/go.mod h1:9RXL0bg/zibRAgZUYszZSwO/z8Y/a8bDuhia5mkpMnE= -gopkg.in/go-playground/validator.v8 v8.18.2 h1:lFB4DoMU6B626w8ny76MV7VX6W2VHct2GVOI3xgiMrQ= gopkg.in/go-playground/validator.v8 v8.18.2/go.mod h1:RX2a/7Ha8BgOhfk7j780h4/u/RRjR0eouCJSH80/M2Y= -gopkg.in/jcmturner/aescts.v1 v1.0.1/go.mod h1:nsR8qBOg+OucoIW+WMhB3GspUQXq9XorLnQb9XtvcOo= -gopkg.in/jcmturner/dnsutils.v1 v1.0.1/go.mod h1:m3v+5svpVOhtFAP/wSz+yzh4Mc0Fg7eRhxkJMWSIz9Q= -gopkg.in/jcmturner/goidentity.v3 v3.0.0/go.mod h1:oG2kH0IvSYNIu80dVAyu/yoefjq1mNfM5bm88whjWx4= -gopkg.in/jcmturner/gokrb5.v7 v7.2.3/go.mod h1:l8VISx+WGYp+Fp7KRbsiUuXTTOnxIc3Tuvyavf11/WM= -gopkg.in/jcmturner/rpc.v1 v1.1.0/go.mod h1:YIdkC4XfD6GXbzje11McwsDuOlZQSb9W4vfLvuNnlv8= -gopkg.in/mgo.v2 v2.0.0-20180705113604-9856a29383ce/go.mod h1:yeKp02qBN3iKW1OzL3MGk2IdtZzaj7SFntXj72NppTA= -gopkg.in/natefinch/npipe.v2 v2.0.0-20160621034901-c1b8fa8bdcce h1:+JknDZhAj8YMt7GC73Ei8pv4MzjDUNPHgQWJdtMAaDU= -gopkg.in/natefinch/npipe.v2 v2.0.0-20160621034901-c1b8fa8bdcce/go.mod h1:5AcXVHNjg+BDxry382+8OKon8SEWiKktQR07RKPsv1c= -gopkg.in/olebedev/go-duktape.v3 v3.0.0-20190709231704-1e4459ed25ff h1:uuol9OUzSvZntY1v963NAbVd7A+PHLMz1FlCe3Lorcs= -gopkg.in/olebedev/go-duktape.v3 v3.0.0-20190709231704-1e4459ed25ff/go.mod h1:uAJfkITjFhyEEuUfm7bsmCZRbW5WRq8s9EY8HZ6hCns= -gopkg.in/redis.v4 v4.2.4/go.mod h1:8KREHdypkCEojGKQcjMqAODMICIVwZAONWq8RowTITA= +gopkg.in/go-playground/validator.v9 v9.29.1/go.mod h1:+c9/zcJMFNgbLvly1L1V+PpxWdVbfP1avr/N00E2vyQ= +gopkg.in/inconshreveable/log15.v2 v2.0.0-20180818164646-67afb5ed74ec/go.mod h1:aPpfJ7XW+gOuirDoZ8gHhLh3kZ1B08FtV2bbmy7Jv3s= +gopkg.in/ini.v1 v1.51.0 h1:AQvPpx3LzTDM0AjnIRlVFwFFGC+npRopjZxLJj6gdno= +gopkg.in/ini.v1 v1.51.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= gopkg.in/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo= -gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ= gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= -gopkg.in/urfave/cli.v1 v1.20.0 h1:NdAVW6RYxDif9DhDHaAortIu956m2c0v+09AZBPTbE0= -gopkg.in/urfave/cli.v1 v1.20.0/go.mod h1:vuBzUtMdQeixQj8LVd+/98pzhxNGQoyuPBlsXHOQNO0= gopkg.in/yaml.v2 v2.0.0-20170812160011-eb3733d160e7/go.mod h1:JAlM8MvJe8wmxCU4Bli9HhUf9+ttbYbLASfIpnQbh74= gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.3/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.2.5 h1:ymVxjfMaHvXD8RqPRmzHHsB3VvucivSkIAvJFDI5O3c= -gopkg.in/yaml.v2 v2.2.5/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -honnef.co/go/tools v0.0.0-20180728063816-88497007e858/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= +gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= +gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo= +gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gorm.io/driver/postgres v1.0.8 h1:PAgM+PaHOSAeroTjHkCHCBIHHoBIf9RgPWGo8dF2DA8= +gorm.io/driver/postgres v1.0.8/go.mod h1:4eOzrI1MUfm6ObJU/UcmbXyiHSs8jSwH95G5P5dxcAg= +gorm.io/gorm v1.20.12 h1:ebZ5KrSHzet+sqOCVdH9mTjW91L298nX3v5lVxAzSUY= +gorm.io/gorm v1.20.12/go.mod h1:0HFTzE/SqkGTzK6TlDPPQbAYCluiVvhzoA1+aVyzenw= +gotest.tools v2.2.0+incompatible h1:VsBPFP1AI068pPrMxtb/S8Zkgf9xEmTLJjfM+P5UIEo= +gotest.tools v2.2.0+incompatible/go.mod h1:DsYFclhRJ6vuDpmuTbkuFWG+y2sxOXAzmJt81HFBacw= honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= -honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg= +rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8= diff --git a/internal/init.go b/internal/init.go new file mode 100644 index 000000000..1abdf98f9 --- /dev/null +++ b/internal/init.go @@ -0,0 +1,60 @@ +package internal + +import ( + "flag" + + "github.com/trustwallet/golibs/network/middleware" + + "github.com/gin-gonic/gin" + log "github.com/sirupsen/logrus" + + "github.com/gin-contrib/cors" + "github.com/trustwallet/blockatlas/config" + "github.com/trustwallet/golibs/network/mq" + + "path/filepath" + "time" +) + +var ( + Build = "dev" + Date = time.Now().String() +) + +func ParseArgs(defaultPort, defaultConfigPath string) (string, string) { + var ( + port, confPath string + ) + + flag.StringVar(&port, "p", defaultPort, "port for api") + flag.StringVar(&confPath, "c", defaultConfigPath, "config file for api") + flag.Parse() + + return port, confPath +} + +func InitConfig(confPath string) { + confPath, err := filepath.Abs(confPath) + if err != nil { + log.Fatal(err) + } + + config.Init(confPath) +} + +func InitEngine(ginMode string) *gin.Engine { + gin.SetMode(ginMode) + engine := gin.New() + + engine.Use(cors.Default()) + engine.Use(middleware.Logger()) + + return engine +} + +func InitMQ(url string) { + err := mq.Init(url) + if err != nil { + log.Fatal("Failed to init Rabbit MQ", err) + } +} diff --git a/internal/metrics/metrics.go b/internal/metrics/metrics.go new file mode 100644 index 000000000..831b69881 --- /dev/null +++ b/internal/metrics/metrics.go @@ -0,0 +1,53 @@ +package metrics + +import ( + "strconv" + "time" + + "github.com/trustwallet/blockatlas/db" + + "github.com/prometheus/client_golang/prometheus" +) + +var ( + namespace = "blockatlas" + + workerBlockParsing = prometheus.NewGaugeVec( + prometheus.GaugeOpts{ + Namespace: namespace, + Subsystem: "worker", + Name: "block_parsing", + Help: "Last parsed block", + }, + []string{ + "coin", + "priority", + "enabled", + }, + ) +) + +func setupUpdateTrackerMetrics(db *db.Instance) { + go func() { + for { + trackers, err := db.GetLastParsedBlockNumbers() + if err != nil { + continue + } + for _, tracker := range trackers { + labels := prometheus.Labels{"coin": tracker.Coin, "priority": tracker.Priority, "enabled": strconv.FormatBool(tracker.Enabled)} + workerBlockParsing.With(labels).Set(float64(tracker.Height)) + } + time.Sleep(1 * time.Second) + } + }() +} + +func Setup(db *db.Instance) { + prometheus.DefaultRegisterer.Unregister(prometheus.NewGoCollector()) + prometheus.DefaultRegisterer.Unregister(prometheus.NewProcessCollector(prometheus.ProcessCollectorOpts{})) + + prometheus.MustRegister(workerBlockParsing) + + setupUpdateTrackerMetrics(db) +} diff --git a/internal/mq.go b/internal/mq.go new file mode 100644 index 000000000..13e61eff4 --- /dev/null +++ b/internal/mq.go @@ -0,0 +1,30 @@ +package internal + +import ( + "github.com/streadway/amqp" + "github.com/trustwallet/blockatlas/db" + "github.com/trustwallet/golibs/network/mq" +) + +const ( + // End consumer of published transactions. Not consumed on blockatlas + TxNotifications mq.Queue = "txNotifications" + // Address:coin subscriptions + Subscriptions mq.Queue = "subscriptions" + SubscriptionsTokens mq.Queue = "subscriptions_tokens" + + // Transactions to process, if match subscriptions, pushed to TxNotifications + RawTransactions mq.Queue = "rawTransactions" + RawTokens mq.Queue = "rawTokens" + RawTransactionsExchange mq.Exchange = "raw_transactions" +) + +type ConsumerDatabase struct { + Database *db.Instance + Delivery func(*db.Instance, amqp.Delivery) error + Tag string +} + +func (c ConsumerDatabase) Callback(msg amqp.Delivery) error { + return c.Delivery(c.Database, msg) +} diff --git a/k8s/deployment.yml b/k8s/deployment.yml deleted file mode 100644 index 5caeea20e..000000000 --- a/k8s/deployment.yml +++ /dev/null @@ -1,30 +0,0 @@ -apiVersion: apps/v1 -kind: Deployment -metadata: - labels: - app: blockatlas - name: blockatlas -spec: - replicas: 1 - selector: - matchLabels: - app: blockatlas - strategy: - type: Recreate - template: - metadata: - labels: - app: blockatlas - spec: - containers: - - env: - - name: ATLAS_MARKET_ENABLED - value: "true" - - name: ATLAS_OBSERVER_ENABLED - value: "true" - - name: ATLAS_STORAGE_REDIS - value: redis://redis-ha:6379 # I can recommend the Redis Helm Chart https://github.com/helm/charts/tree/master/stable/redis - image: trustwallet/blockatlas - name: blockatlas - dnsPolicy: ClusterFirst - restartPolicy: Always diff --git a/k8s/ingress.yml b/k8s/ingress.yml deleted file mode 100644 index 15906625f..000000000 --- a/k8s/ingress.yml +++ /dev/null @@ -1,28 +0,0 @@ -apiVersion: v1 -kind: Service -metadata: - name: blockatlas -spec: - clusterIP: None - ports: - - name: http - port: 8420 - protocol: TCP - targetPort: 8420 - selector: - app: blockatlas - type: ClusterIP - ---- -apiVersion: networking.k8s.io/v1beta1 -kind: Ingress -metadata: - name: blockatlas -spec: - rules: - - host: blockatlas.localhost - http: - paths: - - backend: - serviceName: blockatlas - servicePort: http diff --git a/main.go b/main.go deleted file mode 100644 index 7b465cbac..000000000 --- a/main.go +++ /dev/null @@ -1,9 +0,0 @@ -package main - -import ( - "github.com/trustwallet/blockatlas/cmd" -) - -func main() { - cmd.Execute() -} diff --git a/marketdata/chart/chart.go b/marketdata/chart/chart.go deleted file mode 100644 index 922fecf7a..000000000 --- a/marketdata/chart/chart.go +++ /dev/null @@ -1,9 +0,0 @@ -package chart - -type Chart struct { - Id string -} - -func (c *Chart) GetId() string { - return c.Id -} diff --git a/marketdata/chart/coingecko/coingecko.go b/marketdata/chart/coingecko/coingecko.go deleted file mode 100644 index 9fea50c5a..000000000 --- a/marketdata/chart/coingecko/coingecko.go +++ /dev/null @@ -1,115 +0,0 @@ -package coingecko - -import ( - "github.com/trustwallet/blockatlas/coin" - "github.com/trustwallet/blockatlas/marketdata/chart" - "github.com/trustwallet/blockatlas/marketdata/clients/coingecko" - "github.com/trustwallet/blockatlas/pkg/blockatlas" - "github.com/trustwallet/blockatlas/pkg/errors" - "time" -) - -const ( - id = "coingecko" - chartDataSize = 2 -) - -type Chart struct { - chart.Chart - client *coingecko.Client -} - -func InitChart(api string) chart.Provider { - m := &Chart{ - Chart: chart.Chart{ - Id: id, - }, - client: coingecko.NewClient(api), - } - return m -} - -func (c *Chart) GetChartData(coinId uint, token string, currency string, timeStart int64) (blockatlas.ChartData, error) { - chartsData := blockatlas.ChartData{} - coins, err := c.client.FetchCoinsList() - if err != nil { - return chartsData, err - } - cache := coingecko.NewSymbolsCache(coins) - - coinResult, err := getCoinObj(cache, coinId, token) - if err != nil { - return chartsData, err - } - - timeEndDate := time.Now().Unix() - charts, err := c.client.GetChartsData(coinResult.Id, currency, timeStart, timeEndDate) - if err != nil { - return chartsData, err - } - - return normalizeCharts(charts), nil -} - -func (c *Chart) GetCoinData(coinId uint, token string, currency string) (blockatlas.ChartCoinInfo, error) { - coins, err := c.client.FetchCoinsList() - if err != nil { - return blockatlas.ChartCoinInfo{}, err - } - cache := coingecko.NewSymbolsCache(coins) - - coinResult, err := getCoinObj(cache, coinId, token) - if err != nil { - return blockatlas.ChartCoinInfo{}, err - } - - data := c.client.FetchLatestRates(coingecko.GeckoCoins{coinResult}, currency) - if len(data) == 0 { - return blockatlas.ChartCoinInfo{}, errors.E("No rates found", errors.Params{"id": coinResult.Id}) - } - return normalizeInfo(data[0]), nil -} - -func getCoinObj(cache *coingecko.SymbolsCache, coinId uint, token string) (coingecko.GeckoCoin, error) { - c := coingecko.GeckoCoin{} - coinObj, ok := coin.Coins[coinId] - if !ok { - return c, errors.E("Coin not found", errors.Params{"coindId": coinId}) - } - - c, err := cache.GetCoinsBySymbol(coinObj.Symbol, token) - if err != nil { - return c, err - } - - return c, nil -} - -func normalizeCharts(charts coingecko.Charts) blockatlas.ChartData { - chartsData := blockatlas.ChartData{} - prices := make([]blockatlas.ChartPrice, 0) - for _, quote := range charts.Prices { - if len(quote) != chartDataSize { - continue - } - - date := time.Unix(int64(quote[0])/1000, 0) - prices = append(prices, blockatlas.ChartPrice{ - Price: quote[1], - Date: date.Unix(), - }) - } - - chartsData.Prices = prices - - return chartsData -} - -func normalizeInfo(data coingecko.CoinPrice) blockatlas.ChartCoinInfo { - return blockatlas.ChartCoinInfo{ - Vol24: data.TotalVolume, - MarketCap: data.MarketCap, - CirculatingSupply: data.CirculatingSupply, - TotalSupply: data.TotalSupply, - } -} diff --git a/marketdata/chart/coingecko/coingecko_test.go b/marketdata/chart/coingecko/coingecko_test.go deleted file mode 100644 index 40556411b..000000000 --- a/marketdata/chart/coingecko/coingecko_test.go +++ /dev/null @@ -1,91 +0,0 @@ -package coingecko - -import ( - "github.com/stretchr/testify/assert" - "github.com/trustwallet/blockatlas/marketdata/clients/coingecko" - "github.com/trustwallet/blockatlas/pkg/blockatlas" - "reflect" - "testing" - "time" -) - -func Test_normalizeInfo(t *testing.T) { - type args struct { - data coingecko.CoinPrice - } - tests := []struct { - name string - args args - wantInfo blockatlas.ChartCoinInfo - }{ - { - "test normalize coingecko chart info 1", - args{ - data: coingecko.CoinPrice{ - MarketCap: 555, - TotalVolume: 444, - CirculatingSupply: 111, - TotalSupply: 222, - }, - }, - blockatlas.ChartCoinInfo{ - Vol24: 444, - MarketCap: 555, - CirculatingSupply: 111, - TotalSupply: 222, - }, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - gotInfo := normalizeInfo(tt.args.data) - assert.True(t, reflect.DeepEqual(tt.wantInfo, gotInfo)) - }) - } -} - -func Test_normalizeCharts(t *testing.T) { - type args struct { - charts coingecko.Charts - } - - timeStr1 := "2019-12-19T18:27:23.453Z" - d1, _ := time.Parse(time.RFC3339, timeStr1) - timeStr2 := "2019-11-19T18:27:23.453Z" - d2, _ := time.Parse(time.RFC3339, timeStr2) - tests := []struct { - name string - args args - wantInfo blockatlas.ChartData - }{ - { - "test normalize coingecko chart 1", - args{ - charts: coingecko.Charts{ - Prices: []coingecko.ChartVolume{ - []float64{float64(d1.UnixNano() / int64(time.Millisecond)), 222}, - []float64{float64(d2.UnixNano() / int64(time.Millisecond)), 333}, - }, - }, - }, - blockatlas.ChartData{ - Prices: []blockatlas.ChartPrice{ - { - Price: 222, - Date: d1.Unix(), - }, - { - Price: 333, - Date: d2.Unix(), - }, - }, - }, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - gotInfo := normalizeCharts(tt.args.charts) - assert.True(t, reflect.DeepEqual(tt.wantInfo, gotInfo)) - }) - } -} diff --git a/marketdata/chart/coinmarketcap/cmc.go b/marketdata/chart/coinmarketcap/cmc.go deleted file mode 100644 index f300fa216..000000000 --- a/marketdata/chart/coinmarketcap/cmc.go +++ /dev/null @@ -1,133 +0,0 @@ -package coinmarketcap - -import ( - "github.com/trustwallet/blockatlas/marketdata/chart" - "github.com/trustwallet/blockatlas/marketdata/clients/cmc" - "github.com/trustwallet/blockatlas/pkg/blockatlas" - "github.com/trustwallet/blockatlas/pkg/errors" - "time" -) - -const ( - id = "cmc" - chartDataSize = 3 -) - -type Chart struct { - chart.Chart - mapApi string - webClient *cmc.WebClient - widgetClient *cmc.WidgetClient -} - -func InitChart(webApi string, widgetApi string, mapApi string) chart.Provider { - m := &Chart{ - Chart: chart.Chart{ - Id: id, - }, - mapApi: mapApi, - webClient: cmc.NewWebClient(webApi), - widgetClient: cmc.NewWidgetClient(widgetApi), - } - return m -} - -func (c *Chart) GetChartData(coin uint, token string, currency string, timeStart int64) (blockatlas.ChartData, error) { - chartsData := blockatlas.ChartData{} - cmap, err := cmc.GetCoinMap(c.mapApi) - if err != nil { - return chartsData, err - } - coinObj, err := cmap.GetCoinByContract(coin, token) - if err != nil { - return chartsData, err - } - - timeStartDate := time.Unix(timeStart, 0) - days := int(time.Since(timeStartDate).Hours() / 24) - timeEnd := time.Now().Unix() - charts, err := c.webClient.GetChartsData(coinObj.Id, currency, timeStart, timeEnd, getInterval(days)) - if err != nil { - return chartsData, err - } - - return normalizeCharts(currency, charts), nil -} - -func (c *Chart) GetCoinData(coin uint, token string, currency string) (blockatlas.ChartCoinInfo, error) { - info := blockatlas.ChartCoinInfo{} - - cmap, err := cmc.GetCoinMap(c.mapApi) - if err != nil { - return info, err - } - coinObj, err := cmap.GetCoinByContract(coin, token) - if err != nil { - return info, err - } - - data, err := c.widgetClient.GetCoinData(coinObj.Id, currency) - if err != nil { - return info, err - } - - return normalizeInfo(currency, coinObj.Id, data) -} - -func normalizeCharts(currency string, charts cmc.Charts) blockatlas.ChartData { - chartsData := blockatlas.ChartData{} - prices := make([]blockatlas.ChartPrice, 0) - for dateSrt, q := range charts.Data { - date, err := time.Parse(time.RFC3339, dateSrt) - if err != nil { - continue - } - - quote, ok := q[currency] - if !ok { - continue - } - - if len(quote) < chartDataSize { - continue - } - prices = append(prices, blockatlas.ChartPrice{ - Price: quote[0], - Date: date.Unix(), - }) - } - - chartsData.Prices = prices - - return chartsData -} - -func normalizeInfo(currency string, cmcCoin uint, data cmc.ChartInfo) (blockatlas.ChartCoinInfo, error) { - info := blockatlas.ChartCoinInfo{} - quote, ok := data.Data.Quotes[currency] - if !ok { - return info, errors.E("Cant get coin info", errors.Params{"cmcCoin": cmcCoin, "currency": currency}) - } - - return blockatlas.ChartCoinInfo{ - Vol24: quote.Volume24, - MarketCap: quote.MarketCap, - CirculatingSupply: data.Data.CirculatingSupply, - TotalSupply: data.Data.TotalSupply, - }, nil -} - -func getInterval(days int) string { - switch d := days; { - case d >= 360: - return "1d" - case d >= 90: - return "2h" - case d >= 30: - return "1h" - case d >= 7: - return "15m" - default: - return "5m" - } -} diff --git a/marketdata/chart/coinmarketcap/cmc_test.go b/marketdata/chart/coinmarketcap/cmc_test.go deleted file mode 100644 index dd832e976..000000000 --- a/marketdata/chart/coinmarketcap/cmc_test.go +++ /dev/null @@ -1,219 +0,0 @@ -package coinmarketcap - -import ( - "github.com/stretchr/testify/assert" - "github.com/trustwallet/blockatlas/marketdata/clients/cmc" - "github.com/trustwallet/blockatlas/pkg/blockatlas" - "reflect" - "testing" - "time" -) - -func Test_normalizeInfo(t *testing.T) { - type args struct { - currency string - cmcCoin uint - data cmc.ChartInfo - } - tests := []struct { - name string - args args - wantInfo blockatlas.ChartCoinInfo - }{ - { - "test normalize cmc chart info 1", - args{ - currency: "USD", - cmcCoin: 1, - data: cmc.ChartInfo{ - Data: cmc.ChartInfoData{ - Rank: 1, - CirculatingSupply: 111, - TotalSupply: 222, - Quotes: map[string]cmc.ChartInfoQuote{ - "USD": {Price: 333, Volume24: 444, MarketCap: 555}, - }, - }, - }, - }, - blockatlas.ChartCoinInfo{ - Vol24: 444, - MarketCap: 555, - CirculatingSupply: 111, - TotalSupply: 222, - }, - }, - { - "test normalize cmc chart info 2", - args{ - currency: "EUR", - cmcCoin: 2, - data: cmc.ChartInfo{ - Data: cmc.ChartInfoData{ - Rank: 2, - CirculatingSupply: 111, - TotalSupply: 222, - Quotes: map[string]cmc.ChartInfoQuote{ - "EUR": {Price: 333, Volume24: 444, MarketCap: 555}, - }, - }, - }, - }, - blockatlas.ChartCoinInfo{ - Vol24: 444, - MarketCap: 555, - CirculatingSupply: 111, - TotalSupply: 222, - }, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - gotInfo, err := normalizeInfo(tt.args.currency, tt.args.cmcCoin, tt.args.data) - assert.Nil(t, err) - assert.True(t, reflect.DeepEqual(tt.wantInfo, gotInfo)) - }) - } -} - -func Test_normalizeCharts(t *testing.T) { - type args struct { - currency string - symbol string - charts cmc.Charts - } - - timeStr1 := "2019-12-19T18:27:23.453Z" - d1, _ := time.Parse(time.RFC3339, timeStr1) - timeStr2 := "2019-11-19T18:27:23.453Z" - d2, _ := time.Parse(time.RFC3339, timeStr2) - tests := []struct { - name string - args args - wantInfo blockatlas.ChartData - }{ - { - "test normalize cmc chart 1", - args{ - currency: "USD", - symbol: "BTC", - charts: cmc.Charts{ - Data: cmc.ChartQuotes{ - timeStr1: cmc.ChartQuoteValues{ - "USD": []float64{111, 222, 333}, - }, - }, - }, - }, - blockatlas.ChartData{ - Prices: []blockatlas.ChartPrice{ - { - Price: 111, - Date: d1.Unix(), - }, - }, - }, - }, - { - "test normalize cmc chart 2", - args{ - currency: "EUR", - symbol: "BTC", - charts: cmc.Charts{ - Data: cmc.ChartQuotes{ - timeStr1: cmc.ChartQuoteValues{ - "EUR": []float64{333, 444, 555}, - }, - timeStr2: cmc.ChartQuoteValues{ - "EUR": []float64{555, 666, 777}, - }, - }, - }, - }, - blockatlas.ChartData{ - Prices: []blockatlas.ChartPrice{ - { - Price: 333, - Date: d1.Unix(), - }, - { - Price: 555, - Date: d2.Unix(), - }, - }, - }, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - gotInfo := normalizeCharts(tt.args.currency, tt.args.charts) - assert.True(t, reflect.DeepEqual(tt.wantInfo, gotInfo)) - }) - } -} - -func Test_getInterval(t *testing.T) { - tests := []struct { - name string - days int - wantInfo string - }{ - { - "test getInterval 1", - 1, - "5m", - }, - { - "test getInterval 2", - 5, - "5m", - }, - { - "test getInterval 3", - 7, - "15m", - }, - { - "test getInterval 4", - 8, - "15m", - }, - { - "test getInterval 5", - 30, - "1h", - }, - { - "test getInterval 6", - 40, - "1h", - }, - { - "test getInterval 7", - 90, - "2h", - }, - { - "test getInterval 8", - 120, - "2h", - }, - { - "test getInterval 9", - 360, - "1d", - }, - { - "test getInterval 10", - 800, - "1d", - }, - } - - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - gotInfo := getInterval(tt.days) - assert.Equal(t, tt.wantInfo, gotInfo) - }) - } -} diff --git a/marketdata/chart/provider.go b/marketdata/chart/provider.go deleted file mode 100644 index 0ae1bc277..000000000 --- a/marketdata/chart/provider.go +++ /dev/null @@ -1,22 +0,0 @@ -package chart - -import ( - "github.com/trustwallet/blockatlas/pkg/blockatlas" -) - -type Provider interface { - GetId() string - GetChartData(coin uint, token string, currency string, timeStart int64) (blockatlas.ChartData, error) - GetCoinData(coin uint, token string, currency string) (blockatlas.ChartCoinInfo, error) -} - -type Providers map[int]Provider - -func (ps Providers) GetPriority(providerId string) int { - for priority, provider := range ps { - if provider.GetId() == providerId { - return priority - } - } - return -1 -} diff --git a/marketdata/charts.go b/marketdata/charts.go deleted file mode 100644 index edab1476d..000000000 --- a/marketdata/charts.go +++ /dev/null @@ -1,81 +0,0 @@ -package marketdata - -import ( - "github.com/spf13/viper" - "github.com/trustwallet/blockatlas/marketdata/chart" - "github.com/trustwallet/blockatlas/marketdata/chart/coingecko" - cmc "github.com/trustwallet/blockatlas/marketdata/chart/coinmarketcap" - "github.com/trustwallet/blockatlas/pkg/blockatlas" - "github.com/trustwallet/blockatlas/pkg/errors" - "github.com/trustwallet/blockatlas/pkg/numbers" - "math" - "sort" -) - -const ( - minUnixTime = 1000000000 -) - -type Charts struct { - chartProviders chart.Providers -} - -func InitCharts() *Charts { - return &Charts{chart.Providers{ - 0: cmc.InitChart( - viper.GetString("market.cmc.webapi"), - viper.GetString("market.cmc.widgetapi"), - viper.GetString("market.cmc.map_url"), - ), - 1: coingecko.InitChart( - viper.GetString("market.coingecko.api"), - ), - }} -} - -func (c *Charts) GetChartData(coin uint, token string, currency string, timeStart int64, maxItems int) (blockatlas.ChartData, error) { - chartsData := blockatlas.ChartData{} - timeStart = numbers.Max(timeStart, minUnixTime) - for _, c := range c.chartProviders { - charts, err := c.GetChartData(coin, token, currency, timeStart) - if err != nil { - continue - } - charts.Prices = normalizePrices(charts.Prices, maxItems) - return charts, nil - } - return chartsData, errors.E("No chart data found", errors.Params{"coin": coin, "token": token}) -} - -func (c *Charts) GetCoinInfo(coin uint, token string, currency string) (blockatlas.ChartCoinInfo, error) { - coinInfoData := blockatlas.ChartCoinInfo{} - for _, c := range c.chartProviders { - info, err := c.GetCoinData(coin, token, currency) - if err != nil { - continue - } - return info, nil - } - return coinInfoData, errors.E("No chart coin info data found", errors.Params{"coin": coin, "token": token}) -} - -func normalizePrices(prices []blockatlas.ChartPrice, maxItems int) (result []blockatlas.ChartPrice) { - sort.Slice(prices, func(p, q int) bool { - return prices[p].Date < prices[q].Date - }) - if len(prices) > maxItems && maxItems > 0 { - skip := int(math.Ceil(float64(len(prices) / maxItems))) - i := 0 - for i < len(prices) { - result = append(result, prices[i]) - i += skip + 1 - } - lastPrice := prices[len(prices)-1] - if len(result) > 0 && lastPrice.Date != result[len(result)-1].Date { - result = append(result, lastPrice) - } - } else { - result = prices - } - return -} diff --git a/marketdata/charts_test.go b/marketdata/charts_test.go deleted file mode 100644 index de5801a60..000000000 --- a/marketdata/charts_test.go +++ /dev/null @@ -1,168 +0,0 @@ -package marketdata - -import ( - "github.com/stretchr/testify/assert" - "github.com/trustwallet/blockatlas/pkg/blockatlas" - "reflect" - "testing" -) - -func Test_normalizeInfo(t *testing.T) { - type args struct { - prices []blockatlas.ChartPrice - maxItems int - } - tests := []struct { - args args - wantInfo []blockatlas.ChartPrice - }{ - { - args{ - prices: []blockatlas.ChartPrice{ - { - Price: 1, - Date: 1578741541, - }, - { - Price: 1, - Date: 1578741542, - }, - { - Price: 1, - Date: 1578741549, - }, - { - Price: 1, - Date: 1578741545, - }, - { - Price: 1, - Date: 1578741547, - }, - { - Price: 1, - Date: 1578741546, - }, - }, - maxItems: 3, - }, - []blockatlas.ChartPrice{ - { - Price: 1, - Date: 1578741541, - }, - { - Price: 1, - Date: 1578741546, - }, - { - Price: 1, - Date: 1578741549, - }, - }, - }, - { - args{ - prices: []blockatlas.ChartPrice{ - { - Price: 1, - Date: 1578741541, - }, - { - Price: 1, - Date: 1578741542, - }, - { - Price: 1, - Date: 1578741549, - }, - { - Price: 1, - Date: 1578741545, - }, - { - Price: 1, - Date: 1578741547, - }, - { - Price: 1, - Date: 1578741546, - }, - }, - maxItems: 20, - }, - []blockatlas.ChartPrice{ - { - Price: 1, - Date: 1578741541, - }, - { - Price: 1, - Date: 1578741542, - }, - { - Price: 1, - Date: 1578741545, - }, - { - Price: 1, - Date: 1578741546, - }, - { - Price: 1, - Date: 1578741547, - }, - { - Price: 1, - Date: 1578741549, - }, - }, - }, - { - args{ - prices: []blockatlas.ChartPrice{ - { - Price: 1, - Date: 1578741541, - }, - { - Price: 1, - Date: 1578741542, - }, - { - Price: 1, - Date: 1578741545, - }, - { - Price: 1, - Date: 1578741547, - }, - { - Price: 1, - Date: 1578741546, - }, - }, - maxItems: 3, - }, - []blockatlas.ChartPrice{ - { - Price: 1, - Date: 1578741541, - }, - { - Price: 1, - Date: 1578741545, - }, - { - Price: 1, - Date: 1578741547, - }, - }, - }, - } - for _, tt := range tests { - t.Run("Test prices normalize", func(t *testing.T) { - assert.True(t, reflect.DeepEqual(normalizePrices(tt.args.prices, tt.args.maxItems), tt.wantInfo)) - }) - } -} diff --git a/marketdata/clients/cmc/cache.go b/marketdata/clients/cmc/cache.go deleted file mode 100644 index 19edd520c..000000000 --- a/marketdata/clients/cmc/cache.go +++ /dev/null @@ -1,75 +0,0 @@ -package cmc - -import ( - "fmt" - "github.com/trustwallet/blockatlas/coin" - "github.com/trustwallet/blockatlas/pkg/blockatlas" - "github.com/trustwallet/blockatlas/pkg/errors" -) - -type CoinMap struct { - Coin uint `json:"coin"` - Id uint `json:"id"` - Type string `json:"type"` - TokenId string `json:"token_id"` -} - -type CoinResult struct { - Id uint - Coin coin.Coin - TokenId string - CoinType blockatlas.CoinType -} - -type CmcSlice []CoinMap -type CoinMapping map[string]CoinMap -type CmcMapping map[uint][]CoinMap - -func (c *CmcSlice) coinToCmcMap() (m CoinMapping) { - m = make(map[string]CoinMap) - for _, cm := range *c { - m[generateId(cm.Coin, cm.TokenId)] = cm - } - return -} - -func (c *CmcSlice) cmcToCoinMap() (m CmcMapping) { - m = make(map[uint][]CoinMap) - for _, cm := range *c { - _, ok := m[cm.Id] - if !ok { - m[cm.Id] = make([]CoinMap, 0) - } - m[cm.Id] = append(m[cm.Id], cm) - } - return -} - -func (cm CmcMapping) GetCoins(coinId uint) ([]CoinResult, error) { - cmcCoin, ok := cm[coinId] - if !ok { - return nil, errors.E("CmcMapping.getCoin: coinId notFound") - } - tokens := make([]CoinResult, 0) - for _, cc := range cmcCoin { - c, ok := coin.Coins[cc.Coin] - if !ok { - continue - } - tokens = append(tokens, CoinResult{Coin: c, Id: cc.Id, TokenId: cc.TokenId, CoinType: blockatlas.CoinType(cc.Type)}) - } - return tokens, nil -} - -func (cm CoinMapping) GetCoinByContract(coinId uint, contract string) (c CoinMap, err error) { - c, ok := cm[generateId(coinId, contract)] - if !ok { - err = errors.E("No coin found", errors.Params{"coin": coinId, "token": contract}) - } - - return -} - -func generateId(id uint, token string) string { - return fmt.Sprintf("%d:%s", id, token) -} diff --git a/marketdata/clients/cmc/cache_test.go b/marketdata/clients/cmc/cache_test.go deleted file mode 100644 index 02d2c14d7..000000000 --- a/marketdata/clients/cmc/cache_test.go +++ /dev/null @@ -1,89 +0,0 @@ -package cmc - -import ( - "reflect" - "testing" -) - -func TestCmcMapping_cmcToCoinMap(t *testing.T) { - tests := []struct { - name string - c CmcSlice - wantM CmcMapping - }{ - { - "parse mapping 1", - CmcSlice{{Id: 3}, {Id: 10}, {Id: 44}}, - map[uint][]CoinMap{3: {{Id: 3}}, 10: {{Id: 10}}, 44: {{Id: 44}}}}, - { - "parse mapping 2", - CmcSlice{{Id: 3}, {Id: 10}}, - map[uint][]CoinMap{3: {{Id: 3}}, 10: {{Id: 10}}}}, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - if gotM := tt.c.cmcToCoinMap(); !reflect.DeepEqual(gotM, tt.wantM) { - t.Errorf("cmcToCoinMap() = %v, want %v", gotM, tt.wantM) - } - }) - } -} - -func TestCmcMapping_coinToCmcMap(t *testing.T) { - tests := []struct { - name string - c CmcSlice - wantM CoinMapping - }{ - { - "parse mapping 1", - CmcSlice{{Coin: 60, Id: 3, TokenId: "3211"}, {Coin: 60, Id: 10}, {Coin: 61, Id: 44}}, - CoinMapping{generateId(60, "3211"): {Id: 3, Coin: 60, TokenId: "3211"}, generateId(60, ""): {Coin: 60, Id: 10}, generateId(61, ""): {Coin: 61, Id: 44}}}, - { - "parse mapping 2", - CmcSlice{{Coin: 60, Id: 3}, {Coin: 61, Id: 10}}, - CoinMapping{generateId(60, ""): {Coin: 60, Id: 3, TokenId: ""}, generateId(61, ""): {Coin: 61, Id: 10}}}, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - if gotM := tt.c.coinToCmcMap(); !reflect.DeepEqual(gotM, tt.wantM) { - t.Errorf("coinToCmcMap() = %v, want %v", gotM, tt.wantM) - } - }) - } -} - -func Test_generateId(t *testing.T) { - type args struct { - coin uint - token string - } - tests := []struct { - name string - args args - want string - }{ - { - "generate id 1", - args{coin: 60, token: ""}, - "60:", - }, - { - "generate id 2", - args{coin: 60, token: "12"}, - "60:12", - }, - { - "generate id 2", - args{coin: 185, token: "12"}, - "185:12", - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - if got := generateId(tt.args.coin, tt.args.token); !reflect.DeepEqual(got, tt.want) { - t.Errorf("generateId() = %v, want %v", got, tt.want) - } - }) - } -} diff --git a/marketdata/clients/cmc/client.go b/marketdata/clients/cmc/client.go deleted file mode 100644 index f10829f8e..000000000 --- a/marketdata/clients/cmc/client.go +++ /dev/null @@ -1,56 +0,0 @@ -package cmc - -import ( - "github.com/trustwallet/blockatlas/pkg/blockatlas" - "github.com/trustwallet/blockatlas/pkg/errors" - "net/url" - "time" -) - -type Client struct { - apiKey string - blockatlas.Request -} - -func NewClient(api string, key string) *Client { - c := Client{ - Request: blockatlas.InitClient(api), - apiKey: key, - } - c.Headers["X-CMC_PRO_API_KEY"] = key - return &c -} - -func (c *Client) GetData() (prices CoinPrices, err error) { - err = c.Get(&prices, "v1/cryptocurrency/listings/latest", - url.Values{"limit": {"5000"}, "convert": {blockatlas.DefaultCurrency}}) - return -} - -func GetCmcMap(mapApi string) (CmcMapping, error) { - var results CmcSlice - request := blockatlas.Request{ - BaseUrl: mapApi, - HttpClient: blockatlas.DefaultClient, - ErrorHandler: blockatlas.DefaultErrorHandler, - } - err := request.GetWithCache(&results, "mapping.json", nil, time.Hour*1) - if err != nil { - return nil, errors.E(err).PushToSentry() - } - return results.cmcToCoinMap(), nil -} - -func GetCoinMap(mapApi string) (CoinMapping, error) { - var results CmcSlice - request := blockatlas.Request{ - BaseUrl: mapApi, - HttpClient: blockatlas.DefaultClient, - ErrorHandler: blockatlas.DefaultErrorHandler, - } - err := request.GetWithCache(&results, "mapping.json", nil, time.Hour*1) - if err != nil { - return nil, errors.E(err).PushToSentry() - } - return results.coinToCmcMap(), nil -} diff --git a/marketdata/clients/cmc/models.go b/marketdata/clients/cmc/models.go deleted file mode 100644 index d4b3bd5f7..000000000 --- a/marketdata/clients/cmc/models.go +++ /dev/null @@ -1,63 +0,0 @@ -package cmc - -import "time" - -type Charts struct { - Data ChartQuotes `json:"data"` -} - -type ChartQuotes map[string]ChartQuoteValues - -type ChartQuoteValues map[string][]float64 - -type ChartInfo struct { - Data ChartInfoData `json:"data"` -} - -type ChartInfoData struct { - Rank uint32 `json:"rank"` - CirculatingSupply float64 `json:"circulating_supply"` - TotalSupply float64 `json:"total_supply"` - Quotes map[string]ChartInfoQuote `json:"quotes"` -} - -type ChartInfoQuote struct { - Price float64 `json:"price"` - Volume24 float64 `json:"volume_24h"` - MarketCap float64 `json:"market_cap"` -} - -type CoinPrices struct { - Status struct { - Timestamp time.Time `json:"timestamp"` - ErrorCode int `json:"error_code"` - ErrorMessage interface{} `json:"error_message"` - } `json:"status"` - Data []Data `json:"data"` -} - -type Coin struct { - Id uint `json:"id"` - Symbol string `json:"symbol"` -} - -type Data struct { - Coin - LastUpdated time.Time `json:"last_updated"` - Platform *Platform `json:"platform"` - Quote Quote `json:"quote"` -} - -type Platform struct { - Coin - TokenAddress string `json:"token_address"` -} - -type Quote struct { - USD USD `json:"USD"` -} - -type USD struct { - Price float64 `json:"price"` - PercentChange24h float64 `json:"percent_change_24h"` -} diff --git a/marketdata/clients/cmc/webclient.go b/marketdata/clients/cmc/webclient.go deleted file mode 100644 index 7abd4a55e..000000000 --- a/marketdata/clients/cmc/webclient.go +++ /dev/null @@ -1,32 +0,0 @@ -package cmc - -import ( - "github.com/trustwallet/blockatlas/pkg/blockatlas" - "net/url" - "strconv" - "time" -) - -type WebClient struct { - blockatlas.Request -} - -func NewWebClient(api string) *WebClient { - c := WebClient{ - Request: blockatlas.InitClient(api), - } - return &c -} - -func (c *WebClient) GetChartsData(id uint, currency string, timeStart int64, timeEnd int64, interval string) (charts Charts, err error) { - values := url.Values{ - "convert": {currency}, - "format": {"chart_crypto_details"}, - "id": {strconv.FormatInt(int64(id), 10)}, - "time_start": {strconv.FormatInt(timeStart, 10)}, - "time_end": {strconv.FormatInt(timeEnd, 10)}, - "interval": {interval}, - } - err = c.GetWithCache(&charts, "v1/cryptocurrency/quotes/historical", values, time.Minute*5) - return -} diff --git a/marketdata/clients/cmc/widgetclient.go b/marketdata/clients/cmc/widgetclient.go deleted file mode 100644 index 6bbbf158c..000000000 --- a/marketdata/clients/cmc/widgetclient.go +++ /dev/null @@ -1,28 +0,0 @@ -package cmc - -import ( - "fmt" - "github.com/trustwallet/blockatlas/pkg/blockatlas" - "net/url" - "time" -) - -type WidgetClient struct { - blockatlas.Request -} - -func NewWidgetClient(api string) *WidgetClient { - c := WidgetClient{ - Request: blockatlas.InitClient(api), - } - return &c -} - -func (c *WidgetClient) GetCoinData(id uint, currency string) (charts ChartInfo, err error) { - values := url.Values{ - "convert": {currency}, - "ref": {"widget"}, - } - err = c.GetWithCache(&charts, fmt.Sprintf("v2/ticker/%d", id), values, time.Minute*5) - return -} diff --git a/marketdata/clients/coingecko/cache.go b/marketdata/clients/coingecko/cache.go deleted file mode 100644 index 82587cd91..000000000 --- a/marketdata/clients/coingecko/cache.go +++ /dev/null @@ -1,94 +0,0 @@ -package coingecko - -import ( - "fmt" - "github.com/trustwallet/blockatlas/pkg/address" - "github.com/trustwallet/blockatlas/pkg/blockatlas" - "github.com/trustwallet/blockatlas/pkg/errors" - "strings" -) - -type Cache map[string][]CoinResult -type SymbolsCache map[string]GeckoCoin - -func (c Cache) GetCoinsById(id string) (coins []CoinResult, err error) { - coins, ok := c[id] - if !ok { - err = errors.E("No coin found by id", errors.Params{"id": id}) - } - return -} - -func (c SymbolsCache) generateId(symbol string, token string) string { - if len(token) > 0 { - return fmt.Sprintf("%s:%s", strings.ToUpper(symbol), address.EIP55Checksum(token)) - } - return strings.ToUpper(symbol) -} - -func (c SymbolsCache) GetCoinsBySymbol(symbol string, token string) (coin GeckoCoin, err error) { - coin, ok := c[c.generateId(symbol, token)] - if !ok { - err = errors.E("No coin found by symbol", errors.Params{"symbol": symbol, "token": token}) - } - return -} - -func NewSymbolsCache(coins GeckoCoins) *SymbolsCache { - m := SymbolsCache{} - coinsMap := getCoinsMap(coins) - - for _, coin := range coins { - if len(coin.Platforms) == 0 { - m[m.generateId(coin.Symbol, "")] = coin - } - for platform, address := range coin.Platforms { - if len(platform) == 0 || len(address) == 0 { - continue - } - platformCoin, ok := coinsMap[platform] - if !ok { - continue - } - m[m.generateId(platformCoin.Symbol, address)] = coin - } - } - - return &m -} - -func NewCache(coins GeckoCoins) *Cache { - m := Cache{} - coinsMap := getCoinsMap(coins) - - for _, coin := range coins { - for platform, address := range coin.Platforms { - if len(platform) == 0 || len(address) == 0 { - continue - } - platformCoin, ok := coinsMap[platform] - if !ok { - continue - } - - _, ok = m[coin.Id] - if !ok { - m[coin.Id] = make([]CoinResult, 0) - } - m[coin.Id] = append(m[coin.Id], CoinResult{ - Symbol: platformCoin.Symbol, - TokenId: address, - CoinType: blockatlas.TypeToken, - }) - } - } - return &m -} - -func getCoinsMap(coins GeckoCoins) map[string]GeckoCoin { - coinsMap := make(map[string]GeckoCoin) - for _, coin := range coins { - coinsMap[coin.Id] = coin - } - return coinsMap -} diff --git a/marketdata/clients/coingecko/cache_test.go b/marketdata/clients/coingecko/cache_test.go deleted file mode 100644 index aa53df27c..000000000 --- a/marketdata/clients/coingecko/cache_test.go +++ /dev/null @@ -1,300 +0,0 @@ -package coingecko - -import ( - "github.com/stretchr/testify/assert" - "testing" -) - -func Test_NewCache(t *testing.T) { - tests := []struct { - name string - coins GeckoCoins - expected *Cache - }{ - { - name: "test prepare cache map", - coins: GeckoCoins{ - GeckoCoin{ - Id: "ethtereum", - Symbol: "eth", - Name: "eth", - Platforms: nil, - }, - GeckoCoin{ - Id: "bitcoin", - Symbol: "btc", - Name: "btc", - Platforms: nil, - }, - GeckoCoin{ - Id: "0x", - Symbol: "0x", - Name: "0x", - Platforms: Platforms{ - "ethtereum": "0x812f35b66ec9eee26cd7fdf07fbc1c9c0ac3c4d6", - }, - }, - GeckoCoin{ - Id: "usdt", - Symbol: "usdt", - Name: "usdt", - Platforms: Platforms{ - "ethtereum": "0xdac17f958d2ee523a2206206994597c13d831ec7", - }, - }, - }, - expected: &Cache{ - "0x": { - CoinResult{ - Symbol: "eth", - TokenId: "0x812f35b66ec9eee26cd7fdf07fbc1c9c0ac3c4d6", - CoinType: "token", - }, - }, - "usdt": { - CoinResult{ - Symbol: "eth", - TokenId: "0xdac17f958d2ee523a2206206994597c13d831ec7", - CoinType: "token", - }, - }, - }, - }, - } - - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - assert.Equal(t, tt.expected, NewCache(tt.coins)) - }) - } -} - -func TestClient_GetCoinsById(t *testing.T) { - coins := GeckoCoins{ - GeckoCoin{ - Id: "ethtereum", - Symbol: "eth", - Name: "eth", - Platforms: nil, - }, - GeckoCoin{ - Id: "bitcoin", - Symbol: "btc", - Name: "btc", - Platforms: nil, - }, - GeckoCoin{ - Id: "0x", - Symbol: "0x", - Name: "0x", - Platforms: Platforms{ - "ethtereum": "0x812f35b66ec9eee26cd7fdf07fbc1c9c0ac3c4d6", - }, - }, - GeckoCoin{ - Id: "usdt", - Symbol: "usdt", - Name: "usdt", - Platforms: Platforms{ - "ethtereum": "0xdac17f958d2ee523a2206206994597c13d831ec7", - }, - }, - } - tests := []struct { - name string - id string - expected []CoinResult - }{ - { - name: "test fetching 0x", - id: "0x", - expected: []CoinResult{ - { - Symbol: "eth", - TokenId: "0x812f35b66ec9eee26cd7fdf07fbc1c9c0ac3c4d6", - CoinType: "token", - }, - }, - }, - { - name: "test fetching usdt", - id: "usdt", - expected: []CoinResult{ - { - Symbol: "eth", - TokenId: "0xdac17f958d2ee523a2206206994597c13d831ec7", - CoinType: "token", - }, - }, - }, - } - cache := NewCache(coins) - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - res, err := cache.GetCoinsById(tt.id) - assert.Nil(t, err) - assert.Equal(t, tt.expected, res) - }) - } -} - -func Test_NewSymbolsCache(t *testing.T) { - tests := []struct { - name string - coins GeckoCoins - expected *SymbolsCache - }{ - { - name: "test prepare cache map", - coins: GeckoCoins{ - GeckoCoin{ - Id: "ethtereum", - Symbol: "eth", - Name: "eth", - Platforms: nil, - }, - GeckoCoin{ - Id: "bitcoin", - Symbol: "btc", - Name: "btc", - Platforms: nil, - }, - GeckoCoin{ - Id: "0x", - Symbol: "0x", - Name: "0x", - Platforms: Platforms{ - "ethtereum": "0x812f35b66Ec9EEe26CD7Fdf07Fbc1c9c0ac3C4D6", - }, - }, - GeckoCoin{ - Id: "usdt", - Symbol: "usdt", - Name: "usdt", - Platforms: Platforms{ - "ethtereum": "0xdAC17F958D2ee523a2206206994597C13D831ec7", - }, - }, - }, - expected: &SymbolsCache{ - "ETH:0x812f35b66Ec9EEe26CD7Fdf07Fbc1c9c0ac3C4D6": GeckoCoin{ - Id: "0x", - Symbol: "0x", - Name: "0x", - Platforms: Platforms{ - "ethtereum": "0x812f35b66Ec9EEe26CD7Fdf07Fbc1c9c0ac3C4D6", - }, - }, - "ETH:0xdAC17F958D2ee523a2206206994597C13D831ec7": GeckoCoin{ - Id: "usdt", - Symbol: "usdt", - Name: "usdt", - Platforms: Platforms{ - "ethtereum": "0xdAC17F958D2ee523a2206206994597C13D831ec7", - }, - }, - "BTC": GeckoCoin{Id: "bitcoin", Symbol: "btc", Name: "btc", Platforms: nil}, - "ETH": GeckoCoin{Id: "ethtereum", Symbol: "eth", Name: "eth", Platforms: nil}, - }, - }, - } - - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - assert.Equal(t, tt.expected, NewSymbolsCache(tt.coins)) - }) - } -} - -func TestClient_GetCoinsBySymbol(t *testing.T) { - coins := GeckoCoins{ - GeckoCoin{ - Id: "ethtereum", - Symbol: "eth", - Name: "eth", - Platforms: nil, - }, - GeckoCoin{ - Id: "bitcoin", - Symbol: "btc", - Name: "btc", - Platforms: nil, - }, - GeckoCoin{ - Id: "0x", - Symbol: "0x", - Name: "0x", - Platforms: Platforms{ - "ethtereum": "0x812f35b66Ec9EEe26CD7Fdf07Fbc1c9c0ac3C4D6", - }, - }, - GeckoCoin{ - Id: "usdt", - Symbol: "usdt", - Name: "usdt", - Platforms: Platforms{ - "ethtereum": "0xdAC17F958D2ee523a2206206994597C13D831ec7", - }, - }, - } - tests := []struct { - name string - symbol string - address string - expected GeckoCoin - }{ - { - name: "test fetching 0x", - symbol: "eth", - address: "0x812f35b66Ec9EEe26CD7Fdf07Fbc1c9c0ac3C4D6", - expected: GeckoCoin{ - Id: "0x", - Symbol: "0x", - Name: "0x", - Platforms: Platforms{ - "ethtereum": "0x812f35b66Ec9EEe26CD7Fdf07Fbc1c9c0ac3C4D6", - }, - }, - }, { - name: "test fetching usdt", - symbol: "eth", - address: "0xdAC17F958D2ee523a2206206994597C13D831ec7", - expected: GeckoCoin{ - Id: "usdt", - Symbol: "usdt", - Name: "usdt", - Platforms: Platforms{ - "ethtereum": "0xdAC17F958D2ee523a2206206994597C13D831ec7", - }, - }, - }, - { - name: "test fetching btc", - symbol: "btc", - expected: GeckoCoin{ - Id: "bitcoin", - Symbol: "btc", - Name: "btc", - Platforms: nil, - }, - }, - { - name: "test fetching eth", - symbol: "eth", - expected: GeckoCoin{ - Id: "ethtereum", - Symbol: "eth", - Name: "eth", - Platforms: nil, - }, - }, - } - cache := NewSymbolsCache(coins) - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - res, err := cache.GetCoinsBySymbol(tt.symbol, tt.address) - assert.Nil(t, err) - assert.Equal(t, tt.expected, res) - }) - } -} diff --git a/marketdata/clients/coingecko/client.go b/marketdata/clients/coingecko/client.go deleted file mode 100644 index d8774fc05..000000000 --- a/marketdata/clients/coingecko/client.go +++ /dev/null @@ -1,98 +0,0 @@ -package coingecko - -import ( - "fmt" - "github.com/trustwallet/blockatlas/pkg/blockatlas" - "github.com/trustwallet/blockatlas/pkg/logger" - "net/url" - "strconv" - "strings" - "sync" - "time" -) - -const ( - bucketSize = 500 -) - -type Client struct { - blockatlas.Request -} - -func NewClient(api string) *Client { - c := Client{ - Request: blockatlas.InitClient(api), - } - return &c -} - -func (c *Client) FetchLatestRates(coins GeckoCoins, currency string) (prices CoinPrices) { - ci := coins.coinIds() - - i := 0 - prChan := make(chan CoinPrices) - var wg sync.WaitGroup - for i < len(ci) { - wg.Add(1) - go func(i int) { - defer wg.Done() - var end = len(ci) - if len(ci) > i+bucketSize { - end = i + bucketSize - } - bucket := ci[i:end] - values := url.Values{ - "vs_currency": {currency}, - "sparkline": {"false"}, - "ids": {strings.Join(bucket[:], ",")}, - } - - var cp CoinPrices - err := c.Get(&cp, "v3/coins/markets", values) - if err != nil { - logger.Error(err) - return - } - prChan <- cp - }(i) - - i += bucketSize - } - - go func() { - wg.Wait() - close(prChan) - }() - - for bucket := range prChan { - prices = append(prices, bucket...) - } - - return -} - -func (c *Client) GetChartsData(id string, currency string, timeStart int64, timeEnd int64) (charts Charts, err error) { - values := url.Values{ - "vs_currency": {currency}, - "from": {strconv.FormatInt(timeStart, 10)}, - "to": {strconv.FormatInt(timeEnd, 10)}, - } - err = c.GetWithCache(&charts, fmt.Sprintf("v3/coins/%s/market_chart/range", id), values, time.Minute*5) - return -} - -func (c *Client) FetchCoinsList() (coins GeckoCoins, err error) { - values := url.Values{ - "include_platform": {"true"}, - } - err = c.GetWithCache(&coins, "v3/coins/list", values, time.Hour) - return -} - -func (coins GeckoCoins) coinIds() []string { - coinIds := make([]string, 0) - for _, coin := range coins { - coinIds = append(coinIds, coin.Id) - } - return coinIds -} diff --git a/marketdata/clients/coingecko/client_test.go b/marketdata/clients/coingecko/client_test.go deleted file mode 100644 index c4dd29347..000000000 --- a/marketdata/clients/coingecko/client_test.go +++ /dev/null @@ -1,42 +0,0 @@ -package coingecko - -import ( - "github.com/stretchr/testify/assert" - "testing" -) - -func Test_coinIds(t *testing.T) { - tests := []struct { - name string - coins GeckoCoins - expected []string - }{ - { - name: "test construct coin Ids", - coins: GeckoCoins{ - GeckoCoin{ - Id: "ethtereum", - Symbol: "eth", - Name: "eth", - Platforms: nil, - }, - GeckoCoin{ - Id: "bitcoin", - Symbol: "btc", - Name: "btc", - Platforms: nil, - }, - }, - expected: []string{ - "ethtereum", - "bitcoin", - }, - }, - } - - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - assert.Equal(t, tt.expected, tt.coins.coinIds()) - }) - } -} diff --git a/marketdata/clients/coingecko/models.go b/marketdata/clients/coingecko/models.go deleted file mode 100644 index f1821f6ef..000000000 --- a/marketdata/clients/coingecko/models.go +++ /dev/null @@ -1,49 +0,0 @@ -package coingecko - -import ( - "github.com/trustwallet/blockatlas/pkg/blockatlas" - "time" -) - -type Charts struct { - Prices []ChartVolume `json:"prices"` - MarketCaps []ChartVolume `json:"market_caps"` - Volumes []ChartVolume `json:"total_volumes"` -} - -type ChartVolume []float64 - -type CoinResult struct { - Symbol string - TokenId string - CoinType blockatlas.CoinType -} - -type CoinPrices []CoinPrice - -type CoinPrice struct { - Id string `json:"id"` - Symbol string `json:"symbol"` - Name string `json:"name"` - CurrentPrice float64 `json:"current_price"` - PriceChange24h float64 `json:"price_change_24h"` - PriceChangePercentage24h float64 `json:"price_change_percentage_24h"` - MarketCapChange24h float64 `json:"market_cap_change_24h"` - MarketCapChangePercentage24h float64 `json:"market_cap_change_percentage_24h"` - MarketCap float64 `json:"market_cap"` - TotalVolume float64 `json:"total_volume"` - CirculatingSupply float64 `json:"circulating_supply"` - TotalSupply float64 `json:"total_supply"` - LastUpdated time.Time `json:"last_updated"` -} - -type GeckoCoins []GeckoCoin - -type GeckoCoin struct { - Id string `json:"id"` - Symbol string `json:"symbol"` - Name string `json:"name"` - Platforms Platforms `json:"platforms"` -} - -type Platforms map[string]string diff --git a/marketdata/clients/compound/client.go b/marketdata/clients/compound/client.go deleted file mode 100644 index 52083a569..000000000 --- a/marketdata/clients/compound/client.go +++ /dev/null @@ -1,21 +0,0 @@ -package compound - -import ( - "github.com/trustwallet/blockatlas/pkg/blockatlas" -) - -type Client struct { - blockatlas.Request -} - -func NewClient(api string) *Client { - c := Client{ - Request: blockatlas.InitClient(api), - } - return &c -} - -func (c *Client) GetData() (prices CoinPrices, err error) { - err = c.Get(&prices, "v2/ctoken", nil) - return -} diff --git a/marketdata/clients/compound/models.go b/marketdata/clients/compound/models.go deleted file mode 100644 index 44157eddd..000000000 --- a/marketdata/clients/compound/models.go +++ /dev/null @@ -1,15 +0,0 @@ -package compound - -type CoinPrices struct { - Data []CToken `json:"cToken"` -} - -type CToken struct { - ExchangeRate Amount `json:"exchange_rate"` - Symbol string `json:"symbol"` - TokenAddress string `json:"token_address"` -} - -type Amount struct { - Value float64 `json:"value,string"` -} diff --git a/marketdata/market.go b/marketdata/market.go deleted file mode 100644 index 37f74dd1c..000000000 --- a/marketdata/market.go +++ /dev/null @@ -1,65 +0,0 @@ -package marketdata - -import ( - "github.com/robfig/cron/v3" - "github.com/spf13/viper" - "github.com/trustwallet/blockatlas/marketdata/market" - "github.com/trustwallet/blockatlas/marketdata/market/coingecko" - cmc "github.com/trustwallet/blockatlas/marketdata/market/coinmarketcap" - "github.com/trustwallet/blockatlas/marketdata/market/compound" - "github.com/trustwallet/blockatlas/marketdata/market/dex" - "github.com/trustwallet/blockatlas/pkg/errors" - "github.com/trustwallet/blockatlas/pkg/logger" - "github.com/trustwallet/blockatlas/storage" -) - -var marketProviders market.Providers - -func InitMarkets(storage storage.Market) { - marketProviders = market.Providers{ - // Add Market Quote Providers: - 0: dex.InitMarket( - viper.GetString("market.dex.api"), - viper.GetString("market.dex.quote_update_time"), - ), - 1: cmc.InitMarket( - viper.GetString("market.cmc.api"), - viper.GetString("market.cmc.api_key"), - viper.GetString("market.cmc.map_url"), - viper.GetString("market.quote_update_time"), - ), - 2: compound.InitMarket( - viper.GetString("market.compound.api"), - viper.GetString("market.quote_update_time"), - ), - 3: coingecko.InitMarket( - viper.GetString("market.coingecko.api"), - viper.GetString("market.quote_update_time"), - ), - } - addMarkets(storage, marketProviders) -} - -func addMarkets(storage storage.Market, ps market.Providers) { - c := cron.New() - for _, p := range ps { - scheduleTasks(storage, p, c) - } - c.Start() -} - -func runMarket(storage storage.Market, p market.Provider) error { - data, err := p.GetData() - if err != nil { - return errors.E(err, "GetData") - } - for _, result := range data { - err = storage.SaveTicker(result, marketProviders) - if err != nil { - logger.Error(errors.E(err, "SaveTicker", - errors.Params{"result": result})) - } - } - logger.Info("Market data result", logger.Params{"markets": len(data), "provider": p.GetId()}) - return nil -} diff --git a/marketdata/market/coingecko/coingecko.go b/marketdata/market/coingecko/coingecko.go deleted file mode 100644 index 3e9a91577..000000000 --- a/marketdata/market/coingecko/coingecko.go +++ /dev/null @@ -1,94 +0,0 @@ -package coingecko - -import ( - "github.com/trustwallet/blockatlas/marketdata/clients/coingecko" - "github.com/trustwallet/blockatlas/marketdata/market" - "github.com/trustwallet/blockatlas/pkg/blockatlas" - "strings" -) - -const ( - id = "coingecko" -) - -type Market struct { - client *coingecko.Client - cache *coingecko.Cache - market.Market -} - -func InitMarket(api string, updateTime string) market.Provider { - m := &Market{ - client: coingecko.NewClient(api), - Market: market.Market{ - Id: id, - UpdateTime: updateTime, - }, - } - return m -} - -func (m *Market) GetData() (result blockatlas.Tickers, err error) { - coins, err := m.client.FetchCoinsList() - if err != nil { - return - } - m.cache = coingecko.NewCache(coins) - - rates := m.client.FetchLatestRates(coins, blockatlas.DefaultCurrency) - result = m.normalizeTickers(rates, m.GetId()) - return -} - -func (m *Market) normalizeTicker(price coingecko.CoinPrice, provider string) (tickers blockatlas.Tickers) { - tokenId := "" - coinName := strings.ToUpper(price.Symbol) - coinType := blockatlas.TypeCoin - - cgCoin, err := m.cache.GetCoinsById(price.Id) - if err != nil { - tickers = append(tickers, &blockatlas.Ticker{ - CoinName: coinName, - CoinType: coinType, - TokenId: tokenId, - Price: blockatlas.TickerPrice{ - Value: price.CurrentPrice, - Change24h: price.PriceChangePercentage24h, - Currency: blockatlas.DefaultCurrency, - Provider: provider, - }, - LastUpdate: price.LastUpdated, - }) - return - } - - for _, cg := range cgCoin { - coinName = strings.ToUpper(cg.Symbol) - if cg.CoinType == blockatlas.TypeCoin { - tokenId = "" - } else if len(cg.TokenId) > 0 { - tokenId = cg.TokenId - } - tickers = append(tickers, &blockatlas.Ticker{ - CoinName: coinName, - CoinType: cg.CoinType, - TokenId: tokenId, - Price: blockatlas.TickerPrice{ - Value: price.CurrentPrice, - Change24h: price.PriceChangePercentage24h, - Currency: blockatlas.DefaultCurrency, - Provider: provider, - }, - LastUpdate: price.LastUpdated, - }) - } - return -} - -func (m *Market) normalizeTickers(prices coingecko.CoinPrices, provider string) (tickers blockatlas.Tickers) { - for _, price := range prices { - t := m.normalizeTicker(price, provider) - tickers = append(tickers, t...) - } - return -} diff --git a/marketdata/market/coingecko/coingecko_test.go b/marketdata/market/coingecko/coingecko_test.go deleted file mode 100644 index 4aeb85e51..000000000 --- a/marketdata/market/coingecko/coingecko_test.go +++ /dev/null @@ -1,104 +0,0 @@ -package coingecko - -import ( - "github.com/stretchr/testify/assert" - "github.com/trustwallet/blockatlas/marketdata/clients/coingecko" - "github.com/trustwallet/blockatlas/pkg/blockatlas" - "sort" - "testing" - "time" -) - -func Test_normalizeTickers(t *testing.T) { - coins := coingecko.GeckoCoins{ - coingecko.GeckoCoin{ - Id: "ethtereum", - Symbol: "eth", - Name: "eth", - Platforms: nil, - }, - coingecko.GeckoCoin{ - Id: "bitcoin", - Symbol: "btc", - Name: "btc", - Platforms: nil, - }, - coingecko.GeckoCoin{ - Id: "cREP", - Symbol: "cREP", - Name: "cREP", - Platforms: coingecko.Platforms{ - "ethtereum": "0x158079ee67fce2f58472a96584a73c7ab9ac95c1", - }, - }, - coingecko.GeckoCoin{ - Id: "cUSDC", - Symbol: "cUSDC", - Name: "cUSDC", - Platforms: coingecko.Platforms{ - "ethtereum": "0x39aa39c021dfbae8fac545936693ac917d5e7563", - }, - }, - } - - m := Market{} - m.cache = coingecko.NewCache(coins) - type args struct { - prices coingecko.CoinPrices - provider string - } - tests := []struct { - name string - args args - wantTickers blockatlas.Tickers - }{ - { - "test normalize coingecko quote", - args{prices: coingecko.CoinPrices{ - { - Id: "cUSDC", - Symbol: "cUSDC", - CurrentPrice: 0.0021, - }, - { - Id: "cREP", - Symbol: "cREP", - CurrentPrice: 0.02, - }, - }, provider: id}, - blockatlas.Tickers{ - &blockatlas.Ticker{CoinName: "ETH", TokenId: "0x39aa39c021dfbae8fac545936693ac917d5e7563", CoinType: blockatlas.TypeToken, LastUpdate: time.Unix(222, 0), - Price: blockatlas.TickerPrice{ - Value: 0.0021, - Currency: blockatlas.DefaultCurrency, - Provider: id, - }, - }, - &blockatlas.Ticker{CoinName: "ETH", TokenId: "0x158079ee67fce2f58472a96584a73c7ab9ac95c1", CoinType: blockatlas.TypeToken, LastUpdate: time.Unix(444, 0), - Price: blockatlas.TickerPrice{ - Value: 0.02, - Currency: blockatlas.DefaultCurrency, - Provider: id, - }, - }, - }, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - gotTickers := m.normalizeTickers(tt.args.prices, tt.args.provider) - now := time.Now() - sort.Slice(gotTickers, func(i, j int) bool { - gotTickers[i].LastUpdate = now - gotTickers[j].LastUpdate = now - return gotTickers[i].Coin > gotTickers[j].Coin - }) - sort.Slice(tt.wantTickers, func(i, j int) bool { - tt.wantTickers[i].LastUpdate = now - tt.wantTickers[j].LastUpdate = now - return tt.wantTickers[i].Coin > tt.wantTickers[j].Coin - }) - assert.Equal(t, tt.wantTickers, gotTickers) - }) - } -} diff --git a/marketdata/market/coinmarketcap/cmc.go b/marketdata/market/coinmarketcap/cmc.go deleted file mode 100644 index 0a4fbda13..000000000 --- a/marketdata/market/coinmarketcap/cmc.go +++ /dev/null @@ -1,102 +0,0 @@ -package cmc - -import ( - "github.com/trustwallet/blockatlas/marketdata/clients/cmc" - "github.com/trustwallet/blockatlas/marketdata/market" - "github.com/trustwallet/blockatlas/pkg/blockatlas" -) - -const ( - id = "cmc" -) - -type Market struct { - market.Market - mapApi string - client *cmc.Client -} - -func InitMarket(api string, apiKey string, mapApi string, updateTime string) market.Provider { - m := &Market{ - Market: market.Market{ - Id: id, - UpdateTime: updateTime, - }, - mapApi: mapApi, - client: cmc.NewClient(api, apiKey), - } - return m -} - -func (m *Market) GetData() (blockatlas.Tickers, error) { - cmap, err := cmc.GetCmcMap(m.mapApi) - if err != nil { - return nil, err - } - prices, err := m.client.GetData() - if err != nil { - return nil, err - } - return normalizeTickers(prices, m.GetId(), cmap), nil -} - -func normalizeTicker(price cmc.Data, provider string, cmap cmc.CmcMapping) (tickers blockatlas.Tickers) { - tokenId := "" - coinName := price.Symbol - coinType := blockatlas.TypeCoin - if price.Platform != nil { - coinType = blockatlas.TypeToken - coinName = price.Platform.Symbol - tokenId = price.Platform.TokenAddress - if len(tokenId) == 0 { - tokenId = price.Symbol - } - } - - cmcCoin, err := cmap.GetCoins(price.Id) - if err != nil { - tickers = append(tickers, &blockatlas.Ticker{ - CoinName: coinName, - CoinType: coinType, - TokenId: tokenId, - Price: blockatlas.TickerPrice{ - Value: price.Quote.USD.Price, - Change24h: price.Quote.USD.PercentChange24h, - Currency: blockatlas.DefaultCurrency, - Provider: provider, - }, - LastUpdate: price.LastUpdated, - }) - return - } - - for _, cmc := range cmcCoin { - coinName = cmc.Coin.Symbol - if cmc.CoinType == blockatlas.TypeCoin { - tokenId = "" - } else if len(cmc.TokenId) > 0 { - tokenId = cmc.TokenId - } - tickers = append(tickers, &blockatlas.Ticker{ - CoinName: coinName, - CoinType: cmc.CoinType, - TokenId: tokenId, - Price: blockatlas.TickerPrice{ - Value: price.Quote.USD.Price, - Change24h: price.Quote.USD.PercentChange24h, - Currency: blockatlas.DefaultCurrency, - Provider: provider, - }, - LastUpdate: price.LastUpdated, - }) - } - return -} - -func normalizeTickers(prices cmc.CoinPrices, provider string, cmap cmc.CmcMapping) (tickers blockatlas.Tickers) { - for _, price := range prices.Data { - t := normalizeTicker(price, provider, cmap) - tickers = append(tickers, t...) - } - return -} diff --git a/marketdata/market/coinmarketcap/cmc_test.go b/marketdata/market/coinmarketcap/cmc_test.go deleted file mode 100644 index 1550d394d..000000000 --- a/marketdata/market/coinmarketcap/cmc_test.go +++ /dev/null @@ -1,93 +0,0 @@ -package cmc - -import ( - "github.com/stretchr/testify/assert" - "github.com/trustwallet/blockatlas/marketdata/clients/cmc" - "github.com/trustwallet/blockatlas/pkg/blockatlas" - "sort" - "testing" - "time" -) - -func Test_normalizeTickers(t *testing.T) { - mapping := cmc.CmcMapping{ - 666: {{ - Coin: 1023, - Id: 666, - Type: "coin", - }}, - } - type args struct { - prices cmc.CoinPrices - provider string - } - tests := []struct { - name string - args args - wantTickers blockatlas.Tickers - }{ - { - "test normalize cmc quote", - args{prices: cmc.CoinPrices{Data: []cmc.Data{ - {Coin: cmc.Coin{Symbol: "BTC", Id: 0}, LastUpdated: time.Unix(111, 0), Quote: cmc.Quote{ - USD: cmc.USD{Price: 223.55, PercentChange24h: 10}}}, - {Coin: cmc.Coin{Symbol: "ETH", Id: 60}, LastUpdated: time.Unix(333, 0), Quote: cmc.Quote{ - USD: cmc.USD{Price: 11.11, PercentChange24h: 20}}}, - {Coin: cmc.Coin{Symbol: "SWP", Id: 6969}, LastUpdated: time.Unix(444, 0), Quote: cmc.Quote{ - USD: cmc.USD{Price: 463.22, PercentChange24h: -3}}, - Platform: &cmc.Platform{Coin: cmc.Coin{Symbol: "ETH"}, TokenAddress: "0x8ce9137d39326ad0cd6491fb5cc0cba0e089b6a9"}}, - {Coin: cmc.Coin{Symbol: "ONE", Id: 666}, LastUpdated: time.Unix(555, 0), Quote: cmc.Quote{ - USD: cmc.USD{Price: 123.09, PercentChange24h: -1.4}}, - Platform: &cmc.Platform{Coin: cmc.Coin{Symbol: "BNB"}, TokenAddress: "0x8ce9137d39326ad0cd6491fb5cc0cba0e089b6a9"}}}}, - provider: "cmc"}, - blockatlas.Tickers{ - &blockatlas.Ticker{CoinName: "BTC", CoinType: blockatlas.TypeCoin, LastUpdate: time.Unix(111, 0), - Price: blockatlas.TickerPrice{ - Value: 223.55, - Change24h: 10, - Currency: blockatlas.DefaultCurrency, - Provider: "cmc", - }, - }, - &blockatlas.Ticker{CoinName: "ETH", CoinType: blockatlas.TypeCoin, LastUpdate: time.Unix(333, 0), - Price: blockatlas.TickerPrice{ - Value: 11.11, - Change24h: 20, - Currency: blockatlas.DefaultCurrency, - Provider: "cmc", - }, - }, - &blockatlas.Ticker{CoinName: "ETH", TokenId: "0x8ce9137d39326ad0cd6491fb5cc0cba0e089b6a9", CoinType: blockatlas.TypeToken, LastUpdate: time.Unix(444, 0), - Price: blockatlas.TickerPrice{ - Value: 463.22, - Change24h: -3, - Currency: blockatlas.DefaultCurrency, - Provider: "cmc", - }, - }, - &blockatlas.Ticker{CoinName: "ONE", CoinType: blockatlas.TypeCoin, LastUpdate: time.Unix(555, 0), - Price: blockatlas.TickerPrice{ - Value: 123.09, - Change24h: -1.4, - Currency: blockatlas.DefaultCurrency, - Provider: "cmc", - }, - }, - }, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - gotTickers := normalizeTickers(tt.args.prices, tt.args.provider, mapping) - sort.SliceStable(gotTickers, func(i, j int) bool { - return gotTickers[i].LastUpdate.Unix() < gotTickers[j].LastUpdate.Unix() - }) - if !assert.Equal(t, len(tt.wantTickers), len(gotTickers)) { - t.Fatal("invalid tickers length") - } - for i, obj := range tt.wantTickers { - assert.Equal(t, obj, gotTickers[i]) - } - }) - } -} diff --git a/marketdata/market/compound/compound.go b/marketdata/market/compound/compound.go deleted file mode 100644 index 0c55765c0..000000000 --- a/marketdata/market/compound/compound.go +++ /dev/null @@ -1,64 +0,0 @@ -package compound - -import ( - "github.com/trustwallet/blockatlas/coin" - c "github.com/trustwallet/blockatlas/marketdata/clients/compound" - "github.com/trustwallet/blockatlas/marketdata/market" - "github.com/trustwallet/blockatlas/pkg/blockatlas" - "time" -) - -const ( - id = "compound" -) - -type Market struct { - market.Market - client *c.Client -} - -func InitMarket(api string, updateTime string) market.Provider { - m := &Market{ - Market: market.Market{ - Id: id, - UpdateTime: updateTime, - }, - client: c.NewClient(api), - } - return m -} - -func (m *Market) GetData() (result blockatlas.Tickers, err error) { - coinPrices, err := m.client.GetData() - if err != nil { - return - } - result = normalizeTickers(coinPrices, m.GetId()) - return result, nil -} - -func normalizeTicker(ctoken c.CToken, provider string) (*blockatlas.Ticker, error) { - // TODO: add value24 calculation - return &blockatlas.Ticker{ - CoinName: coin.Ethereum().Symbol, - CoinType: blockatlas.TypeToken, - TokenId: ctoken.TokenAddress, - Price: blockatlas.TickerPrice{ - Value: ctoken.ExchangeRate.Value, - Currency: blockatlas.DefaultCurrency, - Provider: provider, - }, - LastUpdate: time.Now(), - }, nil -} - -func normalizeTickers(prices c.CoinPrices, provider string) (tickers blockatlas.Tickers) { - for _, price := range prices.Data { - t, err := normalizeTicker(price, provider) - if err != nil { - continue - } - tickers = append(tickers, t) - } - return -} diff --git a/marketdata/market/compound/compound_test.go b/marketdata/market/compound/compound_test.go deleted file mode 100644 index 2eafcdab2..000000000 --- a/marketdata/market/compound/compound_test.go +++ /dev/null @@ -1,71 +0,0 @@ -package compound - -import ( - "github.com/stretchr/testify/assert" - "github.com/trustwallet/blockatlas/marketdata/clients/compound" - "github.com/trustwallet/blockatlas/pkg/blockatlas" - "sort" - "testing" - "time" -) - -func Test_normalizeTickers(t *testing.T) { - type args struct { - prices compound.CoinPrices - provider string - } - tests := []struct { - name string - args args - wantTickers blockatlas.Tickers - }{ - { - "test normalize compound quote", - args{prices: compound.CoinPrices{Data: []compound.CToken{ - { - TokenAddress: "0x39aa39c021dfbae8fac545936693ac917d5e7563", - Symbol: "cUSDC", - ExchangeRate: compound.Amount{Value: 0.0021}, - }, - { - TokenAddress: "0x158079ee67fce2f58472a96584a73c7ab9ac95c1", - Symbol: "cREP", - ExchangeRate: compound.Amount{Value: 0.02}, - }, - }}, provider: id}, - blockatlas.Tickers{ - &blockatlas.Ticker{CoinName: "ETH", TokenId: "0x39aa39c021dfbae8fac545936693ac917d5e7563", CoinType: blockatlas.TypeToken, LastUpdate: time.Unix(222, 0), - Price: blockatlas.TickerPrice{ - Value: 0.0021, - Currency: blockatlas.DefaultCurrency, - Provider: id, - }, - }, - &blockatlas.Ticker{CoinName: "ETH", TokenId: "0x158079ee67fce2f58472a96584a73c7ab9ac95c1", CoinType: blockatlas.TypeToken, LastUpdate: time.Unix(444, 0), - Price: blockatlas.TickerPrice{ - Value: 0.02, - Currency: blockatlas.DefaultCurrency, - Provider: id, - }, - }, - }, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - gotTickers := normalizeTickers(tt.args.prices, tt.args.provider) - now := time.Now() - sort.Slice(gotTickers, func(i, j int) bool { - gotTickers[i].LastUpdate = now - gotTickers[j].LastUpdate = now - return gotTickers[i].Coin > gotTickers[j].Coin - }) - sort.Slice(tt.wantTickers, func(i, j int) bool { - tt.wantTickers[i].LastUpdate = now - tt.wantTickers[j].LastUpdate = now - return tt.wantTickers[i].Coin > tt.wantTickers[j].Coin - }) - assert.Equal(t, tt.wantTickers, gotTickers) - }) - } -} diff --git a/marketdata/market/dex/dex.go b/marketdata/market/dex/dex.go deleted file mode 100644 index 64ddc820b..000000000 --- a/marketdata/market/dex/dex.go +++ /dev/null @@ -1,96 +0,0 @@ -package dex - -import ( - "github.com/trustwallet/blockatlas/coin" - "github.com/trustwallet/blockatlas/marketdata/market" - "github.com/trustwallet/blockatlas/pkg/blockatlas" - "github.com/trustwallet/blockatlas/pkg/errors" - "math/big" - "net/url" - "strconv" - "time" -) - -var ( - id = "dex" - BNBAsset = coin.Binance().Symbol -) - -type Market struct { - market.Market - blockatlas.Request -} - -func InitMarket(api string, updateTime string) market.Provider { - m := &Market{ - Market: market.Market{ - Id: id, - UpdateTime: updateTime, - }, - Request: blockatlas.InitClient(api), - } - return m -} - -func (m *Market) GetData() (blockatlas.Tickers, error) { - var prices []*CoinPrice - err := m.Get(&prices, "v1/ticker/24hr", url.Values{"limit": {"1000"}}) - if err != nil { - return nil, err - } - rate, err := m.Storage.GetRate(BNBAsset) - if err != nil { - return nil, errors.E(err, "rate not found", errors.Params{"asset": BNBAsset}) - } - result := normalizeTickers(prices, m.GetId()) - if rate.PercentChange24h != nil { - rate.PercentChange24h.Mul(rate.PercentChange24h, big.NewFloat(-1)) - } - result.ApplyRate(blockatlas.DefaultCurrency, 1/rate.Rate, rate.PercentChange24h) - return result, nil -} - -func normalizeTicker(price *CoinPrice, provider string) (*blockatlas.Ticker, error) { - if price.QuoteAssetName != BNBAsset && price.BaseAssetName != BNBAsset { - return nil, errors.E("invalid quote/base asset", - errors.Params{"Symbol": price.BaseAssetName, "QuoteAsset": price.QuoteAssetName}) - } - value, err := strconv.ParseFloat(price.LastPrice, 64) - if err != nil { - return nil, errors.E(err, "normalizeTicker parse value error", - errors.Params{"LastPrice": price.LastPrice, "Symbol": price.BaseAssetName}) - } - value24h, err := strconv.ParseFloat(price.PriceChangePercent, 64) - if err != nil { - return nil, errors.E(err, "normalizeTicker parse value24h error", - errors.Params{"PriceChange": price.PriceChangePercent, "Symbol": price.BaseAssetName}) - } - tokenId := price.BaseAssetName - if tokenId == BNBAsset { - tokenId = price.QuoteAssetName - value = 1.0 / value - } - return &blockatlas.Ticker{ - CoinName: BNBAsset, - CoinType: blockatlas.TypeToken, - TokenId: tokenId, - Price: blockatlas.TickerPrice{ - Value: value, - Change24h: value24h, - Currency: "BNB", - Provider: provider, - }, - LastUpdate: time.Now(), - }, nil -} - -func normalizeTickers(prices []*CoinPrice, provider string) (tickers blockatlas.Tickers) { - for _, price := range prices { - t, err := normalizeTicker(price, provider) - if err != nil { - continue - } - tickers = append(tickers, t) - } - return -} diff --git a/marketdata/market/dex/dex_test.go b/marketdata/market/dex/dex_test.go deleted file mode 100644 index 14cd5aba9..000000000 --- a/marketdata/market/dex/dex_test.go +++ /dev/null @@ -1,81 +0,0 @@ -package dex - -import ( - "github.com/stretchr/testify/assert" - "github.com/trustwallet/blockatlas/pkg/blockatlas" - "sort" - "testing" - "time" -) - -func Test_normalizeTickers(t *testing.T) { - type args struct { - prices []*CoinPrice - provider string - } - tests := []struct { - name string - args args - wantTickers blockatlas.Tickers - }{ - { - "test normalize dex quote", - args{prices: []*CoinPrice{ - { - BaseAssetName: "RAVEN-F66", - QuoteAssetName: "BNB", - LastPrice: "0.00001082", - PriceChangePercent: "-2.2500", - }, - { - BaseAssetName: "SLV-986", - QuoteAssetName: "BNB", - LastPrice: "0.04494510", - PriceChangePercent: "-5.3700", - }, - { - BaseAssetName: "CBIX-3C9", - QuoteAssetName: "TAUD-888", - LastPrice: "0.00100235", - PriceChangePercent: "5.2700", - }, - }, - provider: "dex"}, - blockatlas.Tickers{ - &blockatlas.Ticker{CoinName: "BNB", TokenId: "RAVEN-F66", CoinType: blockatlas.TypeToken, LastUpdate: time.Now(), - Price: blockatlas.TickerPrice{ - Value: 0.00001082, - Change24h: -2.2500, - Currency: "BNB", - Provider: "dex", - }, - }, - &blockatlas.Ticker{CoinName: "BNB", TokenId: "SLV-986", CoinType: blockatlas.TypeToken, LastUpdate: time.Now(), - Price: blockatlas.TickerPrice{ - Value: 0.0449451, - Change24h: -5.3700, - Currency: "BNB", - Provider: "dex", - }, - }, - }, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - gotTickers := normalizeTickers(tt.args.prices, tt.args.provider) - now := time.Now() - sort.Slice(gotTickers, func(i, j int) bool { - gotTickers[i].LastUpdate = now - gotTickers[j].LastUpdate = now - return gotTickers[i].Coin > gotTickers[j].Coin - }) - sort.Slice(tt.wantTickers, func(i, j int) bool { - tt.wantTickers[i].LastUpdate = now - tt.wantTickers[j].LastUpdate = now - return tt.wantTickers[i].Coin > tt.wantTickers[j].Coin - }) - assert.Equal(t, tt.wantTickers, gotTickers) - }) - } -} diff --git a/marketdata/market/dex/models.go b/marketdata/market/dex/models.go deleted file mode 100644 index f6ae7d701..000000000 --- a/marketdata/market/dex/models.go +++ /dev/null @@ -1,8 +0,0 @@ -package dex - -type CoinPrice struct { - BaseAssetName string `json:"baseAssetName"` - QuoteAssetName string `json:"quoteAssetName"` - PriceChangePercent string `json:"priceChangePercent"` - LastPrice string `json:"lastPrice"` -} diff --git a/marketdata/market/market.go b/marketdata/market/market.go deleted file mode 100644 index 32a660f7e..000000000 --- a/marketdata/market/market.go +++ /dev/null @@ -1,46 +0,0 @@ -package market - -import ( - "github.com/trustwallet/blockatlas/pkg/errors" - "github.com/trustwallet/blockatlas/pkg/logger" - "github.com/trustwallet/blockatlas/storage" -) - -const ( - defaultUpdateTime = "5m" -) - -type Market struct { - Id string - UpdateTime string - Storage storage.Market -} - -func (m *Market) GetId() string { - return m.Id -} - -func (m *Market) GetLogType() string { - return "market-data" -} - -func (m *Market) GetUpdateTime() string { - return m.UpdateTime -} - -func (m *Market) Init(storage storage.Market) error { - logger.Info("Init Market Quote Provider", logger.Params{"market": m.GetId()}) - if len(m.Id) == 0 { - return errors.E("Market Quote: Id cannot be empty") - } - - if storage == nil { - return errors.E("Market Quote: Storage cannot be nil") - } - m.Storage = storage - - if len(m.UpdateTime) == 0 { - m.UpdateTime = defaultUpdateTime - } - return nil -} diff --git a/marketdata/market/provider.go b/marketdata/market/provider.go deleted file mode 100644 index 2db249428..000000000 --- a/marketdata/market/provider.go +++ /dev/null @@ -1,25 +0,0 @@ -package market - -import ( - "github.com/trustwallet/blockatlas/pkg/blockatlas" - "github.com/trustwallet/blockatlas/storage" -) - -type Provider interface { - Init(storage.Market) error - GetId() string - GetUpdateTime() string - GetData() (blockatlas.Tickers, error) - GetLogType() string -} - -type Providers map[int]Provider - -func (ps Providers) GetPriority(providerId string) int { - for priority, provider := range ps { - if provider.GetId() == providerId { - return priority - } - } - return -1 -} diff --git a/marketdata/rate/coingecko/coingecko.go b/marketdata/rate/coingecko/coingecko.go deleted file mode 100644 index dd7aba9fc..000000000 --- a/marketdata/rate/coingecko/coingecko.go +++ /dev/null @@ -1,50 +0,0 @@ -package coingecko - -import ( - "github.com/trustwallet/blockatlas/marketdata/clients/coingecko" - "github.com/trustwallet/blockatlas/marketdata/rate" - "github.com/trustwallet/blockatlas/pkg/blockatlas" - "strings" -) - -const ( - id = "coingecko" -) - -type Coingecko struct { - client *coingecko.Client - rate.Rate -} - -func InitRate(api string, updateTime string) rate.Provider { - return &Coingecko{ - client: coingecko.NewClient(api), - Rate: rate.Rate{ - Id: id, - UpdateTime: updateTime, - }, - } -} - -func (c *Coingecko) FetchLatestRates() (rates blockatlas.Rates, err error) { - coins, err := c.client.FetchCoinsList() - if err != nil { - return - } - prices := c.client.FetchLatestRates(coins, blockatlas.DefaultCurrency) - - rates = normalizeRates(prices, c.GetId()) - return -} - -func normalizeRates(coinPrices coingecko.CoinPrices, provider string) (rates blockatlas.Rates) { - for _, price := range coinPrices { - rates = append(rates, blockatlas.Rate{ - Currency: strings.ToUpper(price.Symbol), - Rate: 1.0 / price.CurrentPrice, - Timestamp: price.LastUpdated.Unix(), - Provider: provider, - }) - } - return -} diff --git a/marketdata/rate/coingecko/coingecko_test.go b/marketdata/rate/coingecko/coingecko_test.go deleted file mode 100644 index 18b48d330..000000000 --- a/marketdata/rate/coingecko/coingecko_test.go +++ /dev/null @@ -1,72 +0,0 @@ -package coingecko - -import ( - "github.com/stretchr/testify/assert" - "github.com/trustwallet/blockatlas/marketdata/clients/coingecko" - "github.com/trustwallet/blockatlas/pkg/blockatlas" - "sort" - "testing" - "time" -) - -func Test_normalizeRates(t *testing.T) { - tests := []struct { - name string - prices coingecko.CoinPrices - wantRates blockatlas.Rates - }{ - { - "test normalize coingecko rate 1", - coingecko.CoinPrices{ - { - Symbol: "cUSDC", - CurrentPrice: 0.0021, - }, - { - Symbol: "cREP", - CurrentPrice: 0.02, - }, - }, - blockatlas.Rates{ - blockatlas.Rate{Currency: "CUSDC", Rate: 1 / 0.0021, Timestamp: 333, Provider: id}, - blockatlas.Rate{Currency: "CREP", Rate: 1 / 0.02, Timestamp: 333, Provider: id}, - }, - }, - { - "test normalize coingecko rate 2", - coingecko.CoinPrices{ - { - Symbol: "cUSDC", - CurrentPrice: 110.0021, - }, - { - Symbol: "cREP", - CurrentPrice: 110.02, - }, - }, - blockatlas.Rates{ - blockatlas.Rate{Currency: "CUSDC", Rate: 1 / 110.0021, Timestamp: 123, Provider: id}, - blockatlas.Rate{Currency: "CREP", Rate: 1 / 110.02, Timestamp: 123, Provider: id}, - }, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - gotRates := normalizeRates(tt.prices, id) - now := time.Now().Unix() - sort.Slice(gotRates, func(i, j int) bool { - gotRates[i].Timestamp = now - gotRates[j].Timestamp = now - return gotRates[i].Rate < gotRates[j].Rate - }) - sort.Slice(tt.wantRates, func(i, j int) bool { - tt.wantRates[i].Timestamp = now - tt.wantRates[j].Timestamp = now - return tt.wantRates[i].Rate < tt.wantRates[j].Rate - }) - if !assert.ObjectsAreEqualValues(gotRates, tt.wantRates) { - t.Errorf("normalizeRates() = %v, want %v", gotRates, tt.wantRates) - } - }) - } -} diff --git a/marketdata/rate/coinmarketcap/cmc.go b/marketdata/rate/coinmarketcap/cmc.go deleted file mode 100644 index 985bff658..000000000 --- a/marketdata/rate/coinmarketcap/cmc.go +++ /dev/null @@ -1,55 +0,0 @@ -package cmc - -import ( - "github.com/trustwallet/blockatlas/marketdata/clients/cmc" - "github.com/trustwallet/blockatlas/marketdata/rate" - "github.com/trustwallet/blockatlas/pkg/blockatlas" - "math/big" -) - -const ( - id = "cmc" -) - -type Cmc struct { - rate.Rate - mapApi string - client *cmc.Client -} - -func InitRate(api string, apiKey string, mapApi string, updateTime string) rate.Provider { - cmc := &Cmc{ - Rate: rate.Rate{ - Id: id, - UpdateTime: updateTime, - }, - mapApi: mapApi, - client: cmc.NewClient(api, apiKey), - } - return cmc -} - -func (c *Cmc) FetchLatestRates() (rates blockatlas.Rates, err error) { - prices, err := c.client.GetData() - if err != nil { - return - } - rates = normalizeRates(prices, c.GetId()) - return -} - -func normalizeRates(prices cmc.CoinPrices, provider string) (rates blockatlas.Rates) { - for _, price := range prices.Data { - if price.Platform != nil { - continue - } - rates = append(rates, blockatlas.Rate{ - Currency: price.Symbol, - Rate: 1.0 / price.Quote.USD.Price, - Timestamp: price.LastUpdated.Unix(), - PercentChange24h: big.NewFloat(price.Quote.USD.PercentChange24h), - Provider: provider, - }) - } - return -} diff --git a/marketdata/rate/coinmarketcap/cmc_test.go b/marketdata/rate/coinmarketcap/cmc_test.go deleted file mode 100644 index 553c801b6..000000000 --- a/marketdata/rate/coinmarketcap/cmc_test.go +++ /dev/null @@ -1,101 +0,0 @@ -package cmc - -import ( - "github.com/stretchr/testify/assert" - "github.com/trustwallet/blockatlas/marketdata/clients/cmc" - "github.com/trustwallet/blockatlas/pkg/blockatlas" - "math/big" - "sort" - "testing" - "time" -) - -func Test_normalizeRates(t *testing.T) { - provider := "cmc" - tests := []struct { - name string - prices cmc.CoinPrices - wantRates blockatlas.Rates - }{ - { - "test normalize cmc rate 1", - cmc.CoinPrices{ - Data: []cmc.Data{ - { - Coin: cmc.Coin{ - Symbol: "BTC", - }, - Quote: cmc.Quote{ - USD: cmc.USD{ - Price: 223.5, - PercentChange24h: 0.33, - }, - }, - LastUpdated: time.Unix(333, 0), - }, - { - Coin: cmc.Coin{ - Symbol: "ETH", - }, - Quote: cmc.Quote{ - USD: cmc.USD{ - Price: 11.11, - PercentChange24h: -1.22, - }, - }, - LastUpdated: time.Unix(333, 0), - }, - }, - }, - blockatlas.Rates{ - blockatlas.Rate{Currency: "BTC", Rate: 1 / 223.5, Timestamp: 333, Provider: provider, PercentChange24h: big.NewFloat(0.33)}, - blockatlas.Rate{Currency: "ETH", Rate: 1 / 11.11, Timestamp: 333, Provider: provider, PercentChange24h: big.NewFloat(-1.22)}, - }, - }, - { - "test normalize cmc rate 2", - cmc.CoinPrices{ - Data: []cmc.Data{ - { - Coin: cmc.Coin{ - Symbol: "BNB", - }, - Quote: cmc.Quote{ - USD: cmc.USD{ - Price: 30.333, - PercentChange24h: 2.1, - }, - }, - LastUpdated: time.Unix(123, 0), - }, - { - Coin: cmc.Coin{ - Symbol: "XRP", - }, - Quote: cmc.Quote{ - USD: cmc.USD{ - Price: 0.4687, - }, - }, - LastUpdated: time.Unix(123, 0), - }, - }, - }, - blockatlas.Rates{ - blockatlas.Rate{Currency: "BNB", Rate: 1 / 30.333, Timestamp: 123, Provider: provider, PercentChange24h: big.NewFloat(2.1)}, - blockatlas.Rate{Currency: "XRP", Rate: 1 / 0.4687, Timestamp: 123, Provider: provider, PercentChange24h: big.NewFloat(0)}, - }, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - gotRates := normalizeRates(tt.prices, provider) - sort.SliceStable(gotRates, func(i, j int) bool { - return gotRates[i].Rate < gotRates[j].Rate - }) - if !assert.ObjectsAreEqualValues(gotRates, tt.wantRates) { - t.Errorf("normalizeRates() = %v, want %v", gotRates, tt.wantRates) - } - }) - } -} diff --git a/marketdata/rate/compound/compound.go b/marketdata/rate/compound/compound.go deleted file mode 100644 index 07b8397f9..000000000 --- a/marketdata/rate/compound/compound.go +++ /dev/null @@ -1,49 +0,0 @@ -package compound - -import ( - c "github.com/trustwallet/blockatlas/marketdata/clients/compound" - "github.com/trustwallet/blockatlas/marketdata/rate" - "github.com/trustwallet/blockatlas/pkg/blockatlas" - "strings" - "time" -) - -const ( - compound = "compound" -) - -type Compound struct { - rate.Rate - client *c.Client -} - -func InitRate(api string, updateTime string) rate.Provider { - return &Compound{ - Rate: rate.Rate{ - Id: compound, - UpdateTime: updateTime, - }, - client: c.NewClient(api), - } -} - -func (c *Compound) FetchLatestRates() (rates blockatlas.Rates, err error) { - coinPrices, err := c.client.GetData() - if err != nil { - return - } - rates = normalizeRates(coinPrices, c.GetId()) - return -} - -func normalizeRates(coinPrices c.CoinPrices, provider string) (rates blockatlas.Rates) { - for _, cToken := range coinPrices.Data { - rates = append(rates, blockatlas.Rate{ - Currency: strings.ToUpper(cToken.Symbol), - Rate: 1.0 / cToken.ExchangeRate.Value, - Timestamp: time.Now().Unix(), - Provider: provider, - }) - } - return -} diff --git a/marketdata/rate/compound/compound_test.go b/marketdata/rate/compound/compound_test.go deleted file mode 100644 index 41e8e1c71..000000000 --- a/marketdata/rate/compound/compound_test.go +++ /dev/null @@ -1,77 +0,0 @@ -package compound - -import ( - "github.com/stretchr/testify/assert" - c "github.com/trustwallet/blockatlas/marketdata/clients/compound" - "github.com/trustwallet/blockatlas/pkg/blockatlas" - "sort" - "testing" - "time" -) - -func Test_normalizeRates(t *testing.T) { - provider := "compound" - tests := []struct { - name string - prices c.CoinPrices - wantRates blockatlas.Rates - }{ - { - "test normalize compound rate 1", - c.CoinPrices{ - Data: []c.CToken{ - { - Symbol: "cUSDC", - ExchangeRate: c.Amount{Value: 0.0021}, - }, - { - Symbol: "cREP", - ExchangeRate: c.Amount{Value: 0.02}, - }, - }, - }, - blockatlas.Rates{ - blockatlas.Rate{Currency: "CUSDC", Rate: 1 / 0.0021, Timestamp: 333, Provider: provider}, - blockatlas.Rate{Currency: "CREP", Rate: 1 / 0.02, Timestamp: 333, Provider: provider}, - }, - }, - { - "test normalize compound rate 2", - c.CoinPrices{ - Data: []c.CToken{ - { - Symbol: "cUSDC", - ExchangeRate: c.Amount{Value: 110.0021}, - }, - { - Symbol: "cREP", - ExchangeRate: c.Amount{Value: 110.02}, - }, - }, - }, - blockatlas.Rates{ - blockatlas.Rate{Currency: "CUSDC", Rate: 1 / 110.0021, Timestamp: 123, Provider: provider}, - blockatlas.Rate{Currency: "CREP", Rate: 1 / 110.02, Timestamp: 123, Provider: provider}, - }, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - gotRates := normalizeRates(tt.prices, provider) - now := time.Now().Unix() - sort.Slice(gotRates, func(i, j int) bool { - gotRates[i].Timestamp = now - gotRates[j].Timestamp = now - return gotRates[i].Rate < gotRates[j].Rate - }) - sort.Slice(tt.wantRates, func(i, j int) bool { - tt.wantRates[i].Timestamp = now - tt.wantRates[j].Timestamp = now - return tt.wantRates[i].Rate < tt.wantRates[j].Rate - }) - if !assert.ObjectsAreEqualValues(gotRates, tt.wantRates) { - t.Errorf("normalizeRates() = %v, want %v", gotRates, tt.wantRates) - } - }) - } -} diff --git a/marketdata/rate/fixer/fixer.go b/marketdata/rate/fixer/fixer.go deleted file mode 100644 index dd0570a89..000000000 --- a/marketdata/rate/fixer/fixer.go +++ /dev/null @@ -1,49 +0,0 @@ -package fixer - -import ( - "github.com/trustwallet/blockatlas/marketdata/rate" - "github.com/trustwallet/blockatlas/pkg/blockatlas" - "net/url" -) - -const ( - id = "fixer" -) - -type Fixer struct { - rate.Rate - APIKey string - blockatlas.Request -} - -func InitRate(api string, apiKey string, updateTime string) rate.Provider { - return &Fixer{ - Rate: rate.Rate{ - Id: id, - UpdateTime: updateTime, - }, - Request: blockatlas.InitClient(api), - APIKey: apiKey, - } -} - -func (f *Fixer) FetchLatestRates() (rates blockatlas.Rates, err error) { - values := url.Values{ - "access_key": {f.APIKey}, - "base": {blockatlas.DefaultCurrency}, // Base USD supported only in paid api - } - var latest Latest - err = f.Get(&latest, "latest", values) - if err != nil { - return - } - rates = normalizeRates(latest, f.GetId()) - return -} - -func normalizeRates(latest Latest, provider string) (rates blockatlas.Rates) { - for currency, rate := range latest.Rates { - rates = append(rates, blockatlas.Rate{Currency: currency, Rate: rate, Timestamp: latest.Timestamp, Provider: provider}) - } - return -} diff --git a/marketdata/rate/fixer/fixer_test.go b/marketdata/rate/fixer/fixer_test.go deleted file mode 100644 index b3a6c0a26..000000000 --- a/marketdata/rate/fixer/fixer_test.go +++ /dev/null @@ -1,56 +0,0 @@ -package fixer - -import ( - "github.com/stretchr/testify/assert" - "github.com/trustwallet/blockatlas/pkg/blockatlas" - "sort" - "testing" - "time" -) - -func Test_normalizeRates(t *testing.T) { - provider := "dex" - tests := []struct { - name string - latest Latest - wantRates blockatlas.Rates - }{ - { - "test normalize fixer rate 1", - Latest{ - Timestamp: 123, - Rates: map[string]float64{"USD": 22.111, "BRL": 33.2, "BTC": 44.99}, - UpdatedAt: time.Now(), - }, - blockatlas.Rates{ - blockatlas.Rate{Currency: "USD", Rate: 22.111, Timestamp: 123, Provider: provider}, - blockatlas.Rate{Currency: "BRL", Rate: 33.2, Timestamp: 123, Provider: provider}, - blockatlas.Rate{Currency: "BTC", Rate: 44.99, Timestamp: 123, Provider: provider}, - }, - }, - { - "test normalize fixer rate 2", - Latest{ - Timestamp: 333, - Rates: map[string]float64{"LSK": 123.321, "IFC": 34.973, "DUO": 998.3}, - UpdatedAt: time.Now(), - }, - blockatlas.Rates{ - blockatlas.Rate{Currency: "IFC", Rate: 34.973, Timestamp: 333, Provider: provider}, - blockatlas.Rate{Currency: "LSK", Rate: 123.321, Timestamp: 333, Provider: provider}, - blockatlas.Rate{Currency: "DUO", Rate: 998.3, Timestamp: 333, Provider: provider}, - }, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - gotRates := normalizeRates(tt.latest, provider) - sort.SliceStable(gotRates, func(i, j int) bool { - return gotRates[i].Rate < gotRates[j].Rate - }) - if !assert.ObjectsAreEqualValues(gotRates, tt.wantRates) { - t.Errorf("normalizeRates() = %v, want %v", gotRates, tt.wantRates) - } - }) - } -} diff --git a/marketdata/rate/fixer/models.go b/marketdata/rate/fixer/models.go deleted file mode 100644 index 6dff9eecb..000000000 --- a/marketdata/rate/fixer/models.go +++ /dev/null @@ -1,11 +0,0 @@ -package fixer - -import ( - "time" -) - -type Latest struct { - Timestamp int64 `json:"timestamp"` - Rates map[string]float64 `json:"rates"` - UpdatedAt time.Time `json:"updated_at"` -} diff --git a/marketdata/rate/provider.go b/marketdata/rate/provider.go deleted file mode 100644 index 5f7b92dcb..000000000 --- a/marketdata/rate/provider.go +++ /dev/null @@ -1,25 +0,0 @@ -package rate - -import ( - "github.com/trustwallet/blockatlas/pkg/blockatlas" - "github.com/trustwallet/blockatlas/storage" -) - -type Provider interface { - Init(storage.Market) error - FetchLatestRates() (blockatlas.Rates, error) - GetUpdateTime() string - GetId() string - GetLogType() string -} - -type Providers map[int]Provider - -func (ps Providers) GetPriority(providerId string) int { - for priority, provider := range ps { - if provider.GetId() == providerId { - return priority - } - } - return -1 -} diff --git a/marketdata/rate/rate.go b/marketdata/rate/rate.go deleted file mode 100644 index 9879c6ff6..000000000 --- a/marketdata/rate/rate.go +++ /dev/null @@ -1,46 +0,0 @@ -package rate - -import ( - "github.com/trustwallet/blockatlas/pkg/errors" - "github.com/trustwallet/blockatlas/pkg/logger" - "github.com/trustwallet/blockatlas/storage" -) - -const ( - defaultUpdateTime = "5m" -) - -type Rate struct { - Id string - UpdateTime string - Storage storage.Market -} - -func (r *Rate) GetUpdateTime() string { - return r.UpdateTime -} - -func (r *Rate) GetId() string { - return r.Id -} - -func (r *Rate) GetLogType() string { - return "market-rate" -} - -func (r *Rate) Init(storage storage.Market) error { - logger.Info("Init Market Rate Provider", logger.Params{"rate": r.GetId()}) - if len(r.Id) == 0 { - return errors.E("Market Rate: Id cannot be empty") - } - - if storage == nil { - return errors.E("Market Rate: Storage cannot be nil") - } - r.Storage = storage - - if len(r.UpdateTime) == 0 { - r.UpdateTime = defaultUpdateTime - } - return nil -} diff --git a/marketdata/rates.go b/marketdata/rates.go deleted file mode 100644 index 6533adc30..000000000 --- a/marketdata/rates.go +++ /dev/null @@ -1,62 +0,0 @@ -package marketdata - -import ( - "github.com/robfig/cron/v3" - "github.com/spf13/viper" - "github.com/trustwallet/blockatlas/marketdata/rate" - "github.com/trustwallet/blockatlas/marketdata/rate/coingecko" - cmc "github.com/trustwallet/blockatlas/marketdata/rate/coinmarketcap" - "github.com/trustwallet/blockatlas/marketdata/rate/compound" - "github.com/trustwallet/blockatlas/marketdata/rate/fixer" - "github.com/trustwallet/blockatlas/pkg/errors" - "github.com/trustwallet/blockatlas/pkg/logger" - "github.com/trustwallet/blockatlas/storage" -) - -var rateProviders rate.Providers - -func InitRates(storage storage.Market) { - rateProviders = rate.Providers{ - // Add Market Quote Providers: - 0: cmc.InitRate( - viper.GetString("market.cmc.api"), - viper.GetString("market.cmc.api_key"), - viper.GetString("market.cmc.map_url"), - viper.GetString("market.rate_update_time"), - ), - 1: fixer.InitRate( - viper.GetString("market.fixer.api"), - viper.GetString("market.fixer.api_key"), - viper.GetString("market.fixer.rate_update_time"), - ), - 2: compound.InitRate( - viper.GetString("market.compound.api"), - viper.GetString("market.rate_update_time"), - ), - 3: coingecko.InitRate( - viper.GetString("market.coingecko.api"), - viper.GetString("market.rate_update_time"), - ), - } - addRates(storage, rateProviders) -} - -func addRates(storage storage.Market, rates rate.Providers) { - c := cron.New() - for _, r := range rates { - scheduleTasks(storage, r, c) - } - c.Start() -} - -func runRate(storage storage.Market, p rate.Provider) error { - rates, err := p.FetchLatestRates() - if err != nil { - return errors.E(err, "FetchLatestRates") - } - if len(rates) > 0 { - storage.SaveRates(rates, rateProviders) - logger.Info("Market rates", logger.Params{"rates": len(rates), "provider": p.GetId()}) - } - return nil -} diff --git a/marketdata/worker.go b/marketdata/worker.go deleted file mode 100644 index 6629eb95f..000000000 --- a/marketdata/worker.go +++ /dev/null @@ -1,70 +0,0 @@ -package marketdata - -import ( - "fmt" - "github.com/cenkalti/backoff" - "github.com/robfig/cron/v3" - "github.com/trustwallet/blockatlas/marketdata/market" - "github.com/trustwallet/blockatlas/marketdata/rate" - "github.com/trustwallet/blockatlas/pkg/errors" - "github.com/trustwallet/blockatlas/pkg/logger" - "github.com/trustwallet/blockatlas/storage" - "time" -) - -const ( - backoffValue = 2 -) - -type Provider interface { - Init(storage.Market) error - GetId() string - GetLogType() string - GetUpdateTime() string -} - -// processBackoff make a exponential backoff for market run -// errors, increasing the retry in a exponential period for each attempt. -func processBackoff(storage storage.Market, md Provider) { - b := backoff.NewExponentialBackOff() - b.MaxElapsedTime = backoffValue * time.Minute - r := func() error { - return run(storage, md) - } - - n := func(err error, t time.Duration) { - logger.Error(err, "process backoff market", logger.Params{"Duration": t.String()}) - } - err := backoff.RetryNotify(r, b, n) - if err != nil { - logger.Error(err, "Market ProcessBackoff") - } -} - -func scheduleTasks(storage storage.Market, md Provider, c *cron.Cron) { - err := md.Init(storage) - if err != nil { - logger.Error(err, "Init Market Error", logger.Params{"Type": md.GetLogType(), "Market": md.GetId()}) - return - } - t := md.GetUpdateTime() - spec := fmt.Sprintf("@every %s", t) - _, err = c.AddFunc(spec, func() { - go processBackoff(storage, md) - }) - processBackoff(storage, md) - if err != nil { - logger.Error(err, "AddFunc") - } -} - -func run(storage storage.Market, md Provider) error { - logger.Info("Starting market data task...", logger.Params{"Type": md.GetLogType(), "Market": md.GetId()}) - switch m := md.(type) { - case market.Provider: - return runMarket(storage, m) - case rate.Provider: - return runRate(storage, m) - } - return errors.E("invalid market interface") -} diff --git a/mock/README.md b/mock/README.md new file mode 100644 index 000000000..6ce727122 --- /dev/null +++ b/mock/README.md @@ -0,0 +1,29 @@ +# Test data files + +Responses for mock tests are stored in data files. +The mock uses these files to return canned responses. + +The data files can be updated, by reading and storing responses from the real external APIs. + +## File list + +There is a file `mock/datafiles.yaml` containing API paths and corresponding data files. + +Example: + +``` +- file: mock/ext-api-data/tron-api_v1_assets_1002814.json + mockURL: /mock/tron-api/v1/assets/1002814 + method: GET + extURL: https://api.trongrid.io/v1/assets/1002814 +``` + +Fields: + +* file: name of response data json file (relative to repository root). +* mockURL: the API path for this call, in the mock server. Usually starts with '/mock/'. +* method: GET or POST +* extURL: Optional. The full URL of the external reap API. Used to refresh the data file, manually during development, or automatically. +* reqFile: In case of POST requests, the json file containing POST request. Used to select which resposne to return, and when invoking external API. +* reqField: Optional. Some POST requests cannot be matched by full request json matching, because they contain a changing field, typically call id. In this case one field can be selected (.e.g 'address'), and input is matched by the field only. + diff --git a/mock/datafiles.yaml b/mock/datafiles.yaml new file mode 100644 index 000000000..caa9a36da --- /dev/null +++ b/mock/datafiles.yaml @@ -0,0 +1,499 @@ +- file: mock/mockserver/mock-healthcheck.json + mockURL: /mock/mock-healthcheck + method: GET +- file: mock/ext-api-data/aeternity-api_middleware_transactions_account_ak_2WGWYMgWy1opZxgA8AVzGCTavCQyUBtbKx5SrCX6E4kmDZMtJb.json + mockURL: /mock/aeternity-api/middleware/transactions/account/ak_2WGWYMgWy1opZxgA8AVzGCTavCQyUBtbKx5SrCX6E4kmDZMtJb + method: GET + extURL: https://mdw.aepps.com/middleware/transactions/account/ak_2WGWYMgWy1opZxgA8AVzGCTavCQyUBtbKx5SrCX6E4kmDZMtJb +- file: mock/ext-api-data/aion-api_getTransactionsByAddress__accountAddress_0xa04f0117864ccf5013861a89f08c6fc790284d72356c8a362025d31b855ed6ed_size_25.json + mockURL: /mock/aion-api/getTransactionsByAddress?accountAddress=0xa04f0117864ccf5013861a89f08c6fc790284d72356c8a362025d31b855ed6ed&size=25 + method: GET + extURL: https://mainnet-api.theoan.com/aion/dashboard/getTransactionsByAddress?accountAddress=0xa04f0117864ccf5013861a89f08c6fc790284d72356c8a362025d31b855ed6ed&size=25 +- file: mock/ext-api-data/algorand-api_v1_account_4EZFQABCVQTHQCK3HQBIYGC4NV2VM42FZHEFTVH77ROG4ZGREC6Y7V5T2U_transactions.json + mockURL: /mock/algorand-api/v1/account/4EZFQABCVQTHQCK3HQBIYGC4NV2VM42FZHEFTVH77ROG4ZGREC6Y7V5T2U/transactions + method: GET + extURL: https://mainnet-algorand.api.purestake.io/ps1/v1/account/4EZFQABCVQTHQCK3HQBIYGC4NV2VM42FZHEFTVH77ROG4ZGREC6Y7V5T2U/transactions +- file: mock/ext-api-data/algorand-api_v1_block_5478346.json + mockURL: /mock/algorand-api/v1/block/5478346 + method: GET + extURL: https://mainnet-algorand.api.purestake.io/ps1/v1/block/5478346 +- file: mock/ext-api-data/binance-api_v1_txs__address_bnb1z35wusfv8twfele77vddclka9z84ugywug48gn_txAsset_BNB.json + mockURL: /mock/binance-api/api/v1/transactions?address=bnb1z35wusfv8twfele77vddclka9z84ugywug48gn&txAsset=BNB + method: GET + extURL: https://dex.binance.org/api/v1/transactions?address=bnb1z35wusfv8twfele77vddclka9z84ugywug48gn&txAsset=BNB +- file: mock/ext-api-data/binance-api_v1_account_bnb1jeu6gscugy6l2wyatxthkh2hmer4hzevgcmf0q + mockURL: /mock/binance-api/api/v1/account/bnb1jeu6gscugy6l2wyatxthkh2hmer4hzevgcmf0q + method: GET + extURL: https://dex.binance.org/api/v1/account/bnb1jeu6gscugy6l2wyatxthkh2hmer4hzevgcmf0q +- file: mock/ext-api-data/binance-api_v1_tokens__limit_1000_offset_0.json + mockURL: /mock/binance-api/api/v1/tokens?limit=1000 + method: GET + extURL: https://dex.binance.org/api/v1/tokens?limit=1000&offset=0 +- file: mock/ext-api-data/bitcoin-api_v2_address_bc1qrfr44n2j4czd5c9txwlnw0yj2h82x9566fglqj__details_txs.json + mockURL: /mock/bitcoin-api/api/v2/address/bc1qrfr44n2j4czd5c9txwlnw0yj2h82x9566fglqj?details=txs + method: GET + extURL: https://btc1.trezor.io/api/v2/address/bc1qrfr44n2j4czd5c9txwlnw0yj2h82x9566fglqj?details=txs&pageSize=10 +- file: mock/ext-api-data/bitcoin-api_v2_xpub_zpub6ruK9k6YGm8BRHWvTiQcrEPnFkuRDJhR7mPYzV2LDvjpLa5CuGgrhCYVZjMGcLcFqv9b2WvsFtY2Gb3xq8NVq8qhk9veozrA2W9QaWtihrC__details_txs.json + mockURL: /mock/bitcoin-api/api/v2/xpub/zpub6ruK9k6YGm8BRHWvTiQcrEPnFkuRDJhR7mPYzV2LDvjpLa5CuGgrhCYVZjMGcLcFqv9b2WvsFtY2Gb3xq8NVq8qhk9veozrA2W9QaWtihrC?details=txs + method: GET + extURL: https://btc1.trezor.io/api/v2/xpub/zpub6ruK9k6YGm8BRHWvTiQcrEPnFkuRDJhR7mPYzV2LDvjpLa5CuGgrhCYVZjMGcLcFqv9b2WvsFtY2Gb3xq8NVq8qhk9veozrA2W9QaWtihrC?details=txs&pageSize=10 +- file: mock/ext-api-data/bitcoincash-api_v2_address_bitcoincash_qq07l6rr5lsdm3m80qxw80ku2ex0tj76vvsxpvmgme__details_txs.json + mockURL: /mock/bitcoincash-api/api/v2/address/bitcoincash:qq07l6rr5lsdm3m80qxw80ku2ex0tj76vvsxpvmgme?details=txs + method: GET + extURL: https:///v2/address/bitcoincash:qq07l6rr5lsdm3m80qxw80ku2ex0tj76vvsxpvmgme?details=txs&pageSize=5 +- file: mock/ext-api-data/bitcoincash-api_v2_xpub_xpub6Bq3UUphocwroXkhA9sn8ACnZpJNuwaBehgo7WbDi2DULYnvT72Uzgsv9cE5EiP8ThDYdMyZREfbpkUY4KZ88ZaUQxXciBcZ1soSi1d8xtX__details_txs.json + mockURL: /mock/bitcoincash-api/api/v2/xpub/xpub6Bq3UUphocwroXkhA9sn8ACnZpJNuwaBehgo7WbDi2DULYnvT72Uzgsv9cE5EiP8ThDYdMyZREfbpkUY4KZ88ZaUQxXciBcZ1soSi1d8xtX?details=txs + method: GET + extURL: https:///api/v2/xpub/xpub6Bq3UUphocwroXkhA9sn8ACnZpJNuwaBehgo7WbDi2DULYnvT72Uzgsv9cE5EiP8ThDYdMyZREfbpkUY4KZ88ZaUQxXciBcZ1soSi1d8xtX?details=txs&pageSize=10 +- file: mock/ext-api-data/callisto-api_tokens__address_0xc3d5b69f65027ddf48f894e6e90121293a2f6615.json + mockURL: /mock/callisto-api/tokens?address=0xc3d5b69f65027ddf48f894e6e90121293a2f6615 + method: GET + extURL: https:///tokens?address=0xc3d5b69f65027ddf48f894e6e90121293a2f6615 +- file: mock/ext-api-data/callisto-api_transactions__address_0x3083a7ec44ca2b038d4be4b0798152f948f0f3d7.json + mockURL: /mock/callisto-api/transactions?address=0x3083a7ec44ca2b038d4be4b0798152f948f0f3d7 + method: GET + extURL: https:///transactions?address=0x3083a7ec44ca2b038d4be4b0798152f948f0f3d7 +- file: mock/ext-api-data/cosmos-api_minting_inflation.json + mockURL: /mock/cosmos-api/minting/inflation + method: GET + extURL: https://api.cosmos.network/minting/inflation +- file: mock/ext-api-data/cosmos-api_staking_delegators_cosmos1dx27g0kzhwej0ekcf2k9hsktcxnmpl7fcehcvq_delegations.json + mockURL: /mock/cosmos-api/staking/delegators/cosmos1dx27g0kzhwej0ekcf2k9hsktcxnmpl7fcehcvq/delegations + method: GET + extURL: https://api.cosmos.network/staking/delegators/cosmos1dx27g0kzhwej0ekcf2k9hsktcxnmpl7fcehcvq/delegations +- file: mock/ext-api-data/cosmos-api_staking_delegators_cosmos1dx27g0kzhwej0ekcf2k9hsktcxnmpl7fcehcvq_delegations.json + mockURL: /mock/cosmos-api/staking/delegators/cosmos1dx27g0kzhwej0ekcf2k9hsktcxnmpl7fcehcvq/unbonding_delegations + method: GET + extURL: https://api.cosmos.network/staking/delegators/cosmos1dx27g0kzhwej0ekcf2k9hsktcxnmpl7fcehcvq/unbonding_delegations +- file: mock/ext-api-data/cosmos-api_staking_pool.json + mockURL: /mock/cosmos-api/staking/pool + method: GET + extURL: https://api.cosmos.network/staking/pool +- file: mock/ext-api-data/cosmos-api_staking_validators__status_bonded.json + mockURL: /mock/cosmos-api/staking/validators?status=bonded + method: GET + extURL: https://api.cosmos.network/staking/validators?status=bonded +- file: mock/ext-api-data/cosmos-api_txs__limit_25_message.sender_cosmos1dx27g0kzhwej0ekcf2k9hsktcxnmpl7fcehcvq_page_1.json + mockURL: /mock/cosmos-api/txs?limit=25&message.sender=cosmos1dx27g0kzhwej0ekcf2k9hsktcxnmpl7fcehcvq&page=1 + method: GET + extURL: https://api.cosmos.network/txs?limit=25&message.sender=cosmos1dx27g0kzhwej0ekcf2k9hsktcxnmpl7fcehcvq&page=1 +- file: mock/ext-api-data/cosmos-api_txs__limit_25_page_1_transfer.recipient_cosmos1dx27g0kzhwej0ekcf2k9hsktcxnmpl7fcehcvq.json + mockURL: /mock/cosmos-api/txs?limit=25&page=1&transfer.recipient=cosmos1dx27g0kzhwej0ekcf2k9hsktcxnmpl7fcehcvq + method: GET + extURL: https://api.cosmos.network/txs?limit=25&page=1&transfer.recipient=cosmos1dx27g0kzhwej0ekcf2k9hsktcxnmpl7fcehcvq +- file: mock/ext-api-data/cosmos-api_auth_accounts_cosmos1dx27g0kzhwej0ekcf2k9hsktcxnmpl7fcehcvq.json + mockURL: /mock/cosmos-api/auth/accounts/cosmos1dx27g0kzhwej0ekcf2k9hsktcxnmpl7fcehcvq + method: GET + extURL: https://api.cosmos.network/auth/accounts/cosmos1dx27g0kzhwej0ekcf2k9hsktcxnmpl7fcehcvq +- file: mock/ext-api-data/dash-api_v2_address_XrcbsQdrFYEzbqA9nCJi8zDtnRZzNKkCtG__details_txs.json + mockURL: /mock/dash-api/api/v2/address/XrcbsQdrFYEzbqA9nCJi8zDtnRZzNKkCtG?details=txs + method: GET + extURL: https://dash1.trezor.io/api/v2/address/XrcbsQdrFYEzbqA9nCJi8zDtnRZzNKkCtG?details=txs&pageSize=10 +- file: mock/ext-api-data/dash-api_v2_xpub_xpub6CKAjCUKKPW7bzYEG5mzRsmzyTRp7XzauqFWNmpGVNqMqsSQpLMCN3ygEmD6ZEGVocNDrDhE7SeGot78noEWpwPDbJjfxREHC848sxNrUkD__details_txs.json + mockURL: /mock/dash-api/api/v2/xpub/xpub6CKAjCUKKPW7bzYEG5mzRsmzyTRp7XzauqFWNmpGVNqMqsSQpLMCN3ygEmD6ZEGVocNDrDhE7SeGot78noEWpwPDbJjfxREHC848sxNrUkD?details=txs + method: GET + extURL: https://dash1.trezor.io/api/v2/xpub/xpub6CKAjCUKKPW7bzYEG5mzRsmzyTRp7XzauqFWNmpGVNqMqsSQpLMCN3ygEmD6ZEGVocNDrDhE7SeGot78noEWpwPDbJjfxREHC848sxNrUkD?details=txs&pageSize=10 +- file: mock/ext-api-data/decred-api_v2_address_DsTxPUVFxXeNgu5fzozr4mTR4tqqMaKcvpY__details_txs.json + mockURL: /mock/decred-api/api/v2/address/DsTxPUVFxXeNgu5fzozr4mTR4tqqMaKcvpY?details=txs + method: GET + extURL: https://blockbook.decred.org:9161/api/v2/address/DsTxPUVFxXeNgu5fzozr4mTR4tqqMaKcvpY?details=txs&pageSize=10 +- file: mock/ext-api-data/decred-api_v2_xpub_dpubZFf1tYMxcku9nvDRxnYdE4yrEESrkuQFRq5RwA4KoYQKpDSRszN2emePTwLgfQpd4mZHGrHbQkKPZdjH1BcopomXRnr5Gt43rjpNEfeuJLN__details_txs.json + mockURL: /mock/decred-api/api/v2/xpub/dpubZFf1tYMxcku9nvDRxnYdE4yrEESrkuQFRq5RwA4KoYQKpDSRszN2emePTwLgfQpd4mZHGrHbQkKPZdjH1BcopomXRnr5Gt43rjpNEfeuJLN?details=txs + method: GET + extURL: https://blockbook.decred.org:9161/api/v2/xpub/dpubZFf1tYMxcku9nvDRxnYdE4yrEESrkuQFRq5RwA4KoYQKpDSRszN2emePTwLgfQpd4mZHGrHbQkKPZdjH1BcopomXRnr5Gt43rjpNEfeuJLN?details=txs&pageSize=10 +- file: mock/ext-api-data/digibyte-api_v2_address_DEs1RJKuASSjfphFJdxX9eidrjWewMZgAi__details_txs.json + mockURL: /mock/digibyte-api/api/v2/address/DEs1RJKuASSjfphFJdxX9eidrjWewMZgAi?details=txs + method: GET + extURL: https://dgb1.trezor.io/api/v2/address/DEs1RJKuASSjfphFJdxX9eidrjWewMZgAi?details=txs&pageSize=10 +- file: mock/ext-api-data/digibyte-api_v2_xpub_zpub6ricE56nzsDeTAVo4w68vQQ3tRvR6C18JjKVsgbiRFjEawGV9SuS2gfkpm5qFxjbTNPPuvAA3cqRsxNHxFwVnpYD2Lawjtb3wowbFdwmjow__details_txs.json + mockURL: /mock/digibyte-api/api/v2/xpub/zpub6ricE56nzsDeTAVo4w68vQQ3tRvR6C18JjKVsgbiRFjEawGV9SuS2gfkpm5qFxjbTNPPuvAA3cqRsxNHxFwVnpYD2Lawjtb3wowbFdwmjow?details=txs + method: GET + extURL: https://dgb1.trezor.io/api/v2/xpub/zpub6ricE56nzsDeTAVo4w68vQQ3tRvR6C18JjKVsgbiRFjEawGV9SuS2gfkpm5qFxjbTNPPuvAA3cqRsxNHxFwVnpYD2Lawjtb3wowbFdwmjow?details=txs&pageSize=10 +- file: mock/ext-api-data/doge-api_v2_address_D5dAUAx3Ezg1q4dRgzKTBsxp4VJietWkDh__details_txs.json + mockURL: /mock/doge-api/api/v2/address/D5dAUAx3Ezg1q4dRgzKTBsxp4VJietWkDh?details=txs + method: GET + extURL: https://doge1.trezor.io/api/v2/address/D5dAUAx3Ezg1q4dRgzKTBsxp4VJietWkDh?details=txs&pageSize=10 +- file: mock/ext-api-data/doge-api_v2_xpub_dgub8rceyfsEvGDexmvJcBqiKBrmuxWGgYJxHjtbouHTwTfQrCQcMjxyNf6vUPY4dUp23QtReFy6WGedutBk9XUaYNupUqVAZcweqGhfsudUELN__details_txs.json + mockURL: /mock/doge-api/api/v2/xpub/dgub8rceyfsEvGDexmvJcBqiKBrmuxWGgYJxHjtbouHTwTfQrCQcMjxyNf6vUPY4dUp23QtReFy6WGedutBk9XUaYNupUqVAZcweqGhfsudUELN?details=txs + method: GET + extURL: https://doge1.trezor.io/api/v2/xpub/dgub8rceyfsEvGDexmvJcBqiKBrmuxWGgYJxHjtbouHTwTfQrCQcMjxyNf6vUPY4dUp23QtReFy6WGedutBk9XUaYNupUqVAZcweqGhfsudUELN?details=txs&pageSize=10 +- file: mock/ext-api-data/eth-api_tokens__address_0x0875BCab22dE3d02402bc38aEe4104e1239374a7.json + mockURL: /mock/eth-api/tokens?address=0x0875BCab22dE3d02402bc38aEe4104e1239374a7 + method: GET + extURL: https://localhost:4567/tokens?address=0x0875BCab22dE3d02402bc38aEe4104e1239374a7 +- file: mock/ext-api-data/eth-api_transactions__address_0x0875BCab22dE3d02402bc38aEe4104e1239374a7.json + mockURL: /mock/eth-api/transactions?address=0x0875BCab22dE3d02402bc38aEe4104e1239374a7 + method: GET + extURL: https://localhost:4567/transactions?address=0x0875BCab22dE3d02402bc38aEe4104e1239374a7 +- file: mock/ext-api-data/eth-blockbook-api_v2_address_0x0875BCab22dE3d02402bc38aEe4104e1239374a7__details_tokenBalances.json + mockURL: /mock/eth-blockbook-api/api/v2/address/0x0875BCab22dE3d02402bc38aEe4104e1239374a7?details=tokenBalances + method: GET + extURL: https:///api/v2/address/0x0875BCab22dE3d02402bc38aEe4104e1239374a7?details=tokenBalances +- file: mock/ext-api-data/eth-blockbook-api_v2_address_0x0875BCab22dE3d02402bc38aEe4104e1239374a7__details_txs.json + mockURL: /mock/eth-blockbook-api/api/v2/address/0x0875BCab22dE3d02402bc38aEe4104e1239374a7?details=txs + method: GET + extURL: https:///api/v2/address/0x0875BCab22dE3d02402bc38aEe4104e1239374a7?details=txs&pageSize=10 +- file: mock/ext-api-data/ethclassic-api_tokens__address_0xa12105efa0663147bddee178f6a741ac15676b79.json + mockURL: /mock/ethclassic-api/tokens?address=0xa12105efa0663147bddee178f6a741ac15676b79 + method: GET + extURL: https:///tokens?address=0xa12105efa0663147bddee178f6a741ac15676b79 +- file: mock/ext-api-data/ethclassic-api_transactions__address_0x7d2d0e153026fb428b885d86de50768d4cfeac37.json + mockURL: /mock/ethclassic-api/transactions?address=0x7d2d0e153026fb428b885d86de50768d4cfeac37 + method: GET + extURL: https:///transactions?address=0x7d2d0e153026fb428b885d86de50768d4cfeac37 +- file: mock/ext-api-data/gochain-api_tokens__address_0x0Fd98FB42C439E5F6484f7E71Caa6661d81d0628.json + mockURL: /mock/gochain-api/tokens?address=0x0Fd98FB42C439E5F6484f7E71Caa6661d81d0628 + method: GET + extURL: https:///tokens?address=0x0Fd98FB42C439E5F6484f7E71Caa6661d81d0628 +- file: mock/ext-api-data/gochain-api_transactions__address_0xEd7F2e81B0264177e0df8f275f97Fd74Fa51A896.json + mockURL: /mock/gochain-api/transactions?address=0xEd7F2e81B0264177e0df8f275f97Fd74Fa51A896 + method: GET + extURL: https:///transactions?address=0xEd7F2e81B0264177e0df8f275f97Fd74Fa51A896 +- file: mock/ext-api-data/groestlcoin-api_v2_address_33Ym3fecmWaHD19jymYt6fGd9TqSDQFfQj__details_txs.json + mockURL: /mock/groestlcoin-api/api/v2/address/33Ym3fecmWaHD19jymYt6fGd9TqSDQFfQj?details=txs + method: GET + extURL: https://blockbook.groestlcoin.org/api/v2/address/33Ym3fecmWaHD19jymYt6fGd9TqSDQFfQj?details=txs&pageSize=10 +- file: mock/ext-api-data/groestlcoin-api_v2_xpub_zpub6rWUMiiVPxjWVHffT8x3AfcbyDu8SZJAiuKUTBmhxT7Bvqk1WitxndDStG1qHN6XzRM7JgsaRaVccRFW3AprWk4Fpaev1N6QSp1aNnP5JPf__details_txs.json + mockURL: /mock/groestlcoin-api/api/v2/xpub/zpub6rWUMiiVPxjWVHffT8x3AfcbyDu8SZJAiuKUTBmhxT7Bvqk1WitxndDStG1qHN6XzRM7JgsaRaVccRFW3AprWk4Fpaev1N6QSp1aNnP5JPf?details=txs + method: GET + extURL: https://blockbook.groestlcoin.org/api/v2/xpub/zpub6rWUMiiVPxjWVHffT8x3AfcbyDu8SZJAiuKUTBmhxT7Bvqk1WitxndDStG1qHN6XzRM7JgsaRaVccRFW3AprWk4Fpaev1N6QSp1aNnP5JPf?details=txs&pageSize=10 +- file: mock/ext-api-data/icon-api_address_txList__address_hxee691e7bccc4eb11fee922896e9f51490e62b12e_count_25.json + mockURL: /mock/icon-api/address/txList?address=hxee691e7bccc4eb11fee922896e9f51490e62b12e&count=25 + method: GET + extURL: https://tracker.icon.foundation/v3/address/txList?address=hxee691e7bccc4eb11fee922896e9f51490e62b12e&count=25 +- file: mock/ext-api-data/iotex-api_accounts_io1mwekae7qqwlr23220k5n9z3fmjxz72tuchra3m.json + mockURL: /mock/iotex-api/accounts/io1mwekae7qqwlr23220k5n9z3fmjxz72tuchra3m + method: GET + extURL: https://pharos.iotex.io/v1/accounts/io1mwekae7qqwlr23220k5n9z3fmjxz72tuchra3m +- file: mock/ext-api-data/iotex-api_accounts_io1vg808avg2ydye8djl2axmkc9j0xhzu6vdaw6g5.json + mockURL: /mock/iotex-api/accounts/io1vg808avg2ydye8djl2axmkc9j0xhzu6vdaw6g5 + method: GET + extURL: https://pharos.iotex.io/v1/accounts/io1vg808avg2ydye8djl2axmkc9j0xhzu6vdaw6g5 +- file: mock/ext-api-data/iotex-api_actions_addr_io1vg808avg2ydye8djl2axmkc9j0xhzu6vdaw6g5__count_25_start_32.json + mockURL: /mock/iotex-api/actions/addr/io1vg808avg2ydye8djl2axmkc9j0xhzu6vdaw6g5?count=25 + method: GET + extURL: https://pharos.iotex.io/v1/actions/addr/io1vg808avg2ydye8djl2axmkc9j0xhzu6vdaw6g5?count=25&start=32 +- file: mock/ext-api-data/iotex-api_staking_delegations_io1mwekae7qqwlr23220k5n9z3fmjxz72tuchra3m.json + mockURL: /mock/iotex-api/staking/delegations/io1mwekae7qqwlr23220k5n9z3fmjxz72tuchra3m + method: GET + extURL: https://pharos.iotex.io/v1/staking/delegations/io1mwekae7qqwlr23220k5n9z3fmjxz72tuchra3m +- file: mock/ext-api-data/iotex-api_staking_validators__status_bonded.json + mockURL: /mock/iotex-api/staking/validators?status=bonded + method: GET + extURL: https://pharos.iotex.io/v1/staking/validators?status=bonded +- file: mock/ext-api-data/kava-api_minting_inflation.json + mockURL: /mock/kava-api/minting/inflation + method: GET + extURL: https://data.kava.io/minting/inflation +- file: mock/ext-api-data/kava-api_staking_delegators_kava1l8va9zyl50cpzv447c694k3jndelc9ygtfll2m_delegations.json + mockURL: /mock/kava-api/staking/delegators/kava1l8va9zyl50cpzv447c694k3jndelc9ygtfll2m/delegations + method: GET + extURL: https://data.kava.io/staking/delegators/kava1l8va9zyl50cpzv447c694k3jndelc9ygtfll2m/delegations +- file: mock/ext-api-data/kava-api_staking_delegators_kava1l8va9zyl50cpzv447c694k3jndelc9ygtfll2m_delegations.json + mockURL: /mock/kava-api/staking/delegators/kava1l8va9zyl50cpzv447c694k3jndelc9ygtfll2m/unbonding_delegations + method: GET + extURL: https://data.kava.io/staking/delegators/kava1l8va9zyl50cpzv447c694k3jndelc9ygtfll2m/unbonding_delegations +- file: mock/ext-api-data/kava-api_staking_pool.json + mockURL: /mock/kava-api/staking/pool + method: GET + extURL: https://data.kava.io/staking/pool +- file: mock/ext-api-data/kava-api_staking_validators__status_bonded.json + mockURL: /mock/kava-api/staking/validators?status=bonded + method: GET + extURL: https://data.kava.io/staking/validators?status=bonded +- file: mock/ext-api-data/kava-api_txs__limit_25_message.sender_kava1l8va9zyl50cpzv447c694k3jndelc9ygtfll2m_page_1.json + mockURL: /mock/kava-api/txs?limit=25&message.sender=kava1l8va9zyl50cpzv447c694k3jndelc9ygtfll2m&page=1 + method: GET + extURL: https://data.kava.io/txs?limit=25&message.sender=kava1l8va9zyl50cpzv447c694k3jndelc9ygtfll2m&page=1 +- file: mock/ext-api-data/kava-api_txs__limit_25_page_1_transfer.recipient_kava1l8va9zyl50cpzv447c694k3jndelc9ygtfll2m.json + mockURL: /mock/kava-api/txs?limit=25&page=1&transfer.recipient=kava1l8va9zyl50cpzv447c694k3jndelc9ygtfll2m + method: GET + extURL: https://data.kava.io/txs?limit=25&page=1&transfer.recipient=kava1l8va9zyl50cpzv447c694k3jndelc9ygtfll2m +- file: mock/ext-api-data/kava-api_auth_accounts_kava1l8va9zyl50cpzv447c694k3jndelc9ygtfll2m.json + mockURL: /mock/kava-api/auth/accounts/kava1l8va9zyl50cpzv447c694k3jndelc9ygtfll2m + method: GET + extURL: https://data.kava.io/auth/accounts/kava1l8va9zyl50cpzv447c694k3jndelc9ygtfll2m +- file: mock/ext-api-data/kin-api_accounts_GBHKUZ7C2SZ5N3X2S7O6TT6LNUWSEA2BXMSR5GTTSR6VZARSVAXIQNGH_payments__limit_25_order_desc.json + mockURL: /mock/kin-api/accounts/GBHKUZ7C2SZ5N3X2S7O6TT6LNUWSEA2BXMSR5GTTSR6VZARSVAXIQNGH/payments?limit=25&order=desc + method: GET + extURL: https://horizon-block-explorer.kininfrastructure.com/accounts/GBHKUZ7C2SZ5N3X2S7O6TT6LNUWSEA2BXMSR5GTTSR6VZARSVAXIQNGH/payments?limit=25&order=desc +- file: mock/ext-api-data/kin-api_transactions_b2131beb8e0c57dfd3309914fce08ac4e094c51dc918087171150dd5b996076a__.json + mockURL: /mock/kin-api/transactions/b2131beb8e0c57dfd3309914fce08ac4e094c51dc918087171150dd5b996076a? + method: GET + extURL: https://horizon-block-explorer.kininfrastructure.com/transactions/b2131beb8e0c57dfd3309914fce08ac4e094c51dc918087171150dd5b996076a? +- file: mock/ext-api-data/kin-api_transactions_eb070218bfde8c48af6071432bc9f19b7690b9dc50535cc135f67ea046e70bed.json + mockURL: /mock/kin-api/transactions/eb070218bfde8c48af6071432bc9f19b7690b9dc50535cc135f67ea046e70bed + method: GET + extURL: https://horizon-block-explorer.kininfrastructure.com/transactions/eb070218bfde8c48af6071432bc9f19b7690b9dc50535cc135f67ea046e70bed +- file: mock/ext-api-data/litecoin-api_v2_address_ltc1qpm594ntjq6ayqjngf6t9td2dxtey9d7985eept__details_txs.json + mockURL: /mock/litecoin-api/api/v2/address/ltc1qpm594ntjq6ayqjngf6t9td2dxtey9d7985eept?details=txs + method: GET + extURL: https://ltc1.trezor.io/api/v2/address/ltc1qpm594ntjq6ayqjngf6t9td2dxtey9d7985eept?details=txs&pageSize=10 +- file: mock/ext-api-data/litecoin-api_v2_xpub_zpub6rpF5Uxuz4KKWePLorSz2QrHMmk1iiZvGUGgtSHpor8yiGekyRuWf5ZNmf6GUKB4v3ibQDuZp5v8RnjEGq58kR3WPtGPn8Lrg677MQ8YeKu__details_txs.json + mockURL: /mock/litecoin-api/api/v2/xpub/zpub6rpF5Uxuz4KKWePLorSz2QrHMmk1iiZvGUGgtSHpor8yiGekyRuWf5ZNmf6GUKB4v3ibQDuZp5v8RnjEGq58kR3WPtGPn8Lrg677MQ8YeKu?details=txs + method: GET + extURL: https://ltc1.trezor.io/api/v2/xpub/zpub6rpF5Uxuz4KKWePLorSz2QrHMmk1iiZvGUGgtSHpor8yiGekyRuWf5ZNmf6GUKB4v3ibQDuZp5v8RnjEGq58kR3WPtGPn8Lrg677MQ8YeKu?details=txs&pageSize=10 +- file: mock/ext-api-data/nebulas-api_tx__a_n1RCYwrpLMpSpUCQ8QUDzGRg6B2PnY8R94a_p_0.json + mockURL: /mock/nebulas-api/tx?a=n1RCYwrpLMpSpUCQ8QUDzGRg6B2PnY8R94a + method: GET + extURL: https://explorer-backend.nebulas.io/api/tx?a=n1RCYwrpLMpSpUCQ8QUDzGRg6B2PnY8R94a&p=0 +- file: mock/ext-api-data/ontology-api_v2_addresses_AUyL4TZ1zFEcSKDJrjFnD7vsq5iFZMZqT7_transactions__page_number_1_page_size_20.json + mockURL: /mock/ontology-api/v2/addresses/AUyL4TZ1zFEcSKDJrjFnD7vsq5iFZMZqT7/transactions?page_number=1&page_size=20 + method: GET + extURL: https://explorer.ont.io/v2/addresses/AUyL4TZ1zFEcSKDJrjFnD7vsq5iFZMZqT7/transactions?page_number=1&page_size=20 +- file: mock/ext-api-data/opensea-api_api_v1_assets___collection_unstoppable-domains_limit_300_owner_0x84E79D544B4b13bC3560069cfD56A9D5bbE7521d.json + mockURL: /mock/opensea-api/api/v1/assets?collection=unstoppable-domains&owner=0x84E79D544B4b13bC3560069cfD56A9D5bbE7521d + method: GET + extURL: https://api.opensea.io/api/v1/assets/?collection=unstoppable-domains&limit=300&owner=0x84E79D544B4b13bC3560069cfD56A9D5bbE7521d +- file: mock/ext-api-data/opensea-api_api_v1_collections___asset_owner_0x84E79D544B4b13bC3560069cfD56A9D5bbE7521d_limit_1000.json + mockURL: /mock/opensea-api/api/v1/collections?asset_owner=0x84E79D544B4b13bC3560069cfD56A9D5bbE7521d + method: GET + extURL: https://api.opensea.io/api/v1/collections/?asset_owner=0x84E79D544B4b13bC3560069cfD56A9D5bbE7521d&limit=1000 +- file: mock/ext-api-data/poa-api_tokens__address_0x0875BCab22dE3d02402bc38aEe4104e1239374a7.json + mockURL: /mock/poa-api/tokens?address=0x0875BCab22dE3d02402bc38aEe4104e1239374a7 + method: GET + extURL: https:///tokens?address=0x0875BCab22dE3d02402bc38aEe4104e1239374a7 +- file: mock/ext-api-data/poa-api_transactions__address_0x55798eCbF17ce1241d543c22dCE46134c13b4bc0.json + mockURL: /mock/poa-api/transactions?address=0x55798eCbF17ce1241d543c22dCE46134c13b4bc0 + method: GET + extURL: https:///transactions?address=0x55798eCbF17ce1241d543c22dCE46134c13b4bc0 +- file: mock/ext-api-data/qtum-api_v2_address_QZJbNrGT3cZ1J1AEHtgH3JWM7uLBNAejLZ__details_txs.json + mockURL: /mock/qtum-api/api/v2/address/QZJbNrGT3cZ1J1AEHtgH3JWM7uLBNAejLZ?details=txs + method: GET + extURL: https://blockv3.qtum.info/api/v2/address/QZJbNrGT3cZ1J1AEHtgH3JWM7uLBNAejLZ?details=txs&pageSize=10 +- file: mock/ext-api-data/qtum-api_v2_xpub_xpub6CvFuU1yPwHjMekXqgEZjcQy22ZWiKgRUY6yAneNNyk1trZhV6ZBFSY8Vt2wygTXTVHBkfi4n823vm79yiw42w6xTL2UjKyh2W9V88sXoNd__details_txs.json + mockURL: /mock/qtum-api/api/v2/xpub/xpub6CvFuU1yPwHjMekXqgEZjcQy22ZWiKgRUY6yAneNNyk1trZhV6ZBFSY8Vt2wygTXTVHBkfi4n823vm79yiw42w6xTL2UjKyh2W9V88sXoNd?details=txs + method: GET + extURL: https://blockv3.qtum.info/api/v2/xpub/xpub6CvFuU1yPwHjMekXqgEZjcQy22ZWiKgRUY6yAneNNyk1trZhV6ZBFSY8Vt2wygTXTVHBkfi4n823vm79yiw42w6xTL2UjKyh2W9V88sXoNd?details=txs&pageSize=10 +- file: mock/ext-api-data/ravencoin-api_v2_address_RGkwvrUors8DtmhKy5bddFwRCTZaunjpvo__details_txs.json + mockURL: /mock/ravencoin-api/api/v2/address/RGkwvrUors8DtmhKy5bddFwRCTZaunjpvo?details=txs + method: GET + extURL: https://blockbook.ravencoin.org/api/v2/address/RGkwvrUors8DtmhKy5bddFwRCTZaunjpvo?details=txs&pageSize=10 +- file: mock/ext-api-data/ravencoin-api_v2_xpub_xpub6BrkWQHMnuGcvKowEn2hpvnZ41SiCsu38mgFThKU3nMzPUN9r9C26puf18rfVdHH3nDwSkeMgsjVniNDKUk5arxekekGpNyVLsWihYAfC5B__details_txs.json + mockURL: /mock/ravencoin-api/api/v2/xpub/xpub6BrkWQHMnuGcvKowEn2hpvnZ41SiCsu38mgFThKU3nMzPUN9r9C26puf18rfVdHH3nDwSkeMgsjVniNDKUk5arxekekGpNyVLsWihYAfC5B?details=txs + method: GET + extURL: https://blockbook.ravencoin.org/api/v2/xpub/xpub6BrkWQHMnuGcvKowEn2hpvnZ41SiCsu38mgFThKU3nMzPUN9r9C26puf18rfVdHH3nDwSkeMgsjVniNDKUk5arxekekGpNyVLsWihYAfC5B?details=txs&pageSize=10 +- file: mock/ext-api-data/ripple-api_accounts_rMQ98K56yXJbDGv49ZSmW51sLn94Xe1mu1_transactions__descending_false_limit_25_type_Payment.json + mockURL: /mock/ripple-api/accounts/rMQ98K56yXJbDGv49ZSmW51sLn94Xe1mu1/transactions?limit=25&type=Payment + method: GET + extURL: https://data.ripple.com/v2/accounts/rMQ98K56yXJbDGv49ZSmW51sLn94Xe1mu1/transactions?descending=false&limit=25&type=Payment +- file: mock/ext-api-data/stellar-api_accounts_GDKIJJIKXLOM2NRMPNQZUUYK24ZPVFC6426GZAEP3KUK6KEJLACCWNMX_payments__limit_25_order_desc.json + mockURL: /mock/stellar-api/accounts/GDKIJJIKXLOM2NRMPNQZUUYK24ZPVFC6426GZAEP3KUK6KEJLACCWNMX/payments?limit=25&order=desc + method: GET + extURL: https://horizon.stellar.org/accounts/GDKIJJIKXLOM2NRMPNQZUUYK24ZPVFC6426GZAEP3KUK6KEJLACCWNMX/payments?limit=25&order=desc +- file: mock/ext-api-data/stellar-api_transactions_23fa4d3c787f22a1755afa4275761ffba516ec4f2e039440ec02a5522b388f2c.json + mockURL: /mock/stellar-api/transactions/23fa4d3c787f22a1755afa4275761ffba516ec4f2e039440ec02a5522b388f2c + method: GET + extURL: https://horizon.stellar.org/transactions/23fa4d3c787f22a1755afa4275761ffba516ec4f2e039440ec02a5522b388f2c +- file: mock/ext-api-data/stellar-api_transactions_2912d519b2c2174b0147a9e02208f3ed14820228913142f8c6a5cd360783c029__.json + mockURL: /mock/stellar-api/transactions/2912d519b2c2174b0147a9e02208f3ed14820228913142f8c6a5cd360783c029? + method: GET + extURL: https://horizon.stellar.org/transactions/2912d519b2c2174b0147a9e02208f3ed14820228913142f8c6a5cd360783c029? +- file: mock/ext-api-data/tezos-api_account_tz1foWxaV3VQyWqFbWTERS6YDJjPT6C7jPp8_op__limit_25_order_desc_type_transaction_delegation.json + mockURL: /mock/tezos-api/account/tz1foWxaV3VQyWqFbWTERS6YDJjPT6C7jPp8/op?limit=25&order=desc&type=transaction,delegation + method: GET + extURL: https://api.tzstats.com/explorer/account/tz1foWxaV3VQyWqFbWTERS6YDJjPT6C7jPp8/op?limit=25&order=desc&type=transaction,delegation +- file: mock/ext-api-data/theta-api_accounttx_0xac0eeb6ee3e32e2c74e14ac74155063e4f4f981f__isEqualType_true_limitNumber_100_pageNumber_1_type_2.json + mockURL: /mock/theta-api/accounttx/0xac0eeb6ee3e32e2c74e14ac74155063e4f4f981f?isEqualType=true&limitNumber=100&pageNumber=1&type=2 + method: GET + extURL: https://explorer.thetatoken.org:9000/api/accounttx/0xac0eeb6ee3e32e2c74e14ac74155063e4f4f981f?isEqualType=true&limitNumber=100&pageNumber=1&type=2 +- file: mock/ext-api-data/thundertoken-api_tokens__address_0x0b230def08139f18a86536d9cfa150f04435414c.json + mockURL: /mock/thundertoken-api/tokens?address=0x0b230def08139f18a86536d9cfa150f04435414c + method: GET + extURL: https:///tokens?address=0x0b230def08139f18a86536d9cfa150f04435414c +- file: mock/ext-api-data/thundertoken-api_transactions__address_0x0b230def08139f18a86536d9cfa150f04435414c.json + mockURL: /mock/thundertoken-api/transactions?address=0x0b230def08139f18a86536d9cfa150f04435414c + method: GET + extURL: https:///transactions?address=0x0b230def08139f18a86536d9cfa150f04435414c +- file: mock/ext-api-data/tomochain-api_tokens__address_0x8b353021189375591723e7384262f45709a3c3dc.json + mockURL: /mock/tomochain-api/tokens?address=0x8b353021189375591723e7384262f45709a3c3dc + method: GET + extURL: https:///tokens?address=0x8b353021189375591723e7384262f45709a3c3dc +- file: mock/ext-api-data/tomochain-api_transactions__address_0x17e4c16605e32adead5fa371bf6117df34ca0200.json + mockURL: /mock/tomochain-api/transactions?address=0x17e4c16605e32adead5fa371bf6117df34ca0200 + method: GET + extURL: https:///transactions?address=0x17e4c16605e32adead5fa371bf6117df34ca0200 +- file: mock/ext-api-data/tron-api_v1_accounts_TFFriedwRtWdFuzerDDtkoQTZ29smDZ1MB_transactions__limit_25_order_by_block_timestamp_desc_token_id_.json + mockURL: /mock/tron-api/v1/accounts/TFFriedwRtWdFuzerDDtkoQTZ29smDZ1MB/transactions?limit=25&order_by=block_timestamp,desc&token_id= + method: GET + extURL: https://api.trongrid.io/v1/accounts/TFFriedwRtWdFuzerDDtkoQTZ29smDZ1MB/transactions?limit=25&order_by=block_timestamp,desc&token_id= +- file: mock/ext-api-data/tron-api_v1_accounts_TFFriedwRtWdFuzerDDtkoQTZ29smDZ1MB.json + mockURL: /mock/tron-api/v1/accounts/TFFriedwRtWdFuzerDDtkoQTZ29smDZ1MB + method: GET + extURL: https://api.trongrid.io/v1/accounts/TFFriedwRtWdFuzerDDtkoQTZ29smDZ1MB +- file: mock/ext-api-data/tron-api_v1_assets_1002000.json + mockURL: /mock/tron-api/v1/assets/1002000 + method: GET + extURL: https://api.trongrid.io/v1/assets/1002000 +- file: mock/ext-api-data/tron-api_v1_assets_1002798.json + mockURL: /mock/tron-api/v1/assets/1002798 + method: GET + extURL: https://api.trongrid.io/v1/assets/1002798 +- file: mock/ext-api-data/tron-api_v1_assets_1002814.json + mockURL: /mock/tron-api/v1/assets/1002814 + method: GET + extURL: https://api.trongrid.io/v1/assets/1002814 +- file: mock/ext-api-data/tron-api_wallet_listwitnesses.json + mockURL: /mock/tron-api/wallet/listwitnesses + method: GET + extURL: https://api.trongrid.io/wallet/listwitnesses +- file: mock/ext-api-data/vechain-api_blocks_best.json + mockURL: /mock/vechain-api/blocks/best + method: GET + extURL: https://vethor-pubnode.digonchain.com/blocks/best +- file: mock/ext-api-data/vechain-api_transactions_0x004aa0448e458105b098aea2a764a1d54ab95451bee488869f417b351857c3c5.json + mockURL: /mock/vechain-api/transactions/0x004aa0448e458105b098aea2a764a1d54ab95451bee488869f417b351857c3c5 + method: GET + extURL: https://vethor-pubnode.digonchain.com/transactions/0x004aa0448e458105b098aea2a764a1d54ab95451bee488869f417b351857c3c5 +- file: mock/ext-api-data/vechain-api_transactions_0x702edd54bd4e13e0012798cc8b2dfa52f7150173945103d203fae26b8e3d2ed7.json + mockURL: /mock/vechain-api/transactions/0x702edd54bd4e13e0012798cc8b2dfa52f7150173945103d203fae26b8e3d2ed7 + method: GET + extURL: https://vethor-pubnode.digonchain.com/transactions/0x702edd54bd4e13e0012798cc8b2dfa52f7150173945103d203fae26b8e3d2ed7 +- file: mock/ext-api-data/viacoin-api_v2_address_VdMPvn7vUTSzbYjiMDs1jku9wAh1Ri2Y1A__details_txs.json + mockURL: /mock/viacoin-api/api/v2/address/VdMPvn7vUTSzbYjiMDs1jku9wAh1Ri2Y1A?details=txs + method: GET + extURL: https://blockbook.viacoin.org/api/v2/address/VdMPvn7vUTSzbYjiMDs1jku9wAh1Ri2Y1A?details=txs&pageSize=10 +- file: mock/ext-api-data/viacoin-api_v2_xpub_zpub6qVn6ubhK9tfepuABqy8wBXXn3qUZTbpqyNBqLyqakqTrZZD9rXZ3L5MZ945g8Mu7vmMSbC7vfLtLatTgxAnVJ8ECCtwmKqCo6TJm2ZsFJK__details_txs.json + mockURL: /mock/viacoin-api/api/v2/xpub/zpub6qVn6ubhK9tfepuABqy8wBXXn3qUZTbpqyNBqLyqakqTrZZD9rXZ3L5MZ945g8Mu7vmMSbC7vfLtLatTgxAnVJ8ECCtwmKqCo6TJm2ZsFJK?details=txs + method: GET + extURL: https://blockbook.viacoin.org/api/v2/xpub/zpub6qVn6ubhK9tfepuABqy8wBXXn3qUZTbpqyNBqLyqakqTrZZD9rXZ3L5MZ945g8Mu7vmMSbC7vfLtLatTgxAnVJ8ECCtwmKqCo6TJm2ZsFJK?details=txs&pageSize=10 +- file: mock/ext-api-data/waves-api_transactions_address_3PJ4q4sqriJs2y7Z45wmbLrbmV9MDecbPxD_limit_25.json + mockURL: /mock/waves-api/transactions/address/3PJ4q4sqriJs2y7Z45wmbLrbmV9MDecbPxD/limit/25 + method: GET + extURL: https://nodes.wavesnodes.com/transactions/address/3PJ4q4sqriJs2y7Z45wmbLrbmV9MDecbPxD/limit/25 +- file: mock/ext-api-data/zcash-api_v2_address_t1LwLWo1Mo3s4RPtUpeyUD1eYd47inL3bwX__details_txs.json + mockURL: /mock/zcash-api/api/v2/address/t1LwLWo1Mo3s4RPtUpeyUD1eYd47inL3bwX?details=txs + method: GET + extURL: https://zec1.trezor.io/api/v2/address/t1LwLWo1Mo3s4RPtUpeyUD1eYd47inL3bwX?details=txs&pageSize=10 +- file: mock/ext-api-data/zcash-api_v2_xpub_xpub6CCXGBJ13akWuKSn4iU7CqQeXzLyDC2Y1Z83Mmg2xz11PX2EeZJJKRECz29iN4eHewRh8yfb7FpnCcjYbkqn6ynHnXW3jczPcJcenThfFeS__details_txs.json + mockURL: /mock/zcash-api/api/v2/xpub/xpub6CCXGBJ13akWuKSn4iU7CqQeXzLyDC2Y1Z83Mmg2xz11PX2EeZJJKRECz29iN4eHewRh8yfb7FpnCcjYbkqn6ynHnXW3jczPcJcenThfFeS?details=txs + method: GET + extURL: https://zec1.trezor.io/api/v2/xpub/xpub6CCXGBJ13akWuKSn4iU7CqQeXzLyDC2Y1Z83Mmg2xz11PX2EeZJJKRECz29iN4eHewRh8yfb7FpnCcjYbkqn6ynHnXW3jczPcJcenThfFeS?details=txs&pageSize=10 +- file: mock/ext-api-data/zcoin-api_v2_address_a8EF4cpenEgEn9hm2NL5KfFK1UmSZZaQVn__details_txs.json + mockURL: /mock/zcoin-api/api/v2/address/a8EF4cpenEgEn9hm2NL5KfFK1UmSZZaQVn?details=txs + method: GET + extURL: https://blockbook.zcoin.io/api/v2/address/a8EF4cpenEgEn9hm2NL5KfFK1UmSZZaQVn?details=txs&pageSize=10 +- file: mock/ext-api-data/zcoin-api_v2_xpub_xpub6Cgu6WtTyo99pRtTabwscog2ncj4BUbTWzk7bt7habdLYwgnXLEWH3TuR1789QSTPVsPjLMa2KQzHffyZHTkLQQyRxeEBmWHaETS2btF5fK__details_txs.json + mockURL: /mock/zcoin-api/api/v2/xpub/xpub6Cgu6WtTyo99pRtTabwscog2ncj4BUbTWzk7bt7habdLYwgnXLEWH3TuR1789QSTPVsPjLMa2KQzHffyZHTkLQQyRxeEBmWHaETS2btF5fK?details=txs + method: GET + extURL: https://blockbook.zcoin.io/api/v2/xpub/xpub6Cgu6WtTyo99pRtTabwscog2ncj4BUbTWzk7bt7habdLYwgnXLEWH3TuR1789QSTPVsPjLMa2KQzHffyZHTkLQQyRxeEBmWHaETS2btF5fK?details=txs&pageSize=10 +- file: mock/ext-api-data/zelcash-api_v2_address_t1JKRwXGfKTGfPV1z48rvoLyabk31z3xwHa__details_txs.json + mockURL: /mock/zelcash-api/api/v2/address/t1JKRwXGfKTGfPV1z48rvoLyabk31z3xwHa?details=txs + method: GET + extURL: https://blockbook.zel.network/api/v2/address/t1JKRwXGfKTGfPV1z48rvoLyabk31z3xwHa?details=txs&&pageSize=10 +- file: mock/ext-api-data/zelcash-api_v2_xpub_xpub6C5soBeFd2uZLCcEvsqaoGXuh9UposMMfk2jSiBKMN8rJKs9NLqjPK51gWv9mYBpUY95GtHYsofwpPRdB6FJ56cEaTJGCba5GKv55wPNZNf__details_txs.json + mockURL: /mock/zelcash-api/api/v2/xpub/xpub6C5soBeFd2uZLCcEvsqaoGXuh9UposMMfk2jSiBKMN8rJKs9NLqjPK51gWv9mYBpUY95GtHYsofwpPRdB6FJ56cEaTJGCba5GKv55wPNZNf?details=txs + method: GET + extURL: https://blockbook.zel.network/api/v2/xpub/xpub6C5soBeFd2uZLCcEvsqaoGXuh9UposMMfk2jSiBKMN8rJKs9NLqjPK51gWv9mYBpUY95GtHYsofwpPRdB6FJ56cEaTJGCba5GKv55wPNZNf?details=txs&pageSize=10 +- file: mock/ext-api-data/zilliqa-api_addresses_zil1l8ddxvejeam70qang54wnqkgtmlu5mwlgzy64z_txs.json + mockURL: /mock/zilliqa-api/addresses/zil1l8ddxvejeam70qang54wnqkgtmlu5mwlgzy64z/txs + method: GET + extURL: https://api.viewblock.io/v1/zilliqa/addresses/zil1l8ddxvejeam70qang54wnqkgtmlu5mwlgzy64z/txs +- file: mock/ext-api-data/fio-api_v1_chain_get_pub_address.0001.json + mockURL: /mock/fio-api/v1/chain/get_pub_address + method: POST + reqFile: mock/ext-api-data/fio-api_v1_chain_get_pub_address.0001.request_json +- file: mock/ext-api-data/fio-api_v1_chain_get_pub_address.0002.json + mockURL: /mock/fio-api/v1/chain/get_pub_address + method: POST + reqFile: mock/ext-api-data/fio-api_v1_chain_get_pub_address.0002.request_json +- file: mock/ext-api-data/fio-api_v1_chain_get_pub_address.json + mockURL: /mock/fio-api/v1/chain/get_pub_address + method: POST + reqFile: mock/ext-api-data/fio-api_v1_chain_get_pub_address.request_json +- file: mock/ext-api-data/fio-api_v1_history_get_actions.0001.json + mockURL: /mock/fio-api/v1/history/get_actions + method: POST + reqFile: mock/ext-api-data/fio-api_v1_history_get_actions.0001.request_json + reqField: account_name +- file: mock/ext-api-data/fio-api_v1_history_get_actions.0002.json + mockURL: /mock/fio-api/v1/history/get_actions + method: POST + reqFile: mock/ext-api-data/fio-api_v1_history_get_actions.0002.request_json + reqField: account_name +- file: mock/ext-api-data/fio-api_v1_history_get_actions.json + mockURL: /mock/fio-api/v1/history/get_actions + method: POST + reqFile: mock/ext-api-data/fio-api_v1_history_get_actions.request_json + reqField: account_name +- file: mock/ext-api-data/harmony-api.json + mockURL: /mock/harmony-api + method: POST + extURL: https://api.s0.t.hmny.io + reqFile: mock/ext-api-data/harmony-api.request_json + reqField: address +- file: mock/ext-api-data/kusama-api_scan_transfers.json + mockURL: /mock/kusama-rpc/scan/transfers + method: POST + extURL: https://kusama.subscan.io/api/scan/transfers + reqFile: mock/ext-api-data/kusama-api_scan_transfers.request_json +- file: mock/ext-api-data/nano-api.json + mockURL: /mock/nano-api + method: POST + extURL: https://nanoverse.io/api/node + reqFile: mock/ext-api-data/nano-api.request_json +- file: mock/ext-api-data/nimiq-rpc.json + mockURL: /mock/nimiq-rpc + method: POST + extURL: https:// + reqFile: mock/ext-api-data/nimiq-rpc.request_json + reqField: params +- file: mock/ext-api-data/tron-api_wallet_getaccount.json + mockURL: /mock/tron-api/wallet/getaccount + method: POST + extURL: https://api.trongrid.io/wallet/getaccount + reqFile: mock/ext-api-data/tron-api_wallet_getaccount.request_json +- file: mock/ext-api-data/vechain-api_logs_transfer.json + mockURL: /mock/vechain-api/logs/transfer + method: POST + extURL: https://vethor-pubnode.digonchain.com/logs/transfer + reqFile: mock/ext-api-data/vechain-api_logs_transfer.request_json + reqField: sender +- file: mock/ext-api-data/eth-rpc__eth_call_data_0x0178b8bfa538cd174de170e8062c97c25c40a7ceb56aca81b12e6f5afc46f5a429999aa4.json + mockURL: /mock/eth-rpc + method: POST + extURL: https:// + reqFile: mock/ext-api-data/eth-rpc__eth_call_data_0x0178b8bfa538cd174de170e8062c97c25c40a7ceb56aca81b12e6f5afc46f5a429999aa4.request_json + reqField: data +- file: mock/ext-api-data/eth-rpc__eth_call_data_0x0178b8bfee6c4522aab0003e8d14cd40a6af439055fd2577951148c14b6cea9a53475835.json + mockURL: /mock/eth-rpc + method: POST + extURL: https:// + reqFile: mock/ext-api-data/eth-rpc__eth_call_data_0x0178b8bfee6c4522aab0003e8d14cd40a6af439055fd2577951148c14b6cea9a53475835.request_json + reqField: data +- file: mock/ext-api-data/eth-rpc__eth_call_data_0x0178b8bf2337fcf9521666fd5114df2902fa9e6da5a6b004b5a192a0f55d2d9fab4f1047.json + mockURL: /mock/eth-rpc + method: POST + extURL: https:// + reqFile: mock/ext-api-data/eth-rpc__eth_call_data_0x0178b8bf2337fcf9521666fd5114df2902fa9e6da5a6b004b5a192a0f55d2d9fab4f1047.request_json + reqField: data +- file: mock/ext-api-data/eth-rpc__eth_call_data_0x3b3b57de2337fcf9521666fd5114df2902fa9e6da5a6b004b5a192a0f55d2d9fab4f1047.json + mockURL: /mock/eth-rpc + method: POST + extURL: https:// + reqFile: mock/ext-api-data/eth-rpc__eth_call_data_0x3b3b57de2337fcf9521666fd5114df2902fa9e6da5a6b004b5a192a0f55d2d9fab4f1047.request_json + reqField: data +- file: mock/ext-api-data/eth-rpc__eth_call_data_0xf1cb7e062337fcf9521666fd5114df2902fa9e6da5a6b004b5a192a0f55d2d9fab4f1047000000000000000000000000000000000000000000000000000000000000003c.json + mockURL: /mock/eth-rpc + method: POST + extURL: https:// + reqFile: mock/ext-api-data/eth-rpc__eth_call_data_0xf1cb7e062337fcf9521666fd5114df2902fa9e6da5a6b004b5a192a0f55d2d9fab4f1047000000000000000000000000000000000000000000000000000000000000003c.request_json + reqField: data +- file: mock/ext-api-data/eth-rpc__eth_call_data_0xf1cb7e06a538cd174de170e8062c97c25c40a7ceb56aca81b12e6f5afc46f5a429999aa4000000000000000000000000000000000000000000000000000000000000003c.json + mockURL: /mock/eth-rpc + method: POST + extURL: https:// + reqFile: mock/ext-api-data/eth-rpc__eth_call_data_0xf1cb7e06a538cd174de170e8062c97c25c40a7ceb56aca81b12e6f5afc46f5a429999aa4000000000000000000000000000000000000000000000000000000000000003c.request_json + reqField: data +- file: mock/ext-api-data/eth-rpc__eth_call_data_0xf1cb7e06ee6c4522aab0003e8d14cd40a6af439055fd2577951148c14b6cea9a53475835000000000000000000000000000000000000000000000000000000000000003c.json + mockURL: /mock/eth-rpc + method: POST + extURL: https:// + reqFile: mock/ext-api-data/eth-rpc__eth_call_data_0xf1cb7e06ee6c4522aab0003e8d14cd40a6af439055fd2577951148c14b6cea9a53475835000000000000000000000000000000000000000000000000000000000000003c.request_json + reqField: data +- file: mock/ext-api-data/eth-rpc__eth_call_data_0x3b3b57dea538cd174de170e8062c97c25c40a7ceb56aca81b12e6f5afc46f5a429999aa4.json + mockURL: /mock/eth-rpc + method: POST + extURL: https:// + reqFile: mock/ext-api-data/eth-rpc__eth_call_data_0x3b3b57dea538cd174de170e8062c97c25c40a7ceb56aca81b12e6f5afc46f5a429999aa4.request_json + reqField: data diff --git a/mock/ext-api-data/aeternity-api_middleware_transactions_account_ak_2WGWYMgWy1opZxgA8AVzGCTavCQyUBtbKx5SrCX6E4kmDZMtJb.json b/mock/ext-api-data/aeternity-api_middleware_transactions_account_ak_2WGWYMgWy1opZxgA8AVzGCTavCQyUBtbKx5SrCX6E4kmDZMtJb.json new file mode 100644 index 000000000..8a2d5deea --- /dev/null +++ b/mock/ext-api-data/aeternity-api_middleware_transactions_account_ak_2WGWYMgWy1opZxgA8AVzGCTavCQyUBtbKx5SrCX6E4kmDZMtJb.json @@ -0,0 +1,139 @@ +[ + { + "block_hash": "mh_9n1WhZB39ppe4hrw1mW5RTz2xLGPBNopC94EvENTz5uN6FgPx", + "block_height": 253953, + "hash": "th_JHJDW5N9HDJQkChm9dzXJfmQMujsYKYtDzh6oAv4UqdMnyRmb", + "signatures": [ + "sg_2F1uswNURBVAkaib5X8YRtqQAZEEHD4y5aSGD8DkGHkZy7EMsWwf63rtZRYLQoVs2i1HrYg3uBkmhVEJJ29bz9KKUYFQV" + ], + "time": 1589238828576, + "tx": { + "amount": 1.99979974992e21, + "fee": 50000000000000, + "nonce": 4, + "payload": "ba_Xfbg4g==", + "recipient_id": "ak_eCBjzjUpjA6uqhj1unF5VC2bvd8yEC9tFArUDTwor21CYaTNZ", + "sender_id": "ak_2WGWYMgWy1opZxgA8AVzGCTavCQyUBtbKx5SrCX6E4kmDZMtJb", + "ttl": 254053, + "type": "SpendTx", + "version": 1 + } + }, + { + "block_hash": "mh_2V2PJ732cTfDqD4CaWr6W1s1fN531PqiVydMiy7gooccQFoGvM", + "block_height": 222994, + "hash": "th_WfeoRYXd13MMmDBzMXjBBdaNSSaRXkwUwJ7tFxJ7ZKPQVNXC4", + "signatures": [ + "sg_MLBxuqnHUD21i747SKnQuyNh1LzLuH7RDHqY1mngZyJMDWL9LFcuMbKdo2XMbwkMmskFsgfsZZBwgyA5w4Xs3ghynF2AF" + ], + "time": 1583633007081, + "tx": { + "amount": 1.99979979992e21, + "fee": 16840000000000, + "nonce": 3, + "payload": "ba_Xfbg4g==", + "recipient_id": "ak_2WGWYMgWy1opZxgA8AVzGCTavCQyUBtbKx5SrCX6E4kmDZMtJb", + "sender_id": "ak_26dGJ7S5ba7LhUXPo8vMPe4QuNaQbskWnM5jkopPuim3PGny9Y", + "type": "SpendTx", + "version": 1 + } + }, + { + "block_hash": "mh_Z1a6HSs9vE5XDf8JtSiQMN5UpX49Spgnf9Sn32TiXxKwSbsP6", + "block_height": 186035, + "hash": "th_2wGEGmqwRMPYdv3vz1EE7ueJEveMTzEWzosgUH9ytERjGMv3rX", + "signatures": [ + "sg_66c2LXv4rvYnn4r2fZ4H1wxieDUuVEUF6fLCB3M13MjB9QNfEH4q9YThUWJCo5WzWKxzqjb3RbumhXdUZh8YDq3v8KZ2M" + ], + "time": 1576946253731, + "tx": { + "amount": 1.00079975e21, + "fee": 50000000000000, + "nonce": 3, + "payload": "ba_Xfbg4g==", + "recipient_id": "ak_26dGJ7S5ba7LhUXPo8vMPe4QuNaQbskWnM5jkopPuim3PGny9Y", + "sender_id": "ak_2WGWYMgWy1opZxgA8AVzGCTavCQyUBtbKx5SrCX6E4kmDZMtJb", + "ttl": 186135, + "type": "SpendTx", + "version": 1 + } + }, + { + "block_hash": "mh_23SfEMQHUqJoDzGjdYHFh2Fw9zUa1LAR6JxstKxpzW51vZSTBG", + "block_height": 186034, + "hash": "th_2CvMDQGNU21Dq9241hjoeDfwcz7FnBE2DhMXUd5rRMCbjG117H", + "signatures": [ + "sg_Y6dTsjGnmCJG6nVRoLVtoXr6QWyk3kYHvJ97QvXKGumjEFvZcnNtVAUZ2oc6fCYBf36PMHRcxKwF8Z4UWqPEj8mz8CCBB" + ], + "time": 1576946179344, + "tx": { + "amount": 9.9800005e20, + "fee": 50000000000000, + "nonce": 2, + "payload": "ba_Xfbg4g==", + "recipient_id": "ak_26dGJ7S5ba7LhUXPo8vMPe4QuNaQbskWnM5jkopPuim3PGny9Y", + "sender_id": "ak_2WGWYMgWy1opZxgA8AVzGCTavCQyUBtbKx5SrCX6E4kmDZMtJb", + "ttl": 186134, + "type": "SpendTx", + "version": 1 + } + }, + { + "block_hash": "mh_2UkBD3ZsjQTjqhqLGqWAERy313ravnLczGjTE3F3Qyzdmikv9q", + "block_height": 185934, + "hash": "th_859Ja4tucJHqjHGmvNibeRVDty2YzGhzKtpz7UDYJVWuW5tGG", + "signatures": [ + "sg_oEsmi674Lqu5K1aJDZ353v48D3UZYUXtkoSoVX5xs6VxDDcKRxg5btnHUJQaFcXC1TFP3eZ6rKSnyeQwNdz11gmAooAg" + ], + "time": 1576928530320, + "tx": { + "amount": 1000050000000000000, + "fee": 50000000000000, + "nonce": 1, + "payload": "ba_Xfbg4g==", + "recipient_id": "ak_26dGJ7S5ba7LhUXPo8vMPe4QuNaQbskWnM5jkopPuim3PGny9Y", + "sender_id": "ak_2WGWYMgWy1opZxgA8AVzGCTavCQyUBtbKx5SrCX6E4kmDZMtJb", + "ttl": 186034, + "type": "SpendTx", + "version": 1 + } + }, + { + "block_hash": "mh_2EnVyYu67Ej9VmAhHAEeVp41NKGQvy13jy6t2wppyuvzRRWhLM", + "block_height": 185931, + "hash": "th_7QM8aAVD299io7VoxEQSfRqmJ9SZqpycupZFUHCy7Whe6NhTJ", + "signatures": [ + "sg_DvkxctVXTnzhs1YJeAtgwbA7uPKKULu5chMoZRpJTjMGKjkhTjcQhGawnyfWfhwdrcrrZs2rzUg1S21MMF71qSLSBttRQ" + ], + "time": 1576927729850, + "tx": { + "amount": 1.9898e21, + "fee": 16880000000000, + "nonce": 5256, + "payload": "ba_Xfbg4g==", + "recipient_id": "ak_2WGWYMgWy1opZxgA8AVzGCTavCQyUBtbKx5SrCX6E4kmDZMtJb", + "sender_id": "ak_dnzaNnchT7f3YT3CtrQ7GUjqGT6VaHzPxpf2efHWPuEAWKcht", + "type": "SpendTx", + "version": 1 + } + }, + { + "block_hash": "mh_2q93r4jZY77kxQsKMGGS4AqXh97spDydfR61MpbSPs3GWXrmWA", + "block_height": 185618, + "hash": "th_2JTC4fK8aHQLywigJCCNYC5wmAWYHSG5fjG6yDzZQM9YPmee5a", + "signatures": [ + "sg_15yUH8Gi9K59WizVVtShzYBcahXgDgiZsuXfUthSkqw4a5QWyeRzr28kxnv6qYrzePhG4RDMVLDtMmQMfjmXemnynR5fy" + ], + "time": 1576872187562, + "tx": { + "amount": 10000000000000000000, + "fee": 16860000000000, + "nonce": 5241, + "payload": "ba_Xfbg4g==", + "recipient_id": "ak_2WGWYMgWy1opZxgA8AVzGCTavCQyUBtbKx5SrCX6E4kmDZMtJb", + "sender_id": "ak_dnzaNnchT7f3YT3CtrQ7GUjqGT6VaHzPxpf2efHWPuEAWKcht", + "type": "SpendTx", + "version": 1 + } + } +] \ No newline at end of file diff --git a/mock/ext-api-data/aion-api_getTransactionsByAddress__accountAddress_0xa04f0117864ccf5013861a89f08c6fc790284d72356c8a362025d31b855ed6ed_size_25.json b/mock/ext-api-data/aion-api_getTransactionsByAddress__accountAddress_0xa04f0117864ccf5013861a89f08c6fc790284d72356c8a362025d31b855ed6ed_size_25.json new file mode 100644 index 000000000..1f51fa373 --- /dev/null +++ b/mock/ext-api-data/aion-api_getTransactionsByAddress__accountAddress_0xa04f0117864ccf5013861a89f08c6fc790284d72356c8a362025d31b855ed6ed_size_25.json @@ -0,0 +1,58 @@ +{ + "page": { + "number": 0, + "size": 25, + "totalPages": 1, + "start": 1582532306, + "end": 1585037906, + "totalElements": 2 + }, + "content": [ + { + "blockHash": "f9aab3a58f9211d9d37458d8a87e49f2e00d1d242390d4650cd4092897650797", + "nrgPrice": 10000000000, + "toAddr": "a0c00cfc4c53bb6d49f385b91f58a23dd7b1dc024976b391bb8b81eb9e8801ab", + "contractAddr": "", + "data": "", + "year": 2020, + "internalTransactionCount": 0, + "transactionIndex": 0, + "type": "DEFAULT", + "nonce": "1e2f", + "transactionHash": "511d3a4aafbdd26825a1655b5c7525df5bea8a8ef0f887d5490b490055b53df7", + "transactionTimestamp": 1584349754, + "nrgConsumed": 21000, + "month": 3, + "blockNumber": 5619712, + "blockTimestamp": 1584349754, + "transactionLog": "[]", + "fromAddr": "a04f0117864ccf5013861a89f08c6fc790284d72356c8a362025d31b855ed6ed", + "day": 16, + "value": "1.002217611212000000000000000000000000", + "txError": "" + }, + { + "blockHash": "ed8d3d92da7228c35c363f55383c602b6f5041b37ff165231245cfa83b863ae7", + "nrgPrice": 10000000000, + "toAddr": "a04f0117864ccf5013861a89f08c6fc790284d72356c8a362025d31b855ed6ed", + "contractAddr": "", + "data": "", + "year": 2020, + "internalTransactionCount": 0, + "transactionIndex": 2, + "type": "DEFAULT", + "nonce": "2b2e55", + "transactionHash": "84789693b108bc3c437f8dccbd517682f611036d54621ec1f4db26f661fde468", + "transactionTimestamp": 1584349550, + "nrgConsumed": 21000, + "month": 3, + "blockNumber": 5619690, + "blockTimestamp": 1584349550, + "transactionLog": "[]", + "fromAddr": "a00983f07c11ee9160a64dd3ba3dc3d1f88332a2869f25725f56cbd0be32ef7a", + "day": 16, + "value": "1.002427611212000000000000000000000000", + "txError": "" + } + ] +} \ No newline at end of file diff --git a/mock/ext-api-data/algorand-api_v1_account_4EZFQABCVQTHQCK3HQBIYGC4NV2VM42FZHEFTVH77ROG4ZGREC6Y7V5T2U_transactions.json b/mock/ext-api-data/algorand-api_v1_account_4EZFQABCVQTHQCK3HQBIYGC4NV2VM42FZHEFTVH77ROG4ZGREC6Y7V5T2U_transactions.json new file mode 100644 index 000000000..0f4be8eed --- /dev/null +++ b/mock/ext-api-data/algorand-api_v1_account_4EZFQABCVQTHQCK3HQBIYGC4NV2VM42FZHEFTVH77ROG4ZGREC6Y7V5T2U_transactions.json @@ -0,0 +1,23 @@ +{ + "transactions": [ + { + "type": "pay", + "tx": "JZTKP6RRFGUDOZ7DQIR26DQWRDYZVYG2G3WDE4WLBJ77AMAEBFBA", + "from": "5TSQNIL54GB545B3WLC6OVH653SHAELMHU6MSVNGTUNMOEHAMWG7EC3AA4", + "fee": 1000, + "first-round": 5478300, + "last-round": 5478749, + "noteb64": "sHLxsLBrP3o=", + "round": 5478346, + "payment": { + "to": "4EZFQABCVQTHQCK3HQBIYGC4NV2VM42FZHEFTVH77ROG4ZGREC6Y7V5T2U", + "amount": 1, + "torewards": 2052177, + "closerewards": 0 + }, + "fromrewards": 0, + "genesisID": "mainnet-v1.0", + "genesishashb64": "wGHE2Pwdvd7S12BL5FaOP20EGYesN73ktiC1qzkkit8=" + } + ] +} \ No newline at end of file diff --git a/mock/ext-api-data/algorand-api_v1_block_5478346.json b/mock/ext-api-data/algorand-api_v1_block_5478346.json new file mode 100644 index 000000000..2705c6448 --- /dev/null +++ b/mock/ext-api-data/algorand-api_v1_block_5478346.json @@ -0,0 +1,43 @@ +{ + "hash": "SU4PUD4YK5DPIXUXDLEZOEHVVIIP4SWZORFPJBW2J22QO444NSAA", + "previousBlockHash": "CC4CQRE2U5AC7S7JLJHDVVGIDCHGWTDFIZM3P34TVTC7AP4BA2AQ", + "seed": "NLAQIQXPCZI5QMKMRFFKMIKANNBC4PTFW5QFVAK7U6FE477T2TRA", + "proposer": "WCFKBT4NEPDUCQP7MGLIWV4QGXIBOCXJFVYNTXF3HZHFHGQGHGR5WWA7XA", + "round": 5478346, + "period": 0, + "txnRoot": "KFADZYI64LDUX76VWVVV3MROORV5RXAVNZA7MVTWOP2QTGW6DZ2A", + "reward": 111421, + "rate": 25999967, + "frac": 2639736378, + "txns": { + "transactions": [ + { + "type": "pay", + "tx": "JZTKP6RRFGUDOZ7DQIR26DQWRDYZVYG2G3WDE4WLBJ77AMAEBFBA", + "from": "5TSQNIL54GB545B3WLC6OVH653SHAELMHU6MSVNGTUNMOEHAMWG7EC3AA4", + "fee": 1000, + "first-round": 5478300, + "last-round": 5478749, + "noteb64": "sHLxsLBrP3o=", + "round": 5478346, + "payment": { + "to": "4EZFQABCVQTHQCK3HQBIYGC4NV2VM42FZHEFTVH77ROG4ZGREC6Y7V5T2U", + "amount": 1, + "torewards": 2052177, + "closerewards": 0 + }, + "fromrewards": 0, + "genesisID": "mainnet-v1.0", + "genesishashb64": "wGHE2Pwdvd7S12BL5FaOP20EGYesN73ktiC1qzkkit8=" + } + ] + }, + "timestamp": 1584332782, + "currentProtocol": "https://github.com/algorandfoundation/specs/tree/4a9db6a25595c6fd097cf9cc137cc83027787eaa", + "nextProtocol": "", + "nextProtocolApprovals": 0, + "nextProtocolVoteBefore": 0, + "nextProtocolSwitchOn": 0, + "upgradePropose": "", + "upgradeApprove": false +} \ No newline at end of file diff --git a/mock/ext-api-data/binance-api_v1_account_bnb1jeu6gscugy6l2wyatxthkh2hmer4hzevgcmf0q b/mock/ext-api-data/binance-api_v1_account_bnb1jeu6gscugy6l2wyatxthkh2hmer4hzevgcmf0q new file mode 100644 index 000000000..ff8e44b50 --- /dev/null +++ b/mock/ext-api-data/binance-api_v1_account_bnb1jeu6gscugy6l2wyatxthkh2hmer4hzevgcmf0q @@ -0,0 +1 @@ +{"account_number":273171,"address":"bnb1jeu6gscugy6l2wyatxthkh2hmer4hzevgcmf0q","balances":[{"free":"226.52883965","frozen":"0.00000000","locked":"0.00000000","symbol":"BNB"},{"free":"3649.96917801","frozen":"0.00000000","locked":"0.00000000","symbol":"BUSD-BD1"},{"free":"0.05000000","frozen":"0.00000000","locked":"0.00000000","symbol":"TWT-8C2"}],"flags":0,"public_key":[2,142,117,1,132,202,113,77,165,176,46,204,240,131,18,251,120,168,140,204,43,27,32,135,157,30,25,86,154,105,108,64,211],"sequence":82} diff --git a/mock/ext-api-data/binance-api_v1_tokens__limit_1000_offset_0.json b/mock/ext-api-data/binance-api_v1_tokens__limit_1000_offset_0.json new file mode 100644 index 000000000..ef085c1eb --- /dev/null +++ b/mock/ext-api-data/binance-api_v1_tokens__limit_1000_offset_0.json @@ -0,0 +1,1466 @@ +[ + { + "mintable": true, + "name": "Africa Stable-Coin", + "original_symbol": "ABCD", + "owner": "bnb1ujvzeuft0ezf9fu4u0mk52t8mc7t8geyfkevms", + "symbol": "ABCD-5D8", + "total_supply": "3000000.00000000" + }, + { + "mintable": false, + "name": "Aditus", + "original_symbol": "ADI", + "owner": "bnb1djdymfgzknmcsu9dzm9s0uavdszn0cl82z4hps", + "symbol": "ADI-6BB", + "total_supply": "750000000.00000000" + }, + { + "mintable": false, + "name": "Aergo", + "original_symbol": "AERGO", + "owner": "bnb1llqhwwwmh878844tm3g8v47k0t7xtnhl4hggjl", + "symbol": "AERGO-46B", + "total_supply": "500000000.00000000" + }, + { + "mintable": false, + "name": "Alaris", + "original_symbol": "ALA", + "owner": "bnb1pmdkvw6cquwylr46wcrl82xzmul0y2jpj5cwx7", + "symbol": "ALA-DCD", + "total_supply": "60000000.00000000" + }, + { + "mintable": false, + "name": "ANKR", + "original_symbol": "ANKR", + "owner": "bnb1hvg059mkwleum35j6y2qjn4fvmgl7zxtlah4tn", + "symbol": "ANKR-E97", + "total_supply": "10000000000.00000000" + }, + { + "mintable": false, + "name": "Aeron", + "original_symbol": "ARN", + "owner": "bnb1dq8ae0ayztqp99peggq5sygzf3n7u2ze4t0jne", + "symbol": "ARN-71B", + "total_supply": "20000000.00000000" + }, + { + "mintable": true, + "name": "ARPA", + "original_symbol": "ARPA", + "owner": "bnb1mecnt25u3j9ne7th5av7hqvnmzvyrr7ny8hg8c", + "symbol": "ARPA-575", + "total_supply": "12000000.00000000" + }, + { + "mintable": false, + "name": "Maecenas ART Token", + "original_symbol": "ART", + "owner": "bnb13plj9kycvcew5v0achpatnd5l5pacys9h0gu8l", + "symbol": "ART-3C9", + "total_supply": "100000000.00000000" + }, + { + "mintable": true, + "name": "Atlas Protocol", + "original_symbol": "ATP", + "owner": "bnb1msw3avv894nlpeu0vn4qlkl0r65a3rp7gtz5hf", + "symbol": "ATP-38C", + "total_supply": "40000000.00000000" + }, + { + "mintable": false, + "name": "Travala.com Token", + "original_symbol": "AVA", + "owner": "bnb1dm9c7gccgd07td5r69m50u8fg8danfgqvlhj6c", + "symbol": "AVA-645", + "total_supply": "61242960.00000000" + }, + { + "mintable": true, + "name": "“Atomic", + "original_symbol": "AWC", + "owner": "bnb1g5xj69c0s0x646hug7j3vr6eamlkf7jw3cr3yw", + "symbol": "AWC-8B2", + "total_supply": "147.00000000" + }, + { + "mintable": false, + "name": "Atomic Wallet Token", + "original_symbol": "AWC", + "owner": "bnb1g5xj69c0s0x646hug7j3vr6eamlkf7jw3cr3yw", + "symbol": "AWC-986", + "total_supply": "50000000.00000000" + }, + { + "mintable": false, + "name": "AXPR.B", + "original_symbol": "AXPR", + "owner": "bnb1zpnmet0vhfupn9ysu26gukzj7a2xkkcry22n9t", + "symbol": "AXPR-777", + "total_supply": "347955111.02000000" + }, + { + "mintable": true, + "name": "BAWnetwork", + "original_symbol": "BAW", + "owner": "bnb1umdp5z4hugur26tcgf48fhr0548fv0q0fga84u", + "symbol": "BAW-DFB", + "total_supply": "25000000000.00000000" + }, + { + "mintable": true, + "name": "BCH BEP2", + "original_symbol": "BCH", + "owner": "bnb15tjhzw85wyywwp7zvc4l3ux3j0393rzp9exl0p", + "symbol": "BCH-1FD", + "total_supply": "5000.00000000" + }, + { + "mintable": false, + "name": "Blockmason Credit Protocol", + "original_symbol": "BCPT", + "owner": "bnb1ed7sfac04uzkg8lsxmgl7sxlj8pvyrpnyjm9ew", + "symbol": "BCPT-95A", + "total_supply": "116158667.00000000" + }, + { + "mintable": true, + "name": "3X Short Bitcoin Token", + "original_symbol": "BEAR", + "owner": "bnb1ff4r0t7j8ll8lf3gm2ltdu3hjy4w690j7vvees", + "symbol": "BEAR-14C", + "total_supply": "50301.00000000" + }, + { + "mintable": false, + "name": "EOSBet Token", + "original_symbol": "BET", + "owner": "bnb1rgylg0f3ka24a63rnq926quvet438fxrz3320c", + "symbol": "BET-844", + "total_supply": "88000000.00000000" + }, + { + "mintable": false, + "name": "BETX Token", + "original_symbol": "BETX", + "owner": "bnb15v9e3c4wy8vpex0c5fj702lexjesh30v2203f2", + "symbol": "BETX-A0C", + "total_supply": "200000000.00000000" + }, + { + "mintable": true, + "name": "Binance GBP Stable Coin", + "original_symbol": "BGBP", + "owner": "bnb1r4ag7kd90rptlhcuuc8trh60v4m4vvzrfyecta", + "symbol": "BGBP-CF3", + "total_supply": "200.00000000" + }, + { + "mintable": true, + "name": "Humanity First Token", + "original_symbol": "BHFT", + "owner": "bnb148t3u8zxa44vhydes5qa8xnxuzuq6zgyxmzt6d", + "symbol": "BHFT-BBE", + "total_supply": "636425000.00000000" + }, + { + "mintable": false, + "name": "Bitwires Token", + "original_symbol": "BKBT", + "owner": "bnb104p50kz2uvep5s5u6j0lr6vkl6rp5g4653d7w4", + "symbol": "BKBT-3A6", + "total_supply": "10000000000.00000000" + }, + { + "mintable": true, + "name": "Binance KRW", + "original_symbol": "BKRW", + "owner": "bnb18kha55gvsxl7gkdh8y329hu3p6wndh6jkwqnxn", + "symbol": "BKRW-AB7", + "total_supply": "1418984074.00000000" + }, + { + "mintable": false, + "name": "Blockmason Link", + "original_symbol": "BLINK", + "owner": "bnb1ed7sfac04uzkg8lsxmgl7sxlj8pvyrpnyjm9ew", + "symbol": "BLINK-9C6", + "total_supply": "5000000000.00000000" + }, + { + "mintable": false, + "name": "Binance Chain Native Token", + "original_symbol": "BNB", + "owner": "bnb1ultyhpw2p2ktvr68swz56570lgj2rdsadq3ym2", + "symbol": "BNB", + "total_supply": "179883948.90000000" + }, + { + "mintable": false, + "name": "BOLT Token", + "original_symbol": "BOLT", + "owner": "bnb177ujwmshxu8r9za4vy9ztqn65tmr54ddw958rt", + "symbol": "BOLT-4C6", + "total_supply": "980230000.00000000" + }, + { + "mintable": false, + "name": "Bitcloud Pro", + "original_symbol": "BPRO", + "owner": "bnb1482svhhrffpga5wmqw8068af4c9u2q9dp3hg4m", + "symbol": "BPRO-5A6", + "total_supply": "5000000000.00000000" + }, + { + "mintable": true, + "name": "BQTX", + "original_symbol": "BQTX", + "owner": "bnb1j42h6j40htujnjmtp4ckw4zx27vp0f93cvmua8", + "symbol": "BQTX-235", + "total_supply": "1000000.00000000" + }, + { + "mintable": false, + "name": "BOOSTO", + "original_symbol": "BST2", + "owner": "bnb19k2av7cmdvp9f0qkeu5vfl59yp8ftqv2s55dzs", + "symbol": "BST2-2F2", + "total_supply": "500000000.00000000" + }, + { + "mintable": true, + "name": "Bitcoin BEP2", + "original_symbol": "BTCB", + "owner": "bnb1akey87kt0r8y3fmhu2l8eyzdjvt9ptl5cppz0v", + "symbol": "BTCB-1DE", + "total_supply": "9001.00000000" + }, + { + "mintable": true, + "name": "BTTB", + "original_symbol": "BTTB", + "owner": "bnb1srm577fgsjg363vsqt8td4tat5arzfvkjchqgq", + "symbol": "BTTB-D31", + "total_supply": "1000000000.00000000" + }, + { + "mintable": true, + "name": "3x Long Bitcoin Token", + "original_symbol": "BULL", + "owner": "bnb1ff4r0t7j8ll8lf3gm2ltdu3hjy4w690j7vvees", + "symbol": "BULL-BE4", + "total_supply": "604.80000000" + }, + { + "mintable": true, + "name": "Binance USD", + "original_symbol": "BUSD", + "owner": "bnb19v2ayq6k6e5x6ny3jdutdm6kpqn3n6mxheegvj", + "symbol": "BUSD-BD1", + "total_supply": "13000000.00000000" + }, + { + "mintable": false, + "name": "Bezant Token", + "original_symbol": "BZNT", + "owner": "bnb1w5a5jywe3cu20uq6n6x3vmzcq342s6st4cz73s", + "symbol": "BZNT-464", + "total_supply": "964511442.00000000" + }, + { + "mintable": false, + "name": "CanYaCoin", + "original_symbol": "CAN", + "owner": "bnb16w59lfh4y2cqvu8f7yr000ll37ldh4w6hnz7l0", + "symbol": "CAN-677", + "total_supply": "95827000.00000000" + }, + { + "mintable": false, + "name": "CASHAA", + "original_symbol": "CAS", + "owner": "bnb1xkw2sagpx6t0cmwzapxpv94tupvqk7tpgy72ku", + "symbol": "CAS-167", + "total_supply": "1000000000.00000000" + }, + { + "mintable": false, + "name": "Cubiex", + "original_symbol": "CBIX", + "owner": "bnb1jlm66w38gpfuqr4s2jcfwlcrlx46p05thdnv7g", + "symbol": "CBIX-3C9", + "total_supply": "150000000.00000000" + }, + { + "mintable": false, + "name": "CryptoBonusMiles", + "original_symbol": "CBM", + "owner": "bnb1dq8ae0ayztqp99peggq5sygzf3n7u2ze4t0jne", + "symbol": "CBM-4B2", + "total_supply": "5000000000.00000000" + }, + { + "mintable": false, + "name": "Clipper Coin", + "original_symbol": "CCCX", + "owner": "bnb1ry99rte8gfnn9c6at9mlmrrq6p2k4u7732j9h7", + "symbol": "CCCX-10D", + "total_supply": "5000000000.00000000" + }, + { + "mintable": false, + "name": "Chiliz", + "original_symbol": "CHZ", + "owner": "bnb1cghr4z8ag440tv4wnk3l6wzynytlpvfqltm9ph", + "symbol": "CHZ-ECD", + "total_supply": "8888888888.00000000" + }, + { + "mintable": false, + "name": "Crypto Neo-value Neural System", + "original_symbol": "CNNS", + "owner": "bnb193wdp4gdnm58urnsjf8nv57lxt58sckt2k50ss", + "symbol": "CNNS-E16", + "total_supply": "10000000000.00000000" + }, + { + "mintable": false, + "name": "Contentos", + "original_symbol": "COS", + "owner": "bnb1u9j9hkst6gf09dkdvxlj7puk8c7vh68a0kkmht", + "symbol": "COS-2E4", + "total_supply": "9400000000.00000000" + }, + { + "mintable": true, + "name": "COTI", + "original_symbol": "COTI", + "owner": "bnb1kn733gkku9xsqkuk6wcz86gftqtl4qvthvrj5m", + "symbol": "COTI-CBB", + "total_supply": "80000000.00000000" + }, + { + "mintable": false, + "name": "Covalent Token", + "original_symbol": "COVA", + "owner": "bnb1pucvxaf3l9rslupza75r9fca9h5892ntumszfm", + "symbol": "COVA-218", + "total_supply": "6500000000.00000000" + }, + { + "mintable": false, + "name": "CPChain", + "original_symbol": "CPC", + "owner": "bnb1wq4rlwrmvvltlarvypql8wrr4vlh0dczd8uksg", + "symbol": "CPC-FED", + "total_supply": "150000000.00000000" + }, + { + "mintable": false, + "name": "Crypterium Token", + "original_symbol": "CRPT", + "owner": "bnb17fk3uvagucxzpvmdvd373fapqsahxvzevdard9", + "symbol": "CRPT-8C9", + "total_supply": "99968575.14285720" + }, + { + "mintable": false, + "name": "“Consentium”", + "original_symbol": "CSM", + "owner": "bnb1gguz7vcrlf7a87et8u5gt40f0890qvkpkn9y79", + "symbol": "CSM-734", + "total_supply": "84000000.00000000" + }, + { + "mintable": true, + "name": "Carbon Dollar", + "original_symbol": "CUSD", + "owner": "bnb1y9797dtklkm3haajsfnevm9ruuxs5fyf5rpj67", + "symbol": "CUSD-24B", + "total_supply": "9999999999.00000000" + }, + { + "mintable": false, + "name": "Konstellation Network", + "original_symbol": "DARC", + "owner": "bnb1gyhnhdns4vf63nfzfq7g25czj8swjgrz3rhah8", + "symbol": "DARC-24B", + "total_supply": "1000000000.00000000" + }, + { + "mintable": true, + "name": "DeepCloud", + "original_symbol": "DEEP", + "owner": "bnb1t0ws9gvnjm7j7qssk8te7m2dt5hmm8s3amqk2d", + "symbol": "DEEP-9D3", + "total_supply": "200000000.00000000" + }, + { + "mintable": false, + "name": "DeFi Token", + "original_symbol": "DEFI", + "owner": "bnb1q5xefr07503pqtfrl5sfyyhlghxwc80d4vpas2", + "symbol": "DEFI-FA5", + "total_supply": "2500000000.00000000" + }, + { + "mintable": true, + "name": "DOS Network Token", + "original_symbol": "DOS", + "owner": "bnb13gse9n7mvrjg5w2cymnt4nmxkgj200k9k2l2nh", + "symbol": "DOS-120", + "total_supply": "1000000000.00000000" + }, + { + "mintable": false, + "name": "DREP", + "original_symbol": "DREP", + "owner": "bnb1ez5s9v4rcgsmhwr4fkrnlv6zwsukjnh4y754kn", + "symbol": "DREP-7D2", + "total_supply": "10000000000.00000000" + }, + { + "mintable": true, + "name": "Dusk Network", + "original_symbol": "DUSK", + "owner": "bnb1dfls6c8y39l7qq4gj2479wkehg85pt5m07y94g", + "symbol": "DUSK-45E", + "total_supply": "50000000.00000000" + }, + { + "mintable": false, + "name": "eBoost", + "original_symbol": "EBST", + "owner": "bnb1pmdkvw6cquwylr46wcrl82xzmul0y2jpj5cwx7", + "symbol": "EBST-783", + "total_supply": "80838159.07000000" + }, + { + "mintable": true, + "name": "Ormeus Ecosystem", + "original_symbol": "ECO", + "owner": "bnb1tr49nv08k828n2lqfw0vrgvwj7xtep5kg8wr4c", + "symbol": "ECO-083", + "total_supply": "2200000000.00000000" + }, + { + "mintable": false, + "name": "Energy Eco Token", + "original_symbol": "EET", + "owner": "bnb1pt353m8ygvvgy4f2ud9xx85tl7fqewkrksh6r5", + "symbol": "EET-45C", + "total_supply": "600000000.00000000" + }, + { + "mintable": false, + "name": "Hut34 Entropy", + "original_symbol": "ENTRP", + "owner": "bnb1wu0hu9pelx3yvplysx0je7d93htcandpj86aev", + "symbol": "ENTRP-C8D", + "total_supply": "100000000.00000000" + }, + { + "mintable": true, + "name": "EOS BEP2", + "original_symbol": "EOS", + "owner": "bnb1la8alalwjzkchd67wza3r75lj5rm7m9e85ffqr", + "symbol": "EOS-CDD", + "total_supply": "500000.00000000" + }, + { + "mintable": true, + "name": "3X Short EOS Token", + "original_symbol": "EOSBEAR", + "owner": "bnb1ff4r0t7j8ll8lf3gm2ltdu3hjy4w690j7vvees", + "symbol": "EOSBEAR-721", + "total_supply": "32301.00000000" + }, + { + "mintable": true, + "name": "3X Long EOS Token", + "original_symbol": "EOSBULL", + "owner": "bnb1ff4r0t7j8ll8lf3gm2ltdu3hjy4w690j7vvees", + "symbol": "EOSBULL-F0D", + "total_supply": "456191.00000000" + }, + { + "mintable": false, + "name": "EQUAL", + "original_symbol": "EQL", + "owner": "bnb1uz0s54rzv022dh66l7atwk83wqcet9qstgg358", + "symbol": "EQL-586", + "total_supply": "675259060.00000000" + }, + { + "mintable": true, + "name": "Elrond", + "original_symbol": "ERD", + "owner": "bnb1m5uzzfxs7x05sl28gg96zyecn9jwgtkpyeftyn", + "symbol": "ERD-D06", + "total_supply": "14500000000.00000000" + }, + { + "mintable": true, + "name": "ETH BEP2", + "original_symbol": "ETH", + "owner": "bnb1yss2345dphss8c823dh2jzje2w8k8x4jguuxhf", + "symbol": "ETH-1C9", + "total_supply": "10000.00000000" + }, + { + "mintable": true, + "name": "3X Short Ethereum Token", + "original_symbol": "ETHBEAR", + "owner": "bnb1ff4r0t7j8ll8lf3gm2ltdu3hjy4w690j7vvees", + "symbol": "ETHBEAR-B2B", + "total_supply": "61821.00000000" + }, + { + "mintable": true, + "name": "3X Long Ethereum Token", + "original_symbol": "ETHBULL", + "owner": "bnb1ff4r0t7j8ll8lf3gm2ltdu3hjy4w690j7vvees", + "symbol": "ETHBULL-D33", + "total_supply": "33684.00000000" + }, + { + "mintable": true, + "name": "everiToken", + "original_symbol": "EVT", + "owner": "bnb1v3fl4kuwuhzf3g7ghscsq7uzmu5dw50waseptd", + "symbol": "EVT-49B", + "total_supply": "1000000000.00000000" + }, + { + "mintable": true, + "name": "The Force Token", + "original_symbol": "FOR", + "owner": "bnb1c46nhwdwm3u2mlfhx6t07fls25shnvktpr9w9m", + "symbol": "FOR-997", + "total_supply": "100000000.00000000" + }, + { + "mintable": false, + "name": "Ferrum Network Token", + "original_symbol": "FRM", + "owner": "bnb1um8ntkgwle8yrdk0yn5hwdf7hckjpyjjg29k2p", + "symbol": "FRM-DE7", + "total_supply": "164609374.50000000" + }, + { + "mintable": false, + "name": "Fusion", + "original_symbol": "FSN", + "owner": "bnb17mnutyduat9fe02r2dawp3kn4rnaqamp5kpg0c", + "symbol": "FSN-E14", + "total_supply": "57344000.00000000" + }, + { + "mintable": true, + "name": "Fantom", + "original_symbol": "FTM", + "owner": "bnb1f6sxnf3nhn9fcfwkuccrzvl2pgu3sq0m8pyjhw", + "symbol": "FTM-A64", + "total_supply": "952500000.00000000" + }, + { + "mintable": true, + "name": "FTX Token", + "original_symbol": "FTT", + "owner": "bnb1msxdh7e7smpg68gxxhs0p3fhuj9tzhrxa4c2x2", + "symbol": "FTT-F11", + "total_supply": "10000000.00000000" + }, + { + "mintable": true, + "name": "Givly Coin", + "original_symbol": "GIV", + "owner": "bnb13jzr6sqz72fl0edg2tpqp8tddyzvyt4su2490m", + "symbol": "GIV-94E", + "total_supply": "1000000000.00000000" + }, + { + "mintable": false, + "name": "GoWithMi", + "original_symbol": "GMAT", + "owner": "bnb1yltla9mnk8999ygmjjn3kwmmz2zs94a9v20sca", + "symbol": "GMAT-FC8", + "total_supply": "14900000000.00000000" + }, + { + "mintable": false, + "name": "Global Gaming", + "original_symbol": "GMNG", + "owner": "bnb1qe6zxqptfxw0kh38t8pg6c3qa527n2x2a87qvm", + "symbol": "GMNG-F3E", + "total_supply": "5000000000.00000000" + }, + { + "mintable": false, + "name": "GTEX", + "original_symbol": "GTEX", + "owner": "bnb1nksrzfl24he9xtvdvpypsl6r5jnh5x2uf9s82z", + "symbol": "GTEX-71B", + "total_supply": "4000000000.00000000" + }, + { + "mintable": false, + "name": "Gifto", + "original_symbol": "GTO", + "owner": "bnb1lvp8k3zenlfp2pl2nyaf428xjgh385m258gzvq", + "symbol": "GTO-908", + "total_supply": "1000000000.00000000" + }, + { + "mintable": true, + "name": "“Hermes", + "original_symbol": "HEC", + "owner": "bnb1dfyydqkmsv5m0rs0pa4uut2gwrcsahppktns2t", + "symbol": "HEC-1A9", + "total_supply": "100000000.00000000" + }, + { + "mintable": false, + "name": "Honest", + "original_symbol": "HNST", + "owner": "bnb1k9fv2hz0w3l9v9z4g9samg3gtc7nc2xgyqw5u0", + "symbol": "HNST-3C9", + "total_supply": "400000000.00000000" + }, + { + "mintable": true, + "name": "Hyperion Token", + "original_symbol": "HYN", + "owner": "bnb1q5cqecuy2g7syl8fssp9a7v2sjamtrzlr3pa0n", + "symbol": "HYN-F21", + "total_supply": "10000000000.00000000" + }, + { + "mintable": true, + "name": "Rupiah Token", + "original_symbol": "IDRTB", + "owner": "bnb1wc44duax6pygh23psx0u945skvs3eh7w59e4sp", + "symbol": "IDRTB-178", + "total_supply": "90000000000.00000000" + }, + { + "mintable": false, + "name": "IKU", + "original_symbol": "IKU", + "owner": "bnb1f52tc9l0qg337qtgu4n024ayllc78wxpc5xhvd", + "symbol": "IKU-416", + "total_supply": "300000000.00000000" + }, + { + "mintable": true, + "name": "IRIS Network", + "original_symbol": "IRIS", + "owner": "bnb1dcpm0jjj8el8g6ekr3mvjxa8kptgu4e5xzvqv8", + "symbol": "IRIS-D88", + "total_supply": "2000000000.00000000" + }, + { + "mintable": false, + "name": "JDXUCoin", + "original_symbol": "JDXU", + "owner": "bnb1dwcsg0t86g7935zpxc054n97styzgdtnu2kzg6", + "symbol": "JDXU-706", + "total_supply": "1000000000.00000000" + }, + { + "mintable": false, + "name": "Kambria Token", + "original_symbol": "KAT", + "owner": "bnb1l68n6equtr925lhnentyq54zfrzqyj45lg8uwj", + "symbol": "KAT-7BB", + "total_supply": "3700000000.00000000" + }, + { + "mintable": true, + "name": "Kava BEP2 Token", + "original_symbol": "KAVA", + "owner": "bnb1uyekdn62yur9zuctzqyd9ckasfvqttjz9c33me", + "symbol": "KAVA-10C", + "total_supply": "6071200.72181900" + }, + { + "mintable": false, + "name": "Sessia Kicks", + "original_symbol": "KICKS", + "owner": "bnb130tmwjd3fc79eh6f5ezl2326ur8rqpsxeeq30x", + "symbol": "KICKS-162", + "total_supply": "5000000.00000000" + }, + { + "mintable": true, + "name": "Lambda", + "original_symbol": "LAMB", + "owner": "bnb19vnwdjwthm9unxe9hxdxmgm6qw0d42d2lmcesw", + "symbol": "LAMB-46C", + "total_supply": "5000000.00000000" + }, + { + "mintable": false, + "name": "Lend-Borrow-Asset", + "original_symbol": "LBA", + "owner": "bnb1m8r74hr532lfwtaf5e88cxeakd36ut0ufpd4yu", + "symbol": "LBA-340", + "total_supply": "1000000000.00000000" + }, + { + "mintable": true, + "name": "LITION", + "original_symbol": "LIT", + "owner": "bnb1fhlxwqlwd7cm5fmurg0wmsaalshnp7lwu46nk9", + "symbol": "LIT-099", + "total_supply": "145061313.45061312" + }, + { + "mintable": true, + "name": "Loki", + "original_symbol": "LOKI", + "owner": "bnb1j5sft8wp7tktjwauy30x79f3tqa53fycmgxxs0", + "symbol": "LOKI-6A9", + "total_supply": "3000000.00000000" + }, + { + "mintable": true, + "name": "LTC BEP2", + "original_symbol": "LTC", + "owner": "bnb1cn4sqm79wqmr8rey923r34cp2wrtyhlr9easpg", + "symbol": "LTC-F07", + "total_supply": "18500.00000000" + }, + { + "mintable": false, + "name": "LTO Network", + "original_symbol": "LTO", + "owner": "bnb1ac6p45m00pv36y9mu48e5xr73fyxke3zv2rhmq", + "symbol": "LTO-BDF", + "total_supply": "500000000.00000000" + }, + { + "mintable": false, + "name": "Matic Token", + "original_symbol": "MATIC", + "owner": "bnb1a6nkf3g7c2z0jcrqhp8c9upcwmme0y49qx58nz", + "symbol": "MATIC-84A", + "total_supply": "10000000000.00000000" + }, + { + "mintable": false, + "name": "Moviebloc", + "original_symbol": "MBL", + "owner": "bnb17p8rc0z5vlysff2wc7xehff464dm0v7nhl27xq", + "symbol": "MBL-2D2", + "total_supply": "30000000000.00000000" + }, + { + "mintable": true, + "name": "Mcashchain", + "original_symbol": "MCASH", + "owner": "bnb1q420q7qpyv7tghfp6aac7vnjq74dhkeutdhqsg", + "symbol": "MCASH-869", + "total_supply": "200000000.00000000" + }, + { + "mintable": false, + "name": "Magic Cube Token", + "original_symbol": "MCC", + "owner": "bnb14nt79d6hzhjefkys2cgrc9nrzugdjwwtggfmu4", + "symbol": "MCC-33B", + "total_supply": "20000000000.00000000" + }, + { + "mintable": false, + "name": "MDAB", + "original_symbol": "MDAB", + "owner": "bnb1m3edd4q4nd3wxg9vm3xe8pnfnetu5yjmhtnrqz", + "symbol": "MDAB-D42", + "total_supply": "1000000000.00000000" + }, + { + "mintable": true, + "name": "MediBloc", + "original_symbol": "MEDB", + "owner": "bnb1za3ytyh55wprmn4ew8gat657lpjdzhafwrded3", + "symbol": "MEDB-87E", + "total_supply": "10000000000.00000000" + }, + { + "mintable": false, + "name": "MEET.ONE", + "original_symbol": "MEETONE", + "owner": "bnb1zquk6usn03xnnht6ws6p0h4ylgk8jkhch6c6ck", + "symbol": "MEETONE-031", + "total_supply": "1000000000.00000000" + }, + { + "mintable": false, + "name": "SyncFab Smart Manufacturing", + "original_symbol": "MFGB", + "owner": "bnb104qhlkx4fu6nvm32v4k7zzgtt4eqtyzvh9yq48", + "symbol": "MFGB-0A0", + "total_supply": "100000000.00000000" + }, + { + "mintable": false, + "name": "Mithril", + "original_symbol": "MITH", + "owner": "bnb15krsh6x2343qskf86cw0hazchl5pkfw53zllut", + "symbol": "MITH-C76", + "total_supply": "988855068.00409432" + }, + { + "mintable": false, + "name": "Morpheus Infrastructure Token", + "original_symbol": "MITX", + "owner": "bnb17e2n869fp6zvdyfaqkq3tgfmj8pskq20mdaz7e", + "symbol": "MITX-CAA", + "total_supply": "400000000.00000000" + }, + { + "mintable": false, + "name": "MultiVAC", + "original_symbol": "MTV", + "owner": "bnb18cjgqwpj2sxdxf7u84hgzh76cmqvthw7fgtr7z", + "symbol": "MTV-4C6", + "total_supply": "8000000000.00000000" + }, + { + "mintable": false, + "name": "Tixl", + "original_symbol": "MTXLT", + "owner": "bnb1pwcluc3a2lswrdd8v3uq43qrgfdl6kv2ahrz43", + "symbol": "MTXLT-286", + "total_supply": "900000.00000000" + }, + { + "mintable": true, + "name": "Mass Vehicle Ledger", + "original_symbol": "MVL", + "owner": "bnb1mqdkp0ujngm58sus3fh5x9c0j59madqxej9q75", + "symbol": "MVL-7B0", + "total_supply": "8000000000.00000000" + }, + { + "mintable": false, + "name": "Muzika", + "original_symbol": "MZK", + "owner": "bnb1dkqsj76yr6nlegs3433m3c59mm0j7vy72nn275", + "symbol": "MZK-2C7", + "total_supply": "1000000000.00000000" + }, + { + "mintable": false, + "name": "NEWTON", + "original_symbol": "NEW", + "owner": "bnb1ud4ak7pj5kg5kqddhx9yacdu6sf7sxhqdv30k0", + "symbol": "NEW-09E", + "total_supply": "90000000000.00000000" + }, + { + "mintable": true, + "name": "Nexo", + "original_symbol": "NEXO", + "owner": "bnb15ngukylwcleljegx32ykefqxw8jz42szar6vf5", + "symbol": "NEXO-A84", + "total_supply": "100000000.00000000" + }, + { + "mintable": false, + "name": "NODE", + "original_symbol": "NODE", + "owner": "bnb1xljnjk7msm5t5lwp4zv2ua80rrxzn2s2afce4j", + "symbol": "NODE-F3A", + "total_supply": "2000000000.00000000" + }, + { + "mintable": false, + "name": "NOIZ Token", + "original_symbol": "NOIZB", + "owner": "bnb1fa9xgszkn57zq0aulfgk5hct09yx5heepum3x7", + "symbol": "NOIZB-878", + "total_supply": "400000000.00000000" + }, + { + "mintable": true, + "name": "NOW Token", + "original_symbol": "NOW", + "owner": "bnb1nug8ls9f0et0t558m4chmm46mf85ehpq0u8gwv", + "symbol": "NOW-E68", + "total_supply": "99939495.70000000" + }, + { + "mintable": false, + "name": "NPX Binance token", + "original_symbol": "NPXB", + "owner": "bnb1wf7z3e8wvcu7gs74stmfmktsa2m5738rd0znae", + "symbol": "NPXB-1E8", + "total_supply": "29800000.00000000" + }, + { + "mintable": false, + "name": "Pundi X NEM", + "original_symbol": "NPXSXEM", + "owner": "bnb1wuww3cqy6wn5jdp6emv0eqwd5khlc3qyy0ympp", + "symbol": "NPXSXEM-89C", + "total_supply": "44815631324.40000000" + }, + { + "mintable": true, + "name": "Harmony.One", + "original_symbol": "ONE", + "owner": "bnb1a03uvqmnqzl85csnxnsx2xy28m76gkkht46f2l", + "symbol": "ONE-5F9", + "total_supply": "12600000000.00000000" + }, + { + "mintable": true, + "name": "ONTBEP2", + "original_symbol": "ONT", + "owner": "bnb1lxlxzanvg5ud02vjcvuxqrdystcehvtj6a05s2", + "symbol": "ONT-33D", + "total_supply": "1500000.00000000" + }, + { + "mintable": false, + "name": "OpenWeb Token", + "original_symbol": "OWTX", + "owner": "bnb1qnzqrxpek5dy6hh4fjywjv60x806yv2kpwt64y", + "symbol": "OWTX-A6B", + "total_supply": "1000000000.00000000" + }, + { + "mintable": true, + "name": "Pink Care Token", + "original_symbol": "PCAT", + "owner": "bnb1xx54pavpran2c36ugvnxnrfszwn36cryqfzufa", + "symbol": "PCAT-4BB", + "total_supply": "50000.00000000" + }, + { + "mintable": true, + "name": "Red Pulse Phoenix Binance", + "original_symbol": "PHB", + "owner": "bnb1vvvm62cezjy35xa46lghjs2jthzzdlpfyqg90a", + "symbol": "PHB-2DF", + "total_supply": "1598758851.80873855" + }, + { + "mintable": true, + "name": "PathHive Network", + "original_symbol": "PHV", + "owner": "bnb13nltf0vw66kw737dej6kc0fy85u3a38avr0xmf", + "symbol": "PHV-4A1", + "total_supply": "350000000.00000000" + }, + { + "mintable": false, + "name": "PCHAIN Token", + "original_symbol": "PIBNB", + "owner": "bnb1lvq8c3ul472aqrsknnvqumjszt2v60s0zagw6r", + "symbol": "PIBNB-43C", + "total_supply": "1071000000.00000000" + }, + { + "mintable": false, + "name": "Pledge Coin", + "original_symbol": "PLG", + "owner": "bnb1wjxhqa6ud4ucxayjqd9necfq0n954ztncsn7zn", + "symbol": "PLG-D8D", + "total_supply": "10000000000.00000000" + }, + { + "mintable": true, + "name": "PPE Token", + "original_symbol": "PPE", + "owner": "bnb1ry96fn3gl3wskha86lhgx8ckrgt3vgrnwq8quz", + "symbol": "PPE-942", + "total_supply": "200000.00000000" + }, + { + "mintable": false, + "name": "Pivot Token", + "original_symbol": "PVT", + "owner": "bnb1vgzzktw8j46hd87npsrukxhzxecq8knnt96tyf", + "symbol": "PVT-554", + "total_supply": "6283185307.00000000" + }, + { + "mintable": false, + "name": "paycentos", + "original_symbol": "PYN", + "owner": "bnb190acfwshh899eylweut9xarls2ma953rvkdlhf", + "symbol": "PYN-C37", + "total_supply": "100000000.00000000" + }, + { + "mintable": false, + "name": "QARK", + "original_symbol": "QARK", + "owner": "bnb1wnwrnmc6y9pl6ve9g7mahd4wkactaldyx3hsmu", + "symbol": "QARK-FCE", + "total_supply": "77000000.00000000" + }, + { + "mintable": true, + "name": "qiibeeToken", + "original_symbol": "QBX", + "owner": "bnb1eq8cytar7a3rer3ms7dpatd3cuhpfhaw3ts6tr", + "symbol": "QBX-38C", + "total_supply": "138039216.00000000" + }, + { + "mintable": false, + "name": "Raven Protocol", + "original_symbol": "RAVEN", + "owner": "bnb1vdjhrkgvt4y76ykyvrvh68pzqg3lvv0y5yfxyf", + "symbol": "RAVEN-F66", + "total_supply": "10000000000.00000000" + }, + { + "mintable": true, + "name": "Reporter News Agency Token", + "original_symbol": "RNA", + "owner": "bnb1m033d9a5fuf6r8wxqcguhwrnnk7sffcljzrc83", + "symbol": "RNA-23B", + "total_supply": "1000000000.00000000" + }, + { + "mintable": false, + "name": "Rasputin Party Mansion Phase2", + "original_symbol": "ROCP2", + "owner": "bnb16fyhf2hw8d5raxtympp48nzt2ezw6dqvfv5cd3", + "symbol": "ROCP2-F01", + "total_supply": "27000000.00000000" + }, + { + "mintable": false, + "name": "Rapids", + "original_symbol": "RPD", + "owner": "bnb1vtpy8dly2jfsn6v3t0qnyfxrex9sdy0entp5zs", + "symbol": "RPD-9E0", + "total_supply": "1500000000.00000000" + }, + { + "mintable": false, + "name": "Rune", + "original_symbol": "RUNE", + "owner": "bnb1e4q8whcufp6d72w8nwmpuhxd96r4n0fstegyuy", + "symbol": "RUNE-B1A", + "total_supply": "500000000.00000000" + }, + { + "mintable": false, + "name": "ShareToken", + "original_symbol": "SHR", + "owner": "bnb12c94hfu5vm77a9xkwfyl2ztgwgk503a06zl70e", + "symbol": "SHR-DB6", + "total_supply": "4396000000.00000000" + }, + { + "mintable": false, + "name": "Silverway", + "original_symbol": "SLV", + "owner": "bnb15nhdv2m09uwgnmmhx73dcguag7n363fdzdsg23", + "symbol": "SLV-986", + "total_supply": "1000000000.00000000" + }, + { + "mintable": true, + "name": "SPIN Protocol", + "original_symbol": "SPIN", + "owner": "bnb12n8fqjp8vh00s5u89paewv0wk8avr3nyvhsl4j", + "symbol": "SPIN-9DD", + "total_supply": "100000000.00000000" + }, + { + "mintable": true, + "name": "Spendcoin", + "original_symbol": "SPNDB", + "owner": "bnb105n32ugq55kzlyz3tuug35d3t0ul37lx9aksah", + "symbol": "SPNDB-916", + "total_supply": "2000000000.00000000" + }, + { + "mintable": false, + "name": "STIPS Token", + "original_symbol": "STIPS", + "owner": "bnb1tug8sgfcuh0rdyr697k5pnwz9expj7v5zr3qs5", + "symbol": "STIPS-14F", + "total_supply": "128806335.86000000" + }, + { + "mintable": false, + "name": "STIPS", + "original_symbol": "STIPS", + "owner": "bnb1tug8sgfcuh0rdyr697k5pnwz9expj7v5zr3qs5", + "symbol": "STIPS-770", + "total_supply": "243585434.00000000" + }, + { + "mintable": false, + "name": "Yin Lang Music IP Token", + "original_symbol": "STYL", + "owner": "bnb1j2dgknw9l4jny8crjdn6vcjsnu23ejxhchrumg", + "symbol": "STYL-65B", + "total_supply": "100000.00000000" + }, + { + "mintable": false, + "name": "Swingby Token", + "original_symbol": "SWINGBY", + "owner": "bnb1thagrtfude74x2j2wuknhj2savucy2tx0k58y9", + "symbol": "SWINGBY-888", + "total_supply": "1000000000.00000000" + }, + { + "mintable": false, + "name": "SWIPE Token", + "original_symbol": "SWIPE.B", + "owner": "bnb17pwyw202w7fssznnnv8f2gukau49uc4m4chz4m", + "symbol": "SWIPE.B-DC0", + "total_supply": "1500000000.00000000" + }, + { + "mintable": true, + "name": "TrueAUD", + "original_symbol": "TAUDB", + "owner": "bnb100dxzy02a6k7vysc5g4kk4fqamr7jhjg4m83l0", + "symbol": "TAUDB-888", + "total_supply": "90000000000.00000000" + }, + { + "mintable": true, + "name": "TBCC Coin", + "original_symbol": "TBC", + "owner": "bnb18hvknjyd73dx3ud02zp3z8v6du50vw7jxp06xt", + "symbol": "TBC-3A7", + "total_supply": "1000000000.00000000" + }, + { + "mintable": true, + "name": "TrueCAD", + "original_symbol": "TCADB", + "owner": "bnb100dxzy02a6k7vysc5g4kk4fqamr7jhjg4m83l0", + "symbol": "TCADB-888", + "total_supply": "90000000000.00000000" + }, + { + "mintable": false, + "name": "TrustED Token", + "original_symbol": "TED", + "owner": "bnb1zwg63xvmn02u8lv8v2sq0ypaejehhv3fceeu8a", + "symbol": "TED-A85", + "total_supply": "1720000000.00000000" + }, + { + "mintable": true, + "name": "TrueGBP", + "original_symbol": "TGBPB", + "owner": "bnb100dxzy02a6k7vysc5g4kk4fqamr7jhjg4m83l0", + "symbol": "TGBPB-888", + "total_supply": "90000000000.00000000" + }, + { + "mintable": true, + "name": "TrueHKD", + "original_symbol": "THKDB", + "owner": "bnb100dxzy02a6k7vysc5g4kk4fqamr7jhjg4m83l0", + "symbol": "THKDB-888", + "total_supply": "90000000000.00000000" + }, + { + "mintable": false, + "name": "Traxia 2", + "original_symbol": "TM2", + "owner": "bnb1pdeggk7lgch37ks7e3l5x3n5y245krl3zmrl8e", + "symbol": "TM2-0C4", + "total_supply": "1000000000.00000000" + }, + { + "mintable": true, + "name": "TomoChain", + "original_symbol": "TOMOB", + "owner": "bnb1jmgew0xvtkfjhnqsglm50tynxgps3xkx0xqffy", + "symbol": "TOMOB-4BC", + "total_supply": "5000000.00000000" + }, + { + "mintable": false, + "name": "TOP Network", + "original_symbol": "TOP", + "owner": "bnb1lqc7vjrag9sdaqeuv22jccr4rxtdxdtq6ve2w6", + "symbol": "TOP-491", + "total_supply": "20000000000.00000000" + }, + { + "mintable": false, + "name": "TROY", + "original_symbol": "TROY", + "owner": "bnb1scrark2sv6fpngyqxrryw9hw7y05euwntz45ae", + "symbol": "TROY-9B8", + "total_supply": "10000000000.00000000" + }, + { + "mintable": false, + "name": "TrueChain", + "original_symbol": "TRUE", + "owner": "bnb1m0llwxe0nwtw98m7knpz3g7r0c98mwn7tfwjcc", + "symbol": "TRUE-D84", + "total_supply": "100000000.00000000" + }, + { + "mintable": true, + "name": "TRXB", + "original_symbol": "TRXB", + "owner": "bnb1srm577fgsjg363vsqt8td4tat5arzfvkjchqgq", + "symbol": "TRXB-2E6", + "total_supply": "100000000.00000000" + }, + { + "mintable": true, + "name": "TrueUSD", + "original_symbol": "TUSDB", + "owner": "bnb100dxzy02a6k7vysc5g4kk4fqamr7jhjg4m83l0", + "symbol": "TUSDB-888", + "total_supply": "90000000000.00000000" + }, + { + "mintable": false, + "name": "Trust Wallet", + "original_symbol": "TWT", + "owner": "bnb1fkyxlq9kz5368ux29aeeztslclgf8e7tja345x", + "symbol": "TWT-8C2", + "total_supply": "90000000000.00000000" + }, + { + "mintable": true, + "name": "“Ubet", + "original_symbol": "UBETS", + "owner": "bnb1gcpctmgmf0am0ft85ttswy2epd9d6vvvxu2ly6", + "symbol": "UBETS-068", + "total_supply": "4000000000.00000000" + }, + { + "mintable": false, + "name": "Ultrain Coin", + "original_symbol": "UGAS", + "owner": "bnb1mj2nncwkmrw9pr6d0spkfmewz5eynz63w67f6e", + "symbol": "UGAS-B0C", + "total_supply": "1000000000.00000000" + }, + { + "mintable": false, + "name": "United Network Distribution", + "original_symbol": "UND", + "owner": "bnb1q5tr6ggvg0h38axzw2dc4606j3edg58qug9ajr", + "symbol": "UND-EBC", + "total_supply": "1000000000.00000000" + }, + { + "mintable": false, + "name": "UPX", + "original_symbol": "UPX", + "owner": "bnb1588jx9ylvfpfhdzy672lk3pulleq8md0a4wcjl", + "symbol": "UPX-F3E", + "total_supply": "10000000000.00000000" + }, + { + "mintable": true, + "name": "HonestCoin", + "original_symbol": "USDH", + "owner": "bnb1kel6x8nl37j2w6963c3gxnwzplvkwkphrkdmx9", + "symbol": "USDH-5B5", + "total_supply": "10000000000.00000000" + }, + { + "mintable": true, + "name": "USDS", + "original_symbol": "USDSB", + "owner": "bnb1nf5qjthrmxwxnfct4j0w4ct03fghthq24qt990", + "symbol": "USDSB-1AC", + "total_supply": "90000000000.00000000" + }, + { + "mintable": false, + "name": "UTU Coin", + "original_symbol": "UTU", + "owner": "bnb1r7whkqt8q2efn3c2ynsshrvxkg07cu8etuxkwr", + "symbol": "UTU-159", + "total_supply": "1000000000.00000000" + }, + { + "mintable": false, + "name": "UNetwork Token", + "original_symbol": "UUU", + "owner": "bnb17mkwwvzxaxa792rggvcmrpe6d7la4j9tjhdaql", + "symbol": "UUU-35C", + "total_supply": "10000000000.00000000" + }, + { + "mintable": true, + "name": "Vodi X", + "original_symbol": "VDX", + "owner": "bnb1pk6umuhxjcd3ggyztw7a7lfggwgyyx2w5h8j59", + "symbol": "VDX-A17", + "total_supply": "300000000.00000000" + }, + { + "mintable": false, + "name": "V-ID Token", + "original_symbol": "VIDT", + "owner": "bnb1k8870xayp29jug2lw9ujcqnjv6q6nu92enkg8v", + "symbol": "VIDT-F53", + "total_supply": "36800171.30000000" + }, + { + "mintable": true, + "name": "VNDC", + "original_symbol": "VNDC", + "owner": "bnb1zxt4xh4xxdnv5aagh77a4zp2kflg6a2c22hp73", + "symbol": "VNDC-DB9", + "total_supply": "2050000000.00000000" + }, + { + "mintable": false, + "name": "Vote", + "original_symbol": "VOTE", + "owner": "bnb1px34z7hw3hjtcf4ul664azxl4jwmkvgdnfep5e", + "symbol": "VOTE-FD4", + "total_supply": "1000000000.00000000" + }, + { + "mintable": false, + "name": "VERA", + "original_symbol": "VRAB", + "owner": "bnb1ucrwnsvjetufca3u6hnqskz0jfrwascwzg5tyf", + "symbol": "VRAB-B56", + "total_supply": "10839985784.00000000" + }, + { + "mintable": true, + "name": "Wagerr", + "original_symbol": "WGR", + "owner": "bnb194yuu322fqk69g2el8c874np5hjc8fykft3wv3", + "symbol": "WGR-D3D", + "total_supply": "205000000.00000000" + }, + { + "mintable": true, + "name": "WaykiChain Coin", + "original_symbol": "WICC", + "owner": "bnb1cw6kw5q0xcaxvpqravfewrcca9jgkdmd3zpc5n", + "symbol": "WICC-01D", + "total_supply": "210000000.00000000" + }, + { + "mintable": true, + "name": "WINB", + "original_symbol": "WINB", + "owner": "bnb1srm577fgsjg363vsqt8td4tat5arzfvkjchqgq", + "symbol": "WINB-41F", + "total_supply": "1000000000.00000000" + }, + { + "mintable": false, + "name": "MyWish", + "original_symbol": "WISH", + "owner": "bnb1tawge8u97slduhhtumm03l4xl4c46dwv5m9yzk", + "symbol": "WISH-2D5", + "total_supply": "9546650.62357825" + }, + { + "mintable": false, + "name": "WazirX Token", + "original_symbol": "WRX", + "owner": "bnb19cvhgyrxmkw30hlqs9c5lp966drjzyylytl74z", + "symbol": "WRX-ED1", + "total_supply": "1000000000.00000000" + }, + { + "mintable": false, + "name": "Eterbase Coin", + "original_symbol": "XBASE", + "owner": "bnb177v0mn59lmuxu90uph5mg065n9l4f3r4zqllvd", + "symbol": "XBASE-CD2", + "total_supply": "1000000000.00000000" + }, + { + "mintable": false, + "name": "XIO", + "original_symbol": "XIO", + "owner": "bnb1egwrlcwqkluqpujfwc5r2d27ggg7kv0lteyez9", + "symbol": "XIO-B05", + "total_supply": "100000000.00000000" + }, + { + "mintable": true, + "name": "Xeonbit Token", + "original_symbol": "XNS", + "owner": "bnb17az2n3ll3wjgf3gnn2chqxawzgrv9xv9vrkc79", + "symbol": "XNS-760", + "total_supply": "300000000.00000000" + }, + { + "mintable": true, + "name": "XRP BEP2", + "original_symbol": "XRP", + "owner": "bnb1x0vv5l6u5c7vpl7c947uxmm0gfstpdhg93gxpt", + "symbol": "XRP-BF2", + "total_supply": "10000000.00000000" + }, + { + "mintable": true, + "name": "3X Short XRP Token", + "original_symbol": "XRPBEAR", + "owner": "bnb1ff4r0t7j8ll8lf3gm2ltdu3hjy4w690j7vvees", + "symbol": "XRPBEAR-00B", + "total_supply": "1348.00000000" + }, + { + "mintable": true, + "name": "3X Long XRP Token", + "original_symbol": "XRPBULL", + "owner": "bnb1ff4r0t7j8ll8lf3gm2ltdu3hjy4w690j7vvees", + "symbol": "XRPBULL-E7C", + "total_supply": "121291.00000000" + }, + { + "mintable": true, + "name": "XTZ BEP2", + "original_symbol": "XTZ", + "owner": "bnb12twkcedchmx3xn09jcf28u7xrg0mqsyluf56g4", + "symbol": "XTZ-F7A", + "total_supply": "250000.00000000" + }, + { + "mintable": false, + "name": "XWG", + "original_symbol": "XWG", + "owner": "bnb10s02g69vhym56ke23nkacmuf9038e8rr7dm8e8", + "symbol": "XWG-478", + "total_supply": "10000000000.00000000" + }, + { + "mintable": false, + "name": "“YeeCo”", + "original_symbol": "YEE", + "owner": "bnb1ykzzc0zevzsade3urq4t27rfz98xgquphm8ucs", + "symbol": "YEE-EAE", + "total_supply": "10000000000.00000000" + }, + { + "mintable": false, + "name": "ZEBI", + "original_symbol": "ZEBI", + "owner": "bnb1gca96lw9zlr8fct47wznsae67pc5wjwsjzamaf", + "symbol": "ZEBI-84F", + "total_supply": "1000000000.00000000" + } +] diff --git a/mock/ext-api-data/binance-api_v1_txs__address_bnb1z35wusfv8twfele77vddclka9z84ugywug48gn_txAsset_BNB.json b/mock/ext-api-data/binance-api_v1_txs__address_bnb1z35wusfv8twfele77vddclka9z84ugywug48gn_txAsset_BNB.json new file mode 100644 index 000000000..e08c30bad --- /dev/null +++ b/mock/ext-api-data/binance-api_v1_txs__address_bnb1z35wusfv8twfele77vddclka9z84ugywug48gn_txAsset_BNB.json @@ -0,0 +1 @@ +{"tx":[{"txHash":"0CE23D9F143F7FAF192BB55F33C8FCBC1095D98410A750F63777987685E2C154","blockHeight":106690566,"txType":"TRANSFER","timeStamp":"2020-08-12T10:18:26.388Z","fromAddr":"bnb1jxfh2g85q3v0tdq56fnevx6xcxtcnhtsmcu64m","toAddr":"bnb1z35wusfv8twfele77vddclka9z84ugywug48gn","value":"6018.97200000","txAsset":"RUNE-B1A","txFee":"0.00037500","proposalId":null,"txAge":8026,"orderId":null,"code":0,"data":null,"confirmBlocks":0,"memo":"","source":0,"sequence":736321}],"total":1} diff --git a/mock/ext-api-data/bitcoin-api_v2_address_bc1qrfr44n2j4czd5c9txwlnw0yj2h82x9566fglqj__details_txs.json b/mock/ext-api-data/bitcoin-api_v2_address_bc1qrfr44n2j4czd5c9txwlnw0yj2h82x9566fglqj__details_txs.json new file mode 100644 index 000000000..c4811b317 --- /dev/null +++ b/mock/ext-api-data/bitcoin-api_v2_address_bc1qrfr44n2j4czd5c9txwlnw0yj2h82x9566fglqj__details_txs.json @@ -0,0 +1,700 @@ +{ + "page": 1, + "totalPages": 1, + "itemsOnPage": 1000, + "address": "bc1qrfr44n2j4czd5c9txwlnw0yj2h82x9566fglqj", + "balance": "16245", + "totalReceived": "92089", + "totalSent": "75844", + "unconfirmedBalance": "0", + "unconfirmedTxs": 0, + "txs": 13, + "transactions": [ + { + "txid": "48554ab85af888894d3f247088fdb8b7fff412612b54f0069f89dda3bd80f0ce", + "version": 1, + "vin": [ + { + "txid": "ffd5f12382137dfc62866694f77405ecb6d4cf2cc286ac66d192f7e842787c0f", + "sequence": 4294967293, + "n": 0, + "addresses": [ + "bc1qhddmnwdqwuvt6zl7auu976scg7rmtpx6amumsd" + ], + "isAddress": true, + "value": "3220" + } + ], + "vout": [ + { + "value": "1000", + "n": 0, + "hex": "00141a475acd52ae04da60ab33bf373c9255cea3169a", + "addresses": [ + "bc1qrfr44n2j4czd5c9txwlnw0yj2h82x9566fglqj" + ], + "isAddress": true + }, + { + "value": "1994", + "n": 1, + "hex": "0014bb5bb9b9a07718bd0bfeef385f6a184787b584da", + "addresses": [ + "bc1qhddmnwdqwuvt6zl7auu976scg7rmtpx6amumsd" + ], + "isAddress": true + } + ], + "blockHash": "000000000000000000005e0a9278dcf1a18390c78c27d5f47dc0777772b1e54b", + "blockHeight": 627865, + "confirmations": 2356, + "blockTime": 1587999059, + "value": "2994", + "valueIn": "3220", + "fees": "226", + "hex": "010000000001010f7c7842e8f792d166ac86c22ccfd4b6ec0574f794668662fc7d138223f1d5ff0000000000fdffffff02e8030000000000001600141a475acd52ae04da60ab33bf373c9255cea3169aca07000000000000160014bb5bb9b9a07718bd0bfeef385f6a184787b584da0247304402203285e50928e3d4f67093bb457fe51b60a9e1981868666d8f79bf272868484f1d02200e7093af7d2d7cb68bc0801587b619c2022f02084fac3902fe93e47977aed6c30121034df96f5dacf5e22fb8611e6863e48f6777c7e96064c81196e23dcefd35017d0e00000000" + }, + { + "txid": "36b1e721a25ea3ac2fcc09a92d4ff1e2ae4ed70d593e276806d9a9fd2a901132", + "version": 1, + "vin": [ + { + "txid": "c6a4c82d5c7a342796e7d81237ab399918d3205f791ebc40e63501cac28c32be", + "vout": 1, + "n": 0, + "addresses": [ + "bc1qrfr44n2j4czd5c9txwlnw0yj2h82x9566fglqj" + ], + "isAddress": true, + "value": "4829" + } + ], + "vout": [ + { + "value": "1000", + "n": 0, + "spent": true, + "hex": "a9141ba5187259ae22520f99ec3522d320279066aafd87", + "addresses": [ + "34DBwkzPz6yeqU1LoZLVzdCm91oeyxq37T" + ], + "isAddress": true + }, + { + "value": "2699", + "n": 1, + "hex": "00148f347b3ea1ce113b09e096125a3ad3310dd0a947", + "addresses": [ + "bc1q3u68k04pecgnkz0qjcf95wknxyxap2287gyzrg" + ], + "isAddress": true + } + ], + "blockHash": "0000000000000000000fccc2c78e235d6ea3da4013ea98c8376c7c41f7f71938", + "blockHeight": 624894, + "confirmations": 5327, + "blockTime": 1586299624, + "value": "3699", + "valueIn": "4829", + "fees": "1130", + "hex": "01000000000101be328cc2ca0135e640bc1e795f20d3189939ab3712d8e79627347a5c2dc8a4c601000000000000000002e80300000000000017a9141ba5187259ae22520f99ec3522d320279066aafd878b0a0000000000001600148f347b3ea1ce113b09e096125a3ad3310dd0a94702483045022100c251d7e2497b42d57ff00c92eeb8a6faa86a3d5d77a9d257b7e464400306fa5502204f532ab553ba711779cf1f93cab47c4f5e0f11dbc6017781c79b76caa6ea322b012102624729d04d58fa33eb3f7be9fe9c307c60aa1bad52f4ffbacc78ba3808faf62500000000" + }, + { + "txid": "8180545030fcfb7b14ee90acb01b606c5a68fe1d520bcf140bd0097108c2b7f4", + "version": 1, + "vin": [ + { + "txid": "270a6490cc806d99aa84bb8079b543d9d7a255fc59364890e7a4cb57970daef8", + "vout": 1, + "sequence": 4294967294, + "n": 0, + "addresses": [ + "bc1q3230a7cqt2drewuza8qff4c4gpt4muy9qyqknw" + ], + "isAddress": true, + "value": "1699" + } + ], + "vout": [ + { + "value": "375", + "n": 0, + "hex": "00141a475acd52ae04da60ab33bf373c9255cea3169a", + "addresses": [ + "bc1qrfr44n2j4czd5c9txwlnw0yj2h82x9566fglqj" + ], + "isAddress": true + }, + { + "value": "1098", + "n": 1, + "hex": "00141a475acd52ae04da60ab33bf373c9255cea3169a", + "addresses": [ + "bc1qrfr44n2j4czd5c9txwlnw0yj2h82x9566fglqj" + ], + "isAddress": true + } + ], + "blockHash": "00000000000000000006ff4c09a5e05c4a28dffe54beb7ef0c61f8dd940a951e", + "blockHeight": 622017, + "confirmations": 8204, + "blockTime": 1584485709, + "value": "1473", + "valueIn": "1699", + "fees": "226", + "hex": "01000000000101f8ae0d9757cba4e790483659fc55a2d7d943b57980bb84aa996d80cc90640a270100000000feffffff0277010000000000001600141a475acd52ae04da60ab33bf373c9255cea3169a4a040000000000001600141a475acd52ae04da60ab33bf373c9255cea3169a024730440220683d9c2b40958fd706623783017300ebbc9b73ce1db571963d9bb40679c3079c02207ee68976e225e1e98d20e66d4d8a498cddf3268d0d7b66827a2ed3ac4330f137012102b7f0cb54c2a6a4da3372fe17d7a07475f575777364633e89dacb39eb1fd5a09c00000000" + }, + { + "txid": "c6a4c82d5c7a342796e7d81237ab399918d3205f791ebc40e63501cac28c32be", + "version": 1, + "vin": [ + { + "txid": "d39d78838d5a3c870aa5acdc9e518945bd6ad86af093b38f85c714f790f28c76", + "vout": 1, + "n": 0, + "addresses": [ + "bc1qrfr44n2j4czd5c9txwlnw0yj2h82x9566fglqj" + ], + "isAddress": true, + "value": "6055" + } + ], + "vout": [ + { + "value": "1000", + "n": 0, + "hex": "00141a475acd52ae04da60ab33bf373c9255cea3169a", + "addresses": [ + "bc1qrfr44n2j4czd5c9txwlnw0yj2h82x9566fglqj" + ], + "isAddress": true + }, + { + "value": "4829", + "n": 1, + "spent": true, + "hex": "00141a475acd52ae04da60ab33bf373c9255cea3169a", + "addresses": [ + "bc1qrfr44n2j4czd5c9txwlnw0yj2h82x9566fglqj" + ], + "isAddress": true + } + ], + "blockHash": "00000000000000000006ff4c09a5e05c4a28dffe54beb7ef0c61f8dd940a951e", + "blockHeight": 622017, + "confirmations": 8204, + "blockTime": 1584485709, + "value": "5829", + "valueIn": "6055", + "fees": "226", + "hex": "01000000000101768cf290f714c7858fb393f06ad86abd4589519edcaca50a873c5a8d83789dd301000000000000000002e8030000000000001600141a475acd52ae04da60ab33bf373c9255cea3169add120000000000001600141a475acd52ae04da60ab33bf373c9255cea3169a02483045022100cb25ac0d9e69ddaaedd49e3a3f9efb218b38bf49c2abf44ff2266bfb941bd3b202206b32cc1337f9a6a176fabadd6aefdf5a95d479e5db856d4e3e8eee7fefc26773012102624729d04d58fa33eb3f7be9fe9c307c60aa1bad52f4ffbacc78ba3808faf62500000000" + }, + { + "txid": "d39d78838d5a3c870aa5acdc9e518945bd6ad86af093b38f85c714f790f28c76", + "version": 1, + "vin": [ + { + "txid": "c215e9c6f9533d584effc4d31d08736a0ef4f717b7d42563ebba053f5f3bc1d5", + "vout": 1, + "sequence": 4294967287, + "n": 0, + "addresses": [ + "bc1qrfr44n2j4czd5c9txwlnw0yj2h82x9566fglqj" + ], + "isAddress": true, + "value": "8185" + } + ], + "vout": [ + { + "value": "1000", + "n": 0, + "hex": "00141a475acd52ae04da60ab33bf373c9255cea3169a", + "addresses": [ + "bc1qrfr44n2j4czd5c9txwlnw0yj2h82x9566fglqj" + ], + "isAddress": true + }, + { + "value": "6055", + "n": 1, + "spent": true, + "hex": "00141a475acd52ae04da60ab33bf373c9255cea3169a", + "addresses": [ + "bc1qrfr44n2j4czd5c9txwlnw0yj2h82x9566fglqj" + ], + "isAddress": true + } + ], + "blockHash": "0000000000000000000ab8b2230f5b63d4d4be1a0aa6b9296cfc09e48c8e42e0", + "blockHeight": 619385, + "confirmations": 10836, + "blockTime": 1582902175, + "value": "7055", + "valueIn": "8185", + "fees": "1130", + "hex": "01000000000101d5c13b5f3f05baeb6325d4b717f7f40e6a73081dd3c4ff4e583d53f9c6e915c20100000000f7ffffff02e8030000000000001600141a475acd52ae04da60ab33bf373c9255cea3169aa7170000000000001600141a475acd52ae04da60ab33bf373c9255cea3169a024730440220158b0d8c5fb6cb9f60d0af05ce8b63abe934dca8eca380013bc7e8463420810f02207d7e6594586ec8196546e2520b6775c2e8659c8f266acb3b861e99f13cf1b380012102624729d04d58fa33eb3f7be9fe9c307c60aa1bad52f4ffbacc78ba3808faf62500000000" + }, + { + "txid": "c215e9c6f9533d584effc4d31d08736a0ef4f717b7d42563ebba053f5f3bc1d5", + "version": 1, + "vin": [ + { + "txid": "1fb8f63b044160a7f918b5db85fa7bed3415848bd733f5827d7ae10cf738b387", + "sequence": 4294967287, + "n": 0, + "addresses": [ + "bc1qrfr44n2j4czd5c9txwlnw0yj2h82x9566fglqj" + ], + "isAddress": true, + "value": "10315" + } + ], + "vout": [ + { + "value": "1000", + "n": 0, + "hex": "00141a475acd52ae04da60ab33bf373c9255cea3169a", + "addresses": [ + "bc1qrfr44n2j4czd5c9txwlnw0yj2h82x9566fglqj" + ], + "isAddress": true + }, + { + "value": "8185", + "n": 1, + "spent": true, + "hex": "00141a475acd52ae04da60ab33bf373c9255cea3169a", + "addresses": [ + "bc1qrfr44n2j4czd5c9txwlnw0yj2h82x9566fglqj" + ], + "isAddress": true + } + ], + "blockHash": "0000000000000000000fc5707f9351bdefada8c42267c9d63baf404268d65ca0", + "blockHeight": 619383, + "confirmations": 10838, + "blockTime": 1582901173, + "value": "9185", + "valueIn": "10315", + "fees": "1130", + "hex": "0100000000010187b338f70ce17a7d82f533d78b841534ed7bfa85dbb518f9a76041043bf6b81f0000000000f7ffffff02e8030000000000001600141a475acd52ae04da60ab33bf373c9255cea3169af91f0000000000001600141a475acd52ae04da60ab33bf373c9255cea3169a024830450221008e721f8e1ec8c22e2cec8fb2744d451cb11decabd0ed6b8080b5949f8c34ad3c022070815d97c02a3befae53dfceae504bd4495f034afba9e8e1e84595d07d933a60012102624729d04d58fa33eb3f7be9fe9c307c60aa1bad52f4ffbacc78ba3808faf62500000000" + }, + { + "txid": "1fb8f63b044160a7f918b5db85fa7bed3415848bd733f5827d7ae10cf738b387", + "version": 1, + "vin": [ + { + "txid": "3eb38e946261c8c7312f02cf72a72ac8d93ede94aa21520fbf06dd9b1f3f4392", + "vout": 1, + "n": 0, + "addresses": [ + "bc1qjar8852c43h73ud79xjluy2e7qce58peymsts8" + ], + "isAddress": true, + "value": "194390" + } + ], + "vout": [ + { + "value": "10315", + "n": 0, + "spent": true, + "hex": "00141a475acd52ae04da60ab33bf373c9255cea3169a", + "addresses": [ + "bc1qrfr44n2j4czd5c9txwlnw0yj2h82x9566fglqj" + ], + "isAddress": true + }, + { + "value": "179781", + "n": 1, + "spent": true, + "hex": "0014974673d158ac6fe8f1be29a5fe1159f0319a1c39", + "addresses": [ + "bc1qjar8852c43h73ud79xjluy2e7qce58peymsts8" + ], + "isAddress": true + } + ], + "blockHash": "000000000000000000099b3509cf7d55c3c1894f814ab45bdccb32aa2b5e3e46", + "blockHeight": 616239, + "confirmations": 13982, + "blockTime": 1580992887, + "value": "190096", + "valueIn": "194390", + "fees": "4294", + "hex": "0100000000010192433f1f9bdd06bf0f5221aa94de3ed9c82aa772cf022f31c7c86162948eb33e010000000000000000024b280000000000001600141a475acd52ae04da60ab33bf373c9255cea3169a45be020000000000160014974673d158ac6fe8f1be29a5fe1159f0319a1c3902483045022100a2cb51287dd8fd1e7eb9c48be73cba46ddf75287617c38f68618062c945ecbc802206f357933216b63a4530687223e60900c29d1d0869461d6707d7fa202a3c09d9301210289f9d29f5e11c87d2cdbc213d05b7f2aef0291b89b87e7a6f747461d2f75fd9a00000000" + }, + { + "txid": "35caac179d1a85f7c495d9a716d85bb02ed925170fc4716e8b04791acd487419", + "version": 1, + "vin": [ + { + "txid": "45cd3053d5393b2959646d023e1f2fa272d950903ed8b44502db88c9a04325fe", + "vout": 1, + "n": 0, + "addresses": [ + "bc1qs6q3tdsa09dtrwn0ml7d6ser4zdagja23rks6a" + ], + "isAddress": true, + "value": "2470973" + } + ], + "vout": [ + { + "value": "10772", + "n": 0, + "hex": "00141a475acd52ae04da60ab33bf373c9255cea3169a", + "addresses": [ + "bc1qrfr44n2j4czd5c9txwlnw0yj2h82x9566fglqj" + ], + "isAddress": true + }, + { + "value": "2455681", + "n": 1, + "spent": true, + "hex": "0014974673d158ac6fe8f1be29a5fe1159f0319a1c39", + "addresses": [ + "bc1qjar8852c43h73ud79xjluy2e7qce58peymsts8" + ], + "isAddress": true + } + ], + "blockHash": "0000000000000000000fcc2170ca9e17fd26747dd40bbf0388324cb872cd7a72", + "blockHeight": 615391, + "confirmations": 14830, + "blockTime": 1580495311, + "value": "2466453", + "valueIn": "2470973", + "fees": "4520", + "hex": "01000000000101fe2543a0c988db0245b4d83e9050d972a22f1f3e026d6459293b39d55330cd4501000000000000000002142a0000000000001600141a475acd52ae04da60ab33bf373c9255cea3169a8178250000000000160014974673d158ac6fe8f1be29a5fe1159f0319a1c390247304402207fd1c5f4e69845d67696f6dd3f9160fba8e66edb959742b3836f9d6b51b7ef3e022066940b74c238971d0f826648a2bc4806b88be512b6c2bbb08f95e32bbd1ad52f0121020201a3d7f2d6e0e63a7f73e6dfad80d47acaba509585fb40c3c0f54ed9e2478700000000" + }, + { + "txid": "f294afc59e9cf67b50485747c595fcced86d80a3b2783e1df7c0e6189e8a9ecc", + "version": 1, + "vin": [ + { + "txid": "cc6a3c78152df7f1d8976bd1eab82b225e71753f7e0070b387ad39d0da405eb2", + "vout": 1, + "sequence": 4294967289, + "n": 0, + "addresses": [ + "bc1q37qr7p2swx4d034htxwfps0sp7lsyztxw7wuqz" + ], + "isAddress": true, + "value": "3015" + }, + { + "txid": "f8a3a4d6a1c6e9d3450330aa69531fa5d4fbbc6756321e535e55019f276d4de1", + "sequence": 4294967294, + "n": 1, + "addresses": [ + "bc1q0gypp968wfjwjll7p5gfpfgtzu5sjezqgqn6df" + ], + "isAddress": true, + "value": "3644" + }, + { + "txid": "6cb59213f5465c2f8f25fad9c4196291135576c3431dbf1bafffd2d8ae11150b", + "vout": 1, + "sequence": 4294967286, + "n": 2, + "addresses": [ + "bc1qa64vqxuws7tystf6ssqrmc4qplx6ertk0t5g4n" + ], + "isAddress": true, + "value": "3976" + }, + { + "txid": "270a6490cc806d99aa84bb8079b543d9d7a255fc59364890e7a4cb57970daef8", + "sequence": 4294967290, + "n": 3, + "addresses": [ + "bc1q08ujs8m9v73hvkgf6ad09r35t8e403creglz2r" + ], + "isAddress": true, + "value": "4000" + }, + { + "txid": "5c532521086fea144904ecac58fc871fb6e153234434347740c5bd100f5d147a", + "sequence": 4294967292, + "n": 4, + "addresses": [ + "bc1q2lk3mssjhcpde3u0mnj76yqlrf579me7fjt3aq" + ], + "isAddress": true, + "value": "5000" + }, + { + "txid": "a456760ad81c5ee66919a64f45aa27c089023586da1866a37c062a2f255a492a", + "sequence": 4294967288, + "n": 5, + "addresses": [ + "bc1qt3wcz3w2rmhhuvr34zsf4f07yfnuctasu7cw6f" + ], + "isAddress": true, + "value": "5274" + }, + { + "txid": "9581050eaba641ff256ec5d9f9bacc22912a1348188e75998f528a3430f69c13", + "sequence": 4294967285, + "n": 6, + "addresses": [ + "bc1qrfr44n2j4czd5c9txwlnw0yj2h82x9566fglqj" + ], + "isAddress": true, + "value": "6460" + }, + { + "txid": "650dbe3adc3ab3a73a5ce16db694dcd39d755fdd235cb486a7f4168bfaa56e8c", + "sequence": 4294967291, + "n": 7, + "addresses": [ + "bc1q0cgg82lx3dd0u99lrfruwqavdprfkv8kg2gadt" + ], + "isAddress": true, + "value": "7000" + }, + { + "txid": "88873dc6a720a5652290bf50e526ad8677668039b8912f0f215a1d020ca707a4", + "sequence": 4294967293, + "n": 8, + "addresses": [ + "bc1q2xx9q6rvjfak33rqxe6xefgdeslzdtmgqd3xg5" + ], + "isAddress": true, + "value": "7032" + }, + { + "txid": "6cb59213f5465c2f8f25fad9c4196291135576c3431dbf1bafffd2d8ae11150b", + "sequence": 4294967287, + "n": 9, + "addresses": [ + "bc1qvcmvtu590a0tchdczqvdswcc6phz2r900u6wa9" + ], + "isAddress": true, + "value": "7769" + } + ], + "vout": [ + { + "value": "24214", + "n": 0, + "spent": true, + "hex": "00149fae2063427349e00e0dc0e7e0f31f783ba4aedb", + "addresses": [ + "bc1qn7hzqc6zwdy7qrsdcrn7pucl0qa6ftkmezxxvx" + ], + "isAddress": true + } + ], + "blockHash": "0000000000000000000a1c05a115781b118c7f0e004b5ea369546bed01b977f8", + "blockHeight": 594666, + "confirmations": 35555, + "blockTime": 1568371428, + "value": "24214", + "valueIn": "53170", + "fees": "28956", + "hex": "0100000000010ab25e40dad039ad87b370007e3f75715e222bb8ead16b97d8f1f72d15783c6acc0100000000f9ffffffe14d6d279f01555e531e325667bcfbd4a51f5369aa300345d3e9c6a1d6a4a3f80000000000feffffff0b1511aed8d2ffaf1bbf1d43c3765513916219c4d9fa258f2f5c46f51392b56c0100000000f6fffffff8ae0d9757cba4e790483659fc55a2d7d943b57980bb84aa996d80cc90640a270000000000faffffff7a145d0f10bdc540773434442353e1b61f87fc58acec044914ea6f082125535c0000000000fcffffff2a495a252f2a067ca36618da86350289c027aa454fa61969e65e1cd80a7656a40000000000f8ffffff139cf630348a528f99758e1848132a9122ccbaf9d9c56e25ff41a6ab0e0581950000000000f5ffffff8c6ea5fa8b16f4a786b45c23dd5f759dd3dc94b66de15c3aa7b33adc3abe0d650000000000fbffffffa407a70c021d5a210f2f91b83980667786ad26e550bf902265a520a7c63d87880000000000fdffffff0b1511aed8d2ffaf1bbf1d43c3765513916219c4d9fa258f2f5c46f51392b56c0000000000f7ffffff01965e0000000000001600149fae2063427349e00e0dc0e7e0f31f783ba4aedb02473044022061d7db5dbbf9f1f754cd0d0e907b63f5304c400c5acf651fe027ddcbec75d2af022029062c9c03f8763ddda455182a72a5caf55b9bc9995b269681eb72f98f953ce5012103972e1fd42a252e79be06cf3b92f91cad5a95d13109f5f6dd424d76dd315aa59302483045022100dcf1041cbdc17cf50829d7c844f1ce75beb4afcf2c5c3811455ae236fb97ee3502201b172291110dc4eebe42f269f0c1d87653bfdae36f906e77578d923a31197bb7012102cac4dcf0eccebb3b8e5b10a0e10c5e2350a7e2b2c2591f05b0f85511dab482fc02483045022100ae38ed7d6562f76bbd3a235126b4c6d699f79ae1c58c2d8a74df274b30ea36c80220154234175104f61c4784492025a2039ac2425dbf057fa5a6bda35ef6a5c8c92f0121029261525063905ff3ae58f5497c9e4d90c6d54cf68d46e01877a8119691cc399402483045022100ecb8f58190b1b9e899a6bc93ea72e2567bc0068ed611ba52c99fdc6ed99845520220515dc894804fe1ec4f72b521b3574f9e6fc7033a276f4ebe97a7fec36edc042701210261cf39d7fb7f3ab145f553b654164b86917a64078e558d47c30a7a99f3b7212d0247304402203ced2182ffe96eb616722a74fcfd9d764a8be6dc0cac0d6c92a434b4b05efacc0220473c2d8f827c77f112ef1c54f71775a830a96eae2e3312951cb8c5a2eafb972a0121028f029b2c38409e68873ebf07431ffa9e71f9a21104c6cddd694dab3607bcfdd6024730440220439a7dc1dc8c8e1e4cbf5faa8cc3fbfee7dd1f0cb7fe5bd6b92affb5fc36c72602200683851cf073f99714cb261b4303a9b20d7f90ea34ecbbbca941a92e9bf0ad7a01210308c0793b4f8fa2c3c98047003d52b21dcce8be18bb99d0f5576cd60504ac544c024830450221009350786cccc44be8386de5f3742467577264cd0e64972be0932cdcdf9da95c3402206e6b594cea10c829ca84591a32844e8b20db273720f750ee7e0476f5d3ab507f012102624729d04d58fa33eb3f7be9fe9c307c60aa1bad52f4ffbacc78ba3808faf6250247304402205bd49cb94b76d43c77b8d3cd737b5cba931b6c1a788456a1e4c15d3506a5c666022011af4e58f9aba52856df9a6a3b6ee5e8b2e0471801da126d1c06a88fcef6eff2012102bc7a575c577e7a5d1abae2d2755b07e027008b8f15ebf2f43db23a4d49c49bf802473044022003f9353abc8190b0eeb5919e89fa24e365ef53c5f324a5d27a03d2e0f676737502206504198edc4ceeb4303b64d2eef7080c43a8fdad4d4e92382ad1f12930ad563f0121033910ba10b8cb78b3fce0ce1a3810869a25151bd162f1b0d20d54bca5c5e8ceb8024830450221008571e0c9314b2fd6689efc895b34f4c2d127e47c6d73fa9a0a1cebf29088030602205eac86149055d2ade3114cc360c784a9f8be273f04b23668481f31d9e0e2660b01210271b8cf7b1845bb4615c40d9049ecac0ef06e86e9806640743ee1a4dd31f96dd300000000" + }, + { + "txid": "9581050eaba641ff256ec5d9f9bacc22912a1348188e75998f528a3430f69c13", + "version": 1, + "vin": [ + { + "txid": "35834d8661b4843a2ba211b436fb7c4286f1128a17a15b09fbb8383b08c88fa3", + "vout": 1, + "sequence": 4294967284, + "n": 0, + "addresses": [ + "bc1q3gnextg4u9lm9rcctnx8jxdmpdz0wde6hlgtnf" + ], + "isAddress": true, + "value": "9194" + } + ], + "vout": [ + { + "value": "6460", + "n": 0, + "spent": true, + "hex": "00141a475acd52ae04da60ab33bf373c9255cea3169a", + "addresses": [ + "bc1qrfr44n2j4czd5c9txwlnw0yj2h82x9566fglqj" + ], + "isAddress": true + }, + { + "value": "2508", + "n": 1, + "spent": true, + "hex": "00141e20cc5c2865017212ce488e765a598d9362ec8c", + "addresses": [ + "bc1qrcsvchpgv5qhyykwfz88vkje3kfk9myv4tpxqz" + ], + "isAddress": true + } + ], + "blockHash": "0000000000000000000789219c989d256be1405088da839989d7ef9eb3b0bfa3", + "blockHeight": 594062, + "confirmations": 36159, + "blockTime": 1568068608, + "value": "8968", + "valueIn": "9194", + "fees": "226", + "hex": "01000000000101a38fc8083b38b8fb095ba1178a12f186427cfb36b411a22b3a84b461864d83350100000000f4ffffff023c190000000000001600141a475acd52ae04da60ab33bf373c9255cea3169acc090000000000001600141e20cc5c2865017212ce488e765a598d9362ec8c02483045022100ef9d266fa275b8bccd3aeb5613c853644c73862e4a58f956ccada4804e34f44c02203a4ccf9562b5dc0fb4f6519c4b54d3c2e0b8da6965ca9356bae06285441e34c701210221a110c08c9ba07f547bcad9b9860b804fe1115490a81478b2bd0fe52d90118d00000000" + }, + { + "txid": "a696d7eeffe8cb6469182ed02aa15cb2ca2720c870bd7074cb1fe688c2bda13a", + "version": 1, + "vin": [ + { + "txid": "e6e04f7537399ef74be5522168746ede370f6ffceb44a0fb490fa52462de5e64", + "sequence": 4294967295, + "n": 0, + "addresses": [ + "bc1qrfr44n2j4czd5c9txwlnw0yj2h82x9566fglqj" + ], + "isAddress": true, + "value": "10000" + }, + { + "txid": "2d0cbc42a2724f3b315e196e6b31ab2188d02e7aaa774e5bb77a1e7c9e70e9fb", + "sequence": 4294967295, + "n": 1, + "addresses": [ + "bc1qrfr44n2j4czd5c9txwlnw0yj2h82x9566fglqj" + ], + "isAddress": true, + "value": "30000" + }, + { + "txid": "274a5dafacd7290d5b17cafe6e5c4241eaba208f454649b183cf4161a141e56f", + "sequence": 4294967295, + "n": 2, + "addresses": [ + "bc1qhn03cww757mnnlpkdvvfkaydxqygm86nvkm92h" + ], + "isAddress": true, + "value": "47433" + } + ], + "vout": [ + { + "value": "78649", + "n": 0, + "spent": true, + "hex": "00147bef09cdf93be69ab9d6c32d37691972592dabdd", + "addresses": [ + "bc1q00hsnn0e80nf4wwkcvknw6gewfvjm27aadnngl" + ], + "isAddress": true + } + ], + "blockHash": "00000000000000000009636519364378c1db859d41f20f476bca69702360a1fe", + "blockHeight": 549442, + "confirmations": 80779, + "blockTime": 1541806207, + "value": "78649", + "valueIn": "87433", + "fees": "8784", + "hex": "01000000000103645ede6224a50f49fba044ebfc6f0f37de6e74682152e54bf79e3937754fe0e60000000000fffffffffbe9709e7c1e7ab75b4e77aa7a2ed08821ab316b6e195e313b4f72a242bc0c2d0000000000ffffffff6fe541a16141cf83b14946458f20baea41425c6efeca175b0d29d7acaf5d4a270000000000ffffffff0139330100000000001600147bef09cdf93be69ab9d6c32d37691972592dabdd02473044022043e5606e519fa1ce40b0681c16431221f50385577afb94c464b0e9d6c1d7396b0220584db57b6beb051f574e50ad1517a744aceccb987caec202a144d6a21158e4c9012102624729d04d58fa33eb3f7be9fe9c307c60aa1bad52f4ffbacc78ba3808faf625024830450221009ed7c4fa473f673daed2f593af66fcf00f5ccd5de65e5d9a099ed01dff9fa30b022021a6d12c8098e94284cb9c65ca773facc0d4847ae7dcbc33b4aecc9eb0248e5a012102624729d04d58fa33eb3f7be9fe9c307c60aa1bad52f4ffbacc78ba3808faf6250247304402205f5f0499cb74b68284276c78930856f50aef1abeb3d6bdc5ab7868cdc8bdc9b20220266b52935959c5d9d039f92d5cc6f1cbf88d5fa8c901bdbc33e8f73b9b1ef7be01210250cf3a4de6e4f2aae2c1aba4ea8e3ce32e3f6135e5809b8224fbd112fbe88a5b00000000" + }, + { + "txid": "2d0cbc42a2724f3b315e196e6b31ab2188d02e7aaa774e5bb77a1e7c9e70e9fb", + "version": 1, + "vin": [ + { + "txid": "40c5c15eb495b674fefa2f4be74e155ad0b39de4e4189ee10c1322e8013fdfd9", + "sequence": 4294967295, + "n": 0, + "addresses": [ + "18kdgiYf3iMkB12hSp8Vz2u9RAv4342xFd" + ], + "isAddress": true, + "value": "50447", + "hex": "47304402201d17cd9abecee131ddbbdf6c7f7ef13709fdab9c3305a2a05121009821ca4cd10220366192ba41a808f76508abb923aa0914b59dc142ef7fb587e86efd4c13c6a710012103078ee784ae3d00d202ddfcf560137440071a258ee0d5cf5e4e54f91821eed447" + } + ], + "vout": [ + { + "value": "30000", + "n": 0, + "spent": true, + "hex": "00141a475acd52ae04da60ab33bf373c9255cea3169a", + "addresses": [ + "bc1qrfr44n2j4czd5c9txwlnw0yj2h82x9566fglqj" + ], + "isAddress": true + }, + { + "value": "19047", + "n": 1, + "spent": true, + "hex": "76a9140a8992dfaa275cbca952ec529427cfe90ccf52cb88ac", + "addresses": [ + "1xiZi5nSPtTfKczArfkqPQfhidt1CHqMu" + ], + "isAddress": true + } + ], + "blockHash": "0000000000000000001bd897b449e61933380ea70285a92027c8d9d801e0f3e0", + "blockHeight": 549191, + "confirmations": 81030, + "blockTime": 1541630955, + "value": "49047", + "valueIn": "50447", + "fees": "1400", + "hex": "0100000001d9df3f01e822130ce19e18e4e49db3d05a154ee74b2ffafe74b695b45ec1c540000000006a47304402201d17cd9abecee131ddbbdf6c7f7ef13709fdab9c3305a2a05121009821ca4cd10220366192ba41a808f76508abb923aa0914b59dc142ef7fb587e86efd4c13c6a710012103078ee784ae3d00d202ddfcf560137440071a258ee0d5cf5e4e54f91821eed447ffffffff0230750000000000001600141a475acd52ae04da60ab33bf373c9255cea3169a674a0000000000001976a9140a8992dfaa275cbca952ec529427cfe90ccf52cb88ac00000000" + }, + { + "txid": "e6e04f7537399ef74be5522168746ede370f6ffceb44a0fb490fa52462de5e64", + "version": 1, + "vin": [ + { + "txid": "b9a34283e300080e7db25153c7fd22514eda0a0af70acde096a1da9ccc7d2d7c", + "vout": 1, + "sequence": 4294967295, + "n": 0, + "addresses": [ + "bc1quzz2sfdghyhu5g9plm2uz9damh6n5k2dr434q8" + ], + "isAddress": true, + "value": "50000" + } + ], + "vout": [ + { + "value": "10000", + "n": 0, + "spent": true, + "hex": "00141a475acd52ae04da60ab33bf373c9255cea3169a", + "addresses": [ + "bc1qrfr44n2j4czd5c9txwlnw0yj2h82x9566fglqj" + ], + "isAddress": true + }, + { + "value": "36384", + "n": 1, + "spent": true, + "hex": "0014a059d7120d076e2ac132281c21b070b6ec7261a0", + "addresses": [ + "bc1q5pvawysdqahz4sfj9qwzrvrskmk8ycdqmu35w5" + ], + "isAddress": true + } + ], + "blockHash": "00000000000000000000f2f0f5e24ce5fda01fd2a5d7545a1cd909850951f96f", + "blockHeight": 549183, + "confirmations": 81038, + "blockTime": 1541624396, + "value": "46384", + "valueIn": "50000", + "fees": "3616", + "hex": "010000000001017c2d7dcc9cdaa196e0cd0af70a0ada4e5122fdc75351b27d0e0800e38342a3b90100000000ffffffff0210270000000000001600141a475acd52ae04da60ab33bf373c9255cea3169a208e000000000000160014a059d7120d076e2ac132281c21b070b6ec7261a0024730440220743b4f5c217b3429101b6213d4aa92922e2960977b3d5e633bb016dada6273a302204e7d588d787845c51bf97cc0a52abaa663a5fb609c275bafbb2cfcd607b1829d01210203389a9e645d4e53a38e449b196b60dfe14ce6e57f814a150d60e912962653bf00000000" + } + ] +} diff --git a/mock/ext-api-data/bitcoin-api_v2_xpub_zpub6ruK9k6YGm8BRHWvTiQcrEPnFkuRDJhR7mPYzV2LDvjpLa5CuGgrhCYVZjMGcLcFqv9b2WvsFtY2Gb3xq8NVq8qhk9veozrA2W9QaWtihrC__details_txs.json b/mock/ext-api-data/bitcoin-api_v2_xpub_zpub6ruK9k6YGm8BRHWvTiQcrEPnFkuRDJhR7mPYzV2LDvjpLa5CuGgrhCYVZjMGcLcFqv9b2WvsFtY2Gb3xq8NVq8qhk9veozrA2W9QaWtihrC__details_txs.json new file mode 100644 index 000000000..bdbfb7803 --- /dev/null +++ b/mock/ext-api-data/bitcoin-api_v2_xpub_zpub6ruK9k6YGm8BRHWvTiQcrEPnFkuRDJhR7mPYzV2LDvjpLa5CuGgrhCYVZjMGcLcFqv9b2WvsFtY2Gb3xq8NVq8qhk9veozrA2W9QaWtihrC__details_txs.json @@ -0,0 +1 @@ +{"page":1,"totalPages":10,"itemsOnPage":10,"address":"zpub6ruK9k6YGm8BRHWvTiQcrEPnFkuRDJhR7mPYzV2LDvjpLa5CuGgrhCYVZjMGcLcFqv9b2WvsFtY2Gb3xq8NVq8qhk9veozrA2W9QaWtihrC","balance":"35963","totalReceived":"4222507","totalSent":"4186544","unconfirmedBalance":"0","unconfirmedTxs":0,"txs":94,"transactions":[{"txid":"48554ab85af888894d3f247088fdb8b7fff412612b54f0069f89dda3bd80f0ce","version":1,"vin":[{"txid":"ffd5f12382137dfc62866694f77405ecb6d4cf2cc286ac66d192f7e842787c0f","sequence":4294967293,"n":0,"addresses":["bc1qhddmnwdqwuvt6zl7auu976scg7rmtpx6amumsd"],"isAddress":true,"value":"3220"}],"vout":[{"value":"1000","n":0,"hex":"00141a475acd52ae04da60ab33bf373c9255cea3169a","addresses":["bc1qrfr44n2j4czd5c9txwlnw0yj2h82x9566fglqj"],"isAddress":true},{"value":"1994","n":1,"hex":"0014bb5bb9b9a07718bd0bfeef385f6a184787b584da","addresses":["bc1qhddmnwdqwuvt6zl7auu976scg7rmtpx6amumsd"],"isAddress":true}],"blockHash":"000000000000000000005e0a9278dcf1a18390c78c27d5f47dc0777772b1e54b","blockHeight":627865,"confirmations":3322,"blockTime":1587999059,"value":"2994","valueIn":"3220","fees":"226","hex":"010000000001010f7c7842e8f792d166ac86c22ccfd4b6ec0574f794668662fc7d138223f1d5ff0000000000fdffffff02e8030000000000001600141a475acd52ae04da60ab33bf373c9255cea3169aca07000000000000160014bb5bb9b9a07718bd0bfeef385f6a184787b584da0247304402203285e50928e3d4f67093bb457fe51b60a9e1981868666d8f79bf272868484f1d02200e7093af7d2d7cb68bc0801587b619c2022f02084fac3902fe93e47977aed6c30121034df96f5dacf5e22fb8611e6863e48f6777c7e96064c81196e23dcefd35017d0e00000000"},{"txid":"36b1e721a25ea3ac2fcc09a92d4ff1e2ae4ed70d593e276806d9a9fd2a901132","version":1,"vin":[{"txid":"c6a4c82d5c7a342796e7d81237ab399918d3205f791ebc40e63501cac28c32be","vout":1,"n":0,"addresses":["bc1qrfr44n2j4czd5c9txwlnw0yj2h82x9566fglqj"],"isAddress":true,"value":"4829"}],"vout":[{"value":"1000","n":0,"spent":true,"hex":"a9141ba5187259ae22520f99ec3522d320279066aafd87","addresses":["34DBwkzPz6yeqU1LoZLVzdCm91oeyxq37T"],"isAddress":true},{"value":"2699","n":1,"hex":"00148f347b3ea1ce113b09e096125a3ad3310dd0a947","addresses":["bc1q3u68k04pecgnkz0qjcf95wknxyxap2287gyzrg"],"isAddress":true}],"blockHash":"0000000000000000000fccc2c78e235d6ea3da4013ea98c8376c7c41f7f71938","blockHeight":624894,"confirmations":6293,"blockTime":1586299624,"value":"3699","valueIn":"4829","fees":"1130","hex":"01000000000101be328cc2ca0135e640bc1e795f20d3189939ab3712d8e79627347a5c2dc8a4c601000000000000000002e80300000000000017a9141ba5187259ae22520f99ec3522d320279066aafd878b0a0000000000001600148f347b3ea1ce113b09e096125a3ad3310dd0a94702483045022100c251d7e2497b42d57ff00c92eeb8a6faa86a3d5d77a9d257b7e464400306fa5502204f532ab553ba711779cf1f93cab47c4f5e0f11dbc6017781c79b76caa6ea322b012102624729d04d58fa33eb3f7be9fe9c307c60aa1bad52f4ffbacc78ba3808faf62500000000"},{"txid":"c6a4c82d5c7a342796e7d81237ab399918d3205f791ebc40e63501cac28c32be","version":1,"vin":[{"txid":"d39d78838d5a3c870aa5acdc9e518945bd6ad86af093b38f85c714f790f28c76","vout":1,"n":0,"addresses":["bc1qrfr44n2j4czd5c9txwlnw0yj2h82x9566fglqj"],"isAddress":true,"value":"6055"}],"vout":[{"value":"1000","n":0,"hex":"00141a475acd52ae04da60ab33bf373c9255cea3169a","addresses":["bc1qrfr44n2j4czd5c9txwlnw0yj2h82x9566fglqj"],"isAddress":true},{"value":"4829","n":1,"spent":true,"hex":"00141a475acd52ae04da60ab33bf373c9255cea3169a","addresses":["bc1qrfr44n2j4czd5c9txwlnw0yj2h82x9566fglqj"],"isAddress":true}],"blockHash":"00000000000000000006ff4c09a5e05c4a28dffe54beb7ef0c61f8dd940a951e","blockHeight":622017,"confirmations":9170,"blockTime":1584485709,"value":"5829","valueIn":"6055","fees":"226","hex":"01000000000101768cf290f714c7858fb393f06ad86abd4589519edcaca50a873c5a8d83789dd301000000000000000002e8030000000000001600141a475acd52ae04da60ab33bf373c9255cea3169add120000000000001600141a475acd52ae04da60ab33bf373c9255cea3169a02483045022100cb25ac0d9e69ddaaedd49e3a3f9efb218b38bf49c2abf44ff2266bfb941bd3b202206b32cc1337f9a6a176fabadd6aefdf5a95d479e5db856d4e3e8eee7fefc26773012102624729d04d58fa33eb3f7be9fe9c307c60aa1bad52f4ffbacc78ba3808faf62500000000"},{"txid":"8180545030fcfb7b14ee90acb01b606c5a68fe1d520bcf140bd0097108c2b7f4","version":1,"vin":[{"txid":"270a6490cc806d99aa84bb8079b543d9d7a255fc59364890e7a4cb57970daef8","vout":1,"sequence":4294967294,"n":0,"addresses":["bc1q3230a7cqt2drewuza8qff4c4gpt4muy9qyqknw"],"isAddress":true,"value":"1699"}],"vout":[{"value":"375","n":0,"hex":"00141a475acd52ae04da60ab33bf373c9255cea3169a","addresses":["bc1qrfr44n2j4czd5c9txwlnw0yj2h82x9566fglqj"],"isAddress":true},{"value":"1098","n":1,"hex":"00141a475acd52ae04da60ab33bf373c9255cea3169a","addresses":["bc1qrfr44n2j4czd5c9txwlnw0yj2h82x9566fglqj"],"isAddress":true}],"blockHash":"00000000000000000006ff4c09a5e05c4a28dffe54beb7ef0c61f8dd940a951e","blockHeight":622017,"confirmations":9170,"blockTime":1584485709,"value":"1473","valueIn":"1699","fees":"226","hex":"01000000000101f8ae0d9757cba4e790483659fc55a2d7d943b57980bb84aa996d80cc90640a270100000000feffffff0277010000000000001600141a475acd52ae04da60ab33bf373c9255cea3169a4a040000000000001600141a475acd52ae04da60ab33bf373c9255cea3169a024730440220683d9c2b40958fd706623783017300ebbc9b73ce1db571963d9bb40679c3079c02207ee68976e225e1e98d20e66d4d8a498cddf3268d0d7b66827a2ed3ac4330f137012102b7f0cb54c2a6a4da3372fe17d7a07475f575777364633e89dacb39eb1fd5a09c00000000"},{"txid":"d39d78838d5a3c870aa5acdc9e518945bd6ad86af093b38f85c714f790f28c76","version":1,"vin":[{"txid":"c215e9c6f9533d584effc4d31d08736a0ef4f717b7d42563ebba053f5f3bc1d5","vout":1,"sequence":4294967287,"n":0,"addresses":["bc1qrfr44n2j4czd5c9txwlnw0yj2h82x9566fglqj"],"isAddress":true,"value":"8185"}],"vout":[{"value":"1000","n":0,"hex":"00141a475acd52ae04da60ab33bf373c9255cea3169a","addresses":["bc1qrfr44n2j4czd5c9txwlnw0yj2h82x9566fglqj"],"isAddress":true},{"value":"6055","n":1,"spent":true,"hex":"00141a475acd52ae04da60ab33bf373c9255cea3169a","addresses":["bc1qrfr44n2j4czd5c9txwlnw0yj2h82x9566fglqj"],"isAddress":true}],"blockHash":"0000000000000000000ab8b2230f5b63d4d4be1a0aa6b9296cfc09e48c8e42e0","blockHeight":619385,"confirmations":11802,"blockTime":1582902175,"value":"7055","valueIn":"8185","fees":"1130","hex":"01000000000101d5c13b5f3f05baeb6325d4b717f7f40e6a73081dd3c4ff4e583d53f9c6e915c20100000000f7ffffff02e8030000000000001600141a475acd52ae04da60ab33bf373c9255cea3169aa7170000000000001600141a475acd52ae04da60ab33bf373c9255cea3169a024730440220158b0d8c5fb6cb9f60d0af05ce8b63abe934dca8eca380013bc7e8463420810f02207d7e6594586ec8196546e2520b6775c2e8659c8f266acb3b861e99f13cf1b380012102624729d04d58fa33eb3f7be9fe9c307c60aa1bad52f4ffbacc78ba3808faf62500000000"},{"txid":"c215e9c6f9533d584effc4d31d08736a0ef4f717b7d42563ebba053f5f3bc1d5","version":1,"vin":[{"txid":"1fb8f63b044160a7f918b5db85fa7bed3415848bd733f5827d7ae10cf738b387","sequence":4294967287,"n":0,"addresses":["bc1qrfr44n2j4czd5c9txwlnw0yj2h82x9566fglqj"],"isAddress":true,"value":"10315"}],"vout":[{"value":"1000","n":0,"hex":"00141a475acd52ae04da60ab33bf373c9255cea3169a","addresses":["bc1qrfr44n2j4czd5c9txwlnw0yj2h82x9566fglqj"],"isAddress":true},{"value":"8185","n":1,"spent":true,"hex":"00141a475acd52ae04da60ab33bf373c9255cea3169a","addresses":["bc1qrfr44n2j4czd5c9txwlnw0yj2h82x9566fglqj"],"isAddress":true}],"blockHash":"0000000000000000000fc5707f9351bdefada8c42267c9d63baf404268d65ca0","blockHeight":619383,"confirmations":11804,"blockTime":1582901173,"value":"9185","valueIn":"10315","fees":"1130","hex":"0100000000010187b338f70ce17a7d82f533d78b841534ed7bfa85dbb518f9a76041043bf6b81f0000000000f7ffffff02e8030000000000001600141a475acd52ae04da60ab33bf373c9255cea3169af91f0000000000001600141a475acd52ae04da60ab33bf373c9255cea3169a024830450221008e721f8e1ec8c22e2cec8fb2744d451cb11decabd0ed6b8080b5949f8c34ad3c022070815d97c02a3befae53dfceae504bd4495f034afba9e8e1e84595d07d933a60012102624729d04d58fa33eb3f7be9fe9c307c60aa1bad52f4ffbacc78ba3808faf62500000000"},{"txid":"1fb8f63b044160a7f918b5db85fa7bed3415848bd733f5827d7ae10cf738b387","version":1,"vin":[{"txid":"3eb38e946261c8c7312f02cf72a72ac8d93ede94aa21520fbf06dd9b1f3f4392","vout":1,"n":0,"addresses":["bc1qjar8852c43h73ud79xjluy2e7qce58peymsts8"],"isAddress":true,"value":"194390"}],"vout":[{"value":"10315","n":0,"spent":true,"hex":"00141a475acd52ae04da60ab33bf373c9255cea3169a","addresses":["bc1qrfr44n2j4czd5c9txwlnw0yj2h82x9566fglqj"],"isAddress":true},{"value":"179781","n":1,"spent":true,"hex":"0014974673d158ac6fe8f1be29a5fe1159f0319a1c39","addresses":["bc1qjar8852c43h73ud79xjluy2e7qce58peymsts8"],"isAddress":true}],"blockHash":"000000000000000000099b3509cf7d55c3c1894f814ab45bdccb32aa2b5e3e46","blockHeight":616239,"confirmations":14948,"blockTime":1580992887,"value":"190096","valueIn":"194390","fees":"4294","hex":"0100000000010192433f1f9bdd06bf0f5221aa94de3ed9c82aa772cf022f31c7c86162948eb33e010000000000000000024b280000000000001600141a475acd52ae04da60ab33bf373c9255cea3169a45be020000000000160014974673d158ac6fe8f1be29a5fe1159f0319a1c3902483045022100a2cb51287dd8fd1e7eb9c48be73cba46ddf75287617c38f68618062c945ecbc802206f357933216b63a4530687223e60900c29d1d0869461d6707d7fa202a3c09d9301210289f9d29f5e11c87d2cdbc213d05b7f2aef0291b89b87e7a6f747461d2f75fd9a00000000"},{"txid":"35caac179d1a85f7c495d9a716d85bb02ed925170fc4716e8b04791acd487419","version":1,"vin":[{"txid":"45cd3053d5393b2959646d023e1f2fa272d950903ed8b44502db88c9a04325fe","vout":1,"n":0,"addresses":["bc1qs6q3tdsa09dtrwn0ml7d6ser4zdagja23rks6a"],"isAddress":true,"value":"2470973"}],"vout":[{"value":"10772","n":0,"hex":"00141a475acd52ae04da60ab33bf373c9255cea3169a","addresses":["bc1qrfr44n2j4czd5c9txwlnw0yj2h82x9566fglqj"],"isAddress":true},{"value":"2455681","n":1,"spent":true,"hex":"0014974673d158ac6fe8f1be29a5fe1159f0319a1c39","addresses":["bc1qjar8852c43h73ud79xjluy2e7qce58peymsts8"],"isAddress":true}],"blockHash":"0000000000000000000fcc2170ca9e17fd26747dd40bbf0388324cb872cd7a72","blockHeight":615391,"confirmations":15796,"blockTime":1580495311,"value":"2466453","valueIn":"2470973","fees":"4520","hex":"01000000000101fe2543a0c988db0245b4d83e9050d972a22f1f3e026d6459293b39d55330cd4501000000000000000002142a0000000000001600141a475acd52ae04da60ab33bf373c9255cea3169a8178250000000000160014974673d158ac6fe8f1be29a5fe1159f0319a1c390247304402207fd1c5f4e69845d67696f6dd3f9160fba8e66edb959742b3836f9d6b51b7ef3e022066940b74c238971d0f826648a2bc4806b88be512b6c2bbb08f95e32bbd1ad52f0121020201a3d7f2d6e0e63a7f73e6dfad80d47acaba509585fb40c3c0f54ed9e2478700000000"},{"txid":"7e9a4659d3ad09889595c36f3a533f7dcd2e8c7cd429a8da8129544e961f5540","version":2,"vin":[{"txid":"56246da72d3f56d151adeb34c76c58d229ea0ddcfdc40f17d9b31033fc8789ad","sequence":4294967295,"n":0,"addresses":["33nzF46dHjjuxX61JCnFqirQoxs6VgHRmC"],"isAddress":true,"value":"13482","hex":"160014f9dc6ee2a72c21e6f2a9638dd28a7ea89c79ac62"}],"vout":[{"value":"12257","n":0,"hex":"0014494d0f8f18046f3774ed234a89cb1c37c82ad194","addresses":["bc1qf9xslrccq3hnwa8dyd9gnjcuxlyz45v5dku5t9"],"isAddress":true}],"blockHash":"000000000000000000112771bad60c0245409ff41f8f853f2688bde7194abceb","blockHeight":613673,"confirmations":17514,"blockTime":1579512534,"value":"12257","valueIn":"13482","fees":"1225","hex":"02000000000101ad8987fc3310b3d9170fc4fddc0dea29d2586cc734ebad51d1563f2da76d24560000000017160014f9dc6ee2a72c21e6f2a9638dd28a7ea89c79ac62ffffffff01e12f000000000000160014494d0f8f18046f3774ed234a89cb1c37c82ad194024730440220346da175f0e165a994897ad2eeb117609e2c36f5f1d0d8c40237ef172c88cc00022071fcdc6adebd73a6627e3ce011dff47634796c3b7371e751f5b6258e308674f6012102b708bb3855591cc04d74a65c67be028fd48ae0911e4a82aed92c1c479eb4cce500000000"},{"txid":"56246da72d3f56d151adeb34c76c58d229ea0ddcfdc40f17d9b31033fc8789ad","version":1,"vin":[{"txid":"2054069427b587c84ec43902eb8a400c932567104cd666eb8db514a60170dc15","vout":1,"n":0,"addresses":["bc1qtrk05l53jdflggp0c9hy32ejq4gs6zrf2jjplj"],"isAddress":true,"value":"6530"},{"txid":"45cd3053d5393b2959646d023e1f2fa272d950903ed8b44502db88c9a04325fe","n":1,"addresses":["bc1qlrfxv4v2fkljgylytypxdnr6cdw3jhlcz3xmrs"],"isAddress":true,"value":"11032"}],"vout":[{"value":"13482","n":0,"spent":true,"hex":"a9141711581f950d42881c52adf5c92f64aed4b27a5187","addresses":["33nzF46dHjjuxX61JCnFqirQoxs6VgHRmC"],"isAddress":true}],"blockHash":"00000000000000000002d1d74426c36e5f97541ab039fcfe617425db12bbcfa3","blockHeight":613671,"confirmations":17516,"blockTime":1579512101,"value":"13482","valueIn":"17562","fees":"4080","hex":"0100000000010215dc7001a614b58deb66d64c106725930c408aeb0239c44ec887b52794065420010000000000000000fe2543a0c988db0245b4d83e9050d972a22f1f3e026d6459293b39d55330cd4500000000000000000001aa3400000000000017a9141711581f950d42881c52adf5c92f64aed4b27a518702483045022100cda0a6afa6263f966095400decdf6c73ee4c0889c8eed5bcf5c4bfc85627978b02203beba56e1ee50371a8ffe1ee27be2f2259ad48881808f5d0e63818ccd367a4100121032c5789121a12483272dbd6e42abf59171896aae32c3354ce4ff0ed34635e6b1802483045022100b724e2ecbd7d76b78930cc11af73ad4981ea0d78e90fc5d0860975e7cc3e1c170220695f053d4f4c059954959822bfb80f9d7d7651176ca99522e6ff5b19d4bae11d0121036c203dd0b21843fc2a1f84aca1ca39d45034dd55ef4030adbc663510df4e454b00000000"}],"usedTokens":100,"tokens":[{"type":"XPUBAddress","name":"bc1qrfr44n2j4czd5c9txwlnw0yj2h82x9566fglqj","path":"m/84'/0'/0'/0/0","transfers":13,"decimals":8,"balance":"16245","totalReceived":"92089","totalSent":"75844"},{"type":"XPUBAddress","name":"bc1qh24nwfr75yt5xuh0ejt6jwme6lg6rgy3nkxscp","path":"m/84'/0'/0'/0/40","transfers":1,"decimals":8,"balance":"643","totalReceived":"643","totalSent":"0"},{"type":"XPUBAddress","name":"bc1q7hhmfl8qlpmcjuq6crm4cu70kzqfm2pj8gp6y0","path":"m/84'/0'/0'/0/42","transfers":1,"decimals":8,"balance":"1000","totalReceived":"1000","totalSent":"0"},{"type":"XPUBAddress","name":"bc1qf9xslrccq3hnwa8dyd9gnjcuxlyz45v5dku5t9","path":"m/84'/0'/0'/0/44","transfers":1,"decimals":8,"balance":"12257","totalReceived":"12257","totalSent":"0"},{"type":"XPUBAddress","name":"bc1q2h0cce60v3cf48lq4ucnk4l998z3c0n7ccd27f","path":"m/84'/0'/0'/0/130","transfers":1,"decimals":8,"balance":"1000","totalReceived":"1000","totalSent":"0"},{"type":"XPUBAddress","name":"bc1qqs8mr36kttyuh3wjzk34dpha9d0gjt7q7vdvhy","path":"m/84'/0'/0'/1/36","transfers":1,"decimals":8,"balance":"1063","totalReceived":"1063","totalSent":"0"},{"type":"XPUBAddress","name":"bc1q8y3g8d0ltmwatqzuh5vq7aqymvq36s6ncn5jv5","path":"m/84'/0'/0'/1/38","transfers":1,"decimals":8,"balance":"1056","totalReceived":"1056","totalSent":"0"},{"type":"XPUBAddress","name":"bc1q3u68k04pecgnkz0qjcf95wknxyxap2287gyzrg","path":"m/84'/0'/0'/1/40","transfers":1,"decimals":8,"balance":"2699","totalReceived":"2699","totalSent":"0"}]} diff --git a/mock/ext-api-data/bitcoincash-api_v2_address_bitcoincash_qq07l6rr5lsdm3m80qxw80ku2ex0tj76vvsxpvmgme__details_txs.json b/mock/ext-api-data/bitcoincash-api_v2_address_bitcoincash_qq07l6rr5lsdm3m80qxw80ku2ex0tj76vvsxpvmgme__details_txs.json new file mode 100644 index 000000000..2ed2ac728 --- /dev/null +++ b/mock/ext-api-data/bitcoincash-api_v2_address_bitcoincash_qq07l6rr5lsdm3m80qxw80ku2ex0tj76vvsxpvmgme__details_txs.json @@ -0,0 +1 @@ +{"page":1,"totalPages":2014,"itemsOnPage":5,"address":"bitcoincash:qq07l6rr5lsdm3m80qxw80ku2ex0tj76vvsxpvmgme","balance":"0","totalReceived":"12502830507987","totalSent":"12502830507987","unconfirmedBalance":"0","unconfirmedTxs":0,"txs":10067,"transactions":[{"txid":"0284cb9b8deb0534efa8fc8911db1e8f9b106d00608c712d31c3680f303fbf36","version":2,"lockTime":611622,"vin":[{"txid":"2f150ee63214982edbaf23c85629e920e16093d0506ed284ec3018ebe8746b12","sequence":4294967294,"n":0,"addresses":["bitcoincash:qq07l6rr5lsdm3m80qxw80ku2ex0tj76vvsxpvmgme"],"isAddress":true,"value":"1250119473","hex":"47304402206f992d73dfa7e518b00190f220ad5dc7b7947b1d75a2fcd8251b59f3d29d89af022036c6c44f52f9aeed406dec72a9aab1f82c3b997c36742f4a3504e4f93e6f8557412102e367f6787fe02523fe7b16fff187757207befd49d038f1a80363592ef5f12806"},{"txid":"550ba873216e6690c8ca34992da41ecaa29e74a557943af604537de13fb84838","sequence":4294967294,"n":1,"addresses":["bitcoincash:qq07l6rr5lsdm3m80qxw80ku2ex0tj76vvsxpvmgme"],"isAddress":true,"value":"1250052374","hex":"483045022100db30ebe47536e42115a507f88bb8d5c97b81ad05ce334872235811134c5948bb0220418d77aed78cc4a332b1858c1d2e9ab169828b9c12e8c0d0f8d155964e5d0b8e412102e367f6787fe02523fe7b16fff187757207befd49d038f1a80363592ef5f12806"},{"txid":"ed8d8d9810ca30cd0512a0e0ca87649713a550a015bb0022c16686c2ccb22143","sequence":4294967294,"n":2,"addresses":["bitcoincash:qq07l6rr5lsdm3m80qxw80ku2ex0tj76vvsxpvmgme"],"isAddress":true,"value":"1250058021","hex":"483045022100d30c9fd598613586d8d0460fb6c9ffc1d0c6dff6f647535d2a9f69cf373193d102207fff687aa035910db124adad8b59607a72b3d24aca9096217ec6b90fa132a2ae412102e367f6787fe02523fe7b16fff187757207befd49d038f1a80363592ef5f12806"},{"txid":"a2d79bacd53918c9ad6b27055eff555130f1af8522f77a09c4d74321dad8a032","sequence":4294967294,"n":3,"addresses":["bitcoincash:qq07l6rr5lsdm3m80qxw80ku2ex0tj76vvsxpvmgme"],"isAddress":true,"value":"1250022804","hex":"47304402207b30e99cb1f6754d227a4511c5b7791f3b896724b170716d6ed238017f191bb102202c1fadc4c572c86288b002a0d6b6d2460a14a6d3c8b49efc17a03e59d2db18e3412102e367f6787fe02523fe7b16fff187757207befd49d038f1a80363592ef5f12806"},{"txid":"9a0679dc735b7774ab3aa55a01188ce4d70613927b1b0ca9f96784b09479f762","vout":1,"sequence":4294967294,"n":4,"addresses":["bitcoincash:qzqn6xdqhaqa8yykvq4e94td4yg0k9ll9vyjf47x0f"],"isAddress":true,"value":"1620505","hex":"48304502210092b7f176f182936323df8e4359b2a329b0c1e4b48a529d6e32867038a2a453cc02203c24a8bb46b7fea4ef5c78ff116a51fd0a04dee25bfcdffe856fb8988a7a97f64121035b4e75dda9fb0d55d856f54f24fc65da6657939b9559ab2c623c8ef325f14d8d"},{"txid":"5d557c0c3331dc1dc4db34776603c01ce24ac8b0adf1f6fc2cc07a88baf5bf5c","sequence":4294967294,"n":5,"addresses":["bitcoincash:qq07l6rr5lsdm3m80qxw80ku2ex0tj76vvsxpvmgme"],"isAddress":true,"value":"1250096547","hex":"47304402202a2bcfdaf12c398ed5372e6b168a786edb8972df1146b705d3cccf2d9601517d022020b90ac89d9141d68817850d1cdffaf6c51f45249a44fd6861b361a6025d8ac4412102e367f6787fe02523fe7b16fff187757207befd49d038f1a80363592ef5f12806"},{"txid":"61dbe706b513c1ee5aa577a07782471cf5c0c13fd7ce31b29cdd1c2362ea0bca","sequence":4294967294,"n":6,"addresses":["bitcoincash:qq07l6rr5lsdm3m80qxw80ku2ex0tj76vvsxpvmgme"],"isAddress":true,"value":"1250179897","hex":"48304502210087ef2709b9fe8e7f136219254229edd45e94c3f6ebd2bb149aadd9b1d44d89e202206ffde3c9491c012832967e4d34e02ece2c08bc4c07967b3b466d4800f9ca0746412102e367f6787fe02523fe7b16fff187757207befd49d038f1a80363592ef5f12806"},{"txid":"54b28d128142bb03aa60e9cf535fe30d5916089f1e70ac94444572008e9b3b84","sequence":4294967294,"n":7,"addresses":["bitcoincash:qq07l6rr5lsdm3m80qxw80ku2ex0tj76vvsxpvmgme"],"isAddress":true,"value":"1250044246","hex":"483045022100c7dbd1117c57eedc8fc006e818371bfe6399c4d25e8b40482c1f0858a3d98a4b0220426d1196513a87fc7afb5b107b770a90af789536799a11686eab96b04afa6326412102e367f6787fe02523fe7b16fff187757207befd49d038f1a80363592ef5f12806"},{"txid":"750c2e638eb26bd271586fe201f48e21ef7fcef1154a6b6335d2bd4381450123","sequence":4294967294,"n":8,"addresses":["bitcoincash:qq07l6rr5lsdm3m80qxw80ku2ex0tj76vvsxpvmgme"],"isAddress":true,"value":"1252404910","hex":"47304402203604fbb20824443899030d2c1f5cd0dc2b88174929861a708bdca878868e910c02200a607b1da53483bc95d3a5c54e5ad66e459827d4ecf8b4ef9909e9d58b2d329b412102e367f6787fe02523fe7b16fff187757207befd49d038f1a80363592ef5f12806"},{"txid":"9b6dc387b59e4af25bfa14067e24c399fae3fbb744e97edb670087265ebcecf9","sequence":4294967294,"n":9,"addresses":["bitcoincash:qq07l6rr5lsdm3m80qxw80ku2ex0tj76vvsxpvmgme"],"isAddress":true,"value":"1256320052","hex":"4730440220399c36174173cca01f6d6a234a935d6f776b549e1ea2fc2635193924c4ac2eb002205aea7741fafd95f862588c480aaa282d7a344d32d6318aec1a908cbb939e5d0e412102e367f6787fe02523fe7b16fff187757207befd49d038f1a80363592ef5f12806"},{"txid":"8f27da29f81ae3ac3ab90f29cd4988d718cd351f965892b073a80b9a9492f49e","vout":1,"sequence":4294967294,"n":10,"addresses":["bitcoincash:qz8mkaldpk8zk2ge27wpn8ue0uwu28xq5552u5c5my"],"isAddress":true,"value":"1687043","hex":"483045022100da9075310e7af59456423be99362f2cc686d50571e0f0b016bcfae1f0bc4692802203379b648d47704dba48542b8b6d5e515bf3c4fd7ff8a7be82cd0c8c0c7be56f7412103a344a84dc1a919a64874605fae200861b7af3ecd02dc5d52dd00eb6f8845525a"},{"txid":"109bf48f720a9d05fd7a74b632164ed96db721b00458420595d799b437305f5c","sequence":4294967294,"n":11,"addresses":["bitcoincash:qq07l6rr5lsdm3m80qxw80ku2ex0tj76vvsxpvmgme"],"isAddress":true,"value":"1251895732","hex":"47304402206cbf93634d6a477a571fa2884c19918b19ddfb008ff9fe405954720047efdb88022003e755313436d406dddfe3cfb68719e8f39e43de7c586489cc543dac0347da9f412102e367f6787fe02523fe7b16fff187757207befd49d038f1a80363592ef5f12806"},{"txid":"d3e570366f647db1f73079b743ec994169875c7af42ff2e9f3cf290fcb3f180b","sequence":4294967294,"n":12,"addresses":["bitcoincash:qq07l6rr5lsdm3m80qxw80ku2ex0tj76vvsxpvmgme"],"isAddress":true,"value":"1250081823","hex":"483045022100f23d4cf11fd0a5ab83dc053ca64066cbdd2fb4107e0977a3a880c68a67636f7d0220220a47c66d3944cfc309c059fe8013c4de742e4d8590003fd56c5e0b3c7da557412102e367f6787fe02523fe7b16fff187757207befd49d038f1a80363592ef5f12806"},{"txid":"6f05f99a402127463db6dc2f8f6b1064109fbfb93bacb258babd2aa861055480","sequence":4294967294,"n":13,"addresses":["bitcoincash:qq07l6rr5lsdm3m80qxw80ku2ex0tj76vvsxpvmgme"],"isAddress":true,"value":"1250020672","hex":"4830450221009f522beef55cbf8c7f10e88739846f78ef1c9d9cbc6959dba6f687a08fec0ef502203a160231733b87c6cfd8afd148994c9b6c5d5db9bb9847aa9e60938a6e79d5b1412102e367f6787fe02523fe7b16fff187757207befd49d038f1a80363592ef5f12806"},{"txid":"3d93b717b0676245a3dc3fb86625d9abffac4f66e2889a81a07733a14e1e4a4a","sequence":4294967294,"n":14,"addresses":["bitcoincash:qq07l6rr5lsdm3m80qxw80ku2ex0tj76vvsxpvmgme"],"isAddress":true,"value":"1250118486","hex":"47304402201f5d29be80192a752fe28ff141ed702640df88083faf3f9573e52405cb4bd79a02202d751649aa600c4fdb8b1d1b21f0d134c2f4e5af9ecbe7d87180d667140f0a11412102e367f6787fe02523fe7b16fff187757207befd49d038f1a80363592ef5f12806"},{"txid":"c77ac92e646677bf9e59873c5f5036831d5d5597cda469b7e6b30a9563a3419b","sequence":4294967294,"n":15,"addresses":["bitcoincash:qq07l6rr5lsdm3m80qxw80ku2ex0tj76vvsxpvmgme"],"isAddress":true,"value":"1250097156","hex":"47304402203f4bea3816d252cb19d4247f587a146901c74d04e783efddfd5089942f2abcdb022069012613c4ee4b3b0212ae71dbd2071e01665148697011eb03eba25431e679cf412102e367f6787fe02523fe7b16fff187757207befd49d038f1a80363592ef5f12806"},{"txid":"90cba3db7e020c7b8943293ecca7f6a2150082a372972c0ed65646337b0b05ab","sequence":4294967294,"n":16,"addresses":["bitcoincash:qq07l6rr5lsdm3m80qxw80ku2ex0tj76vvsxpvmgme"],"isAddress":true,"value":"1250175150","hex":"4730440220782ba77287116d5d735f67a3738fbecc1a802d2141a1fa544f61a5e8ba682a4402205473d68019cc8895ecb1d87bfced62ddb6dc48b81152f2684ae8530122d5b41f412102e367f6787fe02523fe7b16fff187757207befd49d038f1a80363592ef5f12806"},{"txid":"e25ec382049a4d8edd530469e5e41d9e056a2081b661f505414b1348e482dd26","vout":1,"sequence":4294967294,"n":17,"addresses":["bitcoincash:qqnfldeu0yd4wd89c44sujdz2w7hwvvd3y8g9tuech"],"isAddress":true,"value":"1884419","hex":"473044022044ed9bfa8674d7e83112fa22280797169d45bd971b185da2413e36252637529d0220531eefc480e0911d6ccda42002942883149bc1cdd1f3bbde313751d80bcf98b641210328ac4ed2b30ddc04c778a78b24e7256b08c55758c1465defd997ff4bcefacf10"},{"txid":"13a148dff09d7786a7e0d0929e7ece3c9fb8de532597cbb0d045f5ec531b2e9e","sequence":4294967294,"n":18,"addresses":["bitcoincash:qq07l6rr5lsdm3m80qxw80ku2ex0tj76vvsxpvmgme"],"isAddress":true,"value":"1250028570","hex":"4830450221008cfdfd352e268dba2022e7fbfc37a90401c40fdf6f1d8ba9dcb97d67743eddc302202c0a1b604d34aa174fddef63c9115c95465548855c5f783bb206eb4ff8fda235412102e367f6787fe02523fe7b16fff187757207befd49d038f1a80363592ef5f12806"},{"txid":"700dfcfa0847678c56a084b5a75fb8aef1b1a1126512b026ebdb8c45d55efdf9","sequence":4294967294,"n":19,"addresses":["bitcoincash:qq07l6rr5lsdm3m80qxw80ku2ex0tj76vvsxpvmgme"],"isAddress":true,"value":"1250039508","hex":"473044022001b33b610b8d742df2ad98679f1e41f0c647faf272e15e7ea93171ba29c33bcd022061646fbcb81ba30d6e8b030ee12101d1f1bef38ba44a6d5daf40c4ff6d644e6e412102e367f6787fe02523fe7b16fff187757207befd49d038f1a80363592ef5f12806"},{"txid":"6810932357166daa33c2125cf38be6076f7b6f718f199348905459f22ba7f2a6","sequence":4294967294,"n":20,"addresses":["bitcoincash:qq07l6rr5lsdm3m80qxw80ku2ex0tj76vvsxpvmgme"],"isAddress":true,"value":"1250136993","hex":"483045022100ec9b6bbaba90d8902ec8a1ca0e90ea594264bc1add204b756cc89def4d7e9a2a022066b2bc84f94e1a99effe0e929be8de8669631143ca20c73e700d182ad4884e71412102e367f6787fe02523fe7b16fff187757207befd49d038f1a80363592ef5f12806"},{"txid":"42a98564873f7c888a6a569cb97066b4bc43c5fa41d732573774f996b91980b3","sequence":4294967294,"n":21,"addresses":["bitcoincash:qq07l6rr5lsdm3m80qxw80ku2ex0tj76vvsxpvmgme"],"isAddress":true,"value":"1250053520","hex":"473044022057117591cc465c48da58ebcb8f57fcd56359757d41e1397e45b5e33e034ea5d8022001de1d78ce9e8e73370a0778b4a8595045c6faeb2497ab4296d0cff735711276412102e367f6787fe02523fe7b16fff187757207befd49d038f1a80363592ef5f12806"},{"txid":"f7b56e95b5a48a66649fd3e9e9bc94a7a01bd1c4822c4dcc2c40243c8da60bbd","sequence":4294967294,"n":22,"addresses":["bitcoincash:qq07l6rr5lsdm3m80qxw80ku2ex0tj76vvsxpvmgme"],"isAddress":true,"value":"1250111141","hex":"483045022100dace56650d1d9edaef30e8c9ecb4b78499a573984c8a451253295a90c84a3ed702201f4587d4a760cd77a2e21d5f6f2b7aacf668220c8c7c62fc1ae4779f7c0141cd412102e367f6787fe02523fe7b16fff187757207befd49d038f1a80363592ef5f12806"},{"txid":"d58b912c125283ee0249b670a7901bd5a1061d92f7c06627b5e963fb0b2c3d14","sequence":4294967294,"n":23,"addresses":["bitcoincash:qq07l6rr5lsdm3m80qxw80ku2ex0tj76vvsxpvmgme"],"isAddress":true,"value":"1250143132","hex":"47304402200db6b461a0082807f59053bea210d38f5f82f02dd63a57f6e3987339cac23870022064ba927fc11b36318785d4e861a7f94cb3909ef8fe882360e2041f7b4a444692412102e367f6787fe02523fe7b16fff187757207befd49d038f1a80363592ef5f12806"},{"txid":"530326ce09e8f933a604488e5e2f06845c3e805761c02eced5cc02856be1b7b0","sequence":4294967294,"n":24,"addresses":["bitcoincash:qq07l6rr5lsdm3m80qxw80ku2ex0tj76vvsxpvmgme"],"isAddress":true,"value":"1250022822","hex":"483045022100a3e75a6c7918db32a27be348493b831631856ec8f546ca43d143cdc3c1cd03c802201e6ae036423bfce45c500b0c049f68396deae5cb999038de61e972ccd4cba5e7412102e367f6787fe02523fe7b16fff187757207befd49d038f1a80363592ef5f12806"},{"txid":"ca51412ad37c5e5a49b11dc7858b4013ff68288c56e6026b11a4266e184b286d","sequence":4294967294,"n":25,"addresses":["bitcoincash:qq07l6rr5lsdm3m80qxw80ku2ex0tj76vvsxpvmgme"],"isAddress":true,"value":"1250033136","hex":"483045022100caf952ca1760052cfefe8df283fdd0eccb9e1238eea88eef287df9404c622e8b022072027363fa1070548576fbf9bcbddf2e435fd020662b2d8f0582b52bfa487b31412102e367f6787fe02523fe7b16fff187757207befd49d038f1a80363592ef5f12806"},{"txid":"c03e268bbb105f171305f7fd994c0e15fbff5ae3d08f3c332c48cacca66bbb38","sequence":4294967294,"n":26,"addresses":["bitcoincash:qq07l6rr5lsdm3m80qxw80ku2ex0tj76vvsxpvmgme"],"isAddress":true,"value":"1250037356","hex":"47304402201a4b4efff2b70a4039b4dc120141da04ae84f63906df10c3cad08838c01b6b8702205a065d025c338547ea07b2095ad31252658e57f1a7a04c7f4eacc0248e611fa2412102e367f6787fe02523fe7b16fff187757207befd49d038f1a80363592ef5f12806"},{"txid":"46c8b9fca6423412b3d40cf7606b79678807d75b2be1e848765c40f367b326a3","sequence":4294967294,"n":27,"addresses":["bitcoincash:qq07l6rr5lsdm3m80qxw80ku2ex0tj76vvsxpvmgme"],"isAddress":true,"value":"1250061192","hex":"47304402206b0a876d78793710acaa8bbeb58a2d908bd4936f2a88825f944b190041b5e0be0220279560be5009e4a3fab44d08f4748e2dead710a8ccc77e06a03ba8112d728856412102e367f6787fe02523fe7b16fff187757207befd49d038f1a80363592ef5f12806"},{"txid":"fadc6b6f3225ea8686c7a03cd8362765f91e604c260beaf965c4e7093fb16b74","sequence":4294967294,"n":28,"addresses":["bitcoincash:qq07l6rr5lsdm3m80qxw80ku2ex0tj76vvsxpvmgme"],"isAddress":true,"value":"1250118669","hex":"4730440220799bdb7ac60cdf3314cc1f157299858d353e22c00354707337ab5b497619d626022000e41053afe44fa65227b7dd8498300a2dc89367d9daf0586caba5bffdfde567412102e367f6787fe02523fe7b16fff187757207befd49d038f1a80363592ef5f12806"},{"txid":"adb5163c2bd4b1c35c1eac2671e6124e6c6b9b6c3e2abdc8372601528600a98d","sequence":4294967294,"n":29,"addresses":["bitcoincash:qq07l6rr5lsdm3m80qxw80ku2ex0tj76vvsxpvmgme"],"isAddress":true,"value":"1250075561","hex":"483045022100a1af33a83edb7fdc289a48a4f77cf286a88b38c21ddf27dd4ec3df007ce11046022074dd56730730f958039efd70edfe7e181060fec306c6df4cf75209600ebebed7412102e367f6787fe02523fe7b16fff187757207befd49d038f1a80363592ef5f12806"},{"txid":"db1a00011dcc02708d6757b7435a3163d4dc384d8490208656229b0780b4a184","sequence":4294967294,"n":30,"addresses":["bitcoincash:qzduecze3gvxk6y7rcjmvnau8c3ncddvvvs05z5gz6"],"isAddress":true,"value":"1400587","hex":"483045022100eff445419ec63d1e9f51a5324c3be0315911b39f30657639e84ea7d2f739e0510220218e73140a39542ec8055b6645cbb7989f96b9d9a93c67549c059509de06f0ba412103dd71b53aaa823b09a68aba30c7603c6a397e7c183f708c9dfb0d9d0a9cd1c722"},{"txid":"df69893e75d4acee084666c023822f07196dcae429a07b136fe92a87262f87f8","sequence":4294967294,"n":31,"addresses":["bitcoincash:qq07l6rr5lsdm3m80qxw80ku2ex0tj76vvsxpvmgme"],"isAddress":true,"value":"1250118543","hex":"473044022050b7ed06a6832b8831c08ba86049b3793b5a71fd6d5177c9f268b79c3074bca7022047447c23429de30c361875642d9058bf1b5e0e6c5516d6e71b70b7cfb29827aa412102e367f6787fe02523fe7b16fff187757207befd49d038f1a80363592ef5f12806"},{"txid":"8432efebc29ead31beb783d5d27cc379fa31cee352cc19a75746768b2fbfbe7e","sequence":4294967294,"n":32,"addresses":["bitcoincash:qqfs2vp95prfunn2r9wh5lf2g6k7k6jjr5qld8a37e"],"isAddress":true,"value":"1772743","hex":"483045022100fb072bfd399dc11191ac449a9d60119bd191ce6b19a5d92412a805ddc8d4b46f022021e463686560b15ddf272b9943d8e41425ed500f77698aba518ccf546a97aeb4412103e35c58a738805f53af73472ffb671a9bd3556ddef47c62f18ced868bb5033d0d"},{"txid":"29ff4caeaa127c04ecc8141f49462390a13febd47877abda62a7ebb66658f0ba","sequence":4294967294,"n":33,"addresses":["bitcoincash:qq07l6rr5lsdm3m80qxw80ku2ex0tj76vvsxpvmgme"],"isAddress":true,"value":"1250075582","hex":"483045022100b25e7d4ebaa0e7d8e24498b039e756d568b67316aa14d05abafaec59e216a73d0220010d0b6548a74435907eb0d548dfe8e52a949bbb785eb2be3bce14053953784f412102e367f6787fe02523fe7b16fff187757207befd49d038f1a80363592ef5f12806"},{"txid":"3b46f445ddc1b8acd4fa933fb8d7dba9bd95ce53a579339b32a1e97352323013","sequence":4294967294,"n":34,"addresses":["bitcoincash:qq07l6rr5lsdm3m80qxw80ku2ex0tj76vvsxpvmgme"],"isAddress":true,"value":"1250043307","hex":"473044022007d2baa9a766c120e111a727bfa8e8bc2e01cc285d4d4f67d2323b213525a10c022020f32be2d9935b6d9b5091db27ebf00aaeb54adc7032badc7ad63f20741ff28a412102e367f6787fe02523fe7b16fff187757207befd49d038f1a80363592ef5f12806"},{"txid":"1bd4b1e18be85528e214e16c69f459272ec126ff0dfd1948de6838b5b50e5344","sequence":4294967294,"n":35,"addresses":["bitcoincash:qq07l6rr5lsdm3m80qxw80ku2ex0tj76vvsxpvmgme"],"isAddress":true,"value":"1251821842","hex":"483045022100f98ee28ffb66acd04474a120904ec1be2327d727d8ed8fe99d8b95c174b8f46a022041d21406dd8df10cecc1d6435de68fef3f9db71838c1ca2910895bb184b4a6e4412102e367f6787fe02523fe7b16fff187757207befd49d038f1a80363592ef5f12806"},{"txid":"067492a2b7fe0787a44ceba7d6ee64da25aa8be08357576e4cef97ef76babf2f","sequence":4294967294,"n":36,"addresses":["bitcoincash:qr99zjexsl5dtdu38wu8w7jdmsmcxtcr9qw64zjhdk"],"isAddress":true,"value":"1843864","hex":"483045022100ee3f7961f0f23137d753affe85b777e94c1db3f656cf41b8f59fcf82d9226eb7022025009482a6c0002e409590075caf7a78023ebc1457f100c8b922a4974ebf86ba412103f1d1dd7685d3781f58f9aa399a16f6bb9ccc7d008cdb7c63a7945cfcaa6ba0e2"},{"txid":"bcc168ae5cc9dd70fabab262712036bacea7250db404c0d5af438b0b085c52bf","sequence":4294967294,"n":37,"addresses":["bitcoincash:qq07l6rr5lsdm3m80qxw80ku2ex0tj76vvsxpvmgme"],"isAddress":true,"value":"1250034365","hex":"47304402201fed9da4c0526ac5ce257fce2b7fc995646b5f0d2961396327f93e2dfda3e4a0022035b217adc5a9be2ca34f4361ceafd9f2d09a6fa47d4a767f7001ade40c08fe26412102e367f6787fe02523fe7b16fff187757207befd49d038f1a80363592ef5f12806"},{"txid":"025d365f0471a48171c3f50ba4e9ee04ee74f72c2e8d0cddca600f3a900b7b32","sequence":4294967294,"n":38,"addresses":["bitcoincash:qq07l6rr5lsdm3m80qxw80ku2ex0tj76vvsxpvmgme"],"isAddress":true,"value":"1250085848","hex":"483045022100fa8ee82d42f524290319fb3ee47a1afa70cb952f8a37325680d6fd651ac3699f02205ac0cd86fece03ca204bd881d67ccce0cccbbc98704d9e955e2f92b5b77121dd412102e367f6787fe02523fe7b16fff187757207befd49d038f1a80363592ef5f12806"},{"txid":"c61c8a5fd411f160bac0e4b4e703e1caf7d3f8218b0ca5f2aa7b762bb9d3ad5f","sequence":4294967294,"n":39,"addresses":["bitcoincash:qq07l6rr5lsdm3m80qxw80ku2ex0tj76vvsxpvmgme"],"isAddress":true,"value":"1250086233","hex":"483045022100f3cb343c4704bebbc78c6492dd72ca19c388b285f44f574dcff25f993add6d5f02200e050dacd78de955cf552f9158beaac5fa64995f5bf7c8a919a231a39425730c412102e367f6787fe02523fe7b16fff187757207befd49d038f1a80363592ef5f12806"},{"txid":"207dd74726483c593b21c180a9467166af7f5b02450fd3613268cea239aed047","sequence":4294967294,"n":40,"addresses":["bitcoincash:qq07l6rr5lsdm3m80qxw80ku2ex0tj76vvsxpvmgme"],"isAddress":true,"value":"1250080933","hex":"47304402203f05a035f5d42fbfe97172b431a613110ad733e356ebfd08886fa11bedaf1faf022061c4a3bc3417390910612bae46f5acf8b6e8a5b008d273a52e483a315bfb950b412102e367f6787fe02523fe7b16fff187757207befd49d038f1a80363592ef5f12806"},{"txid":"facaafec82e7853c85dca5fcecad9c62d830a2421c98e8c5896b793966face46","sequence":4294967294,"n":41,"addresses":["bitcoincash:qq07l6rr5lsdm3m80qxw80ku2ex0tj76vvsxpvmgme"],"isAddress":true,"value":"1250075132","hex":"483045022100bf60fbd4716339bbb42ce150966ad6caf90b14e57f45eb6804756cf8ff36b23a02202f16aaecdb9994f3b683cc7fab45bd0a3f54795c336b5fc224fc51270a7f3f4f412102e367f6787fe02523fe7b16fff187757207befd49d038f1a80363592ef5f12806"},{"txid":"26703badea466dcf8446e1ee49868ed4259ff22e0f13460db9d79819115b5c4e","sequence":4294967294,"n":42,"addresses":["bitcoincash:qq07l6rr5lsdm3m80qxw80ku2ex0tj76vvsxpvmgme"],"isAddress":true,"value":"1250118800","hex":"483045022100bcdcae99c9289b5fc89d3227daaea8df7d0a0f3a8971d841ebe1ab7a1ecf72e202202ca21447a6b3e96540e32529697d523b7b08c65845d6a13f6b1475de94919bb6412102e367f6787fe02523fe7b16fff187757207befd49d038f1a80363592ef5f12806"},{"txid":"c94103172a643e1ae22c3955749bf7af337a914a48d124fb5cbaae1ab5fa9e48","vout":1,"sequence":4294967294,"n":43,"addresses":["bitcoincash:qzfvx98n9r4yzlvk2h736rn3qftpl2uttuu76kvt5x"],"isAddress":true,"value":"1631430","hex":"4830450221009535c27b5bbca0db2bcf1a0d0b3b283a2171df53f0d68f1a138888fcc6ddd996022068af19252ac4376cffdbfaacb2e0f0c216deb7e2478b586abe7c2679501eac34412103a47e5dea4ab8d785f4e00994d0faf1a8f384c41e74ed8e4b776fa6ce136ebc42"},{"txid":"180544709d0cc711566118b48af548a7b199c639185685c7228676725c28ee7e","sequence":4294967294,"n":44,"addresses":["bitcoincash:qrrv55s5ag0dduyjsc83ds7hstqc0m9htqk764mtaq"],"isAddress":true,"value":"1078385","hex":"483045022100b456847e29f8a648730f0fd34cc7edcfb35daba866ab7d800472beaf2836ce4202207db401f0a5e30efc53c7bf58e57d1dec5874d64768ad9eb4895351cc4be9226f412102291b40a9a927dafeb53cdfc7e722ee5c9dfd6eac2d81331678b9ab405bb25d21"},{"txid":"67c24b19a0f444541bcbcb15e708f7713f5168f89f3d42df51d1909f6e22b093","sequence":4294967294,"n":45,"addresses":["bitcoincash:qq07l6rr5lsdm3m80qxw80ku2ex0tj76vvsxpvmgme"],"isAddress":true,"value":"1250191671","hex":"47304402205ff244c77726def0e3697a3e546bdf74c7f31479c9d01a7a6f8cd1656482d537022045d78dba8ed4d3777f473736daedbdaca6f5698dd306898d144eb43f96259766412102e367f6787fe02523fe7b16fff187757207befd49d038f1a80363592ef5f12806"},{"txid":"208d4a8a6afa218a65416286733a5158e7ca393003e30f88dec606e771e384c7","sequence":4294967294,"n":46,"addresses":["bitcoincash:qq07l6rr5lsdm3m80qxw80ku2ex0tj76vvsxpvmgme"],"isAddress":true,"value":"1250036468","hex":"483045022100ec6b35ce6d24889726480d70a31bc0d62800bf7ac49ecf084b98137322606bca0220432d33e2d8b508f26d7d813d18629453c537a4d90f73a104bbf80627f9fe8d62412102e367f6787fe02523fe7b16fff187757207befd49d038f1a80363592ef5f12806"},{"txid":"60a7eef8d0b9e7cbfe602bedebd75a80121587af1236fcb8ddf00e510cb4caa4","sequence":4294967294,"n":47,"addresses":["bitcoincash:qq788skgg7eqc7unt733wahchmx08h87tgn20l2n3l"],"isAddress":true,"value":"1329593","hex":"4730440220423ea635717cff512d9262b7c8932c0122ca868251f019ae033101c28771a52302200cd3ae05f2e88d9f64207beb4b715ba480bde9ffdd40ab61a36feff88f2968d54121035530745f3cd4d31532991e460bd2a15e1944e690643f73133a9918edb95da53e"},{"txid":"7033ed9dcbb1af754c41046bf1ec51c16285336abc235b9485dd9c8829f32b85","sequence":4294967294,"n":48,"addresses":["bitcoincash:qq07l6rr5lsdm3m80qxw80ku2ex0tj76vvsxpvmgme"],"isAddress":true,"value":"1250053803","hex":"473044022055cc4dfa48a79b8584a9352be34ab5fe9cae4132d264dd827d14ae06d35ad4090220652a83c93505f8a8527c5bc0479f37da0593595c1bf18c12b8fa0b41a2e37a64412102e367f6787fe02523fe7b16fff187757207befd49d038f1a80363592ef5f12806"},{"txid":"929f05541924a6eb7dc7f2e11310037de210718c5896b9d9475ca5724dc13532","sequence":4294967294,"n":49,"addresses":["bitcoincash:qq07l6rr5lsdm3m80qxw80ku2ex0tj76vvsxpvmgme"],"isAddress":true,"value":"1250171060","hex":"4830450221009acc8d0e06d10b0c764a27613bcef41fc75f910875eae3989a7f8725f81814cd02207146ff66f412910ed993fbda4ad6ed48862a02f366dd88a83856a17e7f96d83e412102e367f6787fe02523fe7b16fff187757207befd49d038f1a80363592ef5f12806"},{"txid":"a7e965c2d147a2bcc7d99f61bada49696703563d7b8225c9e69c29e312aab0a0","sequence":4294967294,"n":50,"addresses":["bitcoincash:qq07l6rr5lsdm3m80qxw80ku2ex0tj76vvsxpvmgme"],"isAddress":true,"value":"1250030500","hex":"47304402202d8cd72290f04063c0ae9bc06d2cae3ac74ef4cb6945c92c3e3ccca210c127ef022030471726cd87ac9d55f3d246095f64ae22b611aa8791922236bbdb19ec273322412102e367f6787fe02523fe7b16fff187757207befd49d038f1a80363592ef5f12806"},{"txid":"e6897dfc8254d449f61372cb7c4131c4caaf2781fa60cf930a36421d0bc156c8","vout":1,"sequence":4294967294,"n":51,"addresses":["bitcoincash:qq64kqwmv0gu5naq8ztaj5ecef3042n3pceymy9fw2"],"isAddress":true,"value":"1746309","hex":"483045022100ffaa954e5b86d54ece9bcb9e37895047221828ca381b03266de3d9341599c8f902200ea1c5ed36e893df822c698a474b062d4f93005c32f9d2f0d78ecaf5a56e4fbd4121031a00f43cd99e015c72acace20ac47d887a39ef284f89a5aa09abd968d06f5e9d"},{"txid":"d69c6ead378471a3f30a9a7b10381a88bd8c5e343b8108a0f189f9f665901269","vout":1,"sequence":4294967294,"n":52,"addresses":["bitcoincash:qzudxte3pz9qf5gmnpr5yxj97kv3flcs2gv5mct8gm"],"isAddress":true,"value":"1792586","hex":"4730440220457d59caf24eb6e10664d06f3e936f6ee31d9d59f1cc4f6f62788f022bce8c1b02202ce7c37ae6832b078c1cb9a055e3ffcf4674081f0738fd9c3eb4465b52bcc9ca412102fea9ae922223f2c68c68d7672b7656885c3e1321d35cc8f5f445179df6f7d27a"},{"txid":"212aa8288a75640e62292417bf53dad20d242df7579c38fa10f2f63d8c03d38a","sequence":4294967294,"n":53,"addresses":["bitcoincash:qq07l6rr5lsdm3m80qxw80ku2ex0tj76vvsxpvmgme"],"isAddress":true,"value":"1250046573","hex":"47304402205e0f5cb06f7fd741825c669c87e9db1a433913fb8577adb92b779d3a693b4f080220120648a5f9d2abae83a29cd2c79f5c61b9bc40da8990736ab97ccf6f82c586cb412102e367f6787fe02523fe7b16fff187757207befd49d038f1a80363592ef5f12806"},{"txid":"3d6a1aebc3f48b843e408421c9f421d3934670d86a3f5df49a6530152056da4f","sequence":4294967294,"n":54,"addresses":["bitcoincash:qrt6ljgpzzmamr2ukg9a3jxe46ufaa8fr5yp6f9pfy"],"isAddress":true,"value":"1801618","hex":"483045022100debfb215f94e9d784e91fe0b9d2541d09a4c7591172fad1441506db4a3590fd102200cce728e344933111c9548162e62872fccac624f6f98d92ccdcf98dbed09ac544121039b8a20c23f32f5b14e76fb29e0baade695810aa7b6dac9e9638a8d13b6ad8221"},{"txid":"91585d5312b1a4c8bca993b6db304a65c7bda601113960cccc978f28c381bfe7","sequence":4294967294,"n":55,"addresses":["bitcoincash:qq07l6rr5lsdm3m80qxw80ku2ex0tj76vvsxpvmgme"],"isAddress":true,"value":"1250046545","hex":"4830450221008110aec39b127143891069590fa0d9e1d8b41bdda70d9807848eba92cb48736b02201bcfdc1a1cedfa4c53efd941482f6157774b2aa80af44e500263be6a3cbcbacb412102e367f6787fe02523fe7b16fff187757207befd49d038f1a80363592ef5f12806"},{"txid":"b9b3d23c90954095289ff5feff55de3cbd7469cbb179e38aa74dc813fd6b684c","sequence":4294967294,"n":56,"addresses":["bitcoincash:qq07l6rr5lsdm3m80qxw80ku2ex0tj76vvsxpvmgme"],"isAddress":true,"value":"1250022645","hex":"4830450221009f76d6838b8fd8bb74f50c67920fda9f28054d093b30fd03b54b3fb888db046f0220307944f3abec07c3570614f418056aeff03c0830173c963bb0b65bd5ef24b4a9412102e367f6787fe02523fe7b16fff187757207befd49d038f1a80363592ef5f12806"},{"txid":"65f9a63b7bf753423cca4a5ec229f566e61cd1ec8f745683da2a934b1308713f","vout":1,"sequence":4294967294,"n":57,"addresses":["bitcoincash:qz86ljat9dnhjp2wplpm7ncfm7q69hk58svu9g46ex"],"isAddress":true,"value":"1593178","hex":"47304402207b93e2500b189b51fbc3a49a191c4b92ac76e32ce86f6f1b9af4afbb3a91fbe002200b5617cf52095bf882a5129f5477f119c9c565dd582a9f19493cf1bdae6527ac41210323ab0930ba40688e66bef6e08f673bd6bcd3df687e4c503387f48c24bffdc93d"},{"txid":"48ddbf6a4cc52b15bb4d2cb7e39fcecae29483bcd3d6471e3543785621f3df7e","sequence":4294967294,"n":58,"addresses":["bitcoincash:qq07l6rr5lsdm3m80qxw80ku2ex0tj76vvsxpvmgme"],"isAddress":true,"value":"1250019587","hex":"4730440220731ab37e71d9c6f63333ba205a318d36e5847706381f571b4b562e5e6f6e403c02200704ca9d9a33843d9a16135f56eced1fd18e227385671a8df5fa41e505e3ba3c412102e367f6787fe02523fe7b16fff187757207befd49d038f1a80363592ef5f12806"},{"txid":"5027ac365cb55b21278f32710703d9ad932912919c58de364e1eb1e9d79412f7","sequence":4294967294,"n":59,"addresses":["bitcoincash:qq07l6rr5lsdm3m80qxw80ku2ex0tj76vvsxpvmgme"],"isAddress":true,"value":"1250045268","hex":"483045022100d1d3565175e1f529124ebba1bcdf8c1704e753c2f91ddcd1a093b5f5403cd0ed02207420ee9d6082356cba6d8075b4fbf310bd84dc770734a8ab30e74741a779bae8412102e367f6787fe02523fe7b16fff187757207befd49d038f1a80363592ef5f12806"},{"txid":"93cc92162ee854259d3b3f9ad1886847eadb2ccc86d03bcc6b89718da9ca23f4","sequence":4294967294,"n":60,"addresses":["bitcoincash:qq07l6rr5lsdm3m80qxw80ku2ex0tj76vvsxpvmgme"],"isAddress":true,"value":"1250086952","hex":"47304402203ddf5c6c5065f03229cdf837d9f8d3d22314834b006e0aba8dacabea206b3b150220417c49c9095372d3dfd954688bcd43fdfd2a121989fde18456a9428b2a8e3c63412102e367f6787fe02523fe7b16fff187757207befd49d038f1a80363592ef5f12806"},{"txid":"c672af6e97eeecc79e87e708d57e20e2c7d811bf3431eaa928f7efc24b663dce","sequence":4294967294,"n":61,"addresses":["bitcoincash:qq07l6rr5lsdm3m80qxw80ku2ex0tj76vvsxpvmgme"],"isAddress":true,"value":"1250143426","hex":"483045022100a20e6aaca7df2b142b768d3b1cbf8f783f3d4997d155a32f0e066b4255777c9f02206deb15cf53d6b27a973df9aa7080691e5914538d9e97ec7c6e797ce03333238b412102e367f6787fe02523fe7b16fff187757207befd49d038f1a80363592ef5f12806"},{"txid":"5f64a0a07336a2bad8f9611709653146fad9fc796f1e92dbd12afbf0d6dcf5b8","sequence":4294967294,"n":62,"addresses":["bitcoincash:qq07l6rr5lsdm3m80qxw80ku2ex0tj76vvsxpvmgme"],"isAddress":true,"value":"1250125454","hex":"483045022100cc2cf5c6c2d4862dfdf65407138684ba45565bd8ec46594ed4586bfa37b715dd022013255b2eb22f5bb93d2afdd07ec4c3b5efe0aa16134b2fd084c6bc720f8cfd5c412102e367f6787fe02523fe7b16fff187757207befd49d038f1a80363592ef5f12806"},{"txid":"256b18d5861752fb617796cef5ceba05e42de141e48aa2737c77020e8d1f337c","sequence":4294967294,"n":63,"addresses":["bitcoincash:qq07l6rr5lsdm3m80qxw80ku2ex0tj76vvsxpvmgme"],"isAddress":true,"value":"1250058048","hex":"47304402202c9dd98c9a72e5a8df4b01f09d18e2826d8b9871db89c5d3b24ffd673facaa0702207523bfcf3ab80790167a2b1159fe268770371fcc7d770995c19eace3181ec8af412102e367f6787fe02523fe7b16fff187757207befd49d038f1a80363592ef5f12806"},{"txid":"aeda3cb9ccecf67cabaae458862b2068129297b1b502b862067f578a2201d54c","sequence":4294967294,"n":64,"addresses":["bitcoincash:qq07l6rr5lsdm3m80qxw80ku2ex0tj76vvsxpvmgme"],"isAddress":true,"value":"1250083898","hex":"483045022100bfac8828df10b7911d341c15a532819c429c7185d8883de19de84e71b97d78730220177603a3572908c90dad865770906b5ad228da7ee5da39503ececf60ac735158412102e367f6787fe02523fe7b16fff187757207befd49d038f1a80363592ef5f12806"},{"txid":"0b11e279a95eaf9241bd55fd7f7b045e2ff047b307b25f3885feb6a71140d6db","sequence":4294967294,"n":65,"addresses":["bitcoincash:qq07l6rr5lsdm3m80qxw80ku2ex0tj76vvsxpvmgme"],"isAddress":true,"value":"1250050928","hex":"483045022100d598e2ccdeecfdfea9d5139a49a94fa39414f9e1ecb13d54efeb34c168e58aec02202a59463710905613844f48dc71d316c0cae54ab9e16dd95beb8902e5940024ee412102e367f6787fe02523fe7b16fff187757207befd49d038f1a80363592ef5f12806"},{"txid":"82026eabe17877d3aae729eee2612778389a9246d56b8032706c454223760eb9","sequence":4294967294,"n":66,"addresses":["bitcoincash:qq07l6rr5lsdm3m80qxw80ku2ex0tj76vvsxpvmgme"],"isAddress":true,"value":"1250039790","hex":"4830450221008302d38e9eaccaea812c853047931562417a3665b8b9373cf7f63e58180b002602207ac8fddbbd19560a74333ec92fa077d169b4902a41e0431113f8fdb75b304ecf412102e367f6787fe02523fe7b16fff187757207befd49d038f1a80363592ef5f12806"},{"txid":"43a94c82abb414437ac13038fa5840a6038733dc156bf160cf30db31a82355e1","sequence":4294967294,"n":67,"addresses":["bitcoincash:qq07l6rr5lsdm3m80qxw80ku2ex0tj76vvsxpvmgme"],"isAddress":true,"value":"1250105160","hex":"483045022100c0d85a1f9146e8ef9efaef8ed9b3ed09c55e51b25e189735610da89b6d212360022003a49114e504741befcdb95d52a3dedd1aadef68b7c48f0a4a8c7dddfb4201b5412102e367f6787fe02523fe7b16fff187757207befd49d038f1a80363592ef5f12806"},{"txid":"41f835819365a32c2ce1138c131a4039c6dfeb034d922af573d997697b409378","sequence":4294967294,"n":68,"addresses":["bitcoincash:qq07l6rr5lsdm3m80qxw80ku2ex0tj76vvsxpvmgme"],"isAddress":true,"value":"1250127067","hex":"48304502210091ec8402cafd1e7eb11b56ac56a994ac79c435893108d0b7c8cfff87c07ba0a602204fd98efddc1b4e21bd3cb81217579a7b9621f9c3c204f2f5800e75ce1c60b19c412102e367f6787fe02523fe7b16fff187757207befd49d038f1a80363592ef5f12806"},{"txid":"2f8ca9dea380bd026636e2281f1e42e63dd54a04be1c1526574994450ca36f01","sequence":4294967294,"n":69,"addresses":["bitcoincash:qzzkjplzf0yw2xej4u9he5pr5evgup2snqqxs823e8"],"isAddress":true,"value":"1366913","hex":"483045022100a850bf088a08baac1f1f577da8946befe2e6b0354d6a29f636afd39982569a7e022062652d6b75dee145f741d28d6f1870fde9a7d66b994f0d3162abdc42fbf54458412103ffdeec10b52942b0c46d6578998efdc1d64073de579e92e7c5dfa97fdf3ac391"},{"txid":"404829243c500005d37a95164bf6610005ccfa19cb7660ac9c1ee0da009465d8","vout":1,"sequence":4294967294,"n":70,"addresses":["bitcoincash:qq4kx2926zmnhfa36xzfswf9p9raqlapmysqvr4ck6"],"isAddress":true,"value":"1292340","hex":"4730440220762f7c017672dfc71d487f3730e26d69d0e53902f579ba348095ca164d27b094022076c7e8045ec9fc57af6dd95f35c0ffad2c0ca8f83f112f60fb9851ba4ba15d92412103a2d2d8251728b11fd4afe7b8c73a8442f76dff9bfa424f5cad9b98083936259d"},{"txid":"2624cad28a9b7f55434b68fc8be7aadb87d40003d786f0e414cc1eff74a12b64","sequence":4294967294,"n":71,"addresses":["bitcoincash:qq07l6rr5lsdm3m80qxw80ku2ex0tj76vvsxpvmgme"],"isAddress":true,"value":"1250134907","hex":"47304402200654032c5760f8b94cc089da51773447f19c1cd2108cab89bb53ccfdb6dbee56022015e277622dea4bd1a7913ff934b2bb2d1b3d75f05285b51690160e1197a258c5412102e367f6787fe02523fe7b16fff187757207befd49d038f1a80363592ef5f12806"},{"txid":"893b3cfda77c1371e21df17e45910578fd778958f9b51fcebb24a2e92c604d65","sequence":4294967294,"n":72,"addresses":["bitcoincash:qq07l6rr5lsdm3m80qxw80ku2ex0tj76vvsxpvmgme"],"isAddress":true,"value":"1250033040","hex":"4730440220712877c0dc553096eb0ebf101d1555fda5235db26ad074d2f330163fab63fc7802202c89752dd7645e8a3da7e8af5fb68dc8b177700766b79cf6a35695a0c7c873cb412102e367f6787fe02523fe7b16fff187757207befd49d038f1a80363592ef5f12806"},{"txid":"cd86f3aba8b0553de0041a2173507a34f595a3785dbaeb8c9b2cc1c1c34c61cc","sequence":4294967294,"n":73,"addresses":["bitcoincash:qq07l6rr5lsdm3m80qxw80ku2ex0tj76vvsxpvmgme"],"isAddress":true,"value":"1250105407","hex":"483045022100f3fa1e305666e2a62afaa11fd37025b25c0bdff8709fe1580406615934228cee02204841a7d96f36d3c183f06e22a58175756c3e9a76c93c7cb4e9945f31ddedc902412102e367f6787fe02523fe7b16fff187757207befd49d038f1a80363592ef5f12806"},{"txid":"ae8ae862b5ddba89e69b42aa8a6ea2693e61f90ad3a5625b5f81605c7aedb226","sequence":4294967294,"n":74,"addresses":["bitcoincash:qq07l6rr5lsdm3m80qxw80ku2ex0tj76vvsxpvmgme"],"isAddress":true,"value":"1254457185","hex":"473044022047c158e3fe3f40de3f39796dcecb7df3cf344f14009de9826b62a43837f2cdcb0220759d823cc145fd5e8b651a7bcc399544692bbf596189b1fc50bba5f4ca02cdd1412102e367f6787fe02523fe7b16fff187757207befd49d038f1a80363592ef5f12806"},{"txid":"b402b3d23c910e0ed869045671269210f6594f308b6b01a0bed2052f6012b0eb","sequence":4294967294,"n":75,"addresses":["bitcoincash:qq07l6rr5lsdm3m80qxw80ku2ex0tj76vvsxpvmgme"],"isAddress":true,"value":"1250101109","hex":"483045022100bd70744c867943bc3bf578e192c8a87a5ed5126aac4acd98efa06ea2483911fa02207377e11ae2d2bbaab00da86ec73c26e596bfcc680c0b8eddc5d44bda650bc299412102e367f6787fe02523fe7b16fff187757207befd49d038f1a80363592ef5f12806"},{"txid":"e1deda4073c863ba018bd7334f625f79884854006f27712cd010e57bf59c8087","sequence":4294967294,"n":76,"addresses":["bitcoincash:qq07l6rr5lsdm3m80qxw80ku2ex0tj76vvsxpvmgme"],"isAddress":true,"value":"1250083658","hex":"473044022059ee25066b8a2a4fdfc35f14c5cbb7f22ab181fcfa9702d4f3de7aa4d738c7a402206dff315ad1cd2222cd6ac074bf34241fc22db38a57bf089f7e24542323f1766c412102e367f6787fe02523fe7b16fff187757207befd49d038f1a80363592ef5f12806"},{"txid":"219c39d91c3d5d3d1f81c83ba373df7ccaecb45f5e4a2f7422bb2021afb7338c","sequence":4294967294,"n":77,"addresses":["bitcoincash:qq07l6rr5lsdm3m80qxw80ku2ex0tj76vvsxpvmgme"],"isAddress":true,"value":"1250032757","hex":"473044022039657cdf4fcd5a9e81766ba11db495b8be5664612d3b91f8504bea342c4ecbe702206ca4913e5807cd697d30dbc93e0a9d679eb01ee84b687ab0c642e2f3ebde745b412102e367f6787fe02523fe7b16fff187757207befd49d038f1a80363592ef5f12806"},{"txid":"3a1f594a74bad6de4c762a78a6c06db3900c45408ec0f785c61bf9f29bc34281","sequence":4294967294,"n":78,"addresses":["bitcoincash:qq07l6rr5lsdm3m80qxw80ku2ex0tj76vvsxpvmgme"],"isAddress":true,"value":"1253061599","hex":"47304402200232ee94873317eae275cf715f4c3aca25dd0c8db4800946a45cc1d9c45732fa02203d9ce9c9aedc0a3899dd027df32e683438769d66f33ffe52006454614b77821d412102e367f6787fe02523fe7b16fff187757207befd49d038f1a80363592ef5f12806"},{"txid":"14cf83e6c8b80366b8651c6b4a0f7d2270290066325d686ba671ab5c4c9a3b50","sequence":4294967294,"n":79,"addresses":["bitcoincash:qq07l6rr5lsdm3m80qxw80ku2ex0tj76vvsxpvmgme"],"isAddress":true,"value":"1250121784","hex":"483045022100900bdc6f705efa56449a65f15a67fc7fbbc102f78e7974ea6ac2849c75d2dfec02203b78de71dad2e3f6ffad2779cb9007217c957c8f5db7abd58fd0537fbabb8c6b412102e367f6787fe02523fe7b16fff187757207befd49d038f1a80363592ef5f12806"},{"txid":"1dd1ec6c4b4ec9bf13aec933506376c77e63254d5573c2584d7515554f14ed8b","sequence":4294967294,"n":80,"addresses":["bitcoincash:qq07l6rr5lsdm3m80qxw80ku2ex0tj76vvsxpvmgme"],"isAddress":true,"value":"1250044721","hex":"483045022100becbb21c7937b9b27ea3cdac5f2048ab9ac314de59c3ee2926a5cfb258ce14e902201c8022bf275c1a761e7715b14e15d74526901363ae5f8bf5489d00908dd758eb412102e367f6787fe02523fe7b16fff187757207befd49d038f1a80363592ef5f12806"},{"txid":"9957066f6fe221a9423b0f54ce1188000e1e9f7bf9085527d9e1edb31d88b7bc","sequence":4294967294,"n":81,"addresses":["bitcoincash:qp7zwhgnhhuh4j8644mqg7y3fqejm2jkfvkt6qp4pp"],"isAddress":true,"value":"1876300","hex":"483045022100ad84bcd69a85a0d487fd7cbe4d76b95bffa303e76615a4336419fd182eeae4b902206d21e4f592297e87f1af9e19c80fd978914aaf5a2db2cf499b72cabbbe73c831412102958762ff6c8985dc9656afda59e61afc6c0131a5d8f1d86c87c83c9b37f7bd18"},{"txid":"ca467662c89f207dbfc6ec016e126693a204f17d6151987aa748838852aeffb7","sequence":4294967294,"n":82,"addresses":["bitcoincash:qq7fvpnuflq4cq6wc5t4qjuzj8l59puq75h022fyxs"],"isAddress":true,"value":"1114817","hex":"483045022100edfd64cf9335d094d5873deb38cda5f4ceda3351df722f1c718993a2dd12c8e302203126b0f9470a4d0867ed4e773518b8ad689ce43a2c9f65a1f297525fc22201dc412103f37089783028c0776f2b8a9d8481ec8d6d0652a31edc03cc274032ae17c63c62"},{"txid":"54fde006c8dbb7a3de68e0609d057a3f2337c99ee2ae70cc715d72f5dc881a80","sequence":4294967294,"n":83,"addresses":["bitcoincash:qq07l6rr5lsdm3m80qxw80ku2ex0tj76vvsxpvmgme"],"isAddress":true,"value":"1250175152","hex":"4730440220448751a749e7cccacab0ae1ad4da948b0e0b5d8e3f41ac2b22c18928e8e67d41022051c107c345c06ea82fe8329a8cf3a96b516fd8750611d8ef438b8545416398ee412102e367f6787fe02523fe7b16fff187757207befd49d038f1a80363592ef5f12806"},{"txid":"a08d7c70130d925e33b93e21cf77b5790a2ab5b5dfc4ec2198b9d81a74af06bb","sequence":4294967294,"n":84,"addresses":["bitcoincash:qq07l6rr5lsdm3m80qxw80ku2ex0tj76vvsxpvmgme"],"isAddress":true,"value":"1250056417","hex":"47304402207f9b2802ed1e893168277204b7919ff479efe5c71ad2a255e1738a52bacd758f0220253780485f2e3ee960e058d449c647b147b8f64b49b913e7e9615a6c7114f18e412102e367f6787fe02523fe7b16fff187757207befd49d038f1a80363592ef5f12806"},{"txid":"e2c0a8e67a48286fb8801c0faa3951a268c5f6cc450c445c380e80e09c752778","sequence":4294967294,"n":85,"addresses":["bitcoincash:qq07l6rr5lsdm3m80qxw80ku2ex0tj76vvsxpvmgme"],"isAddress":true,"value":"1250043784","hex":"4730440220778fd8ba1dd9f71df55bbe1c3c4185b8da21dda82198546c2a0c30250f4c1d66022040f17a46187d535c6e943c047942f45159a37b2e171db18c657cd24168c22e2f412102e367f6787fe02523fe7b16fff187757207befd49d038f1a80363592ef5f12806"},{"txid":"221971a381aaba4e963d21b54e625b764016e848a5390a0df32a29aadf35f92a","sequence":4294967294,"n":86,"addresses":["bitcoincash:qq07l6rr5lsdm3m80qxw80ku2ex0tj76vvsxpvmgme"],"isAddress":true,"value":"1250090058","hex":"47304402202cd2fd29fa395a5a80893de065c8bbe71e0bfe0e7b2224cfd5684736a086aabc02206720226ba63a3e5d9e2dc67e404625cdf31a7a08da0e8a22717e558f7abc817c412102e367f6787fe02523fe7b16fff187757207befd49d038f1a80363592ef5f12806"},{"txid":"bf6623abb315d54e6b7d9428133d913121ac875dc4c8e3f698477dff8cb7e3e3","sequence":4294967294,"n":87,"addresses":["bitcoincash:qq07l6rr5lsdm3m80qxw80ku2ex0tj76vvsxpvmgme"],"isAddress":true,"value":"1250229940","hex":"483045022100f8769b797386f0bdd662483096f4e0a33c13f6074a4aaba3fd590b9abbca7c2402201eb064869fcd17a59ac028145b08c73b3552544cd7fc62245d1fd1d369ecf765412102e367f6787fe02523fe7b16fff187757207befd49d038f1a80363592ef5f12806"},{"txid":"e66b832bf71437eeb367e6cd7818658f960a4845bdf3f5081aa474935c9b31dc","sequence":4294967294,"n":88,"addresses":["bitcoincash:qq07l6rr5lsdm3m80qxw80ku2ex0tj76vvsxpvmgme"],"isAddress":true,"value":"1250154777","hex":"4730440220558e65fd916d9c9616a3e0bd41111dba3914867b1ce5d487df4f77feadc0059502203198566c0d58af8551b65f884db98bde161bac140c7a900cd40df97a40c267de412102e367f6787fe02523fe7b16fff187757207befd49d038f1a80363592ef5f12806"},{"txid":"452873e0c38438227a2fcf64230973ea8f5868fabf05603b629881a2b46a4069","sequence":4294967294,"n":89,"addresses":["bitcoincash:qq07l6rr5lsdm3m80qxw80ku2ex0tj76vvsxpvmgme"],"isAddress":true,"value":"1250103829","hex":"483045022100ca93287feb58daad47c5388067b219e44f8533a214eb8eea9b5313040579773002201716a6ad2de70eff6721ae7950edaf9230420648bb8ec53173c215cbd12246c0412102e367f6787fe02523fe7b16fff187757207befd49d038f1a80363592ef5f12806"},{"txid":"60b3b027b67f550a0544a539f173066031914f0a49897379b51ffa127117e521","sequence":4294967294,"n":90,"addresses":["bitcoincash:qq07l6rr5lsdm3m80qxw80ku2ex0tj76vvsxpvmgme"],"isAddress":true,"value":"1250125814","hex":"473044022003240fd71510800910b448c62a03178b4ef62299b17d6d2c06ac8f3293684ff50220637e3ba59fc884a8bd16aa2e884b379d85f38ae4ba049a0365f33644febee6df412102e367f6787fe02523fe7b16fff187757207befd49d038f1a80363592ef5f12806"},{"txid":"6cf9e489432bda9fa9eb865587eb28ff525b5171c38f746c55b85a577ae68854","sequence":4294967294,"n":91,"addresses":["bitcoincash:qq07l6rr5lsdm3m80qxw80ku2ex0tj76vvsxpvmgme"],"isAddress":true,"value":"1250144563","hex":"47304402202e2ac9c8b619b8e2626895c20f6bdd1a24fa27de017d05d5fa2ce120b3421f25022053ef6f82ccf9a132d40ce566d45f4ec18bf30048d415f6ec1c783cda027b6747412102e367f6787fe02523fe7b16fff187757207befd49d038f1a80363592ef5f12806"},{"txid":"9c9923f0c3366eea9c229233d8828825beb12a2c28ae3bfaf46203dd1fe8ab03","sequence":4294967294,"n":92,"addresses":["bitcoincash:qq07l6rr5lsdm3m80qxw80ku2ex0tj76vvsxpvmgme"],"isAddress":true,"value":"1250218730","hex":"4730440220352bdfe541e9e1ce428ac4eb4c8ba9391a118b7dbe57b4fe3c4ecd30f228fbff02204a0b78ada1d74a7e7b9ae912e6f445d9ce9050855d9c5ecc7d477d2590a68b18412102e367f6787fe02523fe7b16fff187757207befd49d038f1a80363592ef5f12806"},{"txid":"5ed23fa46f4db7043e14b845ef13a37712170f7cb25f88ff9acbbd6bc97a9d87","sequence":4294967294,"n":93,"addresses":["bitcoincash:qq07l6rr5lsdm3m80qxw80ku2ex0tj76vvsxpvmgme"],"isAddress":true,"value":"1250079095","hex":"46304302203f767d8f64e3c9e5773d94a325f8029d21d1c9a0f470c9288cd99f70d2d90ec2021f50b395f9329ffe64ff8084c1506e904ffc02dfac7f7e15461c3e8a077f604c412102e367f6787fe02523fe7b16fff187757207befd49d038f1a80363592ef5f12806"},{"txid":"fb09c795e5cf32d174df4efe8b2208de9819ed024511d9fd684556ec8adc00ff","sequence":4294967294,"n":94,"addresses":["bitcoincash:qr3vdgfvrp77mlhac73ujqgtn78cg6yeeurwnjqylu"],"isAddress":true,"value":"1792434","hex":"483045022100f17f8045a627bf96fe09d868109063d8040e3e2df8944e05f9b20a15273d0bdb022059c31e2d849abd57e784f1a3903f49f18c7c5a624545bab98649e8a092e12a10412103ee2a3f78cd4930dac8c030ccc93381ec5eab259c1607360d85d1728fc296dacf"},{"txid":"36bf90cf0b6074a361292ec88ef58d76780d301a1e5709bf013808c068af253f","vout":1,"sequence":4294967294,"n":95,"addresses":["bitcoincash:qzjvk52q08wp84x9uelf7k3572fx4z5q4q7vkpaalx"],"isAddress":true,"value":"1713598","hex":"483045022100b58c7dd3fa1f8dc50edc7b5546b8ccef8ffc5c179fee774999c63fa729ae3cef02205eb611cc887e5a62a4e9da33318ce6e216ca353225f452ebca51be1dd10f544941210267f3c9b9bfb6bc5c1f68dd1d18623a9986408202cf232ad1e4089933c83f186b"},{"txid":"259bc4abb9f14457e323223bcbbf772afc0a0252556e69c9e13e8c7860e7946a","sequence":4294967294,"n":96,"addresses":["bitcoincash:qq07l6rr5lsdm3m80qxw80ku2ex0tj76vvsxpvmgme"],"isAddress":true,"value":"1250075778","hex":"4730440220097f46c588f37ced4846a45905df1a0ae22709760f8a1bc930a58f5054cbe482022053b418af66d1edcb3887616feb23e5dd4095f29e74ac89853c3b909eb42bac34412102e367f6787fe02523fe7b16fff187757207befd49d038f1a80363592ef5f12806"},{"txid":"14a32331f78309de6ddad707840b364aace14cbef8694ab16a55305fd44260b2","sequence":4294967294,"n":97,"addresses":["bitcoincash:qq07l6rr5lsdm3m80qxw80ku2ex0tj76vvsxpvmgme"],"isAddress":true,"value":"1250085059","hex":"483045022100cf98e22a2854c7088a0572e1edb4e876aa622ed10dc0376806e1432f5dc1eef90220527845f8dd2522fbdf423b4fc34a4792a7f82e04b314e0d83e2425daa2f92115412102e367f6787fe02523fe7b16fff187757207befd49d038f1a80363592ef5f12806"},{"txid":"acd836ea3252a7610e6c1d426f2cc739f73fe1a0768048d7431a69d4bff3f0e5","sequence":4294967294,"n":98,"addresses":["bitcoincash:qq07l6rr5lsdm3m80qxw80ku2ex0tj76vvsxpvmgme"],"isAddress":true,"value":"1250132855","hex":"473044022070c7aaa7d7f050b1b520878e55db3ca491fb33211150e2f620b685cb49d7d885022022d9ede63e3b196a1c33c2d211c1eacf2e2411820ecf5155b5e4244f5dfd9f1d412102e367f6787fe02523fe7b16fff187757207befd49d038f1a80363592ef5f12806"},{"txid":"348cdfc73c3172311b972b8c529545591f725b86ad065f88d7a78c2fcc05f9fe","sequence":4294967294,"n":99,"addresses":["bitcoincash:qq07l6rr5lsdm3m80qxw80ku2ex0tj76vvsxpvmgme"],"isAddress":true,"value":"1250023474","hex":"473044022018cd70c3e62563ea92ea12735e2efb4b905df85e6b290d573051f49c63d07c60022037a537ca3514121d5c2b8753833808a5e0432f1a8f277d91495953c8211ad326412102e367f6787fe02523fe7b16fff187757207befd49d038f1a80363592ef5f12806"},{"txid":"af7baa39bec2ba327ff720a7c782f833d18c0677c644080f59996e2270756c55","sequence":4294967294,"n":100,"addresses":["bitcoincash:qq07l6rr5lsdm3m80qxw80ku2ex0tj76vvsxpvmgme"],"isAddress":true,"value":"1250249377","hex":"483045022100a01ad9ec8d24fdf01eb203c2887c1413ae56990d4600a18010959f6df43de08d022056f0f0dccb8f772f29a7835d7dc40f242348805005b5f80ae8f2fbdb600ab2ca412102e367f6787fe02523fe7b16fff187757207befd49d038f1a80363592ef5f12806"},{"txid":"6ba95cc08cb6849c9599eea8ec3abeb7ba7c7b42399cfc6d807dbc5aa8c1be52","sequence":4294967294,"n":101,"addresses":["bitcoincash:qq07l6rr5lsdm3m80qxw80ku2ex0tj76vvsxpvmgme"],"isAddress":true,"value":"1250192878","hex":"483045022100cdd770159d56ac518ecb0dc916df0da06eed536e540582680f742389f53fa4be022012d372e2c04176bcb82b91b02ea23c9c1464baef7d1dda66066bf84c402c0012412102e367f6787fe02523fe7b16fff187757207befd49d038f1a80363592ef5f12806"},{"txid":"41ebe9615cb3037d95ed10c37be1fc80d216619086c5cfc256e489ce42042d3b","sequence":4294967294,"n":102,"addresses":["bitcoincash:qp4h56rtxkel7traz24d3ep3jq0yxqm82stgclvks8"],"isAddress":true,"value":"1288555","hex":"473044022001dc7db378891c1c5bf07a09d14fcc6675965976e2e3e762786b1b1e0f4a4bb702206db6f284dec835823fb516fad89543edd3bd7af3ed33940fa296939fadb41ba841210393ae47ec2e844378cda3630abe12082401f2e0f98d016dde2b152b42e335630d"},{"txid":"a135747cbd99ace7bf495ba29e49b5595f32259ee7df61d9549cf3d4274880c3","sequence":4294967294,"n":103,"addresses":["bitcoincash:qq07l6rr5lsdm3m80qxw80ku2ex0tj76vvsxpvmgme"],"isAddress":true,"value":"1250118091","hex":"4730440220290a5055313d68f9461ce830f8a7395022d2d55abf28f6b4bd665693b4a13730022035d4cc2a6676ed842027dd4f21d31dd5a956f4b1f5cf771b866cc0d4a6400df0412102e367f6787fe02523fe7b16fff187757207befd49d038f1a80363592ef5f12806"},{"txid":"90095e01bb497ffceeb85366ee1b9603b96c33ee0acb47a64fe3af23911410d6","sequence":4294967294,"n":104,"addresses":["bitcoincash:qq07l6rr5lsdm3m80qxw80ku2ex0tj76vvsxpvmgme"],"isAddress":true,"value":"1250028058","hex":"47304402201fd6be6d72ae75b61a624c13476b538ec2f9e5146f3074c879af57ecfbe1679702200ab10ae612e7fe0f76fe943c1f6a02262008407f86782c1536e92e3bad77d3db412102e367f6787fe02523fe7b16fff187757207befd49d038f1a80363592ef5f12806"},{"txid":"44b169e5c5414cd335ef67906c0f4425e8b190ab366dd1e16641a34d85ab5f20","sequence":4294967294,"n":105,"addresses":["bitcoincash:qq07l6rr5lsdm3m80qxw80ku2ex0tj76vvsxpvmgme"],"isAddress":true,"value":"1250132073","hex":"483045022100a4132f408b5299dfed6153b7a331f9fe866f1b042e4263bf7574ea0964c450a202203d99cf8dc9a9194269bce400185a4f86f5d35b5be83f6dbc3166b600392f1b00412102e367f6787fe02523fe7b16fff187757207befd49d038f1a80363592ef5f12806"},{"txid":"f7f16d4c8f00cb446063f53a75d2dbb2c54d9d474abc836b92d48ed76a5ead8e","sequence":4294967294,"n":106,"addresses":["bitcoincash:qq07l6rr5lsdm3m80qxw80ku2ex0tj76vvsxpvmgme"],"isAddress":true,"value":"1250210684","hex":"483045022100bbcc2e2d77458abc30898cddc7eda060b23a62f0a53b81c3db47f284cd7b29cf0220705328a29bd30792a7f5a704fd74b771c3c8a099265f5e7c9d70046da5b03ff4412102e367f6787fe02523fe7b16fff187757207befd49d038f1a80363592ef5f12806"},{"txid":"0252408a18fc77479f6e664fab80cbc6d90c1c5e369c34661effa52b9f1f36f2","vout":1,"sequence":4294967294,"n":107,"addresses":["bitcoincash:qqe36s4qsvdfjzwrv8whsc0z94unav03agzr35m4d7"],"isAddress":true,"value":"1591983","hex":"483045022100d2f40145c4b9a17b3582aabdf7d9ac2d47546b3eea5350c4e2ec1e9c2466343d02203354ce620aa056a749de847f867c49dd121579c9fc50bd6258bff7cfb173c5f24121035bf755e8b075665a85155618f6e9022196a09c486415587dd3af0d25b76e9c27"},{"txid":"74002fe81a5931658cbde74c28933bb36cdaed62201be1c0e26a53c92d6bf5c8","sequence":4294967294,"n":108,"addresses":["bitcoincash:qq07l6rr5lsdm3m80qxw80ku2ex0tj76vvsxpvmgme"],"isAddress":true,"value":"1250148696","hex":"483045022100cf8c593dec0724644d034f17ccde99feaf0416334219f158f884badf500fc93e022035af1b68574e88ef15e1c05c1b36638401613a31aa7096d97efba6df62695706412102e367f6787fe02523fe7b16fff187757207befd49d038f1a80363592ef5f12806"},{"txid":"496b4d67e0a734740962920c116d56121c16ca60787812fea76d69b9161f8395","sequence":4294967294,"n":109,"addresses":["bitcoincash:qq99u7jj9ujglljvh8nzaqtq0kfl8matf5eldrwhmm"],"isAddress":true,"value":"1859920","hex":"483045022100a669e8918ba68754b84d584f38afdd34be387773449784a6c61ef3f33d0fd99e02204d007ef31f5a3a7c412ac3d2660633fcef137964ef2ff6269c41e933896d918b41210383b6491fd80e1411675d7c8eda9b756c30a814b45fa565b7ac24d7be9dedcaaa"},{"txid":"4a6f608d6ce8efcc0cbd3b55bfa0feef86f5493331564dee943fa554fc84111e","sequence":4294967294,"n":110,"addresses":["bitcoincash:qq07l6rr5lsdm3m80qxw80ku2ex0tj76vvsxpvmgme"],"isAddress":true,"value":"1250058421","hex":"483045022100fc35ed21833c3ea3ff5f832ef02236a08ded0999ea367aa6eaaff364ecac3e5002206e291d7c4fca0485dd8ea22519544ac632909d706741710a6e5f0d472c0b0656412102e367f6787fe02523fe7b16fff187757207befd49d038f1a80363592ef5f12806"},{"txid":"a9cfa2539cb07c0903e2a01a343c6ea8566bc063b4c301ce2efee45760e36448","sequence":4294967294,"n":111,"addresses":["bitcoincash:qq07l6rr5lsdm3m80qxw80ku2ex0tj76vvsxpvmgme"],"isAddress":true,"value":"1251645868","hex":"4730440220485937c55c67c8eb46b94523cb06f9572ffb55094536d8b1a458c76b67dec75b02204e5007f610e491d043a412696d4fd769bb2f5d8c3e8b3a59e6ec3bb598f775a7412102e367f6787fe02523fe7b16fff187757207befd49d038f1a80363592ef5f12806"},{"txid":"62466cac8a8cb05584af3ce85d0eb8d4a5edf644a374aa23989bfa2adad2d8ee","sequence":4294967294,"n":112,"addresses":["bitcoincash:qzl7yg7fxw5ls4jum50st5z7valsu7qa7v63ks2730"],"isAddress":true,"value":"1579507","hex":"483045022100b430528ddfca4431cf5cec08964f7325c036fdee55edc0ea0181d34ed72469bc022074b75bfa66dd4a87fab93da0f2f0def65b785fb0b51fe07355799cbd8b30c39a41210316d35753d58318c06d0faadcb723563316847ae06019984f42f2c75deaf3727d"},{"txid":"559927367907ed4d3822c2b4c0dca89ba2a4df844daa1033123e9939c9e81743","sequence":4294967294,"n":113,"addresses":["bitcoincash:qq07l6rr5lsdm3m80qxw80ku2ex0tj76vvsxpvmgme"],"isAddress":true,"value":"1250110065","hex":"483045022100c6ccc3891fa3924c7b1e69b855628230c48d85d1e1331f037823ab7c5928610c0220050c9c0e078f34ced537e88f95289863a663b28488880f6ada3f1dbbcb1743a1412102e367f6787fe02523fe7b16fff187757207befd49d038f1a80363592ef5f12806"},{"txid":"7b5bfd94b29844e13c3fce76d9579dc7d20b3fa0ef15309714530152e4d5ae85","sequence":4294967294,"n":114,"addresses":["bitcoincash:qq07l6rr5lsdm3m80qxw80ku2ex0tj76vvsxpvmgme"],"isAddress":true,"value":"1251309649","hex":"4730440220168f31f413d65ce64bccb62390490dae2e4a00f98c2c44bd4fd689cd942da8b1022006f1b2aa4fae9587c688e8b7ca5c07db3b3c3afd6961f9f843099ed30b583369412102e367f6787fe02523fe7b16fff187757207befd49d038f1a80363592ef5f12806"}],"vout":[{"value":"32902","n":0,"spent":true,"hex":"76a9149a262d0621819c8c17d34a7feca1b39b39157af988ac","addresses":["bitcoincash:qzdzvtgxyxqeerqh6d98lm9pkwdnj9t6lydxqg82t6"],"isAddress":true},{"value":"115067302350","n":1,"spent":true,"hex":"76a9142ed9aeddd3aa62d922d33025901531e344914a6288ac","addresses":["bitcoincash:qqhdntka6w4x9kfz6vcztyq4x835fy22vg3yc55de7"],"isAddress":true}],"blockHash":"0000000000000000023414a6f8ec13dd4f85b3fb1c71b937d5dcaa14e350cd4d","blockHeight":611623,"confirmations":24477,"blockTime":1575319726,"value":"115067335252","valueIn":"115067352350","fees":"17098","hex":"0200000073126b74e8eb1830ec84d26e50d09360e120e92956c823afdb2e981432e60e152f000000006a47304402206f992d73dfa7e518b00190f220ad5dc7b7947b1d75a2fcd8251b59f3d29d89af022036c6c44f52f9aeed406dec72a9aab1f82c3b997c36742f4a3504e4f93e6f8557412102e367f6787fe02523fe7b16fff187757207befd49d038f1a80363592ef5f12806feffffff3848b83fe17d5304f63a9457a5749ea2ca1ea42d9934cac890666e2173a80b55000000006b483045022100db30ebe47536e42115a507f88bb8d5c97b81ad05ce334872235811134c5948bb0220418d77aed78cc4a332b1858c1d2e9ab169828b9c12e8c0d0f8d155964e5d0b8e412102e367f6787fe02523fe7b16fff187757207befd49d038f1a80363592ef5f12806feffffff4321b2ccc28666c12200bb15a050a513976487cae0a01205cd30ca10988d8ded000000006b483045022100d30c9fd598613586d8d0460fb6c9ffc1d0c6dff6f647535d2a9f69cf373193d102207fff687aa035910db124adad8b59607a72b3d24aca9096217ec6b90fa132a2ae412102e367f6787fe02523fe7b16fff187757207befd49d038f1a80363592ef5f12806feffffff32a0d8da2143d7c4097af72285aff1305155ff5e05276badc91839d5ac9bd7a2000000006a47304402207b30e99cb1f6754d227a4511c5b7791f3b896724b170716d6ed238017f191bb102202c1fadc4c572c86288b002a0d6b6d2460a14a6d3c8b49efc17a03e59d2db18e3412102e367f6787fe02523fe7b16fff187757207befd49d038f1a80363592ef5f12806feffffff62f77994b08467f9a90c1b7b921306d7e48c18015aa53aab74775b73dc79069a010000006b48304502210092b7f176f182936323df8e4359b2a329b0c1e4b48a529d6e32867038a2a453cc02203c24a8bb46b7fea4ef5c78ff116a51fd0a04dee25bfcdffe856fb8988a7a97f64121035b4e75dda9fb0d55d856f54f24fc65da6657939b9559ab2c623c8ef325f14d8dfeffffff5cbff5ba887ac02cfcf6f1adb0c84ae21cc003667734dbc41ddc31330c7c555d000000006a47304402202a2bcfdaf12c398ed5372e6b168a786edb8972df1146b705d3cccf2d9601517d022020b90ac89d9141d68817850d1cdffaf6c51f45249a44fd6861b361a6025d8ac4412102e367f6787fe02523fe7b16fff187757207befd49d038f1a80363592ef5f12806feffffffca0bea62231cdd9cb231ced73fc1c0f51c478277a077a55aeec113b506e7db61000000006b48304502210087ef2709b9fe8e7f136219254229edd45e94c3f6ebd2bb149aadd9b1d44d89e202206ffde3c9491c012832967e4d34e02ece2c08bc4c07967b3b466d4800f9ca0746412102e367f6787fe02523fe7b16fff187757207befd49d038f1a80363592ef5f12806feffffff843b9b8e0072454494ac701e9f0816590de35f53cfe960aa03bb4281128db254000000006b483045022100c7dbd1117c57eedc8fc006e818371bfe6399c4d25e8b40482c1f0858a3d98a4b0220426d1196513a87fc7afb5b107b770a90af789536799a11686eab96b04afa6326412102e367f6787fe02523fe7b16fff187757207befd49d038f1a80363592ef5f12806feffffff2301458143bdd235636b4a15f1ce7fef218ef401e26f5871d26bb28e632e0c75000000006a47304402203604fbb20824443899030d2c1f5cd0dc2b88174929861a708bdca878868e910c02200a607b1da53483bc95d3a5c54e5ad66e459827d4ecf8b4ef9909e9d58b2d329b412102e367f6787fe02523fe7b16fff187757207befd49d038f1a80363592ef5f12806fefffffff9ecbc5e26870067db7ee944b7fbe3fa99c3247e0614fa5bf24a9eb587c36d9b000000006a4730440220399c36174173cca01f6d6a234a935d6f776b549e1ea2fc2635193924c4ac2eb002205aea7741fafd95f862588c480aaa282d7a344d32d6318aec1a908cbb939e5d0e412102e367f6787fe02523fe7b16fff187757207befd49d038f1a80363592ef5f12806feffffff9ef492949a0ba873b09258961f35cd18d78849cd290fb93aace31af829da278f010000006b483045022100da9075310e7af59456423be99362f2cc686d50571e0f0b016bcfae1f0bc4692802203379b648d47704dba48542b8b6d5e515bf3c4fd7ff8a7be82cd0c8c0c7be56f7412103a344a84dc1a919a64874605fae200861b7af3ecd02dc5d52dd00eb6f8845525afeffffff5c5f3037b499d79505425804b021b76dd94e1632b6747afd059d0a728ff49b10000000006a47304402206cbf93634d6a477a571fa2884c19918b19ddfb008ff9fe405954720047efdb88022003e755313436d406dddfe3cfb68719e8f39e43de7c586489cc543dac0347da9f412102e367f6787fe02523fe7b16fff187757207befd49d038f1a80363592ef5f12806feffffff0b183fcb0f29cff3e9f22ff47a5c87694199ec43b77930f7b17d646f3670e5d3000000006b483045022100f23d4cf11fd0a5ab83dc053ca64066cbdd2fb4107e0977a3a880c68a67636f7d0220220a47c66d3944cfc309c059fe8013c4de742e4d8590003fd56c5e0b3c7da557412102e367f6787fe02523fe7b16fff187757207befd49d038f1a80363592ef5f12806feffffff80540561a82abdba58b2ac3bb9bf9f1064106b8f2fdcb63d462721409af9056f000000006b4830450221009f522beef55cbf8c7f10e88739846f78ef1c9d9cbc6959dba6f687a08fec0ef502203a160231733b87c6cfd8afd148994c9b6c5d5db9bb9847aa9e60938a6e79d5b1412102e367f6787fe02523fe7b16fff187757207befd49d038f1a80363592ef5f12806feffffff4a4a1e4ea13377a0819a88e2664facffabd92566b83fdca3456267b017b7933d000000006a47304402201f5d29be80192a752fe28ff141ed702640df88083faf3f9573e52405cb4bd79a02202d751649aa600c4fdb8b1d1b21f0d134c2f4e5af9ecbe7d87180d667140f0a11412102e367f6787fe02523fe7b16fff187757207befd49d038f1a80363592ef5f12806feffffff9b41a363950ab3e6b769a4cd97555d1d8336505f3c87599ebf7766642ec97ac7000000006a47304402203f4bea3816d252cb19d4247f587a146901c74d04e783efddfd5089942f2abcdb022069012613c4ee4b3b0212ae71dbd2071e01665148697011eb03eba25431e679cf412102e367f6787fe02523fe7b16fff187757207befd49d038f1a80363592ef5f12806feffffffab050b7b334656d60e2c9772a3820015a2f6a7cc3e2943897b0c027edba3cb90000000006a4730440220782ba77287116d5d735f67a3738fbecc1a802d2141a1fa544f61a5e8ba682a4402205473d68019cc8895ecb1d87bfced62ddb6dc48b81152f2684ae8530122d5b41f412102e367f6787fe02523fe7b16fff187757207befd49d038f1a80363592ef5f12806feffffff26dd82e448134b4105f561b681206a059e1de4e5690453dd8e4d9a0482c35ee2010000006a473044022044ed9bfa8674d7e83112fa22280797169d45bd971b185da2413e36252637529d0220531eefc480e0911d6ccda42002942883149bc1cdd1f3bbde313751d80bcf98b641210328ac4ed2b30ddc04c778a78b24e7256b08c55758c1465defd997ff4bcefacf10feffffff9e2e1b53ecf545d0b0cb972553deb89f3cce7e9e92d0e0a786779df0df48a113000000006b4830450221008cfdfd352e268dba2022e7fbfc37a90401c40fdf6f1d8ba9dcb97d67743eddc302202c0a1b604d34aa174fddef63c9115c95465548855c5f783bb206eb4ff8fda235412102e367f6787fe02523fe7b16fff187757207befd49d038f1a80363592ef5f12806fefffffff9fd5ed5458cdbeb26b0126512a1b1f1aeb85fa7b584a0568c674708fafc0d70000000006a473044022001b33b610b8d742df2ad98679f1e41f0c647faf272e15e7ea93171ba29c33bcd022061646fbcb81ba30d6e8b030ee12101d1f1bef38ba44a6d5daf40c4ff6d644e6e412102e367f6787fe02523fe7b16fff187757207befd49d038f1a80363592ef5f12806feffffffa6f2a72bf25954904893198f716f7b6f07e68bf35c12c233aa6d165723931068000000006b483045022100ec9b6bbaba90d8902ec8a1ca0e90ea594264bc1add204b756cc89def4d7e9a2a022066b2bc84f94e1a99effe0e929be8de8669631143ca20c73e700d182ad4884e71412102e367f6787fe02523fe7b16fff187757207befd49d038f1a80363592ef5f12806feffffffb38019b996f974375732d741fac543bcb46670b99c566a8a887c3f876485a942000000006a473044022057117591cc465c48da58ebcb8f57fcd56359757d41e1397e45b5e33e034ea5d8022001de1d78ce9e8e73370a0778b4a8595045c6faeb2497ab4296d0cff735711276412102e367f6787fe02523fe7b16fff187757207befd49d038f1a80363592ef5f12806feffffffbd0ba68d3c24402ccc4d2c82c4d11ba0a794bce9e9d39f64668aa4b5956eb5f7000000006b483045022100dace56650d1d9edaef30e8c9ecb4b78499a573984c8a451253295a90c84a3ed702201f4587d4a760cd77a2e21d5f6f2b7aacf668220c8c7c62fc1ae4779f7c0141cd412102e367f6787fe02523fe7b16fff187757207befd49d038f1a80363592ef5f12806feffffff143d2c0bfb63e9b52766c0f7921d06a1d51b90a770b64902ee8352122c918bd5000000006a47304402200db6b461a0082807f59053bea210d38f5f82f02dd63a57f6e3987339cac23870022064ba927fc11b36318785d4e861a7f94cb3909ef8fe882360e2041f7b4a444692412102e367f6787fe02523fe7b16fff187757207befd49d038f1a80363592ef5f12806feffffffb0b7e16b8502ccd5ce2ec06157803e5c84062f5e8e4804a633f9e809ce260353000000006b483045022100a3e75a6c7918db32a27be348493b831631856ec8f546ca43d143cdc3c1cd03c802201e6ae036423bfce45c500b0c049f68396deae5cb999038de61e972ccd4cba5e7412102e367f6787fe02523fe7b16fff187757207befd49d038f1a80363592ef5f12806feffffff6d284b186e26a4116b02e6568c2868ff13408b85c71db1495a5e7cd32a4151ca000000006b483045022100caf952ca1760052cfefe8df283fdd0eccb9e1238eea88eef287df9404c622e8b022072027363fa1070548576fbf9bcbddf2e435fd020662b2d8f0582b52bfa487b31412102e367f6787fe02523fe7b16fff187757207befd49d038f1a80363592ef5f12806feffffff38bb6ba6ccca482c333c8fd0e35afffb150e4c99fdf70513175f10bb8b263ec0000000006a47304402201a4b4efff2b70a4039b4dc120141da04ae84f63906df10c3cad08838c01b6b8702205a065d025c338547ea07b2095ad31252658e57f1a7a04c7f4eacc0248e611fa2412102e367f6787fe02523fe7b16fff187757207befd49d038f1a80363592ef5f12806feffffffa326b367f3405c7648e8e12b5bd7078867796b60f70cd4b3123442a6fcb9c846000000006a47304402206b0a876d78793710acaa8bbeb58a2d908bd4936f2a88825f944b190041b5e0be0220279560be5009e4a3fab44d08f4748e2dead710a8ccc77e06a03ba8112d728856412102e367f6787fe02523fe7b16fff187757207befd49d038f1a80363592ef5f12806feffffff746bb13f09e7c465f9ea0b264c601ef9652736d83ca0c78686ea25326f6bdcfa000000006a4730440220799bdb7ac60cdf3314cc1f157299858d353e22c00354707337ab5b497619d626022000e41053afe44fa65227b7dd8498300a2dc89367d9daf0586caba5bffdfde567412102e367f6787fe02523fe7b16fff187757207befd49d038f1a80363592ef5f12806feffffff8da9008652012637c8bd2a3e6c9b6b6c4e12e67126ac1e5cc3b1d42b3c16b5ad000000006b483045022100a1af33a83edb7fdc289a48a4f77cf286a88b38c21ddf27dd4ec3df007ce11046022074dd56730730f958039efd70edfe7e181060fec306c6df4cf75209600ebebed7412102e367f6787fe02523fe7b16fff187757207befd49d038f1a80363592ef5f12806feffffff84a1b480079b2256862090844d38dcd463315a43b757678d7002cc1d01001adb000000006b483045022100eff445419ec63d1e9f51a5324c3be0315911b39f30657639e84ea7d2f739e0510220218e73140a39542ec8055b6645cbb7989f96b9d9a93c67549c059509de06f0ba412103dd71b53aaa823b09a68aba30c7603c6a397e7c183f708c9dfb0d9d0a9cd1c722fefffffff8872f26872ae96f137ba029e4ca6d19072f8223c0664608eeacd4753e8969df000000006a473044022050b7ed06a6832b8831c08ba86049b3793b5a71fd6d5177c9f268b79c3074bca7022047447c23429de30c361875642d9058bf1b5e0e6c5516d6e71b70b7cfb29827aa412102e367f6787fe02523fe7b16fff187757207befd49d038f1a80363592ef5f12806feffffff7ebebf2f8b764657a719cc52e3ce31fa79c37cd2d583b7be31ad9ec2ebef3284000000006b483045022100fb072bfd399dc11191ac449a9d60119bd191ce6b19a5d92412a805ddc8d4b46f022021e463686560b15ddf272b9943d8e41425ed500f77698aba518ccf546a97aeb4412103e35c58a738805f53af73472ffb671a9bd3556ddef47c62f18ced868bb5033d0dfeffffffbaf05866b6eba762daab7778d4eb3fa1902346491f14c8ec047c12aaae4cff29000000006b483045022100b25e7d4ebaa0e7d8e24498b039e756d568b67316aa14d05abafaec59e216a73d0220010d0b6548a74435907eb0d548dfe8e52a949bbb785eb2be3bce14053953784f412102e367f6787fe02523fe7b16fff187757207befd49d038f1a80363592ef5f12806feffffff1330325273e9a1329b3379a553ce95bda9dbd7b83f93fad4acb8c1dd45f4463b000000006a473044022007d2baa9a766c120e111a727bfa8e8bc2e01cc285d4d4f67d2323b213525a10c022020f32be2d9935b6d9b5091db27ebf00aaeb54adc7032badc7ad63f20741ff28a412102e367f6787fe02523fe7b16fff187757207befd49d038f1a80363592ef5f12806feffffff44530eb5b53868de4819fd0dff26c12e2759f4696ce114e22855e88be1b1d41b000000006b483045022100f98ee28ffb66acd04474a120904ec1be2327d727d8ed8fe99d8b95c174b8f46a022041d21406dd8df10cecc1d6435de68fef3f9db71838c1ca2910895bb184b4a6e4412102e367f6787fe02523fe7b16fff187757207befd49d038f1a80363592ef5f12806feffffff2fbfba76ef97ef4c6e575783e08baa25da64eed6a7eb4ca48707feb7a2927406000000006b483045022100ee3f7961f0f23137d753affe85b777e94c1db3f656cf41b8f59fcf82d9226eb7022025009482a6c0002e409590075caf7a78023ebc1457f100c8b922a4974ebf86ba412103f1d1dd7685d3781f58f9aa399a16f6bb9ccc7d008cdb7c63a7945cfcaa6ba0e2feffffffbf525c080b8b43afd5c004b40d25a7ceba36207162b2bafa70ddc95cae68c1bc000000006a47304402201fed9da4c0526ac5ce257fce2b7fc995646b5f0d2961396327f93e2dfda3e4a0022035b217adc5a9be2ca34f4361ceafd9f2d09a6fa47d4a767f7001ade40c08fe26412102e367f6787fe02523fe7b16fff187757207befd49d038f1a80363592ef5f12806feffffff327b0b903a0f60cadd0c8d2e2cf774ee04eee9a40bf5c37181a471045f365d02000000006b483045022100fa8ee82d42f524290319fb3ee47a1afa70cb952f8a37325680d6fd651ac3699f02205ac0cd86fece03ca204bd881d67ccce0cccbbc98704d9e955e2f92b5b77121dd412102e367f6787fe02523fe7b16fff187757207befd49d038f1a80363592ef5f12806feffffff5fadd3b92b767baaf2a50c8b21f8d3f7cae103e7b4e4c0ba60f111d45f8a1cc6000000006b483045022100f3cb343c4704bebbc78c6492dd72ca19c388b285f44f574dcff25f993add6d5f02200e050dacd78de955cf552f9158beaac5fa64995f5bf7c8a919a231a39425730c412102e367f6787fe02523fe7b16fff187757207befd49d038f1a80363592ef5f12806feffffff47d0ae39a2ce683261d30f45025b7faf667146a980c1213b593c482647d77d20000000006a47304402203f05a035f5d42fbfe97172b431a613110ad733e356ebfd08886fa11bedaf1faf022061c4a3bc3417390910612bae46f5acf8b6e8a5b008d273a52e483a315bfb950b412102e367f6787fe02523fe7b16fff187757207befd49d038f1a80363592ef5f12806feffffff46cefa6639796b89c5e8981c42a230d8629cadecfca5dc853c85e782ecafcafa000000006b483045022100bf60fbd4716339bbb42ce150966ad6caf90b14e57f45eb6804756cf8ff36b23a02202f16aaecdb9994f3b683cc7fab45bd0a3f54795c336b5fc224fc51270a7f3f4f412102e367f6787fe02523fe7b16fff187757207befd49d038f1a80363592ef5f12806feffffff4e5c5b111998d7b90d46130f2ef29f25d48e8649eee14684cf6d46eaad3b7026000000006b483045022100bcdcae99c9289b5fc89d3227daaea8df7d0a0f3a8971d841ebe1ab7a1ecf72e202202ca21447a6b3e96540e32529697d523b7b08c65845d6a13f6b1475de94919bb6412102e367f6787fe02523fe7b16fff187757207befd49d038f1a80363592ef5f12806feffffff489efab51aaeba5cfb24d1484a917a33aff79b7455392ce21a3e642a170341c9010000006b4830450221009535c27b5bbca0db2bcf1a0d0b3b283a2171df53f0d68f1a138888fcc6ddd996022068af19252ac4376cffdbfaacb2e0f0c216deb7e2478b586abe7c2679501eac34412103a47e5dea4ab8d785f4e00994d0faf1a8f384c41e74ed8e4b776fa6ce136ebc42feffffff7eee285c72768622c785561839c699b1a748f58ab418615611c70c9d70440518000000006b483045022100b456847e29f8a648730f0fd34cc7edcfb35daba866ab7d800472beaf2836ce4202207db401f0a5e30efc53c7bf58e57d1dec5874d64768ad9eb4895351cc4be9226f412102291b40a9a927dafeb53cdfc7e722ee5c9dfd6eac2d81331678b9ab405bb25d21feffffff93b0226e9f90d151df423d9ff868513f71f708e715cbcb1b5444f4a0194bc267000000006a47304402205ff244c77726def0e3697a3e546bdf74c7f31479c9d01a7a6f8cd1656482d537022045d78dba8ed4d3777f473736daedbdaca6f5698dd306898d144eb43f96259766412102e367f6787fe02523fe7b16fff187757207befd49d038f1a80363592ef5f12806feffffffc784e371e706c6de880fe3033039cae758513a73866241658a21fa6a8a4a8d20000000006b483045022100ec6b35ce6d24889726480d70a31bc0d62800bf7ac49ecf084b98137322606bca0220432d33e2d8b508f26d7d813d18629453c537a4d90f73a104bbf80627f9fe8d62412102e367f6787fe02523fe7b16fff187757207befd49d038f1a80363592ef5f12806feffffffa4cab40c510ef0ddb8fc3612af871512805ad7ebed2b60fecbe7b9d0f8eea760000000006a4730440220423ea635717cff512d9262b7c8932c0122ca868251f019ae033101c28771a52302200cd3ae05f2e88d9f64207beb4b715ba480bde9ffdd40ab61a36feff88f2968d54121035530745f3cd4d31532991e460bd2a15e1944e690643f73133a9918edb95da53efeffffff852bf329889cdd85945b23bc6a338562c151ecf16b04414c75afb1cb9ded3370000000006a473044022055cc4dfa48a79b8584a9352be34ab5fe9cae4132d264dd827d14ae06d35ad4090220652a83c93505f8a8527c5bc0479f37da0593595c1bf18c12b8fa0b41a2e37a64412102e367f6787fe02523fe7b16fff187757207befd49d038f1a80363592ef5f12806feffffff3235c14d72a55c47d9b996588c7110e27d031013e1f2c77deba6241954059f92000000006b4830450221009acc8d0e06d10b0c764a27613bcef41fc75f910875eae3989a7f8725f81814cd02207146ff66f412910ed993fbda4ad6ed48862a02f366dd88a83856a17e7f96d83e412102e367f6787fe02523fe7b16fff187757207befd49d038f1a80363592ef5f12806feffffffa0b0aa12e3299ce6c925827b3d5603676949daba619fd9c7bca247d1c265e9a7000000006a47304402202d8cd72290f04063c0ae9bc06d2cae3ac74ef4cb6945c92c3e3ccca210c127ef022030471726cd87ac9d55f3d246095f64ae22b611aa8791922236bbdb19ec273322412102e367f6787fe02523fe7b16fff187757207befd49d038f1a80363592ef5f12806feffffffc856c10b1d42360a93cf60fa8127afcac431417ccb7213f649d45482fc7d89e6010000006b483045022100ffaa954e5b86d54ece9bcb9e37895047221828ca381b03266de3d9341599c8f902200ea1c5ed36e893df822c698a474b062d4f93005c32f9d2f0d78ecaf5a56e4fbd4121031a00f43cd99e015c72acace20ac47d887a39ef284f89a5aa09abd968d06f5e9dfeffffff69129065f6f989f1a008813b345e8cbd881a38107b9a0af3a3718437ad6e9cd6010000006a4730440220457d59caf24eb6e10664d06f3e936f6ee31d9d59f1cc4f6f62788f022bce8c1b02202ce7c37ae6832b078c1cb9a055e3ffcf4674081f0738fd9c3eb4465b52bcc9ca412102fea9ae922223f2c68c68d7672b7656885c3e1321d35cc8f5f445179df6f7d27afeffffff8ad3038c3df6f210fa389c57f72d240dd2da53bf172429620e64758a28a82a21000000006a47304402205e0f5cb06f7fd741825c669c87e9db1a433913fb8577adb92b779d3a693b4f080220120648a5f9d2abae83a29cd2c79f5c61b9bc40da8990736ab97ccf6f82c586cb412102e367f6787fe02523fe7b16fff187757207befd49d038f1a80363592ef5f12806feffffff4fda56201530659af45d3f6ad8704693d321f4c92184403e848bf4c3eb1a6a3d000000006b483045022100debfb215f94e9d784e91fe0b9d2541d09a4c7591172fad1441506db4a3590fd102200cce728e344933111c9548162e62872fccac624f6f98d92ccdcf98dbed09ac544121039b8a20c23f32f5b14e76fb29e0baade695810aa7b6dac9e9638a8d13b6ad8221feffffffe7bf81c3288f97cccc60391101a6bdc7654a30dbb693a9bcc8a4b112535d5891000000006b4830450221008110aec39b127143891069590fa0d9e1d8b41bdda70d9807848eba92cb48736b02201bcfdc1a1cedfa4c53efd941482f6157774b2aa80af44e500263be6a3cbcbacb412102e367f6787fe02523fe7b16fff187757207befd49d038f1a80363592ef5f12806feffffff4c686bfd13c84da78ae379b1cb6974bd3cde55fffef59f28954095903cd2b3b9000000006b4830450221009f76d6838b8fd8bb74f50c67920fda9f28054d093b30fd03b54b3fb888db046f0220307944f3abec07c3570614f418056aeff03c0830173c963bb0b65bd5ef24b4a9412102e367f6787fe02523fe7b16fff187757207befd49d038f1a80363592ef5f12806feffffff3f7108134b932ada8356748fecd11ce666f529c25e4aca3c4253f77b3ba6f965010000006a47304402207b93e2500b189b51fbc3a49a191c4b92ac76e32ce86f6f1b9af4afbb3a91fbe002200b5617cf52095bf882a5129f5477f119c9c565dd582a9f19493cf1bdae6527ac41210323ab0930ba40688e66bef6e08f673bd6bcd3df687e4c503387f48c24bffdc93dfeffffff7edff321567843351e47d6d3bc8394e2cace9fe3b72c4dbb152bc54c6abfdd48000000006a4730440220731ab37e71d9c6f63333ba205a318d36e5847706381f571b4b562e5e6f6e403c02200704ca9d9a33843d9a16135f56eced1fd18e227385671a8df5fa41e505e3ba3c412102e367f6787fe02523fe7b16fff187757207befd49d038f1a80363592ef5f12806fefffffff71294d7e9b11e4e36de589c91122993add9030771328f27215bb55c36ac2750000000006b483045022100d1d3565175e1f529124ebba1bcdf8c1704e753c2f91ddcd1a093b5f5403cd0ed02207420ee9d6082356cba6d8075b4fbf310bd84dc770734a8ab30e74741a779bae8412102e367f6787fe02523fe7b16fff187757207befd49d038f1a80363592ef5f12806fefffffff423caa98d71896bcc3bd086cc2cdbea476888d19a3f3b9d2554e82e1692cc93000000006a47304402203ddf5c6c5065f03229cdf837d9f8d3d22314834b006e0aba8dacabea206b3b150220417c49c9095372d3dfd954688bcd43fdfd2a121989fde18456a9428b2a8e3c63412102e367f6787fe02523fe7b16fff187757207befd49d038f1a80363592ef5f12806feffffffce3d664bc2eff728a9ea3134bf11d8c7e2207ed508e7879ec7ecee976eaf72c6000000006b483045022100a20e6aaca7df2b142b768d3b1cbf8f783f3d4997d155a32f0e066b4255777c9f02206deb15cf53d6b27a973df9aa7080691e5914538d9e97ec7c6e797ce03333238b412102e367f6787fe02523fe7b16fff187757207befd49d038f1a80363592ef5f12806feffffffb8f5dcd6f0fb2ad1db921e6f79fcd9fa463165091761f9d8baa23673a0a0645f000000006b483045022100cc2cf5c6c2d4862dfdf65407138684ba45565bd8ec46594ed4586bfa37b715dd022013255b2eb22f5bb93d2afdd07ec4c3b5efe0aa16134b2fd084c6bc720f8cfd5c412102e367f6787fe02523fe7b16fff187757207befd49d038f1a80363592ef5f12806feffffff7c331f8d0e02777c73a28ae441e12de405bacef5ce967761fb521786d5186b25000000006a47304402202c9dd98c9a72e5a8df4b01f09d18e2826d8b9871db89c5d3b24ffd673facaa0702207523bfcf3ab80790167a2b1159fe268770371fcc7d770995c19eace3181ec8af412102e367f6787fe02523fe7b16fff187757207befd49d038f1a80363592ef5f12806feffffff4cd501228a577f0662b802b5b197921268202b8658e4aaab7cf6ecccb93cdaae000000006b483045022100bfac8828df10b7911d341c15a532819c429c7185d8883de19de84e71b97d78730220177603a3572908c90dad865770906b5ad228da7ee5da39503ececf60ac735158412102e367f6787fe02523fe7b16fff187757207befd49d038f1a80363592ef5f12806feffffffdbd64011a7b6fe85385fb207b347f02f5e047b7ffd55bd4192af5ea979e2110b000000006b483045022100d598e2ccdeecfdfea9d5139a49a94fa39414f9e1ecb13d54efeb34c168e58aec02202a59463710905613844f48dc71d316c0cae54ab9e16dd95beb8902e5940024ee412102e367f6787fe02523fe7b16fff187757207befd49d038f1a80363592ef5f12806feffffffb90e762342456c7032806bd546929a38782761e2ee29e7aad37778e1ab6e0282000000006b4830450221008302d38e9eaccaea812c853047931562417a3665b8b9373cf7f63e58180b002602207ac8fddbbd19560a74333ec92fa077d169b4902a41e0431113f8fdb75b304ecf412102e367f6787fe02523fe7b16fff187757207befd49d038f1a80363592ef5f12806feffffffe15523a831db30cf60f16b15dc338703a64058fa3830c17a4314b4ab824ca943000000006b483045022100c0d85a1f9146e8ef9efaef8ed9b3ed09c55e51b25e189735610da89b6d212360022003a49114e504741befcdb95d52a3dedd1aadef68b7c48f0a4a8c7dddfb4201b5412102e367f6787fe02523fe7b16fff187757207befd49d038f1a80363592ef5f12806feffffff7893407b6997d973f52a924d03ebdfc639401a138c13e12c2ca365938135f841000000006b48304502210091ec8402cafd1e7eb11b56ac56a994ac79c435893108d0b7c8cfff87c07ba0a602204fd98efddc1b4e21bd3cb81217579a7b9621f9c3c204f2f5800e75ce1c60b19c412102e367f6787fe02523fe7b16fff187757207befd49d038f1a80363592ef5f12806feffffff016fa30c4594495726151cbe044ad53de6421e1f28e2366602bd80a3dea98c2f000000006b483045022100a850bf088a08baac1f1f577da8946befe2e6b0354d6a29f636afd39982569a7e022062652d6b75dee145f741d28d6f1870fde9a7d66b994f0d3162abdc42fbf54458412103ffdeec10b52942b0c46d6578998efdc1d64073de579e92e7c5dfa97fdf3ac391feffffffd8659400dae01e9cac6076cb19facc050061f64b16957ad30500503c24294840010000006a4730440220762f7c017672dfc71d487f3730e26d69d0e53902f579ba348095ca164d27b094022076c7e8045ec9fc57af6dd95f35c0ffad2c0ca8f83f112f60fb9851ba4ba15d92412103a2d2d8251728b11fd4afe7b8c73a8442f76dff9bfa424f5cad9b98083936259dfeffffff642ba174ff1ecc14e4f086d70300d487dbaae78bfc684b43557f9b8ad2ca2426000000006a47304402200654032c5760f8b94cc089da51773447f19c1cd2108cab89bb53ccfdb6dbee56022015e277622dea4bd1a7913ff934b2bb2d1b3d75f05285b51690160e1197a258c5412102e367f6787fe02523fe7b16fff187757207befd49d038f1a80363592ef5f12806feffffff654d602ce9a224bbce1fb5f9588977fd780591457ef11de271137ca7fd3c3b89000000006a4730440220712877c0dc553096eb0ebf101d1555fda5235db26ad074d2f330163fab63fc7802202c89752dd7645e8a3da7e8af5fb68dc8b177700766b79cf6a35695a0c7c873cb412102e367f6787fe02523fe7b16fff187757207befd49d038f1a80363592ef5f12806feffffffcc614cc3c1c12c9b8cebba5d78a395f5347a5073211a04e03d55b0a8abf386cd000000006b483045022100f3fa1e305666e2a62afaa11fd37025b25c0bdff8709fe1580406615934228cee02204841a7d96f36d3c183f06e22a58175756c3e9a76c93c7cb4e9945f31ddedc902412102e367f6787fe02523fe7b16fff187757207befd49d038f1a80363592ef5f12806feffffff26b2ed7a5c60815f5b62a5d30af9613e69a26e8aaa429be689baddb562e88aae000000006a473044022047c158e3fe3f40de3f39796dcecb7df3cf344f14009de9826b62a43837f2cdcb0220759d823cc145fd5e8b651a7bcc399544692bbf596189b1fc50bba5f4ca02cdd1412102e367f6787fe02523fe7b16fff187757207befd49d038f1a80363592ef5f12806feffffffebb012602f05d2bea0016b8b304f59f610922671560469d80e0e913cd2b302b4000000006b483045022100bd70744c867943bc3bf578e192c8a87a5ed5126aac4acd98efa06ea2483911fa02207377e11ae2d2bbaab00da86ec73c26e596bfcc680c0b8eddc5d44bda650bc299412102e367f6787fe02523fe7b16fff187757207befd49d038f1a80363592ef5f12806feffffff87809cf57be510d02c71276f00544888795f624f33d78b01ba63c87340dadee1000000006a473044022059ee25066b8a2a4fdfc35f14c5cbb7f22ab181fcfa9702d4f3de7aa4d738c7a402206dff315ad1cd2222cd6ac074bf34241fc22db38a57bf089f7e24542323f1766c412102e367f6787fe02523fe7b16fff187757207befd49d038f1a80363592ef5f12806feffffff8c33b7af2120bb22742f4a5e5fb4ecca7cdf73a33bc8811f3d5d3d1cd9399c21000000006a473044022039657cdf4fcd5a9e81766ba11db495b8be5664612d3b91f8504bea342c4ecbe702206ca4913e5807cd697d30dbc93e0a9d679eb01ee84b687ab0c642e2f3ebde745b412102e367f6787fe02523fe7b16fff187757207befd49d038f1a80363592ef5f12806feffffff8142c39bf2f91bc685f7c08e40450c90b36dc0a6782a764cded6ba744a591f3a000000006a47304402200232ee94873317eae275cf715f4c3aca25dd0c8db4800946a45cc1d9c45732fa02203d9ce9c9aedc0a3899dd027df32e683438769d66f33ffe52006454614b77821d412102e367f6787fe02523fe7b16fff187757207befd49d038f1a80363592ef5f12806feffffff503b9a4c5cab71a66b685d3266002970227d0f4a6b1c65b86603b8c8e683cf14000000006b483045022100900bdc6f705efa56449a65f15a67fc7fbbc102f78e7974ea6ac2849c75d2dfec02203b78de71dad2e3f6ffad2779cb9007217c957c8f5db7abd58fd0537fbabb8c6b412102e367f6787fe02523fe7b16fff187757207befd49d038f1a80363592ef5f12806feffffff8bed144f5515754d58c273554d25637ec776635033c9ae13bfc94e4b6cecd11d000000006b483045022100becbb21c7937b9b27ea3cdac5f2048ab9ac314de59c3ee2926a5cfb258ce14e902201c8022bf275c1a761e7715b14e15d74526901363ae5f8bf5489d00908dd758eb412102e367f6787fe02523fe7b16fff187757207befd49d038f1a80363592ef5f12806feffffffbcb7881db3ede1d9275508f97b9f1e0e008811ce540f3b42a921e26f6f065799000000006b483045022100ad84bcd69a85a0d487fd7cbe4d76b95bffa303e76615a4336419fd182eeae4b902206d21e4f592297e87f1af9e19c80fd978914aaf5a2db2cf499b72cabbbe73c831412102958762ff6c8985dc9656afda59e61afc6c0131a5d8f1d86c87c83c9b37f7bd18feffffffb7ffae52888348a77a9851617df104a29366126e01ecc6bf7d209fc8627646ca000000006b483045022100edfd64cf9335d094d5873deb38cda5f4ceda3351df722f1c718993a2dd12c8e302203126b0f9470a4d0867ed4e773518b8ad689ce43a2c9f65a1f297525fc22201dc412103f37089783028c0776f2b8a9d8481ec8d6d0652a31edc03cc274032ae17c63c62feffffff801a88dcf5725d71cc70aee29ec937233f7a059d60e068dea3b7dbc806e0fd54000000006a4730440220448751a749e7cccacab0ae1ad4da948b0e0b5d8e3f41ac2b22c18928e8e67d41022051c107c345c06ea82fe8329a8cf3a96b516fd8750611d8ef438b8545416398ee412102e367f6787fe02523fe7b16fff187757207befd49d038f1a80363592ef5f12806feffffffbb06af741ad8b99821ecc4dfb5b52a0a79b577cf213eb9335e920d13707c8da0000000006a47304402207f9b2802ed1e893168277204b7919ff479efe5c71ad2a255e1738a52bacd758f0220253780485f2e3ee960e058d449c647b147b8f64b49b913e7e9615a6c7114f18e412102e367f6787fe02523fe7b16fff187757207befd49d038f1a80363592ef5f12806feffffff7827759ce0800e385c440c45ccf6c568a25139aa0f1c80b86f28487ae6a8c0e2000000006a4730440220778fd8ba1dd9f71df55bbe1c3c4185b8da21dda82198546c2a0c30250f4c1d66022040f17a46187d535c6e943c047942f45159a37b2e171db18c657cd24168c22e2f412102e367f6787fe02523fe7b16fff187757207befd49d038f1a80363592ef5f12806feffffff2af935dfaa292af30d0a39a548e81640765b624eb5213d964ebaaa81a3711922000000006a47304402202cd2fd29fa395a5a80893de065c8bbe71e0bfe0e7b2224cfd5684736a086aabc02206720226ba63a3e5d9e2dc67e404625cdf31a7a08da0e8a22717e558f7abc817c412102e367f6787fe02523fe7b16fff187757207befd49d038f1a80363592ef5f12806feffffffe3e3b78cff7d4798f6e3c8c45d87ac2131913d1328947d6b4ed515b3ab2366bf000000006b483045022100f8769b797386f0bdd662483096f4e0a33c13f6074a4aaba3fd590b9abbca7c2402201eb064869fcd17a59ac028145b08c73b3552544cd7fc62245d1fd1d369ecf765412102e367f6787fe02523fe7b16fff187757207befd49d038f1a80363592ef5f12806feffffffdc319b5c9374a41a08f5f3bd45480a968f651878cde667b3ee3714f72b836be6000000006a4730440220558e65fd916d9c9616a3e0bd41111dba3914867b1ce5d487df4f77feadc0059502203198566c0d58af8551b65f884db98bde161bac140c7a900cd40df97a40c267de412102e367f6787fe02523fe7b16fff187757207befd49d038f1a80363592ef5f12806feffffff69406ab4a28198623b6005bffa68588fea73092364cf2f7a223884c3e0732845000000006b483045022100ca93287feb58daad47c5388067b219e44f8533a214eb8eea9b5313040579773002201716a6ad2de70eff6721ae7950edaf9230420648bb8ec53173c215cbd12246c0412102e367f6787fe02523fe7b16fff187757207befd49d038f1a80363592ef5f12806feffffff21e5177112fa1fb5797389490a4f9131600673f139a544050a557fb627b0b360000000006a473044022003240fd71510800910b448c62a03178b4ef62299b17d6d2c06ac8f3293684ff50220637e3ba59fc884a8bd16aa2e884b379d85f38ae4ba049a0365f33644febee6df412102e367f6787fe02523fe7b16fff187757207befd49d038f1a80363592ef5f12806feffffff5488e67a575ab8556c748fc371515b52ff28eb875586eba99fda2b4389e4f96c000000006a47304402202e2ac9c8b619b8e2626895c20f6bdd1a24fa27de017d05d5fa2ce120b3421f25022053ef6f82ccf9a132d40ce566d45f4ec18bf30048d415f6ec1c783cda027b6747412102e367f6787fe02523fe7b16fff187757207befd49d038f1a80363592ef5f12806feffffff03abe81fdd0362f4fa3bae282c2ab1be258882d83392229cea6e36c3f023999c000000006a4730440220352bdfe541e9e1ce428ac4eb4c8ba9391a118b7dbe57b4fe3c4ecd30f228fbff02204a0b78ada1d74a7e7b9ae912e6f445d9ce9050855d9c5ecc7d477d2590a68b18412102e367f6787fe02523fe7b16fff187757207befd49d038f1a80363592ef5f12806feffffff879d7ac96bbdcb9aff885fb27c0f171277a313ef45b8143e04b74d6fa43fd25e000000006946304302203f767d8f64e3c9e5773d94a325f8029d21d1c9a0f470c9288cd99f70d2d90ec2021f50b395f9329ffe64ff8084c1506e904ffc02dfac7f7e15461c3e8a077f604c412102e367f6787fe02523fe7b16fff187757207befd49d038f1a80363592ef5f12806feffffffff00dc8aec564568fdd9114502ed1998de08228bfe4edf74d132cfe595c709fb000000006b483045022100f17f8045a627bf96fe09d868109063d8040e3e2df8944e05f9b20a15273d0bdb022059c31e2d849abd57e784f1a3903f49f18c7c5a624545bab98649e8a092e12a10412103ee2a3f78cd4930dac8c030ccc93381ec5eab259c1607360d85d1728fc296dacffeffffff3f25af68c0083801bf09571e1a300d78768df58ec82e2961a374600bcf90bf36010000006b483045022100b58c7dd3fa1f8dc50edc7b5546b8ccef8ffc5c179fee774999c63fa729ae3cef02205eb611cc887e5a62a4e9da33318ce6e216ca353225f452ebca51be1dd10f544941210267f3c9b9bfb6bc5c1f68dd1d18623a9986408202cf232ad1e4089933c83f186bfeffffff6a94e760788c3ee1c9696e5552020afc2a77bfcb3b2223e35744f1b9abc49b25000000006a4730440220097f46c588f37ced4846a45905df1a0ae22709760f8a1bc930a58f5054cbe482022053b418af66d1edcb3887616feb23e5dd4095f29e74ac89853c3b909eb42bac34412102e367f6787fe02523fe7b16fff187757207befd49d038f1a80363592ef5f12806feffffffb26042d45f30556ab14a69f8be4ce1ac4a360b8407d7da6dde0983f73123a314000000006b483045022100cf98e22a2854c7088a0572e1edb4e876aa622ed10dc0376806e1432f5dc1eef90220527845f8dd2522fbdf423b4fc34a4792a7f82e04b314e0d83e2425daa2f92115412102e367f6787fe02523fe7b16fff187757207befd49d038f1a80363592ef5f12806feffffffe5f0f3bfd4691a43d7488076a0e13ff739c72c6f421d6c0e61a75232ea36d8ac000000006a473044022070c7aaa7d7f050b1b520878e55db3ca491fb33211150e2f620b685cb49d7d885022022d9ede63e3b196a1c33c2d211c1eacf2e2411820ecf5155b5e4244f5dfd9f1d412102e367f6787fe02523fe7b16fff187757207befd49d038f1a80363592ef5f12806fefffffffef905cc2f8ca7d7885f06ad865b721f594595528c2b971b3172313cc7df8c34000000006a473044022018cd70c3e62563ea92ea12735e2efb4b905df85e6b290d573051f49c63d07c60022037a537ca3514121d5c2b8753833808a5e0432f1a8f277d91495953c8211ad326412102e367f6787fe02523fe7b16fff187757207befd49d038f1a80363592ef5f12806feffffff556c7570226e99590f0844c677068cd133f882c7a720f77f32bac2be39aa7baf000000006b483045022100a01ad9ec8d24fdf01eb203c2887c1413ae56990d4600a18010959f6df43de08d022056f0f0dccb8f772f29a7835d7dc40f242348805005b5f80ae8f2fbdb600ab2ca412102e367f6787fe02523fe7b16fff187757207befd49d038f1a80363592ef5f12806feffffff52bec1a85abc7d806dfc9c39427b7cbab7be3aeca8ee99959c84b68cc05ca96b000000006b483045022100cdd770159d56ac518ecb0dc916df0da06eed536e540582680f742389f53fa4be022012d372e2c04176bcb82b91b02ea23c9c1464baef7d1dda66066bf84c402c0012412102e367f6787fe02523fe7b16fff187757207befd49d038f1a80363592ef5f12806feffffff3b2d0442ce89e456c2cfc586906116d280fce17bc310ed957d03b35c61e9eb41000000006a473044022001dc7db378891c1c5bf07a09d14fcc6675965976e2e3e762786b1b1e0f4a4bb702206db6f284dec835823fb516fad89543edd3bd7af3ed33940fa296939fadb41ba841210393ae47ec2e844378cda3630abe12082401f2e0f98d016dde2b152b42e335630dfeffffffc3804827d4f39c54d961dfe79e25325f59b5499ea25b49bfe7ac99bd7c7435a1000000006a4730440220290a5055313d68f9461ce830f8a7395022d2d55abf28f6b4bd665693b4a13730022035d4cc2a6676ed842027dd4f21d31dd5a956f4b1f5cf771b866cc0d4a6400df0412102e367f6787fe02523fe7b16fff187757207befd49d038f1a80363592ef5f12806feffffffd610149123afe34fa647cb0aee336cb903961bee6653b8eefc7f49bb015e0990000000006a47304402201fd6be6d72ae75b61a624c13476b538ec2f9e5146f3074c879af57ecfbe1679702200ab10ae612e7fe0f76fe943c1f6a02262008407f86782c1536e92e3bad77d3db412102e367f6787fe02523fe7b16fff187757207befd49d038f1a80363592ef5f12806feffffff205fab854da34166e1d16d36ab90b1e825440f6c9067ef35d34c41c5e569b144000000006b483045022100a4132f408b5299dfed6153b7a331f9fe866f1b042e4263bf7574ea0964c450a202203d99cf8dc9a9194269bce400185a4f86f5d35b5be83f6dbc3166b600392f1b00412102e367f6787fe02523fe7b16fff187757207befd49d038f1a80363592ef5f12806feffffff8ead5e6ad78ed4926b83bc4a479d4dc5b2dbd2753af5636044cb008f4c6df1f7000000006b483045022100bbcc2e2d77458abc30898cddc7eda060b23a62f0a53b81c3db47f284cd7b29cf0220705328a29bd30792a7f5a704fd74b771c3c8a099265f5e7c9d70046da5b03ff4412102e367f6787fe02523fe7b16fff187757207befd49d038f1a80363592ef5f12806fefffffff2361f9f2ba5ff1e66349c365e1c0cd9c6cb80ab4f666e9f4777fc188a405202010000006b483045022100d2f40145c4b9a17b3582aabdf7d9ac2d47546b3eea5350c4e2ec1e9c2466343d02203354ce620aa056a749de847f867c49dd121579c9fc50bd6258bff7cfb173c5f24121035bf755e8b075665a85155618f6e9022196a09c486415587dd3af0d25b76e9c27feffffffc8f56b2dc9536ae2c0e11b2062edda6cb33b93284ce7bd8c6531591ae82f0074000000006b483045022100cf8c593dec0724644d034f17ccde99feaf0416334219f158f884badf500fc93e022035af1b68574e88ef15e1c05c1b36638401613a31aa7096d97efba6df62695706412102e367f6787fe02523fe7b16fff187757207befd49d038f1a80363592ef5f12806feffffff95831f16b9696da7fe12787860ca161c12566d110c9262097434a7e0674d6b49000000006b483045022100a669e8918ba68754b84d584f38afdd34be387773449784a6c61ef3f33d0fd99e02204d007ef31f5a3a7c412ac3d2660633fcef137964ef2ff6269c41e933896d918b41210383b6491fd80e1411675d7c8eda9b756c30a814b45fa565b7ac24d7be9dedcaaafeffffff1e1184fc54a53f94ee4d56313349f586effea0bf553bbd0cccefe86c8d606f4a000000006b483045022100fc35ed21833c3ea3ff5f832ef02236a08ded0999ea367aa6eaaff364ecac3e5002206e291d7c4fca0485dd8ea22519544ac632909d706741710a6e5f0d472c0b0656412102e367f6787fe02523fe7b16fff187757207befd49d038f1a80363592ef5f12806feffffff4864e36057e4fe2ece01c3b463c06b56a86e3c341aa0e203097cb09c53a2cfa9000000006a4730440220485937c55c67c8eb46b94523cb06f9572ffb55094536d8b1a458c76b67dec75b02204e5007f610e491d043a412696d4fd769bb2f5d8c3e8b3a59e6ec3bb598f775a7412102e367f6787fe02523fe7b16fff187757207befd49d038f1a80363592ef5f12806feffffffeed8d2da2afa9b9823aa74a344f6eda5d4b80e5de83caf8455b08c8aac6c4662000000006b483045022100b430528ddfca4431cf5cec08964f7325c036fdee55edc0ea0181d34ed72469bc022074b75bfa66dd4a87fab93da0f2f0def65b785fb0b51fe07355799cbd8b30c39a41210316d35753d58318c06d0faadcb723563316847ae06019984f42f2c75deaf3727dfeffffff4317e8c939993e123310aa4d84dfa4a29ba8dcc0b4c222384ded077936279955000000006b483045022100c6ccc3891fa3924c7b1e69b855628230c48d85d1e1331f037823ab7c5928610c0220050c9c0e078f34ced537e88f95289863a663b28488880f6ada3f1dbbcb1743a1412102e367f6787fe02523fe7b16fff187757207befd49d038f1a80363592ef5f12806feffffff85aed5e452015314973015efa03f0bd2c79d57d976ce3f3ce14498b294fd5b7b000000006a4730440220168f31f413d65ce64bccb62390490dae2e4a00f98c2c44bd4fd689cd942da8b1022006f1b2aa4fae9587c688e8b7ca5c07db3b3c3afd6961f9f843099ed30b583369412102e367f6787fe02523fe7b16fff187757207befd49d038f1a80363592ef5f12806feffffff0286800000000000001976a9149a262d0621819c8c17d34a7feca1b39b39157af988acceb18bca1a0000001976a9142ed9aeddd3aa62d922d33025901531e344914a6288ac26550900"},{"txid":"99300f90ced7d053b3b24ef3a8fdb5774418e616f07971366a63b9938944ab2d","version":2,"lockTime":609135,"vin":[{"txid":"f0202389fab209e6975199ec2d8abf76fd4cea5d7d441ea0938ff47a35366c45","sequence":4294967294,"n":0,"addresses":["bitcoincash:qq07l6rr5lsdm3m80qxw80ku2ex0tj76vvsxpvmgme"],"isAddress":true,"value":"1250016811","hex":"473044022001b8ba5dbc580e3bf4419b65892f15423e8b0e48d52479fd0317fe4c03ede0a002204013a50c3914aeb7f59183f9e44c880bc94fe9c23045a6311ae4b07da3c2d209412102e367f6787fe02523fe7b16fff187757207befd49d038f1a80363592ef5f12806"}],"vout":[{"value":"1000000000","n":0,"spent":true,"hex":"76a9142ed9aeddd3aa62d922d33025901531e344914a6288ac","addresses":["bitcoincash:qqhdntka6w4x9kfz6vcztyq4x835fy22vg3yc55de7"],"isAddress":true},{"value":"250016585","n":1,"spent":true,"hex":"76a9146932df2f990838523783075db0b985b9bd2330b088ac","addresses":["bitcoincash:qp5n9he0nyyrs53hsvr4mv9eskum6geskqthlx9n4d"],"isAddress":true}],"blockHash":"000000000000000002132a5e60d7b9de0524eeffb36fc91972a7d68afdf17b65","blockHeight":611545,"confirmations":24555,"blockTime":1575274423,"value":"1250016585","valueIn":"1250016811","fees":"226","hex":"0200000001456c36357af48f93a01e447d5dea4cfd76bf8a2dec995197e609b2fa892320f0000000006a473044022001b8ba5dbc580e3bf4419b65892f15423e8b0e48d52479fd0317fe4c03ede0a002204013a50c3914aeb7f59183f9e44c880bc94fe9c23045a6311ae4b07da3c2d209412102e367f6787fe02523fe7b16fff187757207befd49d038f1a80363592ef5f12806feffffff0200ca9a3b000000001976a9142ed9aeddd3aa62d922d33025901531e344914a6288ac49f3e60e000000001976a9146932df2f990838523783075db0b985b9bd2330b088ac6f4b0900"},{"txid":"637d7e47d7de2d9da6aa081dd8534ea3f907e8bfcbbaf46dd528f15a71897ab8","version":2,"lockTime":609135,"vin":[{"txid":"62b7b059c7970576e7105dba731a668cc56d8df6e0a683caf69ca6f0b0443a69","sequence":4294967294,"n":0,"addresses":["bitcoincash:qq07l6rr5lsdm3m80qxw80ku2ex0tj76vvsxpvmgme"],"isAddress":true,"value":"1250018032","hex":"483045022100f2a03dcbea54b74d1a9db4a97e9e4fac3618f7b90eacefc8bb364d6fe3001e99022075b6ad6ac445dceab967fef530bfeafbe7b0b66bb484ceab492a857354f631fd412102e367f6787fe02523fe7b16fff187757207befd49d038f1a80363592ef5f12806"}],"vout":[{"value":"1000000000","n":0,"spent":true,"hex":"76a9142ed9aeddd3aa62d922d33025901531e344914a6288ac","addresses":["bitcoincash:qqhdntka6w4x9kfz6vcztyq4x835fy22vg3yc55de7"],"isAddress":true},{"value":"250017806","n":1,"spent":true,"hex":"76a914b27503ce07faeb2e71e1b937d871c1e5abc33ce188ac","addresses":["bitcoincash:qze82q7wqlawktn3uxun0kr3c8j6hseuuyz7t4eh7x"],"isAddress":true}],"blockHash":"000000000000000002132a5e60d7b9de0524eeffb36fc91972a7d68afdf17b65","blockHeight":611545,"confirmations":24555,"blockTime":1575274423,"value":"1250017806","valueIn":"1250018032","fees":"226","hex":"0200000001693a44b0f0a69cf6ca83a6e0f68d6dc58c661a73ba5d10e7760597c759b0b762000000006b483045022100f2a03dcbea54b74d1a9db4a97e9e4fac3618f7b90eacefc8bb364d6fe3001e99022075b6ad6ac445dceab967fef530bfeafbe7b0b66bb484ceab492a857354f631fd412102e367f6787fe02523fe7b16fff187757207befd49d038f1a80363592ef5f12806feffffff0200ca9a3b000000001976a9142ed9aeddd3aa62d922d33025901531e344914a6288ac0ef8e60e000000001976a914b27503ce07faeb2e71e1b937d871c1e5abc33ce188ac6f4b0900"},{"txid":"fbd9cfbe97c857b2a03b431d8e28faa324ccf4122b769701d3cd013ffa197fe3","version":2,"lockTime":598145,"vin":[{"txid":"58f0bd01660fe9c835929b684134319aae65d11564bfc00071b5457463554d9d","sequence":4294967294,"n":0,"addresses":["bitcoincash:qq07l6rr5lsdm3m80qxw80ku2ex0tj76vvsxpvmgme"],"isAddress":true,"value":"1251118684","hex":"483045022100eee97aebf4fec547551a14929ca063d7d6a679044470e0168f4205396cff4410022047aa3e87d09229e6530ce1545729c2954fda1c7cd037464ec366552098879f00412102e367f6787fe02523fe7b16fff187757207befd49d038f1a80363592ef5f12806"},{"txid":"5d2c2e1e37a2aa835c757869c28e5b81e51c2caeacf913955a960ffe7a26d3b2","sequence":4294967294,"n":1,"addresses":["bitcoincash:qq07l6rr5lsdm3m80qxw80ku2ex0tj76vvsxpvmgme"],"isAddress":true,"value":"1250470637","hex":"483045022100e9c68ab8bbf083eb282c449b7eb697b8d7e86d925447c49927cd0a68267c63cb0220526670fc9ca852ae8da916e3a7fd5afcb57731502014f25365bd30ddf1ed98e1412102e367f6787fe02523fe7b16fff187757207befd49d038f1a80363592ef5f12806"},{"txid":"67192afdc712d878a5cfb7a2318bcbccec4ad4bf6f6b45009719d341a383f045","sequence":4294967294,"n":2,"addresses":["bitcoincash:qq07l6rr5lsdm3m80qxw80ku2ex0tj76vvsxpvmgme"],"isAddress":true,"value":"1250720617","hex":"483045022100f65bd8daf7c1dcfa07190e4262058e30aa09a2f05e64c36988ffdb0114babc5902205d7dd1c0432c0d0f87965c1de3ae43313fc8e23fd03dea69de98e9b21049beda412102e367f6787fe02523fe7b16fff187757207befd49d038f1a80363592ef5f12806"},{"txid":"8b798be5bcec847ca23f0a0cc567542187eb70a11db721e7fe2954c48b83a6ea","sequence":4294967294,"n":3,"addresses":["bitcoincash:qq07l6rr5lsdm3m80qxw80ku2ex0tj76vvsxpvmgme"],"isAddress":true,"value":"1250575364","hex":"47304402201b9827502c66a65e5d218abf666dbc6857164d64753ba4dcd211ad12dfe42ea202206b48300b4ed1d6501201732b70ad22172c12d2a971fb5253caa86c94b43c482a412102e367f6787fe02523fe7b16fff187757207befd49d038f1a80363592ef5f12806"},{"txid":"9dd2f09a34aad4c512d4d26a082d37866ab6b1061d2a66cd33e7681b6c9ee038","sequence":4294967294,"n":4,"addresses":["bitcoincash:qq07l6rr5lsdm3m80qxw80ku2ex0tj76vvsxpvmgme"],"isAddress":true,"value":"1251194095","hex":"483045022100ba98ff0f91e60be7d22516d2bd101599ddfd8a901daa4ddb3114e6d2b1b595fc02204cfde2b51fbeff3548744118518889825597882ffc6d7a4284907adb041f9dba412102e367f6787fe02523fe7b16fff187757207befd49d038f1a80363592ef5f12806"},{"txid":"a96814c561344ea7a19b57836dfa62e0c86a49e10087436fbce4336031c26d95","sequence":4294967294,"n":5,"addresses":["bitcoincash:qq07l6rr5lsdm3m80qxw80ku2ex0tj76vvsxpvmgme"],"isAddress":true,"value":"1250008334","hex":"483045022100e3b2fe47a20658f8e1eeff6d27467ad7dd1523f4269a9a61817144ca885af74a02200d265761767b129aebdd39a7958a79994204b2ae40b08a85f08bba21dc91223a412102e367f6787fe02523fe7b16fff187757207befd49d038f1a80363592ef5f12806"},{"txid":"cac688b6f4345668588abcdf9d89b5541c552855d9a8f2f4918df53d17ab6218","sequence":4294967294,"n":6,"addresses":["bitcoincash:qq07l6rr5lsdm3m80qxw80ku2ex0tj76vvsxpvmgme"],"isAddress":true,"value":"1250451164","hex":"48304502210091e7b82967a71a2f98b14080444868dbc98b1bd77d15158fbc0b40591c5cd85f022005ed9e017b417a261f9f33dec1845858f19c210540ae4b6c8f67845c24bf135b412102e367f6787fe02523fe7b16fff187757207befd49d038f1a80363592ef5f12806"},{"txid":"e499e4f058684ef3569ee0bd0306404c4f8a047fe34689f36909e5c83dd976d7","sequence":4294967294,"n":7,"addresses":["bitcoincash:qq07l6rr5lsdm3m80qxw80ku2ex0tj76vvsxpvmgme"],"isAddress":true,"value":"1252046891","hex":"47304402207058f613922e647c29f9d4508cd4b1b834d2c51972d98c44c80e79ac90747b4102201b0aa0081a8b045b1ce01aa0b7a34ec138015aac9c0961891be043975887dc9e412102e367f6787fe02523fe7b16fff187757207befd49d038f1a80363592ef5f12806"}],"vout":[{"value":"6584524","n":0,"spent":true,"hex":"76a914ed64792c4a5cbc13e7ada63de24d004a928a05a788ac","addresses":["bitcoincash:qrkkg7fvffwtcyl84knrmcjdqp9f9zs95uecncksuh"],"isAddress":true},{"value":"10000000000","n":1,"spent":true,"hex":"76a9149a31ab0abf1974a97c7da6fb6d0921710db6bc7c88ac","addresses":["bitcoincash:qzdrr2c2huvhf2tu0kn0kmgfy9csmd4u0szcc8tvkl"],"isAddress":true}],"blockHash":"00000000000000000162f226fdfaa36a83255640d78976086153bb3b96cbc3c9","blockHeight":598147,"confirmations":37953,"blockTime":1567227161,"value":"10006584524","valueIn":"10006585786","fees":"1262","hex":"02000000089d4d55637445b57100c0bf6415d165ae9a313441689b9235c8e90f6601bdf058000000006b483045022100eee97aebf4fec547551a14929ca063d7d6a679044470e0168f4205396cff4410022047aa3e87d09229e6530ce1545729c2954fda1c7cd037464ec366552098879f00412102e367f6787fe02523fe7b16fff187757207befd49d038f1a80363592ef5f12806feffffffb2d3267afe0f965a9513f9acae2c1ce5815b8ec26978755c83aaa2371e2e2c5d000000006b483045022100e9c68ab8bbf083eb282c449b7eb697b8d7e86d925447c49927cd0a68267c63cb0220526670fc9ca852ae8da916e3a7fd5afcb57731502014f25365bd30ddf1ed98e1412102e367f6787fe02523fe7b16fff187757207befd49d038f1a80363592ef5f12806feffffff45f083a341d3199700456b6fbfd44aeccccb8b31a2b7cfa578d812c7fd2a1967000000006b483045022100f65bd8daf7c1dcfa07190e4262058e30aa09a2f05e64c36988ffdb0114babc5902205d7dd1c0432c0d0f87965c1de3ae43313fc8e23fd03dea69de98e9b21049beda412102e367f6787fe02523fe7b16fff187757207befd49d038f1a80363592ef5f12806feffffffeaa6838bc45429fee721b71da170eb87215467c50c0a3fa27c84ecbce58b798b000000006a47304402201b9827502c66a65e5d218abf666dbc6857164d64753ba4dcd211ad12dfe42ea202206b48300b4ed1d6501201732b70ad22172c12d2a971fb5253caa86c94b43c482a412102e367f6787fe02523fe7b16fff187757207befd49d038f1a80363592ef5f12806feffffff38e09e6c1b68e733cd662a1d06b1b66a86372d086ad2d412c5d4aa349af0d29d000000006b483045022100ba98ff0f91e60be7d22516d2bd101599ddfd8a901daa4ddb3114e6d2b1b595fc02204cfde2b51fbeff3548744118518889825597882ffc6d7a4284907adb041f9dba412102e367f6787fe02523fe7b16fff187757207befd49d038f1a80363592ef5f12806feffffff956dc2316033e4bc6f438700e1496ac8e062fa6d83579ba1a74e3461c51468a9000000006b483045022100e3b2fe47a20658f8e1eeff6d27467ad7dd1523f4269a9a61817144ca885af74a02200d265761767b129aebdd39a7958a79994204b2ae40b08a85f08bba21dc91223a412102e367f6787fe02523fe7b16fff187757207befd49d038f1a80363592ef5f12806feffffff1862ab173df58d91f4f2a8d95528551c54b5899ddfbc8a58685634f4b688c6ca000000006b48304502210091e7b82967a71a2f98b14080444868dbc98b1bd77d15158fbc0b40591c5cd85f022005ed9e017b417a261f9f33dec1845858f19c210540ae4b6c8f67845c24bf135b412102e367f6787fe02523fe7b16fff187757207befd49d038f1a80363592ef5f12806feffffffd776d93dc8e50969f38946e37f048a4f4c400603bde09e56f34e6858f0e499e4000000006a47304402207058f613922e647c29f9d4508cd4b1b834d2c51972d98c44c80e79ac90747b4102201b0aa0081a8b045b1ce01aa0b7a34ec138015aac9c0961891be043975887dc9e412102e367f6787fe02523fe7b16fff187757207befd49d038f1a80363592ef5f12806feffffff02cc786400000000001976a914ed64792c4a5cbc13e7ada63de24d004a928a05a788ac00e40b54020000001976a9149a31ab0abf1974a97c7da6fb6d0921710db6bc7c88ac81200900"},{"txid":"e0edb9635d9174d59934abf31cfd54da916423949b5d2dcdbb1f8f5e6723dca6","version":2,"lockTime":598089,"vin":[{"txid":"04f378ab91b96625368f786f7a0452773e36a3e7e6732a737a68f66348763c3a","sequence":4294967294,"n":0,"addresses":["bitcoincash:qq07l6rr5lsdm3m80qxw80ku2ex0tj76vvsxpvmgme"],"isAddress":true,"value":"1250313984","hex":"4830450221008a92cb387e315443cd96cd2add24816d0bb8f671aae99e52cd58654a60b0554f022007bdbbdd2565782c6987bda716a8f0eb4d12a8e28b1332a418b25d031253ca36412102e367f6787fe02523fe7b16fff187757207befd49d038f1a80363592ef5f12806"},{"txid":"42fde1dcb31533906c694dcfd9141f7c099c8ba58176fddc9b6532dc9afc2ea6","sequence":4294967294,"n":1,"addresses":["bitcoincash:qq07l6rr5lsdm3m80qxw80ku2ex0tj76vvsxpvmgme"],"isAddress":true,"value":"1250272096","hex":"47304402207b9f6131318c0fdc3dab08e3a6c6a00279714058fc19ed056674ef28a5cf8d240220791bff750505d7febe7e0bc702508925be6e03344056c91bb904d4170dfff67f412102e367f6787fe02523fe7b16fff187757207befd49d038f1a80363592ef5f12806"},{"txid":"606f9f8c03c66824612cfd2aca07d75f2f063dc7b5b7989298a4a4dbdd156314","sequence":4294967294,"n":2,"addresses":["bitcoincash:qq07l6rr5lsdm3m80qxw80ku2ex0tj76vvsxpvmgme"],"isAddress":true,"value":"1250333923","hex":"483045022100cd449fcf73e96bb49571f35f41a23765f4c473a1aebdeb25ea7c10718544ff6802206069e40e484e2ee6e7fe626698dc82d9b0839e80461ed940131d55bb5c7d1dc1412102e367f6787fe02523fe7b16fff187757207befd49d038f1a80363592ef5f12806"},{"txid":"80370d88df2f654a47f9c278499ae8cd4e591e03dbb45dd205b14939cd771844","sequence":4294967294,"n":3,"addresses":["bitcoincash:qq07l6rr5lsdm3m80qxw80ku2ex0tj76vvsxpvmgme"],"isAddress":true,"value":"1250308273","hex":"47304402206629f28dfb75786ac40f3c93957f2658b823b682037ee61fe6ad5e223f0ef962022073975b7cbfe40f9749ba96b097aa7126d26aa9c7623b2c640f707b20e9a86c99412102e367f6787fe02523fe7b16fff187757207befd49d038f1a80363592ef5f12806"},{"txid":"a24c25d181abdb21e408b764e7201b090bdc35b653d121717f132a19423800b3","sequence":4294967294,"n":4,"addresses":["bitcoincash:qq07l6rr5lsdm3m80qxw80ku2ex0tj76vvsxpvmgme"],"isAddress":true,"value":"1250358384","hex":"47304402206abb92b77747fd651b6d44ad2200d787fbd47f4ae64301295174522c5308bad1022033b86a6734e68c4f553b4e83dec37e722ca1c62ae2062bc52c7e23a1a0104985412102e367f6787fe02523fe7b16fff187757207befd49d038f1a80363592ef5f12806"},{"txid":"a5fa2ae52bb352a42588a97b98a294386c777c86dcaf5f708f3656bc844e9c84","sequence":4294967294,"n":5,"addresses":["bitcoincash:qq07l6rr5lsdm3m80qxw80ku2ex0tj76vvsxpvmgme"],"isAddress":true,"value":"1250329832","hex":"483045022100aa7c5cdab10928dceb54ae9e57de784b33a2a6059353760ec0a5a6fbbedcd1b302202d1241bfd163f8085a55ce3ccdacbe9ef9c785d4ef821bd26d81c0d12cccca2f412102e367f6787fe02523fe7b16fff187757207befd49d038f1a80363592ef5f12806"},{"txid":"a7a24f2a96fdcb3e58f11c6e288aca7fe44d611769226bceebc94de70fb7c372","sequence":4294967294,"n":6,"addresses":["bitcoincash:qq07l6rr5lsdm3m80qxw80ku2ex0tj76vvsxpvmgme"],"isAddress":true,"value":"1250416002","hex":"47304402207701d283a3d166f92b45f58c739921ba08ce9ae367a80b7f4f8d2224e628f46002206e7d08a6f17edda81c182930df7d8272a3c8b821246ec71def6911778382f7f8412102e367f6787fe02523fe7b16fff187757207befd49d038f1a80363592ef5f12806"},{"txid":"f84ba6248b511a24cf393e9c46ef0d87bf141d4a6a98cfa696da9d0ccc23a8c3","sequence":4294967294,"n":7,"addresses":["bitcoincash:qq07l6rr5lsdm3m80qxw80ku2ex0tj76vvsxpvmgme"],"isAddress":true,"value":"1250012299","hex":"483045022100853a8d9536e224198b5fe594cd76427a299531335fd085000efd91133c4940a6022033af175997096234143c07493c8611c1ab5be145d2c8c60a3d762a2743d1a20e412102e367f6787fe02523fe7b16fff187757207befd49d038f1a80363592ef5f12806"}],"vout":[{"value":"2343531","n":0,"spent":true,"hex":"76a9145e0a0344a13ededc2e256b7de017dc50fea0985388ac","addresses":["bitcoincash:qp0q5q6y5yldahpwy44hmcqhm3g0agyc2vwxyyqf3r"],"isAddress":true},{"value":"10000000000","n":1,"spent":true,"hex":"76a9149a31ab0abf1974a97c7da6fb6d0921710db6bc7c88ac","addresses":["bitcoincash:qzdrr2c2huvhf2tu0kn0kmgfy9csmd4u0szcc8tvkl"],"isAddress":true}],"blockHash":"00000000000000000162f226fdfaa36a83255640d78976086153bb3b96cbc3c9","blockHeight":598147,"confirmations":37953,"blockTime":1567227161,"value":"10002343531","valueIn":"10002344793","fees":"1262","hex":"02000000083a3c764863f6687a732a73e6e7a3363e7752047a6f788f362566b991ab78f304000000006b4830450221008a92cb387e315443cd96cd2add24816d0bb8f671aae99e52cd58654a60b0554f022007bdbbdd2565782c6987bda716a8f0eb4d12a8e28b1332a418b25d031253ca36412102e367f6787fe02523fe7b16fff187757207befd49d038f1a80363592ef5f12806feffffffa62efc9adc32659bdcfd7681a58b9c097c1f14d9cf4d696c903315b3dce1fd42000000006a47304402207b9f6131318c0fdc3dab08e3a6c6a00279714058fc19ed056674ef28a5cf8d240220791bff750505d7febe7e0bc702508925be6e03344056c91bb904d4170dfff67f412102e367f6787fe02523fe7b16fff187757207befd49d038f1a80363592ef5f12806feffffff146315dddba4a4989298b7b5c73d062f5fd707ca2afd2c612468c6038c9f6f60000000006b483045022100cd449fcf73e96bb49571f35f41a23765f4c473a1aebdeb25ea7c10718544ff6802206069e40e484e2ee6e7fe626698dc82d9b0839e80461ed940131d55bb5c7d1dc1412102e367f6787fe02523fe7b16fff187757207befd49d038f1a80363592ef5f12806feffffff441877cd3949b105d25db4db031e594ecde89a4978c2f9474a652fdf880d3780000000006a47304402206629f28dfb75786ac40f3c93957f2658b823b682037ee61fe6ad5e223f0ef962022073975b7cbfe40f9749ba96b097aa7126d26aa9c7623b2c640f707b20e9a86c99412102e367f6787fe02523fe7b16fff187757207befd49d038f1a80363592ef5f12806feffffffb3003842192a137f7121d153b635dc0b091b20e764b708e421dbab81d1254ca2000000006a47304402206abb92b77747fd651b6d44ad2200d787fbd47f4ae64301295174522c5308bad1022033b86a6734e68c4f553b4e83dec37e722ca1c62ae2062bc52c7e23a1a0104985412102e367f6787fe02523fe7b16fff187757207befd49d038f1a80363592ef5f12806feffffff849c4e84bc56368f705fafdc867c776c3894a2987ba98825a452b32be52afaa5000000006b483045022100aa7c5cdab10928dceb54ae9e57de784b33a2a6059353760ec0a5a6fbbedcd1b302202d1241bfd163f8085a55ce3ccdacbe9ef9c785d4ef821bd26d81c0d12cccca2f412102e367f6787fe02523fe7b16fff187757207befd49d038f1a80363592ef5f12806feffffff72c3b70fe74dc9ebce6b226917614de47fca8a286e1cf1583ecbfd962a4fa2a7000000006a47304402207701d283a3d166f92b45f58c739921ba08ce9ae367a80b7f4f8d2224e628f46002206e7d08a6f17edda81c182930df7d8272a3c8b821246ec71def6911778382f7f8412102e367f6787fe02523fe7b16fff187757207befd49d038f1a80363592ef5f12806feffffffc3a823cc0c9dda96a6cf986a4a1d14bf870def469c3e39cf241a518b24a64bf8000000006b483045022100853a8d9536e224198b5fe594cd76427a299531335fd085000efd91133c4940a6022033af175997096234143c07493c8611c1ab5be145d2c8c60a3d762a2743d1a20e412102e367f6787fe02523fe7b16fff187757207befd49d038f1a80363592ef5f12806feffffff026bc22300000000001976a9145e0a0344a13ededc2e256b7de017dc50fea0985388ac00e40b54020000001976a9149a31ab0abf1974a97c7da6fb6d0921710db6bc7c88ac49200900"}]} diff --git a/mock/ext-api-data/bitcoincash-api_v2_xpub_xpub6Bq3UUphocwroXkhA9sn8ACnZpJNuwaBehgo7WbDi2DULYnvT72Uzgsv9cE5EiP8ThDYdMyZREfbpkUY4KZ88ZaUQxXciBcZ1soSi1d8xtX__details_txs.json b/mock/ext-api-data/bitcoincash-api_v2_xpub_xpub6Bq3UUphocwroXkhA9sn8ACnZpJNuwaBehgo7WbDi2DULYnvT72Uzgsv9cE5EiP8ThDYdMyZREfbpkUY4KZ88ZaUQxXciBcZ1soSi1d8xtX__details_txs.json new file mode 100644 index 000000000..35b323e6b --- /dev/null +++ b/mock/ext-api-data/bitcoincash-api_v2_xpub_xpub6Bq3UUphocwroXkhA9sn8ACnZpJNuwaBehgo7WbDi2DULYnvT72Uzgsv9cE5EiP8ThDYdMyZREfbpkUY4KZ88ZaUQxXciBcZ1soSi1d8xtX__details_txs.json @@ -0,0 +1,165 @@ +{ + "page": 1, + "totalPages": 1, + "itemsOnPage": 1000, + "address": "xpub6Bq3UUphocwroXkhA9sn8ACnZpJNuwaBehgo7WbDi2DULYnvT72Uzgsv9cE5EiP8ThDYdMyZREfbpkUY4KZ88ZaUQxXciBcZ1soSi1d8xtX", + "balance": "177672", + "totalReceived": "13221795", + "totalSent": "13044123", + "unconfirmedBalance": "0", + "unconfirmedTxs": 0, + "txs": 72, + "transactions": [ + { + "txid": "269d428f01fbe49cd6d2c2ca5e6e2f0ff68aece905313932156078d4341d347a", + "version": 1, + "vin": [ + { + "txid": "5536327a38fddb32a92a98582aca4e85b4e50f40b9d3c03db360eaca7b512f97", + "n": 0, + "addresses": [ + "bitcoincash:qzvqpsyaupwcu24dear47va7m96gr3rf4g9gcq4h25" + ], + "isAddress": true, + "value": "188124", + "hex": "473044022057e811d95dfce16c7f1d1da574ab4ca1bf883359da34a1e7a380f5045fcffc960220149c357343f0172301f06b914a2844d3755a3e990a236ae33f71afed52f0849d41210259dc89eeb4c7b349faab20e932be226a1ed7d582f25b64e9abf84f73e1d25fd5" + } + ], + "vout": [ + { + "value": "10000", + "n": 0, + "hex": "76a9147222fa3e0a256cc45823a641aa4060e66718276288ac", + "addresses": [ + "bitcoincash:qpez9737pgjke3zcywnyr2jqvrnxwxp8vgu3nnxf6x" + ], + "isAddress": true + }, + { + "value": "177672", + "n": 1, + "hex": "76a9149800c09de05d8e2aadcf475f33bed97481c469aa88ac", + "addresses": [ + "bitcoincash:qzvqpsyaupwcu24dear47va7m96gr3rf4g9gcq4h25" + ], + "isAddress": true + } + ], + "blockHash": "000000000000000000e0846c675bda2ea268eaa290287aef83f8877c40f07743", + "blockHeight": 620315, + "confirmations": 7640, + "blockTime": 1580517507, + "value": "187672", + "valueIn": "188124", + "fees": "452", + "hex": "0100000001972f517bcaea60b33dc0d3b9400fe5b4854eca2a58982aa932dbfd387a323655000000006a473044022057e811d95dfce16c7f1d1da574ab4ca1bf883359da34a1e7a380f5045fcffc960220149c357343f0172301f06b914a2844d3755a3e990a236ae33f71afed52f0849d41210259dc89eeb4c7b349faab20e932be226a1ed7d582f25b64e9abf84f73e1d25fd5000000000210270000000000001976a9147222fa3e0a256cc45823a641aa4060e66718276288ac08b60200000000001976a9149800c09de05d8e2aadcf475f33bed97481c469aa88ac00000000" + }, + { + "txid": "5536327a38fddb32a92a98582aca4e85b4e50f40b9d3c03db360eaca7b512f97", + "version": 1, + "vin": [ + { + "txid": "feac34105f3f0bd442f75acaff6b2e840b9e2c0e32e897393d9d0fe47fe76ba1", + "vout": 1, + "n": 0, + "addresses": [ + "bitcoincash:qzvqpsyaupwcu24dear47va7m96gr3rf4g9gcq4h25" + ], + "isAddress": true, + "value": "38804", + "hex": "483045022100dbbf18561baf7fdb46c21d27801594209f2067f1d7735e245c56001c4e462d3c0220016e052ebbcf350bd64a257f7cc52ef23730fe50b24355d098f87c528fcd839641210259dc89eeb4c7b349faab20e932be226a1ed7d582f25b64e9abf84f73e1d25fd5" + }, + { + "txid": "01b8958ff2a939534269d05af5ac747238eb3a8c91b2a564107af20e4de55680", + "n": 1, + "addresses": [ + "bitcoincash:qzvqpsyaupwcu24dear47va7m96gr3rf4g9gcq4h25" + ], + "isAddress": true, + "value": "150000", + "hex": "47304402202100334789951706405faa9ddc191702b88d9438d5a461d1f008a9bd097bd9b0022062cd93003ad63bfbb16386b90e619c2b32d9caef5229d8943c11309f26b6c19f41210259dc89eeb4c7b349faab20e932be226a1ed7d582f25b64e9abf84f73e1d25fd5" + } + ], + "vout": [ + { + "value": "188124", + "n": 0, + "spent": true, + "hex": "76a9149800c09de05d8e2aadcf475f33bed97481c469aa88ac", + "addresses": [ + "bitcoincash:qzvqpsyaupwcu24dear47va7m96gr3rf4g9gcq4h25" + ], + "isAddress": true + } + ], + "blockHash": "00000000000000000028351f97cd867acbba39b5a81137ce35a1ac18444aaa76", + "blockHeight": 619773, + "confirmations": 8182, + "blockTime": 1580201823, + "value": "188124", + "valueIn": "188804", + "fees": "680", + "hex": "0100000002a16be77fe40f9d3d3997e8320e2c9e0b842e6bffca5af742d40b3f5f1034acfe010000006b483045022100dbbf18561baf7fdb46c21d27801594209f2067f1d7735e245c56001c4e462d3c0220016e052ebbcf350bd64a257f7cc52ef23730fe50b24355d098f87c528fcd839641210259dc89eeb4c7b349faab20e932be226a1ed7d582f25b64e9abf84f73e1d25fd5000000008056e54d0ef27a1064a5b2918c3aeb387274acf55ad069425339a9f28f95b801000000006a47304402202100334789951706405faa9ddc191702b88d9438d5a461d1f008a9bd097bd9b0022062cd93003ad63bfbb16386b90e619c2b32d9caef5229d8943c11309f26b6c19f41210259dc89eeb4c7b349faab20e932be226a1ed7d582f25b64e9abf84f73e1d25fd50000000001dcde0200000000001976a9149800c09de05d8e2aadcf475f33bed97481c469aa88ac00000000" + }, + { + "txid": "feac34105f3f0bd442f75acaff6b2e840b9e2c0e32e897393d9d0fe47fe76ba1", + "version": 1, + "vin": [ + { + "txid": "6f2d6fb46039f192f82cfd9bc85dcf0575fdf5eda9b726643314be883c8c0559", + "vout": 1, + "n": 0, + "addresses": [ + "bitcoincash:qzvqpsyaupwcu24dear47va7m96gr3rf4g9gcq4h25" + ], + "isAddress": true, + "value": "49256", + "hex": "47304402207df4bd44f74e9a077b84f547b29c595e808bfb3ebc23e070e975905e2012044c02206fa66e30f9afe063c5a5c30d0bb20c6d0eece782a9b6211676180c25d745e98c41210259dc89eeb4c7b349faab20e932be226a1ed7d582f25b64e9abf84f73e1d25fd5" + } + ], + "vout": [ + { + "value": "10000", + "n": 0, + "spent": true, + "hex": "76a914045891bcbb214544c47a8dbc75350584d8042bc288ac", + "addresses": [ + "bitcoincash:qqz93yduhvs523xy02xmcaf4qkzdspptcgq4dscr8c" + ], + "isAddress": true + }, + { + "value": "38804", + "n": 1, + "spent": true, + "hex": "76a9149800c09de05d8e2aadcf475f33bed97481c469aa88ac", + "addresses": [ + "bitcoincash:qzvqpsyaupwcu24dear47va7m96gr3rf4g9gcq4h25" + ], + "isAddress": true + } + ], + "blockHash": "0000000000000000015997ed69ac8b1e1d19c006bca7fb08faf3442890b2fed5", + "blockHeight": 619764, + "confirmations": 8191, + "blockTime": 1580198433, + "value": "48804", + "valueIn": "49256", + "fees": "452", + "hex": "010000000159058c3c88be14336426b7a9edf5fd7505cf5dc89bfd2cf892f13960b46f2d6f010000006a47304402207df4bd44f74e9a077b84f547b29c595e808bfb3ebc23e070e975905e2012044c02206fa66e30f9afe063c5a5c30d0bb20c6d0eece782a9b6211676180c25d745e98c41210259dc89eeb4c7b349faab20e932be226a1ed7d582f25b64e9abf84f73e1d25fd5000000000210270000000000001976a914045891bcbb214544c47a8dbc75350584d8042bc288ac94970000000000001976a9149800c09de05d8e2aadcf475f33bed97481c469aa88ac00000000" + } + ], + "usedTokens": 71, + "tokens": [ + { + "type": "XPUBAddress", + "name": "bitcoincash:qzvqpsyaupwcu24dear47va7m96gr3rf4g9gcq4h25", + "path": "m/44'/145'/0'/0/0", + "transfers": 11, + "decimals": 8, + "balance": "177672", + "totalReceived": "850002", + "totalSent": "672330" + } + ] +} diff --git a/mock/ext-api-data/callisto-api_tokens__address_0xc3d5b69f65027ddf48f894e6e90121293a2f6615.json b/mock/ext-api-data/callisto-api_tokens__address_0xc3d5b69f65027ddf48f894e6e90121293a2f6615.json new file mode 100644 index 000000000..e87b48373 --- /dev/null +++ b/mock/ext-api-data/callisto-api_tokens__address_0xc3d5b69f65027ddf48f894e6e90121293a2f6615.json @@ -0,0 +1 @@ +{"total":1,"docs":[{"address":"0xc3d5B69F65027dDF48f894E6e90121293a2F6615","name":"The Hitchhikers Guide to the Galaxy","decimals":18,"symbol":"H2G2"}]} \ No newline at end of file diff --git a/mock/ext-api-data/callisto-api_transactions__address_0x3083a7ec44ca2b038d4be4b0798152f948f0f3d7.json b/mock/ext-api-data/callisto-api_transactions__address_0x3083a7ec44ca2b038d4be4b0798152f948f0f3d7.json new file mode 100644 index 000000000..6a10f16b3 --- /dev/null +++ b/mock/ext-api-data/callisto-api_transactions__address_0x3083a7ec44ca2b038d4be4b0798152f948f0f3d7.json @@ -0,0 +1 @@ +{"docs":[{"operations":[],"contract":null,"_id":"0x82b5678e0ba3b46b0102d5ff433a9f115eaf91402d613ffbca0dd5338a51c44f","blockNumber":5035151,"time":1589316023,"nonce":1723,"from":"0xbb120a8195ebD3EA66C1C6dfF45c18D38d786E06","to":"0x3083a7Ec44ca2b038D4BE4B0798152F948f0f3d7","value":"129028387687000000000","gas":"21000","gasPrice":"30000000000","gasUsed":"21000","input":"0x","error":"","id":"0x82b5678e0ba3b46b0102d5ff433a9f115eaf91402d613ffbca0dd5338a51c44f","timeStamp":"1589316023"},{"operations":[],"contract":null,"_id":"0x90b487c9db0efd161f8e1a88150002cc5cf9f8b9e697aaf55495d5fa69d80a71","blockNumber":5035135,"time":1589315810,"nonce":276,"from":"0xe91406762704Cdbf495f3bdE76cD400C970d2aDE","to":"0x3083a7Ec44ca2b038D4BE4B0798152F948f0f3d7","value":"342351173250000000000","gas":"21000","gasPrice":"30000000000","gasUsed":"21000","input":"0x","error":"","id":"0x90b487c9db0efd161f8e1a88150002cc5cf9f8b9e697aaf55495d5fa69d80a71","timeStamp":"1589315810"},{"operations":[],"contract":null,"_id":"0x8e64dcd6de7e37596d51af0583ec6dc2f2638d9f8e23166962e9bdb4a8866352","blockNumber":5035134,"time":1589315799,"nonce":2914,"from":"0xCd82593B48E9a58c9b09ee6C3dED7C3036835871","to":"0x3083a7Ec44ca2b038D4BE4B0798152F948f0f3d7","value":"231388157710000000000","gas":"21000","gasPrice":"30000000000","gasUsed":"21000","input":"0x","error":"","id":"0x8e64dcd6de7e37596d51af0583ec6dc2f2638d9f8e23166962e9bdb4a8866352","timeStamp":"1589315799"},{"operations":[],"contract":null,"_id":"0xab22889ab91804259cf0495a79b13e85f137c64303653c5b3b244410b5924ca3","blockNumber":5035134,"time":1589315799,"nonce":4358,"from":"0xCDAe1A9880Fcc52733b087c2a415e294371F009e","to":"0x3083a7Ec44ca2b038D4BE4B0798152F948f0f3d7","value":"153244647883000000000","gas":"21000","gasPrice":"30000000000","gasUsed":"21000","input":"0x","error":"","id":"0xab22889ab91804259cf0495a79b13e85f137c64303653c5b3b244410b5924ca3","timeStamp":"1589315799"},{"operations":[],"contract":null,"_id":"0x54b3afa576a7f7eb7d2d60903e70d1768012dfe213b11ced6ea07f3ccf886c75","blockNumber":5035134,"time":1589315799,"nonce":5051,"from":"0x1c48A9E67AFA9Ddf2DEDA4139D60030d1B999D4A","to":"0x3083a7Ec44ca2b038D4BE4B0798152F948f0f3d7","value":"378400830789000000000","gas":"21000","gasPrice":"30000000000","gasUsed":"21000","input":"0x","error":"","id":"0x54b3afa576a7f7eb7d2d60903e70d1768012dfe213b11ced6ea07f3ccf886c75","timeStamp":"1589315799"},{"operations":[],"contract":null,"_id":"0xae126b8e6ab2717537f0d54849c6d4ba52f1ca1832ebf3fce270589459e9a4cf","blockNumber":5035133,"time":1589315778,"nonce":2048,"from":"0x5e641A17913fdE89c4CE07aFf26411B10aB784DB","to":"0x3083a7Ec44ca2b038D4BE4B0798152F948f0f3d7","value":"111733740240000000000","gas":"21000","gasPrice":"30000000000","gasUsed":"21000","input":"0x","error":"","id":"0xae126b8e6ab2717537f0d54849c6d4ba52f1ca1832ebf3fce270589459e9a4cf","timeStamp":"1589315778"},{"operations":[],"contract":null,"_id":"0xc3915ee14aea901db1500117ba949250c72a491506da8d604e052ae231911646","blockNumber":5035133,"time":1589315778,"nonce":3836,"from":"0x2D926778faa368EBAF115C7Cd2a9789A66c65C06","to":"0x3083a7Ec44ca2b038D4BE4B0798152F948f0f3d7","value":"169969278070000000000","gas":"21000","gasPrice":"30000000000","gasUsed":"21000","input":"0x","error":"","id":"0xc3915ee14aea901db1500117ba949250c72a491506da8d604e052ae231911646","timeStamp":"1589315778"},{"operations":[],"contract":null,"_id":"0xb5a4b98bf365e2fced0de8e9628631d1b3833426da20db7ccb7a36d41d00a1d7","blockNumber":5035133,"time":1589315778,"nonce":2975,"from":"0xBabb1E29027edde95ac20cd1d2938e9c579bAa65","to":"0x3083a7Ec44ca2b038D4BE4B0798152F948f0f3d7","value":"207855558241000000000","gas":"21000","gasPrice":"30000000000","gasUsed":"21000","input":"0x","error":"","id":"0xb5a4b98bf365e2fced0de8e9628631d1b3833426da20db7ccb7a36d41d00a1d7","timeStamp":"1589315778"},{"operations":[],"contract":null,"_id":"0x881b0f9a3774f500cf0587e6a4933a70945311478545607d566cdb4299909e08","blockNumber":5035133,"time":1589315778,"nonce":3358,"from":"0xE0bfc2658C7b1b297327a4BCf4C41ae1e6aD6f7b","to":"0x3083a7Ec44ca2b038D4BE4B0798152F948f0f3d7","value":"131733221089000000000","gas":"21000","gasPrice":"30000000000","gasUsed":"21000","input":"0x","error":"","id":"0x881b0f9a3774f500cf0587e6a4933a70945311478545607d566cdb4299909e08","timeStamp":"1589315778"},{"operations":[],"contract":null,"_id":"0x70196354cfd0ec5e228cb1ac677de3f416179ba43e1c12cb890f8d0185e8a88a","blockNumber":5035133,"time":1589315778,"nonce":5402,"from":"0x1434f888964A9BB48ce1499dDC07e62dB3696098","to":"0x3083a7Ec44ca2b038D4BE4B0798152F948f0f3d7","value":"532374455895000000000","gas":"21000","gasPrice":"30000000000","gasUsed":"21000","input":"0x","error":"","id":"0x70196354cfd0ec5e228cb1ac677de3f416179ba43e1c12cb890f8d0185e8a88a","timeStamp":"1589315778"},{"operations":[],"contract":null,"_id":"0x02ffc6e44d59e0af56c8fbd00f4ab3b5f6894731f2c17f140933fa2dc3c28e15","blockNumber":5035133,"time":1589315778,"nonce":336,"from":"0xab5F56365c2C1CAc4cC880cc99F9E13834B49116","to":"0x3083a7Ec44ca2b038D4BE4B0798152F948f0f3d7","value":"183175717108000000000","gas":"21000","gasPrice":"30000000000","gasUsed":"21000","input":"0x","error":"","id":"0x02ffc6e44d59e0af56c8fbd00f4ab3b5f6894731f2c17f140933fa2dc3c28e15","timeStamp":"1589315778"},{"operations":[],"contract":null,"_id":"0x5bfab15fa70c0db470bd3a9be14eafdfd09ff54d73649ed8878135d35b0b9707","blockNumber":5035131,"time":1589315758,"nonce":3108,"from":"0xB346eeBdAd639777DD49773339CA64369D11b354","to":"0x3083a7Ec44ca2b038D4BE4B0798152F948f0f3d7","value":"140432086672000000000","gas":"21000","gasPrice":"30000000000","gasUsed":"21000","input":"0x","error":"","id":"0x5bfab15fa70c0db470bd3a9be14eafdfd09ff54d73649ed8878135d35b0b9707","timeStamp":"1589315758"},{"operations":[],"contract":null,"_id":"0xda1351efecec883529d10f180436405d711e2ba048508a3f91fbdcc6ea8a7694","blockNumber":5035128,"time":1589315724,"nonce":2862,"from":"0xd3324d82bce0AD0957AFe71Ea20200A7Cf9B271f","to":"0x3083a7Ec44ca2b038D4BE4B0798152F948f0f3d7","value":"168228497950000000000","gas":"21000","gasPrice":"30000000000","gasUsed":"21000","input":"0x","error":"","id":"0xda1351efecec883529d10f180436405d711e2ba048508a3f91fbdcc6ea8a7694","timeStamp":"1589315724"},{"operations":[],"contract":null,"_id":"0x26428836a77ccd7693ecd8cb1758ca526f5dcc7c4ad87fcb79f1bd9053a3b4eb","blockNumber":5035128,"time":1589315724,"nonce":5138,"from":"0xa60ca31a47F35471D5679a19E8f8c873f6373A4C","to":"0x3083a7Ec44ca2b038D4BE4B0798152F948f0f3d7","value":"141750177027000000000","gas":"21000","gasPrice":"30000000000","gasUsed":"21000","input":"0x","error":"","id":"0x26428836a77ccd7693ecd8cb1758ca526f5dcc7c4ad87fcb79f1bd9053a3b4eb","timeStamp":"1589315724"},{"operations":[],"contract":null,"_id":"0x88b7213a7eeb8cd2682b0b1893796b9fe6e655013aa1e4c175666574498e0fe6","blockNumber":5035127,"time":1589315620,"nonce":6031,"from":"0x85D382a464cbFE155f1cd2e51Cdf70e1848e0B30","to":"0x3083a7Ec44ca2b038D4BE4B0798152F948f0f3d7","value":"234799792180000000000","gas":"21000","gasPrice":"30000000000","gasUsed":"21000","input":"0x","error":"","id":"0x88b7213a7eeb8cd2682b0b1893796b9fe6e655013aa1e4c175666574498e0fe6","timeStamp":"1589315620"},{"operations":[],"contract":null,"_id":"0x7b2e66adb872dc5145f2ae906b8f3708623598d8a43defa230d12300e6d24167","blockNumber":5035127,"time":1589315620,"nonce":1501,"from":"0x037EE208fbedB2aB659da61bE5D3d7d59a680450","to":"0x3083a7Ec44ca2b038D4BE4B0798152F948f0f3d7","value":"114044051373000000000","gas":"21000","gasPrice":"30000000000","gasUsed":"21000","input":"0x","error":"","id":"0x7b2e66adb872dc5145f2ae906b8f3708623598d8a43defa230d12300e6d24167","timeStamp":"1589315620"},{"operations":[],"contract":null,"_id":"0xd40fda506a9c4ec79bdfb9849b22bb2783ff0fd90677de17fe83542b3171267e","blockNumber":5035127,"time":1589315620,"nonce":4209,"from":"0x80CAE9A0F67Ece88917a0dFdebeAA796A8Ad6baB","to":"0x3083a7Ec44ca2b038D4BE4B0798152F948f0f3d7","value":"267270750139000000000","gas":"21000","gasPrice":"30000000000","gasUsed":"21000","input":"0x","error":"","id":"0xd40fda506a9c4ec79bdfb9849b22bb2783ff0fd90677de17fe83542b3171267e","timeStamp":"1589315620"},{"operations":[],"contract":null,"_id":"0x95e2b3ffb9ea38f7a12929c56a083ff1e218abe3a6ee4a496e93d192ed7349ba","blockNumber":5035127,"time":1589315620,"nonce":5729,"from":"0x9246E7498358b8E48b7B4fCfB6b6B288a32CF88c","to":"0x3083a7Ec44ca2b038D4BE4B0798152F948f0f3d7","value":"110097850354000000000","gas":"21000","gasPrice":"30000000000","gasUsed":"21000","input":"0x","error":"","id":"0x95e2b3ffb9ea38f7a12929c56a083ff1e218abe3a6ee4a496e93d192ed7349ba","timeStamp":"1589315620"},{"operations":[],"contract":null,"_id":"0x52c30c78b9babab02a49bed0b372027995e8770520a3f5e7731ce15530f926ed","blockNumber":5035127,"time":1589315620,"nonce":1821,"from":"0x866c5c04B9F76bf3937E8ba6D55296766f4AA68e","to":"0x3083a7Ec44ca2b038D4BE4B0798152F948f0f3d7","value":"154521636030000000000","gas":"21000","gasPrice":"30000000000","gasUsed":"21000","input":"0x","error":"","id":"0x52c30c78b9babab02a49bed0b372027995e8770520a3f5e7731ce15530f926ed","timeStamp":"1589315620"},{"operations":[],"contract":null,"_id":"0x7b044c4e2554436812d6f4e47e6061b9c781077b3249465a11650d96a1386903","blockNumber":5035124,"time":1589315584,"nonce":4707,"from":"0x84dDF97c4500c2eDDAeE8965170Ba15843830Ca6","to":"0x3083a7Ec44ca2b038D4BE4B0798152F948f0f3d7","value":"348242860332000000000","gas":"21000","gasPrice":"30000000000","gasUsed":"21000","input":"0x","error":"","id":"0x7b044c4e2554436812d6f4e47e6061b9c781077b3249465a11650d96a1386903","timeStamp":"1589315584"},{"operations":[],"contract":null,"_id":"0x9bc139292a22ceee805c1aa2e4f04d949987e7e8db2ec977ad68718e754a2501","blockNumber":5035020,"time":1589314043,"nonce":1249,"from":"0x3EBe5E81f99F8711C29872059197C776875A6d39","to":"0x3083a7Ec44ca2b038D4BE4B0798152F948f0f3d7","value":"169702326013000000000","gas":"21000","gasPrice":"30000000000","gasUsed":"21000","input":"0x","error":"","id":"0x9bc139292a22ceee805c1aa2e4f04d949987e7e8db2ec977ad68718e754a2501","timeStamp":"1589314043"},{"operations":[],"contract":null,"_id":"0x85486da3117d18fd789eb83974f8e050e19a7c382eb950a5a9a6d0509fb9b4e8","blockNumber":5035005,"time":1589313889,"nonce":1825,"from":"0x1212c7aE2d01E3d174C759EF616c46C9C50bd94f","to":"0x3083a7Ec44ca2b038D4BE4B0798152F948f0f3d7","value":"205825126533000000000","gas":"21000","gasPrice":"30000000000","gasUsed":"21000","input":"0x","error":"","id":"0x85486da3117d18fd789eb83974f8e050e19a7c382eb950a5a9a6d0509fb9b4e8","timeStamp":"1589313889"},{"operations":[],"contract":null,"_id":"0xbf01f666ed9b94b8ad5f6ee364e501fbf449faf9bc9f3024b610d961d575ecad","blockNumber":5035004,"time":1589313876,"nonce":5168,"from":"0xdb9EdDA5E1473D6D893418B95B93DC6abCa03449","to":"0x3083a7Ec44ca2b038D4BE4B0798152F948f0f3d7","value":"117070306775000000000","gas":"21000","gasPrice":"30000000000","gasUsed":"21000","input":"0x","error":"","id":"0xbf01f666ed9b94b8ad5f6ee364e501fbf449faf9bc9f3024b610d961d575ecad","timeStamp":"1589313876"},{"operations":[],"contract":null,"_id":"0xe640264a9fc8ba3688be9cb4ec9af4b955689315d84a1c85113348242a45e1c2","blockNumber":5035004,"time":1589313876,"nonce":3348,"from":"0xC345943EEE93D60FA2A8A33A8D6D0015Ca16A4Fe","to":"0x3083a7Ec44ca2b038D4BE4B0798152F948f0f3d7","value":"118206180675000000000","gas":"21000","gasPrice":"30000000000","gasUsed":"21000","input":"0x","error":"","id":"0xe640264a9fc8ba3688be9cb4ec9af4b955689315d84a1c85113348242a45e1c2","timeStamp":"1589313876"},{"operations":[],"contract":null,"_id":"0x3dc87c1cbab90500c956976465e08de6e10cc7d27dfbacc3e6b0fa9023930a7e","blockNumber":5035004,"time":1589313876,"nonce":440,"from":"0x8d1A02bf0b94DaeFC38fA47Be37B76Bab818cD65","to":"0x3083a7Ec44ca2b038D4BE4B0798152F948f0f3d7","value":"339711659473000000000","gas":"21000","gasPrice":"30000000000","gasUsed":"21000","input":"0x","error":"","id":"0x3dc87c1cbab90500c956976465e08de6e10cc7d27dfbacc3e6b0fa9023930a7e","timeStamp":"1589313876"}],"total":25} \ No newline at end of file diff --git a/mock/ext-api-data/cosmos-api_auth_accounts_cosmos1dx27g0kzhwej0ekcf2k9hsktcxnmpl7fcehcvq.json b/mock/ext-api-data/cosmos-api_auth_accounts_cosmos1dx27g0kzhwej0ekcf2k9hsktcxnmpl7fcehcvq.json new file mode 100644 index 000000000..03520a934 --- /dev/null +++ b/mock/ext-api-data/cosmos-api_auth_accounts_cosmos1dx27g0kzhwej0ekcf2k9hsktcxnmpl7fcehcvq.json @@ -0,0 +1 @@ +{"height":"1900975","result":{"type":"cosmos-sdk/Account","value":{"address":"cosmos1dx27g0kzhwej0ekcf2k9hsktcxnmpl7fcehcvq","coins":[],"public_key":{"type":"tendermint/PubKeySecp256k1","value":"A782zo6TI2H3DfHJ7X1WHOJz6p4fUYVRYhb/XqMTcVQt"},"account_number":"10373","sequence":"3"}}} \ No newline at end of file diff --git a/mock/ext-api-data/cosmos-api_minting_inflation.json b/mock/ext-api-data/cosmos-api_minting_inflation.json new file mode 100644 index 000000000..0fe813926 --- /dev/null +++ b/mock/ext-api-data/cosmos-api_minting_inflation.json @@ -0,0 +1,4 @@ +{ + "height": "1869960", + "result": "0.070000000000000000" +} \ No newline at end of file diff --git a/mock/ext-api-data/cosmos-api_staking_delegators_cosmos1dx27g0kzhwej0ekcf2k9hsktcxnmpl7fcehcvq_delegations.json b/mock/ext-api-data/cosmos-api_staking_delegators_cosmos1dx27g0kzhwej0ekcf2k9hsktcxnmpl7fcehcvq_delegations.json new file mode 100644 index 000000000..523cda5f1 --- /dev/null +++ b/mock/ext-api-data/cosmos-api_staking_delegators_cosmos1dx27g0kzhwej0ekcf2k9hsktcxnmpl7fcehcvq_delegations.json @@ -0,0 +1,11 @@ +{ + "height": "1869960", + "result": [ + { + "delegator_address": "cosmos1dx27g0kzhwej0ekcf2k9hsktcxnmpl7fcehcvq", + "validator_address": "cosmosvaloper17h2x3j7u44qkrq0sk8ul0r2qr440rwgjkfg0gh", + "shares": "2211271.000000000000000000", + "balance": "2211271" + } + ] +} \ No newline at end of file diff --git a/mock/ext-api-data/cosmos-api_staking_pool.json b/mock/ext-api-data/cosmos-api_staking_pool.json new file mode 100644 index 000000000..6275f5280 --- /dev/null +++ b/mock/ext-api-data/cosmos-api_staking_pool.json @@ -0,0 +1,7 @@ +{ + "height": "1869960", + "result": { + "not_bonded_tokens": "4596456385348", + "bonded_tokens": "182417010067615" + } +} \ No newline at end of file diff --git a/mock/ext-api-data/cosmos-api_staking_validators__status_bonded.json b/mock/ext-api-data/cosmos-api_staking_validators__status_bonded.json new file mode 100644 index 000000000..b107e93f5 --- /dev/null +++ b/mock/ext-api-data/cosmos-api_staking_validators__status_bonded.json @@ -0,0 +1,3130 @@ +{ + "height": "1863094", + "result": [ + { + "operator_address": "cosmosvaloper1qdxmyqkvt8jsxpn5pp45a38ngs36mn2604cqk9", + "consensus_pubkey": "cosmosvalconspub1zcjduepqmq2l5ehgl3rxwjgzgr6sgzp69qwjl5ufvtyvacc9ms8p3phazl2qh3ulfw", + "jailed": false, + "status": 2, + "tokens": "74844486443", + "delegator_shares": "74844486443.000000000000000000", + "description": { + "moniker": "真本聪\u0026IOSG", + "identity": "8A79F44CC25D26DF", + "website": "realsatoshi.net", + "details": "To The Moon Then Cosmos. We are a crypto community and venture capital combined staking service provider" + }, + "unbonding_height": "0", + "unbonding_time": "2019-06-24T19:55:42.604341211Z", + "commission": { + "commission_rates": { + "rate": "0.100000000000000000", + "max_rate": "1.000000000000000000", + "max_change_rate": "1.000000000000000000" + }, + "update_time": "2019-08-05T07:24:32.572614545Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1qwl879nx9t6kef4supyazayf7vjhennyh568ys", + "consensus_pubkey": "cosmosvalconspub1zcjduepqwrjpn0slu86e32zfu5xxg8l42uk40guuw6er44vw2yl6s7wc38est6l0ux", + "jailed": false, + "status": 2, + "tokens": "5603064313542", + "delegator_shares": "5603064313542.000000000000000000", + "description": { + "moniker": "Certus One", + "identity": "ABD51DF68C0D1ECF", + "website": "https://certus.one", + "details": "Stake and earn rewards with the most secure and stable validator. Winner of the Game of Stakes. Operated by Certus One Inc. By delegating, you confirm that you are aware of the risk of slashing and that Certus One Inc is not liable for any potential damages to your investment." + }, + "unbonding_height": "0", + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.125000000000000000", + "max_rate": "0.300000000000000000", + "max_change_rate": "0.010000000000000000" + }, + "update_time": "2019-03-13T23:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1qs8tnw2t8l6amtzvdemnnsq9dzk0ag0z52uzay", + "consensus_pubkey": "cosmosvalconspub1zcjduepqsszd2gzte82dzt0xpa3w0ky8lxhjs6zpd5ft8akmkscwujpftymsnt83qc", + "jailed": false, + "status": 2, + "tokens": "1604777219007", + "delegator_shares": "1604777219007.000000000000000000", + "description": { + "moniker": "Castlenode", + "identity": "F685CC35D748424C", + "website": "https://www.castlenode.com/cosmos", + "details": "Castlenode is a validator operator focused on security and run by experienced professionals. Please read our Terms and Conditions on our website before delegating" + }, + "unbonding_height": "0", + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.090000000000000000", + "max_rate": "0.500000000000000000", + "max_change_rate": "0.050000000000000000" + }, + "update_time": "2019-03-13T23:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1qaa9zej9a0ge3ugpx3pxyx602lxh3ztqgfnp42", + "consensus_pubkey": "cosmosvalconspub1zcjduepqgx5wxl6eygqf6rx4gura2dy5vzelthjgqntk7q9l2hnpjqam6atsq8u0lx", + "jailed": false, + "status": 2, + "tokens": "69345300547", + "delegator_shares": "69345300547.000000000000000000", + "description": { + "moniker": "CCN", + "identity": "", + "website": "", + "details": "" + }, + "unbonding_height": "0", + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.000000000000000000", + "max_rate": "0.200000000000000000", + "max_change_rate": "0.100000000000000000" + }, + "update_time": "2020-04-06T14:37:22.97012847Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1pz0lfq40sa63n0wany3v95x3yvznc5gyf8u28w", + "consensus_pubkey": "cosmosvalconspub1zcjduepqv03r9c26w884sqw0zdqg9cdx4xxwgn3dd2s6wa3x346tm83nxudqwhm3jl", + "jailed": false, + "status": 2, + "tokens": "252842798220", + "delegator_shares": "252842798220.000000000000000000", + "description": { + "moniker": "Cobo", + "identity": "3B7C85200D5B57A9", + "website": "https://cobo.com/", + "details": "Cobo is the first leading company in the world to offer Proof-of-Stake (PoS) and masternode rewards on user holdings, making it easy for users to grow their digital assets effortlessly." + }, + "unbonding_height": "0", + "unbonding_time": "2019-05-18T11:34:21.668987388Z", + "commission": { + "commission_rates": { + "rate": "0.100000000000000000", + "max_rate": "0.200000000000000000", + "max_change_rate": "0.010000000000000000" + }, + "update_time": "2019-06-15T05:45:23.950986198Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1pgsjyvkg3y2m7qas534zzdhsqsxqyph2jh3uck", + "consensus_pubkey": "cosmosvalconspub1zcjduepq5tycuhznpjuwlr93ypflreaddk0r66hdryzgmfvmlj2ekdd5sqrqnxclgg", + "jailed": false, + "status": 2, + "tokens": "460520445065", + "delegator_shares": "460520445065.000000000000000000", + "description": { + "moniker": "OneSixtyTwo", + "identity": "1C136F82A18BB2E2", + "website": "", + "details": "OneSixtyTwo" + }, + "unbonding_height": "0", + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.130000000000000000", + "max_rate": "0.200000000000000000", + "max_change_rate": "0.010000000000000000" + }, + "update_time": "2020-05-12T13:45:02.654424038Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1ptyzewnns2kn37ewtmv6ppsvhdnmeapvtfc9y5", + "consensus_pubkey": "cosmosvalconspub1zcjduepqtcsm8lp7n6ph98vd59qa9esgyuysuntww9juz5wynxrhzpspmuuq6g5pzg", + "jailed": false, + "status": 2, + "tokens": "925719899399", + "delegator_shares": "925719899399.000000000000000000", + "description": { + "moniker": "WeStaking", + "identity": "DA9C5AD3E308E426", + "website": "https://www.westaking.io", + "details": "Delegate your atom to us for the staking rewards. We will do our best as secure and stable validator." + }, + "unbonding_height": "0", + "unbonding_time": "2019-09-07T12:24:58.270714195Z", + "commission": { + "commission_rates": { + "rate": "0.030000000000000000", + "max_rate": "0.200000000000000000", + "max_change_rate": "0.010000000000000000" + }, + "update_time": "2020-03-29T00:37:22.163935678Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1pjmngrwcsatsuyy8m3qrunaun67sr9x7z5r2qs", + "consensus_pubkey": "cosmosvalconspub1zcjduepqcdav5ylt2zst90qmuh8e5w07xmxv9y6wufp5k9ngzmx7v9qewqtqkcq4z8", + "jailed": false, + "status": 2, + "tokens": "654800077136", + "delegator_shares": "654800077136.000000000000000000", + "description": { + "moniker": "Cypher Core", + "identity": "", + "website": "", + "details": "" + }, + "unbonding_height": "0", + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.100000000000000000", + "max_rate": "0.200000000000000000", + "max_change_rate": "0.010000000000000000" + }, + "update_time": "2019-03-13T23:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1p650epkdwj0jte6sjc3ep0n3wz6jc9ehh8jutg", + "consensus_pubkey": "cosmosvalconspub1zcjduepqmy5ja8dee3sprtmxkekcuvwz20y2x9d6llcsjl6p6553rpqev0eql6qccf", + "jailed": false, + "status": 2, + "tokens": "109356501526", + "delegator_shares": "109389314898.340406887282218010", + "description": { + "moniker": "Cosmos Suisse", + "identity": "2D875495A911A943", + "website": "https://cosmos-suisse.com", + "details": "An awesome Validator based in Crypto Valley, Switzerland." + }, + "unbonding_height": "970101", + "unbonding_time": "2020-03-21T06:33:36.130547135Z", + "commission": { + "commission_rates": { + "rate": "0.295000000000000000", + "max_rate": "0.500000000000000000", + "max_change_rate": "0.010000000000000000" + }, + "update_time": "2020-04-05T06:40:17.027131003Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1zqgheeawp7cmqk27dgyctd80rd8ryhqs6la9wc", + "consensus_pubkey": "cosmosvalconspub1zcjduepq5tm478lhn4du7l46yp6fgu9e8fcfks0j4kf87pk4z8vc3clckxzqvh2q72", + "jailed": false, + "status": 2, + "tokens": "685457020651", + "delegator_shares": "685457020651.000000000000000000", + "description": { + "moniker": "melea-◮👁◭", + "identity": "4BE49EABAA41B8BF", + "website": "https://meleatrust.com/", + "details": "Validator service secure and trusted, awarded in Game Of Steaks" + }, + "unbonding_height": "0", + "unbonding_time": "2019-06-26T23:50:09.38840326Z", + "commission": { + "commission_rates": { + "rate": "0.150000000000000000", + "max_rate": "0.500000000000000000", + "max_change_rate": "0.010000000000000000" + }, + "update_time": "2019-11-27T05:18:46.405341672Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1rpgtz9pskr5geavkjz02caqmeep7cwwpv73axj", + "consensus_pubkey": "cosmosvalconspub1zcjduepq04y0dtylyed2f8drc9t78dmptfuta7l6xyujwmsgrqefs0sxpgjsnzpsj6", + "jailed": false, + "status": 2, + "tokens": "4009701343250", + "delegator_shares": "4010503403720.896323597221447607", + "description": { + "moniker": "Blockpower", + "identity": "C374865C7ADE710B", + "website": "http://blockpower.capital/cosmos", + "details": "We self-bond 1m atoms and will keep our fee low till transfer enabled. We are top-ten validator in Tezos and operate professional staking services for multiple PoS platforms. Twitter: https://twitter.com/blockpowercap and TG: https://t.me/blockpowercosmos" + }, + "unbonding_height": "0", + "unbonding_time": "2019-11-04T04:14:24.222468286Z", + "commission": { + "commission_rates": { + "rate": "0.030000000000000000", + "max_rate": "1.000000000000000000", + "max_change_rate": "0.010000000000000000" + }, + "update_time": "2019-03-31T19:58:53.172697095Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1r8kyvg4me2upnvlk26n2ay0zd5t4jktna8hhxp", + "consensus_pubkey": "cosmosvalconspub1zcjduepqsl29jhapyxf4fa5a947dmnlvrt266fm959hfg2c657ju80hq0ljs3qejr7", + "jailed": false, + "status": 2, + "tokens": "250002000000", + "delegator_shares": "250002000000.000000000000000000", + "description": { + "moniker": "noma", + "identity": "", + "website": "", + "details": "" + }, + "unbonding_height": "0", + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.200000000000000000", + "max_rate": "1.000000000000000000", + "max_change_rate": "1.000000000000000000" + }, + "update_time": "2019-03-14T03:50:13.123302789Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1rwh0cxa72d3yle3r4l8gd7vyphrmjy2kpe4x72", + "consensus_pubkey": "cosmosvalconspub1zcjduepq5kg8xls9l35ftulkm2rt70hexeeyr5cqqkcv4h7936z5uasvvazqla8eck", + "jailed": false, + "status": 2, + "tokens": "5176992318281", + "delegator_shares": "5176992318281.000000000000000000", + "description": { + "moniker": "SparkPool", + "identity": "DE8E37240061B04E", + "website": "https://cosmos.sparkpool.com/", + "details": "The biggest Ethereum mining pool, we can be a reliable validator with our 3 years" + }, + "unbonding_height": "0", + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.060000000000000000", + "max_rate": "0.200000000000000000", + "max_change_rate": "0.050000000000000000" + }, + "update_time": "2020-05-09T08:01:06.223552512Z" + }, + "min_self_delegation": "100000000000" + }, + { + "operator_address": "cosmosvaloper1rcp29q3hpd246n6qak7jluqep4v006cdsc2kkl", + "consensus_pubkey": "cosmosvalconspub1zcjduepq7mft6gfls57a0a42d7uhx656cckhfvtrlmw744jv4q0mvlv0dypskehfk8", + "jailed": false, + "status": 2, + "tokens": "244367809379", + "delegator_shares": "244367809379.000000000000000000", + "description": { + "moniker": "2nd only to Certus One in GoS: in3s.com", + "identity": "0CE19EE3E4BA48E5", + "website": "https://in3s.com/Services#CosmosValidator", + "details": "https://in3s.com/Delegate#Delegate" + }, + "unbonding_height": "0", + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "1.000000000000000000", + "max_rate": "1.000000000000000000", + "max_change_rate": "1.000000000000000000" + }, + "update_time": "2019-03-18T20:31:50.23335594Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1y0us8xvsvfvqkk9c6nt5cfyu5au5tww2ztve7q", + "consensus_pubkey": "cosmosvalconspub1zcjduepqqhkzzgfc876q287ny2v9lqwmjpenuzkzlsnstrmg7krwrrf0pfqs9fxvs0", + "jailed": false, + "status": 2, + "tokens": "21746516100", + "delegator_shares": "21746516100.000000000000000000", + "description": { + "moniker": "Swiss Staking", + "identity": "165F85FC0194320D", + "website": "https://swiss-staking.ch", + "details": "Experienced PoS Validator. We refund downtime slashing to 100%." + }, + "unbonding_height": "0", + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.000000000000000000", + "max_rate": "0.250000000000000000", + "max_change_rate": "0.050000000000000000" + }, + "update_time": "2019-12-11T18:25:42.711862818Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper19yy989ka5usws6gsd8vl94y7l6ssgdwsrnscjc", + "consensus_pubkey": "cosmosvalconspub1zcjduepqf22yaz9nsxlh043qm0tmupw8pnpver2n8lm3mwz6jzmsql76fkmqa482y8", + "jailed": false, + "status": 2, + "tokens": "500001550260", + "delegator_shares": "500001550260.000000000000000000", + "description": { + "moniker": "OKEx Pool", + "identity": "406C257E090E70AA", + "website": "http://www.okpool.top", + "details": "An innovative mining pool with higher yield" + }, + "unbonding_height": "0", + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.100000000000000000", + "max_rate": "0.200000000000000000", + "max_change_rate": "0.010000000000000000" + }, + "update_time": "2019-09-26T10:31:26.722694911Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1998928nfs697ep5d825y5jah0nq9zrtd00yyj7", + "consensus_pubkey": "cosmosvalconspub1zcjduepqlecm0rrfrr0vfgl624s7su9xvd3ycsaetndeuw2c7us0v8vfyfsq7cqz80", + "jailed": false, + "status": 2, + "tokens": "106659805308", + "delegator_shares": "106691809472.979562886817139796", + "description": { + "moniker": "HLT", + "identity": "", + "website": "", + "details": "" + }, + "unbonding_height": "1500089", + "unbonding_time": "2020-05-04T04:00:49.545065159Z", + "commission": { + "commission_rates": { + "rate": "0.100000000000000000", + "max_rate": "0.200000000000000000", + "max_change_rate": "0.010000000000000000" + }, + "update_time": "2019-06-17T11:29:36.731435956Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper199mlc7fr6ll5t54w7tts7f4s0cvnqgc59nmuxf", + "consensus_pubkey": "cosmosvalconspub1zcjduepqajqpmv4j70a08ahs8lyjt8qk28ffa77zjegd7yajghchy8au575qmmxuyt", + "jailed": false, + "status": 2, + "tokens": "573776259593", + "delegator_shares": "573776259593.000000000000000000", + "description": { + "moniker": "Velocity V1", + "identity": "", + "website": "", + "details": "" + }, + "unbonding_height": "0", + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.100000000000000000", + "max_rate": "0.500000000000000000", + "max_change_rate": "0.010000000000000000" + }, + "update_time": "2019-05-30T20:41:10.689796224Z" + }, + "min_self_delegation": "1000000" + }, + { + "operator_address": "cosmosvaloper19v9ej55ataqrfl39v83pf4e0dm69u89rngf928", + "consensus_pubkey": "cosmosvalconspub1zcjduepqa32xgy8y5s69j6dynjmr3rlpv5dv35whz2tyaedwtjeqckm5gg4s2hj8ss", + "jailed": false, + "status": 2, + "tokens": "14371186654", + "delegator_shares": "14371186654.000000000000000000", + "description": { + "moniker": "blockscape", + "identity": "C46C8329BB5F48D8", + "website": "https://blockscape.network/", + "details": "By delegating, you confirm that you are aware of the risk of slashing and that M-Way Solutions GmbH is not liable for any potential damages to your investment." + }, + "unbonding_height": "483", + "unbonding_time": "2020-01-01T17:32:11.54021567Z", + "commission": { + "commission_rates": { + "rate": "0.099900000000000000", + "max_rate": "0.399900000000000000", + "max_change_rate": "0.010000000000000000" + }, + "update_time": "2019-12-02T09:18:02.304119479Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper19j2hd230c3hw6ds843yu8akc0xgvdvyuz9v02v", + "consensus_pubkey": "cosmosvalconspub1zcjduepq9ge7uqrfp9qkdapzd29tjtwrqpt2mm9meptx395ygxgm40tdc8ysrzj40a", + "jailed": false, + "status": 2, + "tokens": "441636806408", + "delegator_shares": "441636806408.000000000000000000", + "description": { + "moniker": "syncnode", + "identity": "F422F328C14AFBFA", + "website": "wallet.syncnode.ro", + "details": "email: g@ysncnode.ro || Operator's LinkedIn: https://www.linkedin.com/in/gbunea/ || Telegram Channel: https://t.me/syncnodeValidator || Blog: https://medium.com/syncnode-validator" + }, + "unbonding_height": "0", + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.100000000000000000", + "max_rate": "0.200000000000000000", + "max_change_rate": "0.010000000000000000" + }, + "update_time": "2020-01-15T11:41:35.747062104Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper19kwwdw0j64xhrmgkz49l0lmu5uyujjayxakwsn", + "consensus_pubkey": "cosmosvalconspub1zcjduepq668g4epaumjtx35rk3ucz2nlm7l7zuewkt0kzutg9hha859zjxmsvl2v67", + "jailed": false, + "status": 2, + "tokens": "631012799749", + "delegator_shares": "631012799749.000000000000000000", + "description": { + "moniker": "Firmamint", + "identity": "2FE4BC7A59E09FD0", + "website": "https://www.firmamint.io/", + "details": "The FUTURE is at STAKE - Proudly Canadian - Tier 1 WINNER of Game of Stakes Adversarial Testnet" + }, + "unbonding_height": "0", + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.150000000000000000", + "max_rate": "0.300000000000000000", + "max_change_rate": "0.030000000000000000" + }, + "update_time": "2019-03-18T22:02:43.333950761Z" + }, + "min_self_delegation": "1500000000" + }, + { + "operator_address": "cosmosvaloper1xym2qygmr9vanpa0m7ndk3n0qxgey3ffzcyd5c", + "consensus_pubkey": "cosmosvalconspub1zcjduepq5evf9e4qhkxym6lx0ur2mwuz5e09u2v7u54yz3wcfanqwvhkc7rqcgpmlw", + "jailed": false, + "status": 2, + "tokens": "100686973548", + "delegator_shares": "100686973548.000000000000000000", + "description": { + "moniker": "🐡grant.fish", + "identity": "BE328F9A089F50C9", + "website": "http://grant.fish", + "details": "Providing grants to projects contributing to the Cosmos ecosystem." + }, + "unbonding_height": "0", + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "1.000000000000000000", + "max_rate": "1.000000000000000000", + "max_change_rate": "1.000000000000000000" + }, + "update_time": "2019-12-11T17:14:13.747872899Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1x8rr4hcf54nz6hfckyy2n05sxss54h8wz9puzg", + "consensus_pubkey": "cosmosvalconspub1zcjduepq8xpk5nh78lmgg0s0qqdyh4xtcw66xemt8anjsr6hrvlhauq252kstq7zr7", + "jailed": false, + "status": 2, + "tokens": "945088518708", + "delegator_shares": "945088518708.000000000000000000", + "description": { + "moniker": "cosmosgbt", + "identity": "", + "website": "", + "details": "" + }, + "unbonding_height": "0", + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.000000000000000000", + "max_rate": "0.500000000000000000", + "max_change_rate": "0.100000000000000000" + }, + "update_time": "2019-10-18T04:22:16.555340871Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1x88j7vp2xnw3zec8ur3g4waxycyz7m0mahdv3p", + "consensus_pubkey": "cosmosvalconspub1zcjduepqhm6gjjkwecqyfrgey96s5up7drnspnl4t3rdr79grklkg9ff6zaqnfl2dg", + "jailed": false, + "status": 2, + "tokens": "2069213291905", + "delegator_shares": "2069213291905.000000000000000000", + "description": { + "moniker": "Staking Facilities", + "identity": "6B0DF6793DE1FB1F", + "website": "stakingfacilities.com", + "details": "Earn rewards with one of the most experienced and secure validators. More than 150k USD in customer rewards paid out. We exclude liability for any financial damage resulting from delegating." + }, + "unbonding_height": "0", + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.100000000000000000", + "max_rate": "0.250000000000000000", + "max_change_rate": "0.010000000000000000" + }, + "update_time": "2019-03-23T22:11:43.172644866Z" + }, + "min_self_delegation": "100000000000" + }, + { + "operator_address": "cosmosvaloper1x065cjlgejk2p2la0029akfvdy52gtq9mm58ta", + "consensus_pubkey": "cosmosvalconspub1zcjduepqny59kv2elgh89tq9qr4jje2n0my4gyvh2hlnydzljtt542a5plwswtas48", + "jailed": false, + "status": 2, + "tokens": "141325143037", + "delegator_shares": "141325143037.000000000000000000", + "description": { + "moniker": "MathWallet麦子钱包", + "identity": "58320327FF6C928C", + "website": "https://mathwallet.org", + "details": "Math Wallet is a powerful and secure universal crypto wallet that enables storage of all BTC, ETH/ERC20, NEO/NEP5, EOS/ENU/Telos, TRON, ONT, BinanceChain, Cosmos/IRISnet tokens, supports cross-chain token exchange and a multi-chain dApp store." + }, + "unbonding_height": "0", + "unbonding_time": "2019-07-21T13:52:13.251185336Z", + "commission": { + "commission_rates": { + "rate": "0.100000000000000000", + "max_rate": "0.200000000000000000", + "max_change_rate": "0.010000000000000000" + }, + "update_time": "2019-09-09T03:44:27.230973438Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1grgelyng2v6v3t8z87wu3sxgt9m5s03xfytvz7", + "consensus_pubkey": "cosmosvalconspub1zcjduepqdgvppnyr5c9pulsrmzr9e9rp7qpgm9jwp5yu8g3aumekgjugxacq8a9p2c", + "jailed": false, + "status": 2, + "tokens": "5356417408061", + "delegator_shares": "5356417408061.000000000000000000", + "description": { + "moniker": "iqlusion", + "identity": "DCB176E79AE7D51F", + "website": "iqlusion.io", + "details": "" + }, + "unbonding_height": "0", + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.100000000000000000", + "max_rate": "1.000000000000000000", + "max_change_rate": "0.010000000000000000" + }, + "update_time": "2019-03-13T23:00:00Z" + }, + "min_self_delegation": "100000000000" + }, + { + "operator_address": "cosmosvaloper1gdg6qqe5a3u483unqlqsnullja23g0xvqkxtk0", + "consensus_pubkey": "cosmosvalconspub1zcjduepqlsvqw4vacnv2qtwxmm8tq32lrcdhau3szqxevrrzy8u0jvwz69pqphnkzk", + "jailed": false, + "status": 2, + "tokens": "103362106837", + "delegator_shares": "103362106837.000000000000000000", + "description": { + "moniker": "zugerselfdelegation", + "identity": "", + "website": "", + "details": "" + }, + "unbonding_height": "0", + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "1.000000000000000000", + "max_rate": "1.000000000000000000", + "max_change_rate": "1.000000000000000000" + }, + "update_time": "2020-02-21T16:46:55.500729256Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1fqzqejwkk898fcslw4z4eeqjzesynvrdfr5hte", + "consensus_pubkey": "cosmosvalconspub1zcjduepqd4hvh0rwfkhtwrj4ly3ptyxs8pyfaser57wx2tcnzzp0rlref90sxm5kwr", + "jailed": false, + "status": 2, + "tokens": "412391812468", + "delegator_shares": "412391812468.000000000000000000", + "description": { + "moniker": "commercio.network", + "identity": "ADBDB0178E4441BE", + "website": "https://commercio.network", + "details": "The Documents Blockchain" + }, + "unbonding_height": "0", + "unbonding_time": "2019-06-23T11:25:09.272949514Z", + "commission": { + "commission_rates": { + "rate": "0.090000000000000000", + "max_rate": "0.200000000000000000", + "max_change_rate": "0.010000000000000000" + }, + "update_time": "2019-05-25T10:53:14.835657659Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1ff0dw8kawsnxkrgj7p65kvw7jxxakyf8n583gx", + "consensus_pubkey": "cosmosvalconspub1zcjduepqu08f7tuce8k88tgewhwer69kfvk5az3cn5lz3v8phl8gvu9nxu8qhrjxfj", + "jailed": false, + "status": 2, + "tokens": "686014025437", + "delegator_shares": "686082633630.242664780687029960", + "description": { + "moniker": "Compass", + "identity": "72CB5AAAAFB1CE69", + "website": "http://val.network/", + "details": "EasyZone is a decentralized light client, which means users can access account, stake and earn rewords with local key store. For the time being we focus on Tendermint ecosystem, including Cosmos, QOS and Irisnet etc. Winner of the Game of Stakes." + }, + "unbonding_height": "0", + "unbonding_time": "2019-10-14T04:10:07.163539573Z", + "commission": { + "commission_rates": { + "rate": "0.100000000000000000", + "max_rate": "1.000000000000000000", + "max_change_rate": "0.100000000000000000" + }, + "update_time": "2019-03-13T23:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1fhr7e04ct0zslmkzqt9smakg3sxrdve6ulclj2", + "consensus_pubkey": "cosmosvalconspub1zcjduepqzu34dgs2p6ysz52hpdycls4jcfwgnf2pvxv0eh539ypmadkjfmes6mwaa3", + "jailed": false, + "status": 2, + "tokens": "1341410982718", + "delegator_shares": "1341410982718.000000000000000000", + "description": { + "moniker": "Stakin by POS Bakerz", + "identity": "83D300CB42D06962", + "website": "http://stakin.com/", + "details": "Your Trusted Crypto Rewards" + }, + "unbonding_height": "0", + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.000000000000000000", + "max_rate": "0.200000000000000000", + "max_change_rate": "0.010000000000000000" + }, + "update_time": "2020-03-02T09:39:28.188566867Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper12w6tynmjzq4l8zdla3v4x0jt8lt4rcz5gk7zg2", + "consensus_pubkey": "cosmosvalconspub1zcjduepquuc5k7egx8ymejamr27c3sgw6tyhmt0eq0ak4qvflvhxx56nvjzsx9etmd", + "jailed": false, + "status": 2, + "tokens": "3480806611496", + "delegator_shares": "3480806611496.000000000000000000", + "description": { + "moniker": "Huobi Wallet", + "identity": "CF01514DBF6583FE", + "website": "https://www.huobiwallet.com", + "details": "Huobi Wallet is a leading multi-chain wallet from Huobi Group and also offering competitive Proof-of-Stake (PoS) rewards for users to grow their digital assets. As a Cosmos validator, Huobi Wallet offers the one and only hard slashing insurance fund to our delegators" + }, + "unbonding_height": "0", + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.020000000000000000", + "max_rate": "0.200000000000000000", + "max_change_rate": "0.010000000000000000" + }, + "update_time": "2020-01-06T02:06:36.387455308Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper125umsz3fws7gepn5ccsh0sv4gre9r6a3tccz4r", + "consensus_pubkey": "cosmosvalconspub1zcjduepqkzserh5aetg6m33vrfcsuz60qpkgkpkpzkh8gp9lsd7cxffgph4qjzkxft", + "jailed": false, + "status": 2, + "tokens": "10670148807", + "delegator_shares": "10671215847.540238522991345421", + "description": { + "moniker": "Moonstake", + "identity": "742F7B64C32DF7A6", + "website": "https://www.moonstake.io/", + "details": "Shoot For The Moon" + }, + "unbonding_height": "1592315", + "unbonding_time": "2020-05-11T16:50:24.308799306Z", + "commission": { + "commission_rates": { + "rate": "0.030000000000000000", + "max_rate": "1.000000000000000000", + "max_change_rate": "1.000000000000000000" + }, + "update_time": "2020-03-03T10:05:22.79594206Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper124maqmcqv8tquy764ktz7cu0gxnzfw54n3vww8", + "consensus_pubkey": "cosmosvalconspub1zcjduepq279zs0zgd53ujngs6v2hus2le9rk2a2rs66j4yvv6ewvvxn29yqqk95h8x", + "jailed": false, + "status": 2, + "tokens": "606545418213", + "delegator_shares": "606545418213.000000000000000000", + "description": { + "moniker": "Simply Staking", + "identity": "F74595D6D5D568A2", + "website": "https://www.simply-vc.com.mt", + "details": "Simply VC runs highly reliable and secure infrastructure in our own datacentre in Malta, built with the aim of supporting the growth of the blockchain ecosystem." + }, + "unbonding_height": "0", + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.070000000000000000", + "max_rate": "0.300000000000000000", + "max_change_rate": "0.010000000000000000" + }, + "update_time": "2019-05-11T17:29:59.537654017Z" + }, + "min_self_delegation": "1000000" + }, + { + "operator_address": "cosmosvaloper1tflk30mq5vgqjdly92kkhhq3raev2hnz6eete3", + "consensus_pubkey": "cosmosvalconspub1zcjduepqwcvy8hyw2phdp080ggj7prxv972rvqc9gwyjnl0uwf7uxn63s8vqdctdcw", + "jailed": false, + "status": 2, + "tokens": "166014730256", + "delegator_shares": "166014730256.000000000000000000", + "description": { + "moniker": "Everstake", + "identity": "", + "website": "https://everstake.one", + "details": "Reliable and experienced staking service provider from Ukraine. Visit our website for more details." + }, + "unbonding_height": "0", + "unbonding_time": "2019-12-07T19:10:59.878559804Z", + "commission": { + "commission_rates": { + "rate": "0.030000000000000000", + "max_rate": "0.200000000000000000", + "max_change_rate": "0.010000000000000000" + }, + "update_time": "2019-07-14T19:56:46.186760169Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1ttfytaf43nkytzp8hkfjfgjc693ky4t3y2n2ku", + "consensus_pubkey": "cosmosvalconspub1zcjduepq2nfs6lcwu6ksq54yf0ptgrmjjrnm5p5ywng3x0t0767m777hvctq30rwcs", + "jailed": false, + "status": 2, + "tokens": "67995376247", + "delegator_shares": "68002176461.716837847819163406", + "description": { + "moniker": "StarCluster", + "identity": "F97B6EF4FD82202F", + "website": "https://starcluster.tech", + "details": "With decades of passion invested in tech, we provide a team of top security and infrastructure engineers as a service. With extensive knowledge in the blockchain space and having run a successful ICO, we are confident that providing our experience \u0026 skills could benefit many." + }, + "unbonding_height": "0", + "unbonding_time": "2019-12-24T15:27:58.293852371Z", + "commission": { + "commission_rates": { + "rate": "0.150000000000000000", + "max_rate": "0.150000000000000000", + "max_change_rate": "0.010000000000000000" + }, + "update_time": "2019-10-26T21:50:11.42045872Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1te8nxpc2myjfrhaty0dnzdhs5ahdh5agzuym9v", + "consensus_pubkey": "cosmosvalconspub1zcjduepqjg26g27dtvjqstyqktmp4jsn98473vfz0mek2eyklfp0yqapav5szdrvpd", + "jailed": false, + "status": 2, + "tokens": "3368758736271", + "delegator_shares": "3368758736271.000000000000000000", + "description": { + "moniker": "CoinoneNode", + "identity": "F4E86EE9BD73A11F", + "website": "https://node.coinone.co.kr", + "details": "The more, the easier. Coinone Node manages your assets securely." + }, + "unbonding_height": "0", + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.100000000000000000", + "max_rate": "1.000000000000000000", + "max_change_rate": "0.010000000000000000" + }, + "update_time": "2019-03-14T09:22:28.276013718Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1vrg6ruw00lhszl4sjgwt5ldvl8z0f7pfp5va85", + "consensus_pubkey": "cosmosvalconspub1zcjduepq2hfnf0rvk6nksvtzkqly4vy362sencfkt7tgsrvx30krj5vxw0asa7hmjh", + "jailed": false, + "status": 2, + "tokens": "371297506211", + "delegator_shares": "371297506211.000000000000000000", + "description": { + "moniker": "SSSnodes", + "identity": "C5B68615F8828EC0", + "website": "http://sssnodes.com/cosmos", + "details": "Stake and earn rewards with the most secure and stable validator. Winner of the Game of Stakes. Operated by SSSnodes, a Corp. focused on delegation service for multiple Proof of Stake networks, such as COSMOS, ChainX, IOST, CyberMiles, Lambda, ONT, etc." + }, + "unbonding_height": "0", + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.018000000000000000", + "max_rate": "0.200000000000000000", + "max_change_rate": "0.010000000000000000" + }, + "update_time": "2019-11-28T08:09:59.47667909Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1vf44d85es37hwl9f4h9gv0e064m0lla60j9luj", + "consensus_pubkey": "cosmosvalconspub1zcjduepqtj2urav4g9wex3hku588au0x4sucrc9lpky46zp5u8w4mvd584sqmcxxhs", + "jailed": false, + "status": 2, + "tokens": "7276799410408", + "delegator_shares": "7276799410408.000000000000000000", + "description": { + "moniker": "MultiChain Ventures", + "identity": "06E24C7678282B53", + "website": "https://www.multichain-ventures.com", + "details": "Secure stake and earn rewards with MultiCahin ventures" + }, + "unbonding_height": "0", + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.020000000000000000", + "max_rate": "0.500000000000000000", + "max_change_rate": "0.010000000000000000" + }, + "update_time": "2019-08-21T08:01:01.670548948Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1v5y0tg0jllvxf5c3afml8s3awue0ymju89frut", + "consensus_pubkey": "cosmosvalconspub1zcjduepq9kun5ty55rl3lnmf46tfxhj06as8h7zpxcdhujm6d708ffn6kgss43q6u9", + "jailed": false, + "status": 2, + "tokens": "5856297267830", + "delegator_shares": "5856297267830.000000000000000000", + "description": { + "moniker": "Zero Knowledge Validator (ZKV)", + "identity": "3E38E52A12F94561", + "website": "https://zkvalidator.com/", + "details": "Zero Knowledge Validator: Stake \u0026 Support ZKP Research \u0026 Privacy Tech" + }, + "unbonding_height": "0", + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.100000000000000000", + "max_rate": "1.000000000000000000", + "max_change_rate": "0.050000000000000000" + }, + "update_time": "2019-11-11T15:48:18.737920871Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1vk706z2tfnqhdg6jrkngyx7f463jq58nj0x7p7", + "consensus_pubkey": "cosmosvalconspub1zcjduepq0qdudwaluzpy5ptluu5umck5fp2ns2qf2kjp367qlr7yf65agx5s0n8h7f", + "jailed": false, + "status": 2, + "tokens": "29009856874", + "delegator_shares": "29009856874.000000000000000000", + "description": { + "moniker": "Public Payments", + "identity": "1850627141D54797", + "website": "https://www.publicpayments.io", + "details": "" + }, + "unbonding_height": "0", + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.000000000000000000", + "max_rate": "0.200000000000000000", + "max_change_rate": "0.010000000000000000" + }, + "update_time": "2020-01-02T12:25:53.791107872Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1d0aup392g3enru7eash83sedqclaxvp7fzh6gk", + "consensus_pubkey": "cosmosvalconspub1zcjduepql9j7qpwvfl0pspymhesj48t3t0aazjx0m2jwjuyxd7zw53hqnkss4hmasl", + "jailed": false, + "status": 2, + "tokens": "190898805499", + "delegator_shares": "190917897121.968489215822622695", + "description": { + "moniker": "Stir", + "identity": "", + "website": "", + "details": "" + }, + "unbonding_height": "0", + "unbonding_time": "2019-06-21T20:37:09.115641759Z", + "commission": { + "commission_rates": { + "rate": "0.100000000000000000", + "max_rate": "0.200000000000000000", + "max_change_rate": "0.010000000000000000" + }, + "update_time": "2019-03-14T13:03:10.437070061Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1dse76yk5jmj85jsd77ewsczc4k3u4s7a870wtj", + "consensus_pubkey": "cosmosvalconspub1zcjduepqjdc9grwq5mxdtg26hv9t75y3ltsau3rtmg6p72p0dh8343nj4s6qr6xymd", + "jailed": false, + "status": 2, + "tokens": "399992036873", + "delegator_shares": "400032040000.820061751426683457", + "description": { + "moniker": "gf.network", + "identity": "", + "website": "", + "details": "" + }, + "unbonding_height": "10001", + "unbonding_time": "2020-01-02T11:58:18.459331455Z", + "commission": { + "commission_rates": { + "rate": "0.080000000000000000", + "max_rate": "0.500000000000000000", + "max_change_rate": "0.010000000000000000" + }, + "update_time": "2019-05-27T12:23:08.242833465Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1de7qx00pz2j6gn9k88ntxxylelkazfk3g8fgh9", + "consensus_pubkey": "cosmosvalconspub1zcjduepqwr5p8j076mfydn7wckqz748lr0j50zwgsftnfpvgz6rz0rkvvqwqg5fyaf", + "jailed": false, + "status": 2, + "tokens": "365449381771", + "delegator_shares": "365449381771.000000000000000000", + "description": { + "moniker": "Cosmic Validator", + "identity": "FF4B91B50B71CEDA", + "website": "", + "details": "A reliable, passionate and service oriented Cosmos, Polkadot and Sentinel validator. We are long term trusted community members and have received delegation from the Interchain Foundation (ICF) as a reward for our continuous support and effort." + }, + "unbonding_height": "0", + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.000000000000000000", + "max_rate": "1.000000000000000000", + "max_change_rate": "0.100000000000000000" + }, + "update_time": "2019-10-07T05:35:40.25581859Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1d7ufwp2rgfj7s7pfw2q7vm2lc9txmr8vh77ztr", + "consensus_pubkey": "cosmosvalconspub1zcjduepq2x456pyef8jdnjgk8j62fuug24xfg9cnnjl66ewtgttwr00phz8sdzatkj", + "jailed": false, + "status": 2, + "tokens": "117924360855", + "delegator_shares": "117924360855.000000000000000000", + "description": { + "moniker": "Cybernetic Destiny", + "identity": "", + "website": "", + "details": "The future you’ve always wanted." + }, + "unbonding_height": "0", + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.200000000000000000", + "max_rate": "1.000000000000000000", + "max_change_rate": "0.100000000000000000" + }, + "update_time": "2020-02-07T23:19:03.834895518Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1wp9jne5t3e4au7u8gfep90g59j0qdhpeqvlg7n", + "consensus_pubkey": "cosmosvalconspub1zcjduepq6740f8r23xr74w94l5ew9fh6n8wquutgm22pw6yyrydq507mgdkqghsjtd", + "jailed": false, + "status": 2, + "tokens": "89466618968", + "delegator_shares": "89466618968.000000000000000000", + "description": { + "moniker": "Newroad Network", + "identity": "F898ACE263EC1C4E", + "website": "https://newroad.network/cosmos/", + "details": "We provide a professional delegation service for multiple Proof of Stake networks. We use a secure and redundant setup. Visit our website for more information." + }, + "unbonding_height": "0", + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.080000000000000000", + "max_rate": "0.300000000000000000", + "max_change_rate": "0.100000000000000000" + }, + "update_time": "2020-04-26T18:30:05.33496777Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1wtv0kp6ydt03edd8kyr5arr4f3yc52vp3u2x3u", + "consensus_pubkey": "cosmosvalconspub1zcjduepq0zyaquh6c8vmjfzft43uqylf2ejjpjcvup2zrtsk40uyz8xsq29s0k4eaw", + "jailed": false, + "status": 2, + "tokens": "353702000001", + "delegator_shares": "353702000001.000000000000000000", + "description": { + "moniker": "kytzu", + "identity": "909A480D5643CCC5", + "website": "https://www.linkedin.com/in/calinchitu", + "details": "Blockchain consultant, running on IPSX infrastructure (calin@ip.sx)" + }, + "unbonding_height": "0", + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.150000000000000000", + "max_rate": "0.200000000000000000", + "max_change_rate": "0.010000000000000000" + }, + "update_time": "2019-07-13T04:46:58.395203387Z" + }, + "min_self_delegation": "1000000" + }, + { + "operator_address": "cosmosvaloper1wdrypwex63geqswmcy5qynv4w3z3dyef2qmyna", + "consensus_pubkey": "cosmosvalconspub1zcjduepqs0et7kpf82glsw5j9jnppekrpa7kl6gr6xk67ztqg9ynmhgj82ks9edcrw", + "jailed": false, + "status": 2, + "tokens": "457220203123", + "delegator_shares": "457220203123.000000000000000000", + "description": { + "moniker": "Genesis Lab", + "identity": "C1A123F2723041F0", + "website": "https://genesislab.net", + "details": "Genesis Lab is a blockchain-focused development company and validation nodes operator in PoS networks" + }, + "unbonding_height": "0", + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.070000000000000000", + "max_rate": "0.200000000000000000", + "max_change_rate": "0.010000000000000000" + }, + "update_time": "2019-03-15T17:32:00.387570437Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1w0494h0l4mneaq7ajkrcjvn73m2n04l87j2nst", + "consensus_pubkey": "cosmosvalconspub1zcjduepquxeuhp0gj88u5mrukuazzrxc4rnjjuakls4fr2gzxlwj4f9p8lfs965r7z", + "jailed": false, + "status": 2, + "tokens": "96455451062", + "delegator_shares": "96484393351.999596821444782714", + "description": { + "moniker": "Angel", + "identity": "", + "website": "", + "details": "" + }, + "unbonding_height": "804087", + "unbonding_time": "2020-03-07T13:08:49.834368524Z", + "commission": { + "commission_rates": { + "rate": "0.200000000000000000", + "max_rate": "1.000000000000000000", + "max_change_rate": "0.500000000000000000" + }, + "update_time": "2019-03-18T15:40:26.600089741Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1w42lm7zv55jrh5ggpecg0v643qeatfkd9aqf3f", + "consensus_pubkey": "cosmosvalconspub1zcjduepqz679nxu2dkfd6y9hytqwvf2z4yuevraqykkm2464ag4e6z278h3qdq92xu", + "jailed": false, + "status": 2, + "tokens": "758514561374", + "delegator_shares": "758514561374.000000000000000000", + "description": { + "moniker": "Mythos", + "identity": "2E9FDF34351A5112", + "website": "https://mythos.services", + "details": "Staking and validator services for crypto networks" + }, + "unbonding_height": "0", + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.150000000000000000", + "max_rate": "0.200000000000000000", + "max_change_rate": "0.010000000000000000" + }, + "update_time": "2019-03-13T23:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1we6knm8qartmmh2r0qfpsz6pq0s7emv3e0meuw", + "consensus_pubkey": "cosmosvalconspub1zcjduepq6adydsk7nw3d63qtn30t5rexhfg56pq44sw4l9ld0tcj6jvnx30s5xw9ar", + "jailed": false, + "status": 2, + "tokens": "1873921877156", + "delegator_shares": "1873921877156.000000000000000000", + "description": { + "moniker": "Staked", + "identity": "E7BFA6515FB02B3B", + "website": "https://staked.us/", + "details": "Staked operates highly available and highly secure, institutional grade staking infrastructure for leading proof-of-stake (PoS) protocols." + }, + "unbonding_height": "0", + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.100000000000000000", + "max_rate": "0.200000000000000000", + "max_change_rate": "0.020000000000000000" + }, + "update_time": "2019-03-13T23:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1wauge4px27c257nfn4k3329wteddqw7gs3n66u", + "consensus_pubkey": "cosmosvalconspub1zcjduepqqaffdhuhdtr0d6nl8twpraxps74q3mxn68qknrex465yd9cc9l0qeh6lkk", + "jailed": false, + "status": 2, + "tokens": "169436163344", + "delegator_shares": "169436163344.000000000000000000", + "description": { + "moniker": "DappPub", + "identity": "BB2D113EFC6DFDC4", + "website": "https://dapp.pub", + "details": "DappPub, Unleashing the Power of DApps" + }, + "unbonding_height": "0", + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.000000000000000000", + "max_rate": "1.000000000000000000", + "max_change_rate": "0.050000000000000000" + }, + "update_time": "2019-05-15T10:37:35.020580984Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper102ruvpv2srmunfffxavttxnhezln6fnc54at8c", + "consensus_pubkey": "cosmosvalconspub1zcjduepq9weu2v0za8fdcvx0w3ps972k5v7sm6h5as9qaznc437vwpfxu37q0f3lyg", + "jailed": false, + "status": 2, + "tokens": "419077200660", + "delegator_shares": "419077200660.000000000000000000", + "description": { + "moniker": "Ztake.org", + "identity": "09A303A2C724C591", + "website": "https://ztake.org/", + "details": "Support reliable independent validator" + }, + "unbonding_height": "0", + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.070000000000000000", + "max_rate": "0.250000000000000000", + "max_change_rate": "0.100000000000000000" + }, + "update_time": "2019-08-14T05:12:52.848294105Z" + }, + "min_self_delegation": "10" + }, + { + "operator_address": "cosmosvaloper10wz6lfhmqfw6egg0062ytnawaj6vr89ly5g4yg", + "consensus_pubkey": "cosmosvalconspub1zcjduepqtm62lxg8hm4tcnqvgk69xs6egltfsq9w6ed3cmq73jjgd3avslvq9d0sy9", + "jailed": false, + "status": 2, + "tokens": "95001650000", + "delegator_shares": "95001650000.000000000000000000", + "description": { + "moniker": "BitMax Staking", + "identity": "", + "website": "https://bitmax.io/", + "details": "Trading Platform Industry Leader driven by Product Innovation" + }, + "unbonding_height": "0", + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.100000000000000000", + "max_rate": "0.200000000000000000", + "max_change_rate": "0.010000000000000000" + }, + "update_time": "2020-01-19T12:21:32.956535488Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1000ya26q2cmh399q4c5aaacd9lmmdqp90kw2jn", + "consensus_pubkey": "cosmosvalconspub1zcjduepqe93asg05nlnj30ej2pe3r8rkeryyuflhtfw3clqjphxn4j3u27msrr63nk", + "jailed": false, + "status": 2, + "tokens": "457347172083", + "delegator_shares": "457347172083.000000000000000000", + "description": { + "moniker": "Staking Fund", + "identity": "805F39B20E881861", + "website": "https://www.staking.fund", + "details": "Staking Fund has been participating in the validating role since early 2018 and is a proud member of the Never Jailed Crew of Game of Stakes." + }, + "unbonding_height": "0", + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.120000000000000000", + "max_rate": "0.334000000000000000", + "max_change_rate": "0.012019031323000000" + }, + "update_time": "2020-02-02T00:47:46.138000758Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper10nzaaeh2kq28t3nqsh5m8kmyv90vx7ym5mpakx", + "consensus_pubkey": "cosmosvalconspub1zcjduepqmuspsp8739l0lgn2qz0arargk6ccfy2p82mwflsrsqzwpvhuh5usuwykf6", + "jailed": false, + "status": 2, + "tokens": "73145988986", + "delegator_shares": "73145988986.000000000000000000", + "description": { + "moniker": "Blockdaemon", + "identity": "8F898657DE26D645", + "website": "https://blockdaemon.com/node-marketplace/#staking", + "details": "Blockdaemon provides maximum uptime for the Cosmos network so that you can be confident your node will be there, ready and secure, for optimal reward generation. Contact us to stake on Cosmos today." + }, + "unbonding_height": "0", + "unbonding_time": "2019-12-19T03:19:44.114438899Z", + "commission": { + "commission_rates": { + "rate": "0.100000000000000000", + "max_rate": "0.200000000000000000", + "max_change_rate": "0.010000000000000000" + }, + "update_time": "2019-10-29T19:55:36.41178089Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper10e4vsut6suau8tk9m6dnrm0slgd6npe3jx5xpv", + "consensus_pubkey": "cosmosvalconspub1zcjduepqteacnywz7urnac46wtrcy34myyj82j250ny7866yffypdgavae5s0lf4a0", + "jailed": false, + "status": 2, + "tokens": "3679445632111", + "delegator_shares": "3679445632111.000000000000000000", + "description": { + "moniker": "B-Harvest", + "identity": "8957C5091FBF4192", + "website": "https://bharvest.io", + "details": "B-Harvest focus on the value of high standard security \u0026 stability, active community participation on Cosmos Network, and real world practical use-case of blockchain technology." + }, + "unbonding_height": "0", + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.100000000000000000", + "max_rate": "0.300000000000000000", + "max_change_rate": "0.010000000000000000" + }, + "update_time": "2019-03-24T11:21:51.694254562Z" + }, + "min_self_delegation": "9000000000" + }, + { + "operator_address": "cosmosvaloper1sxx9mszve0gaedz5ld7qdkjkfv8z992ax69k08", + "consensus_pubkey": "cosmosvalconspub1zcjduepqjnnwe2jsywv0kfc97pz04zkm7tc9k2437cde2my3y5js9t7cw9mstfg3sa", + "jailed": false, + "status": 2, + "tokens": "2268794946053", + "delegator_shares": "2268794946053.000000000000000000", + "description": { + "moniker": "validator.network | Security first. Highly available.", + "identity": "357F80896B3311B4", + "website": "https://validator.network", + "details": "Highly resilient and secure validator operating out of Northern Europe. See website for terms of service." + }, + "unbonding_height": "0", + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.100000000000000000", + "max_rate": "1.000000000000000000", + "max_change_rate": "0.010000000000000000" + }, + "update_time": "2019-06-30T08:32:22.562118158Z" + }, + "min_self_delegation": "100000000" + }, + { + "operator_address": "cosmosvaloper1sd4tl9aljmmezzudugs7zlaya7pg2895ws8tfs", + "consensus_pubkey": "cosmosvalconspub1zcjduepq8y846wm58fmmuctxp7csqmaz3594xnykcean0lp722ntf6u5ycaqss4prd", + "jailed": false, + "status": 2, + "tokens": "1246459015415", + "delegator_shares": "1246459015415.000000000000000000", + "description": { + "moniker": "InfStones (Infinity Stones)", + "identity": "39A41C2FDE0AD040", + "website": "https://infstones.io", + "details": "Fueling Blockchain Beyond Infinity!" + }, + "unbonding_height": "0", + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.100000000000000000", + "max_rate": "1.000000000000000000", + "max_change_rate": "1.000000000000000000" + }, + "update_time": "2019-05-10T06:56:55.530159974Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1s05va5d09xlq3et8mapsesqh6r5lqy7mkhwshm", + "consensus_pubkey": "cosmosvalconspub1zcjduepqgx5xdrx0xktl5r8e3w7vj329fgh3fnep8ahgx8027nd5nkjxzuqs5us5en", + "jailed": false, + "status": 2, + "tokens": "556817046823", + "delegator_shares": "556817046823.000000000000000000", + "description": { + "moniker": "Wetez", + "identity": "26FA2B24F46A98EF", + "website": "https://www.wetez.io", + "details": "Wetez is the most professional team in the POS ( Proof of Stake) field.Wetez是POS领域最专业的团队,为POS带来的权益做更多赋能。" + }, + "unbonding_height": "0", + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.100000000000000000", + "max_rate": "1.000000000000000000", + "max_change_rate": "0.100000000000000000" + }, + "update_time": "2019-03-25T02:35:12.908955321Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1ssm0d433seakyak8kcf93yefhknjleeds4y3em", + "consensus_pubkey": "cosmosvalconspub1zcjduepqrgyyjxpe0ujefxwnkpmqz9m0hj03y09tdz9lwc0s7mvy469hulfq69f8sd", + "jailed": false, + "status": 2, + "tokens": "1516027838065", + "delegator_shares": "1516027838065.000000000000000000", + "description": { + "moniker": "IRISnet-Bianjie", + "identity": "DB667A6F239969F5", + "website": "https://irisnet.org/irisnet-bianjie", + "details": "Interchain Service Hub for NextGen Distributed Applications." + }, + "unbonding_height": "0", + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.100000000000000000", + "max_rate": "1.000000000000000000", + "max_change_rate": "0.020000000000000000" + }, + "update_time": "2019-06-21T04:33:57.044358454Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1sjllsnramtg3ewxqwwrwjxfgc4n4ef9u2lcnj0", + "consensus_pubkey": "cosmosvalconspub1zcjduepq6fpkt3qn9xd7u44478ypkhrvtx45uhfj3uhdny420hzgsssrvh3qnzwdpe", + "jailed": false, + "status": 2, + "tokens": "12683713751295", + "delegator_shares": "12683713751295.000000000000000000", + "description": { + "moniker": "🐠stake.fish", + "identity": "90B597A673FC950E", + "website": "stake.fish", + "details": "We are the leading staking service provider for blockchain projects. Join our community to help secure networks and earn rewards. We know staking." + }, + "unbonding_height": "0", + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.040000000000000000", + "max_rate": "1.000000000000000000", + "max_change_rate": "0.010000000000000000" + }, + "update_time": "2019-03-13T23:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1s6x9fy4wc49wj9jx4jv6czredqsmp46h7vnk2q", + "consensus_pubkey": "cosmosvalconspub1zcjduepqfkkyuexns2l7rw2mx2ms988heah0rjv42e9q88scc3ms5hzg45psycrvr4", + "jailed": false, + "status": 2, + "tokens": "727981844212", + "delegator_shares": "727981844212.000000000000000000", + "description": { + "moniker": "SNZPool", + "identity": "FF2019D4CF1F3185", + "website": "https://snzholding.com", + "details": "SNZ is a crypto assets capital, consulting agency, community builder and professional \u0026 reliable POS validator for a dozen of projects like Cosmos, IRISnet, EOS, ONT, Loom, etc." + }, + "unbonding_height": "0", + "unbonding_time": "2019-05-31T14:02:51.669843605Z", + "commission": { + "commission_rates": { + "rate": "0.100000000000000000", + "max_rate": "0.200000000000000000", + "max_change_rate": "0.010000000000000000" + }, + "update_time": "2019-03-13T23:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1s6t3wzx6mcv3pjg5fp2ddzplm3gj4pg6d330wg", + "consensus_pubkey": "cosmosvalconspub1zcjduepqncdd6lvm4r42eke822e5eg0alentpvlxjwzat7nvpynlp0vcu55sl5z96g", + "jailed": false, + "status": 2, + "tokens": "245002260000", + "delegator_shares": "245002260000.000000000000000000", + "description": { + "moniker": "omega3", + "identity": "", + "website": "", + "details": "" + }, + "unbonding_height": "0", + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.200000000000000000", + "max_rate": "1.000000000000000000", + "max_change_rate": "1.000000000000000000" + }, + "update_time": "2019-03-22T01:22:56.42711479Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1s65zmn32zugl57ysj47s7vmfcek0rtd7he7wde", + "consensus_pubkey": "cosmosvalconspub1zcjduepqrc6g9m2eyy4zs7kyeph8vk5ldpgnceveelc39zf7lc32j8k3shqssevdlg", + "jailed": false, + "status": 2, + "tokens": "194202250000", + "delegator_shares": "194202250000.000000000000000000", + "description": { + "moniker": "firstblock", + "identity": "23D9B8528FC93D58", + "website": "https://firstblock.io", + "details": "You Delegate. We Validate." + }, + "unbonding_height": "0", + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.200000000000000000", + "max_rate": "0.200000000000000000", + "max_change_rate": "0.010000000000000000" + }, + "update_time": "2020-01-09T03:45:47.112144406Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1s7jnk7t6yqzensdgpvkvkag022udk842qdjdtd", + "consensus_pubkey": "cosmosvalconspub1zcjduepqnnh28nlj55sc329ppnhcr0xx7kuc9vnsp3dpwc28wdhhxtjc7jfs9k57f7", + "jailed": false, + "status": 2, + "tokens": "337881031694", + "delegator_shares": "337881031694.000000000000000000", + "description": { + "moniker": "Blockscale", + "identity": "F38EDEA063FD446C", + "website": "https://blockscale.net", + "details": "Planet-scale blockchain infrastructure." + }, + "unbonding_height": "0", + "unbonding_time": "2019-06-14T07:33:07.032714186Z", + "commission": { + "commission_rates": { + "rate": "0.250000000000000000", + "max_rate": "1.000000000000000000", + "max_change_rate": "0.010000000000000000" + }, + "update_time": "2019-09-21T01:23:56.63727699Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper132juzk0gdmwuxvx4phug7m3ymyatxlh9734g4w", + "consensus_pubkey": "cosmosvalconspub1zcjduepq9xu9z6ky3nz3k544ar4zhupjehkxdlpmt2l90kekxkrvuu7hxfgslcdqwy", + "jailed": false, + "status": 2, + "tokens": "2917176802437", + "delegator_shares": "2917176802437.000000000000000000", + "description": { + "moniker": "P2P.ORG - P2P Validator", + "identity": "E12F4695036D8072", + "website": "https://p2p.org", + "details": "One of the winners of Cosmos Game of Stakes. We provide a simple, secure and intelligent staking service to help you generate rewards on your blockchain assets across 9+ networks within a single interface. Let’s stake together - p2p.org." + }, + "unbonding_height": "0", + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.010000000000000000", + "max_rate": "0.500000000000000000", + "max_change_rate": "0.010000000000000000" + }, + "update_time": "2019-12-11T17:13:40.302520375Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper130mdu9a0etmeuw52qfxk73pn0ga6gawkxsrlwf", + "consensus_pubkey": "cosmosvalconspub1zcjduepqfahazsjeru5wqulfuzklmkh272ggss2ru6fk00zq2fmlfzcq773sqlqe42", + "jailed": false, + "status": 2, + "tokens": "1128473573419", + "delegator_shares": "1128473573419.000000000000000000", + "description": { + "moniker": "jackzampolin", + "identity": "0979483D4F669CFF", + "website": "https://pylonvalidator.com", + "details": "'You must construct additional pylons' -StarCraft" + }, + "unbonding_height": "0", + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.100000000000000000", + "max_rate": "0.150000000000000000", + "max_change_rate": "0.100000000000000000" + }, + "update_time": "2019-03-25T15:28:01.171914203Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper13sduv92y3xdhy3rpmhakrc3v7t37e7ps9l0kpv", + "consensus_pubkey": "cosmosvalconspub1zcjduepqqddwwkhkfrsd66u49kg3h6q36t4kv557vlszqaed4c3y936ncq9s0r0tm2", + "jailed": false, + "status": 2, + "tokens": "1574051576303", + "delegator_shares": "1574051576303.000000000000000000", + "description": { + "moniker": "nylira.net", + "identity": "6A0D65E29A4CBC8E", + "website": "https://nylira.net", + "details": "Stake and earn with security and peace of mind. Operated by Peng Zhong." + }, + "unbonding_height": "0", + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.100000000000000000", + "max_rate": "0.300000000000000000", + "max_change_rate": "0.010000000000000000" + }, + "update_time": "2019-05-14T21:33:23.86382871Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper13ce7hhqa0z3tpc2l7jm0lcvwe073hdkkpp2nst", + "consensus_pubkey": "cosmosvalconspub1zcjduepqmx0dcpmd9uq7ueck8d880lrt8tp9kvkfmaz0mtv0arye2cda2zrsrlla3n", + "jailed": false, + "status": 2, + "tokens": "10101347732", + "delegator_shares": "10101347732.000000000000000000", + "description": { + "moniker": "RockX", + "identity": "A15B586AB203F14E", + "website": "www.rockx.com", + "details": "Unlocking the full value of digital assets and decentralized governance" + }, + "unbonding_height": "1813403", + "unbonding_time": "2020-05-29T19:33:46.045420571Z", + "commission": { + "commission_rates": { + "rate": "0.100000000000000000", + "max_rate": "0.200000000000000000", + "max_change_rate": "0.010000000000000000" + }, + "update_time": "2019-09-05T08:00:55.144718017Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1jxv0u20scum4trha72c7ltfgfqef6nsch7q6cu", + "consensus_pubkey": "cosmosvalconspub1zcjduepqnru7aa6ayyuwddd5qsa6tvutzs7xl9jk6pfx4ka5dr4y9d3q6eesgz9rz7", + "jailed": false, + "status": 2, + "tokens": "302793155457", + "delegator_shares": "302793155457.000000000000000000", + "description": { + "moniker": "Ping.pub", + "identity": "6EA723DA332200B2", + "website": "https://ping.pub", + "details": "We are one of the most secure and stable validator, welcome to delegate to us. 我们是最安全,最稳定,性价比最高的验证人节点,欢迎委托给我们!" + }, + "unbonding_height": "0", + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.020000000000000000", + "max_rate": "1.000000000000000000", + "max_change_rate": "0.200000000000000000" + }, + "update_time": "2019-11-18T12:14:35.328556Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1j0vaeh27t4rll7zhmarwcuq8xtrmvqhudrgcky", + "consensus_pubkey": "cosmosvalconspub1zcjduepqvn4a4skwj88c8e0jvns3qjrhyy0whvnuwmth3k8kexvqk5vupw4qsdje47", + "jailed": false, + "status": 2, + "tokens": "1081673849444", + "delegator_shares": "1081673849444.000000000000000000", + "description": { + "moniker": "chainflow-cosmos-prodval-01", + "identity": "81D443FA08A4A926", + "website": "https://chainflow.io/cosmos", + "details": "Operated by Chris Remus (Twitter @cjremus) / Validating since the Validator Working Group formed in October 2017" + }, + "unbonding_height": "0", + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.120000000000000000", + "max_rate": "1.000000000000000000", + "max_change_rate": "0.010000000000000000" + }, + "update_time": "2019-04-01T15:19:20.666364183Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1jlr62guqwrwkdt4m3y00zh2rrsamhjf9num5xr", + "consensus_pubkey": "cosmosvalconspub1zcjduepq5e8w7t7k9pwfewgrwy8vn6cghk0x49chx64vt0054yl4wwsmjgrqfackxm", + "jailed": false, + "status": 2, + "tokens": "691322889269", + "delegator_shares": "691322889269.000000000000000000", + "description": { + "moniker": "StakeWith.Us", + "identity": "609F83752053AD57", + "website": "https://stakewith.us", + "details": "Secured Staking Made Easy. Put Your Crypto to Work - Hassle Free. Disclaimer: Delegators should understand that delegation comes with slashing risk. By delegating to StakeWithUs Pte Ltd, you acknowledge that StakeWithUs Pte Ltd is not liable for any losses on your investment." + }, + "unbonding_height": "0", + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.150000000000000000", + "max_rate": "0.250000000000000000", + "max_change_rate": "0.050000000000000000" + }, + "update_time": "2019-04-22T12:01:25.715205208Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1n3f5lm7xtlrp05z9ud2xk2cnvk2xnzkm2he6er", + "consensus_pubkey": "cosmosvalconspub1zcjduepqghz45rfwczrvwl7u2xsm8dpamqg8gtzej66dtn57ax99g59klpfsm3yxyu", + "jailed": false, + "status": 2, + "tokens": "16071388577", + "delegator_shares": "16072995876.587658765876587650", + "description": { + "moniker": "AirGap 🛡", + "identity": "", + "website": "", + "details": "" + }, + "unbonding_height": "882174", + "unbonding_time": "2020-03-14T00:03:41.116898617Z", + "commission": { + "commission_rates": { + "rate": "0.100000000000000000", + "max_rate": "0.300000000000000000", + "max_change_rate": "0.050000000000000000" + }, + "update_time": "2020-02-13T08:38:50.239783489Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1n5pu2rtz4e2skaeatcmlexza7kheedzh8a2680", + "consensus_pubkey": "cosmosvalconspub1zcjduepqnd9kzfhhvuv5k2cq62yu0e5v73ymsgxa0wlen9c7999ucwg7hg6qdm34pm", + "jailed": false, + "status": 2, + "tokens": "576087977754", + "delegator_shares": "576087977754.000000000000000000", + "description": { + "moniker": "BlockMatrix 🚀", + "identity": "DA33F58EC17769B4", + "website": "https://blockmatrix.network", + "details": "Experienced validator across multiple PoS and DPoS networks. Winners in the Game of Stakes. Cosmos FTW!" + }, + "unbonding_height": "0", + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.150000000000000000", + "max_rate": "0.250000000000000000", + "max_change_rate": "0.010000000000000000" + }, + "update_time": "2019-03-13T23:00:00Z" + }, + "min_self_delegation": "10" + }, + { + "operator_address": "cosmosvaloper1nm0rrq86ucezaf8uj35pq9fpwr5r82clzyvtd8", + "consensus_pubkey": "cosmosvalconspub1zcjduepqsnngsdda53d9aqwezvpsx4uh2nkwkn4nra5lw4tyl9n3m02q4kvsrqq0pw", + "jailed": false, + "status": 2, + "tokens": "145001000000", + "delegator_shares": "145001000000.000000000000000000", + "description": { + "moniker": "Cthulhu", + "identity": "Cthulhu", + "website": "Cthul.hu", + "details": "Cthulhu" + }, + "unbonding_height": "644758", + "unbonding_time": "2020-02-23T10:33:51.593569686Z", + "commission": { + "commission_rates": { + "rate": "1.000000000000000000", + "max_rate": "1.000000000000000000", + "max_change_rate": "1.000000000000000000" + }, + "update_time": "2020-01-22T08:27:20.214359212Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper15r4tc0m6hc7z8drq3dzlrtcs6rq2q9l2nvwher", + "consensus_pubkey": "cosmosvalconspub1zcjduepqjcp9ez3dzmvsdfcw2h5kllmqvjgqnhtlvhad4q9wzcqf34gf6ewq6zl5mm", + "jailed": false, + "status": 2, + "tokens": "731466206153", + "delegator_shares": "731466206153.000000000000000000", + "description": { + "moniker": "DragonStake", + "identity": "EA61A46F31742B22", + "website": "https://dragonstake.io", + "details": "Forking the Banks" + }, + "unbonding_height": "0", + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.200000000000000000", + "max_rate": "1.000000000000000000", + "max_change_rate": "0.010000000000000000" + }, + "update_time": "2020-03-24T18:52:31.67294751Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper159eexl76jlygrxnfreehl3j9tt70d8wfnn39fw", + "consensus_pubkey": "cosmosvalconspub1zcjduepq0jhujmf2ur4uk7al8pht6rpxwf7a24gqmhggeche0w09fglj9tmss4a0ql", + "jailed": false, + "status": 2, + "tokens": "12181850000", + "delegator_shares": "12181850000.000000000000000000", + "description": { + "moniker": "fishegg.net", + "identity": "", + "website": "http://www.fishegg.net", + "details": "welcome to join staking" + }, + "unbonding_height": "7949", + "unbonding_time": "2020-01-02T07:58:37.125916904Z", + "commission": { + "commission_rates": { + "rate": "0.000000000000000000", + "max_rate": "0.200000000000000000", + "max_change_rate": "0.010000000000000000" + }, + "update_time": "2019-12-13T14:17:35.977287639Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper156gqf9837u7d4c4678yt3rl4ls9c5vuursrrzf", + "consensus_pubkey": "cosmosvalconspub1zcjduepqtw8862dhw8uty58d6t2szfd6kqram2t234zjteaaeem6l45wclaq8l60gn", + "jailed": false, + "status": 2, + "tokens": "9838730453054", + "delegator_shares": "9838730453054.000000000000000000", + "description": { + "moniker": "Binance Staking", + "identity": "", + "website": "https://binance.com", + "details": "Exchange the world" + }, + "unbonding_height": "0", + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.025000000000000000", + "max_rate": "1.000000000000000000", + "max_change_rate": "0.010000000000000000" + }, + "update_time": "2020-03-06T07:47:39.033746293Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper15urq2dtp9qce4fyc85m6upwm9xul3049e02707", + "consensus_pubkey": "cosmosvalconspub1zcjduepqjc07nu2ya8tyzl8m385rnc382pkulwt2gh8yary73f3a96jak7pqsf63xf", + "jailed": false, + "status": 2, + "tokens": "4747063386985", + "delegator_shares": "4747063386985.000000000000000000", + "description": { + "moniker": "Chorus One", + "identity": "00B79D689B7DC1CE", + "website": "https://chorus.one/", + "details": "Secure Cosmos and shape its future by delegating to Chorus One, a highly secure and stable validator. By delegating, you agree to the terms of service at: https://chorus.one/cosmos/tos" + }, + "unbonding_height": "0", + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.075000000000000000", + "max_rate": "0.250000000000000000", + "max_change_rate": "0.020000000000000000" + }, + "update_time": "2019-08-13T17:43:26.871706216Z" + }, + "min_self_delegation": "10" + }, + { + "operator_address": "cosmosvaloper1402ggxz5u6vm29sqztwqq8vxs3ke6dmwl2z5dk", + "consensus_pubkey": "cosmosvalconspub1zcjduepqd4qh9dqgyce948kn48r2aqk7qlgtuwdmfeewj0z9aj4dr30v33cq6pmlql", + "jailed": false, + "status": 2, + "tokens": "10136799592", + "delegator_shares": "10137813287.465132892679104584", + "description": { + "moniker": "Cosmoon", + "identity": "8935A6F323FA0881", + "website": "https://cosmoon.org/", + "details": " Professional Stake Rewards Service " + }, + "unbonding_height": "1795893", + "unbonding_time": "2020-05-28T09:10:59.90142555Z", + "commission": { + "commission_rates": { + "rate": "0.000000000000000000", + "max_rate": "0.300000000000000000", + "max_change_rate": "0.050000000000000000" + }, + "update_time": "2020-01-27T22:18:16.158833459Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper14kn0kk33szpwus9nh8n87fjel8djx0y070ymmj", + "consensus_pubkey": "cosmosvalconspub1zcjduepqmfxl36td7rcdzszzrk6c7kzp5l3jlw4lnxz8zms3py7qcsa9xlns7zxfd6", + "jailed": false, + "status": 2, + "tokens": "2268966311115", + "delegator_shares": "2268966311115.000000000000000000", + "description": { + "moniker": "Forbole", + "identity": "2861F5EE06627224", + "website": "https://www.forbole.com/cosmos-hub-validator/", + "details": "As a prominent validator and contributor in Cosmos since 2017, Forbole is devoted to build a stronger Cosmos ecosystem. We are award winners in Game of Stakes and HackAtom. Please join our [community](https://t.me/forbole) or visit [our website](https://www.forbole.com/)." + }, + "unbonding_height": "0", + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.095000000000000000", + "max_rate": "0.250000000000000000", + "max_change_rate": "0.010000000000000000" + }, + "update_time": "2019-11-10T16:52:29.417872059Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper14k4pzckkre6uxxyd2lnhnpp8sngys9m6hl6ml7", + "consensus_pubkey": "cosmosvalconspub1zcjduepquhlqdhjw4qp2c2t6qh5z7tfk52qc72623f0etc8f3n7hy8uuh25ql34fvu", + "jailed": false, + "status": 2, + "tokens": "9676167562461", + "delegator_shares": "9676167562461.000000000000000000", + "description": { + "moniker": "Polychain Labs", + "identity": "A51CE3B9CD649C3F", + "website": "https://cosmos.polychainlabs.com", + "details": "Secure staking with Polychain Labs, the most experienced institutional grade staking team." + }, + "unbonding_height": "0", + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.200000000000000000", + "max_rate": "1.000000000000000000", + "max_change_rate": "0.010000000000000000" + }, + "update_time": "2019-04-22T04:57:29.717811274Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper146kwpzhmleafmhtaxulfptyhnvwxzlvm87hwnm", + "consensus_pubkey": "cosmosvalconspub1zcjduepqfc7vnpgls3an0w2pv60pu4vr30p2dxqlmhmlrdv0m38y3tg689vs5qg4u5", + "jailed": false, + "status": 2, + "tokens": "85907400798", + "delegator_shares": "85907400798.000000000000000000", + "description": { + "moniker": "🌐 KysenPool.io", + "identity": "2474A8FCC4426BC5", + "website": "https://www.kysenpool.io", + "details": "Based in Silicon Valley. Help secure Cosmos by delegating to Kysen. Validators are backed by HSMs in Tier 3 enterprise-grade data centers." + }, + "unbonding_height": "0", + "unbonding_time": "2019-09-06T03:47:00.801583378Z", + "commission": { + "commission_rates": { + "rate": "0.079000000000000000", + "max_rate": "0.200000000000000000", + "max_change_rate": "0.010000000000000000" + }, + "update_time": "2020-03-23T06:10:09.194879379Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper14az9dmutwtz4vuycvae8csm4wwwtm0aumtlppe", + "consensus_pubkey": "cosmosvalconspub1zcjduepq59t2nm3ph5k6uc804w0n7ey69ul8ntee2dy47d7u53q248ud822sunv93j", + "jailed": false, + "status": 2, + "tokens": "1662093108440", + "delegator_shares": "1662259334359.167802676016861987", + "description": { + "moniker": "F4RM", + "identity": "181FAE6C0E4FA498", + "website": "http://www.f4rm.io", + "details": "F4RM - secure network validation \u0026 pooled digital asset staking" + }, + "unbonding_height": "546055", + "unbonding_time": "2020-02-15T08:28:57.815140271Z", + "commission": { + "commission_rates": { + "rate": "0.200000000000000000", + "max_rate": "1.000000000000000000", + "max_change_rate": "0.010000000000000000" + }, + "update_time": "2019-03-15T10:36:44.571237954Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper14l0fp639yudfl46zauvv8rkzjgd4u0zk2aseys", + "consensus_pubkey": "cosmosvalconspub1zcjduepq7jsrkl9fgqk0wj3ahmfr8pgxj6vakj2wzn656s8pehh0zhv2w5as5gd80a", + "jailed": false, + "status": 2, + "tokens": "2123604959964", + "delegator_shares": "2123604959964.000000000000000000", + "description": { + "moniker": "ATEAM", + "identity": "0CB9A4E7643FF992", + "website": "nodeateam.com", + "details": "[GOS Never Jailed crew \u0026 Top-Tier] Node A-Team promises to provide validator node operation services at the highest quality" + }, + "unbonding_height": "0", + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.099000000000000000", + "max_rate": "1.000000000000000000", + "max_change_rate": "1.000000000000000000" + }, + "update_time": "2019-03-15T00:18:37.289241198Z" + }, + "min_self_delegation": "5000" + }, + { + "operator_address": "cosmosvaloper14lultfckehtszvzw4ehu0apvsr77afvyju5zzy", + "consensus_pubkey": "cosmosvalconspub1zcjduepqp0j4vum7ryt6nl6zsgq9ar347afmq2c5z6jmzeavv2p2ns6m0dgs5zmg4z", + "jailed": false, + "status": 2, + "tokens": "11307847355414", + "delegator_shares": "11307847355414.000000000000000000", + "description": { + "moniker": "DokiaCapital", + "identity": "25422F4ADF3F6765", + "website": "https://staking.dokia.cloud", + "details": "Downtime is not an option for Dokia Capital. We operate an enterprise-grade infrastructure that is robust and secure." + }, + "unbonding_height": "0", + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.150000000000000000", + "max_rate": "0.150000000000000000", + "max_change_rate": "0.010000000000000000" + }, + "update_time": "2019-03-13T23:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1k9a0cs97vul8w2vwknlfmpez6prv8klv03lv3d", + "consensus_pubkey": "cosmosvalconspub1zcjduepqfgpyq4xk4s96ksmkfrr7juea9kmdxkl5ht94xgpxe240743u9cvsht489p", + "jailed": false, + "status": 2, + "tokens": "900489276086", + "delegator_shares": "900489276086.000000000000000000", + "description": { + "moniker": "Stake Capital", + "identity": "1DD9A932591FA928", + "website": "https://stake.capital", + "details": "\"Trustless Digital Asset Management\", Twitter: @StakeCapital, operated by @bneiluj @leopoldjoy" + }, + "unbonding_height": "0", + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.080000000000000000", + "max_rate": "0.300000000000000000", + "max_change_rate": "0.030000000000000000" + }, + "update_time": "2019-03-13T23:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1kgquh04ffqvadekf6e47070gskm0s0h28cl7ht", + "consensus_pubkey": "cosmosvalconspub1zcjduepqz76h035hfdt8tka2k4ra3cwkqn8rs6qqmjytgrnzte70qemvnzhsy7gfdu", + "jailed": false, + "status": 2, + "tokens": "25536940606", + "delegator_shares": "25536940606.000000000000000000", + "description": { + "moniker": "tokenweb.io", + "identity": "AD74AC2CC498CD7A", + "website": "https://tokenweb.io", + "details": "put your tokens to work" + }, + "unbonding_height": "0", + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.100000000000000000", + "max_rate": "0.200000000000000000", + "max_change_rate": "0.010000000000000000" + }, + "update_time": "2020-04-23T10:08:28.783704301Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1kgddca7qj96z0qcxr2c45z73cfl0c75p7f3s2e", + "consensus_pubkey": "cosmosvalconspub1zcjduepqay5ldqdmyzy9qfr93enxmm7cwsd5aafz6huqvczytqahpw4twa8qvtrwhv", + "jailed": false, + "status": 2, + "tokens": "568604464471", + "delegator_shares": "568604464471.000000000000000000", + "description": { + "moniker": "ChainLayer", + "identity": "AD3CDBC91802F94A", + "website": "https://www.chainlayer.io", + "details": "Secure and reliable validator. TG: https://t.me/chainlayer" + }, + "unbonding_height": "0", + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.100000000000000000", + "max_rate": "0.200000000000000000", + "max_change_rate": "0.010000000000000000" + }, + "update_time": "2019-04-01T18:02:13.514368678Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1ktecz4dr56j9tsfh7nwg8s9suvhfu70qykhu5s", + "consensus_pubkey": "cosmosvalconspub1zcjduepq4euv7ertqhgvxrla583fg9g6z2v2dzrkl9spche4j4r23vukmx2q8gqvev", + "jailed": false, + "status": 2, + "tokens": "10244999999", + "delegator_shares": "10244999999.000000000000000000", + "description": { + "moniker": "Dawns.World", + "identity": "AA70E5B206F952A3", + "website": "https://dawns.world", + "details": "To discover token's intrinsic real value and enhance its liquidity" + }, + "unbonding_height": "1690790", + "unbonding_time": "2020-05-19T18:55:51.96148342Z", + "commission": { + "commission_rates": { + "rate": "0.200000000000000000", + "max_rate": "0.300000000000000000", + "max_change_rate": "0.010000000000000000" + }, + "update_time": "2019-12-17T15:57:42.95929171Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1kj0h4kn4z5xvedu2nd9c4a9a559wvpuvu0h6qn", + "consensus_pubkey": "cosmosvalconspub1zcjduepqvc5xdrpvduse3fc084s56n4a6dhzudyzjmywjx25fkgw2fhsj70searwgy", + "jailed": false, + "status": 2, + "tokens": "1556931328488", + "delegator_shares": "1556931328488.000000000000000000", + "description": { + "moniker": "Cryptium Labs", + "identity": "5A309B5CA189D8B3", + "website": "https://cryptium.ch", + "details": "Secure and available validation from the Swiss Alps" + }, + "unbonding_height": "0", + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.110000000000000000", + "max_rate": "1.000000000000000000", + "max_change_rate": "0.010000000000000000" + }, + "update_time": "2019-03-27T11:16:35.284063151Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1kn3wugetjuy4zetlq6wadchfhvu3x740ae6z6x", + "consensus_pubkey": "cosmosvalconspub1zcjduepqc8slfqdszcd85wzzweuanv0em4h4gdc5wkh3et6e7t8z93z24u0s0rdlx2", + "jailed": false, + "status": 2, + "tokens": "2142209666422", + "delegator_shares": "2142209666422.000000000000000000", + "description": { + "moniker": "HuobiPool", + "identity": "23536C5BDE3EB949", + "website": "https://www.huobipool.com/", + "details": "Huobi Pool is a sub-brand of Huobi Group, which is an important part of the global ecological strategy of Huobi.Huobi Pool has become one of the largest POS communities in the Asia- Pacific region, the leading POW pool and nodes of a number of public chains." + }, + "unbonding_height": "0", + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.040000000000000000", + "max_rate": "0.200000000000000000", + "max_change_rate": "0.010000000000000000" + }, + "update_time": "2020-04-14T01:41:12.728555379Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1hvsdf03tl6w5pnfvfv5g8uphjd4wfw2h4gvnl7", + "consensus_pubkey": "cosmosvalconspub1zcjduepq5l63vgd8m9chc3c32wn5lthzsax6xxdylpzmhqmjwrgfhd3m2swsj2wc2d", + "jailed": false, + "status": 2, + "tokens": "100005083421", + "delegator_shares": "100015084598.752158521030469918", + "description": { + "moniker": "Atom.Bi23", + "identity": "EB3470949B3E89E2", + "website": "https://atom.bi23.com", + "details": "Bi23 focuses on the Crypto-Assets, providing customers with Staking and DeFi services." + }, + "unbonding_height": "0", + "unbonding_time": "2019-08-16T15:34:04.702756371Z", + "commission": { + "commission_rates": { + "rate": "0.500000000000000000", + "max_rate": "0.500000000000000000", + "max_change_rate": "0.010000000000000000" + }, + "update_time": "2020-03-11T04:30:32.134491966Z" + }, + "min_self_delegation": "2" + }, + { + "operator_address": "cosmosvaloper1hjct6q7npsspsg3dgvzk3sdf89spmlpfdn6m9d", + "consensus_pubkey": "cosmosvalconspub1zcjduepqnltddase4lqjcfhup8ymg0qex3srakg54ppv06pstvwdjxkm6tmq08znvs", + "jailed": false, + "status": 2, + "tokens": "4532884973675", + "delegator_shares": "4532884973675.000000000000000000", + "description": { + "moniker": "Figment Networks", + "identity": "E5F274B870BDA01D", + "website": "https://figment.network", + "details": "Makers of Hubble and Canada’s largest Cosmos validator, Figment is the easiest and most secure way to stake your Atoms." + }, + "unbonding_height": "0", + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.090000000000000000", + "max_rate": "0.300000000000000000", + "max_change_rate": "0.010000000000000000" + }, + "update_time": "2019-12-06T12:17:54.693866931Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1crqm3598z6qmyn2kkcl9dz7uqs4qdqnr6s8jdn", + "consensus_pubkey": "cosmosvalconspub1zcjduepqt0fpxxufuuhavfqh8zg3pjnnwdvvzw9huemzxe59kpjt5e3xprhs7d8khn", + "jailed": false, + "status": 2, + "tokens": "449558836978", + "delegator_shares": "449558836978.000000000000000000", + "description": { + "moniker": "Bison Trails", + "identity": "A296556FF603197C", + "website": "bisontrails.co", + "details": "Bison Trails is the easiest way to run infrastructure on multiple blockchains." + }, + "unbonding_height": "0", + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.080000000000000000", + "max_rate": "0.200000000000000000", + "max_change_rate": "0.010000000000000000" + }, + "update_time": "2019-10-30T20:21:03.030621767Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1cgh5ksjwy2sd407lyre4l3uj2fdrqhpkzp06e6", + "consensus_pubkey": "cosmosvalconspub1zcjduepq3f6wnsk6k6qu6g8n5vly4z7ajw7q930wh3qx6zkxhktnh49l40kszf5lry", + "jailed": false, + "status": 2, + "tokens": "930138172612", + "delegator_shares": "930138172612.000000000000000000", + "description": { + "moniker": "HashQuark", + "identity": "31AFBBE0A52FA1ED", + "website": "https://www.hashquark.io", + "details": "Staking made easier!" + }, + "unbonding_height": "0", + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.100000000000000000", + "max_rate": "0.200000000000000000", + "max_change_rate": "0.010000000000000000" + }, + "update_time": "2019-10-23T02:48:39.22540691Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1clpqr4nrk4khgkxj78fcwwh6dl3uw4epsluffn", + "consensus_pubkey": "cosmosvalconspub1zcjduepq0dc9apn3pz2x2qyujcnl2heqq4aceput2uaucuvhrjts75q0rv5smjjn7v", + "jailed": false, + "status": 2, + "tokens": "6046984071675", + "delegator_shares": "6046984071675.000000000000000000", + "description": { + "moniker": "Cosmostation", + "identity": "AE4C403A6E7AA1AC", + "website": "https://www.cosmostation.io", + "details": "CØSMOSTATION Validator. Delegate your atoms and Start Earning Staking Rewards" + }, + "unbonding_height": "0", + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.120000000000000000", + "max_rate": "0.200000000000000000", + "max_change_rate": "0.100000000000000000" + }, + "update_time": "2019-03-13T23:00:00Z" + }, + "min_self_delegation": "10" + }, + { + "operator_address": "cosmosvaloper1ey69r37gfxvxg62sh4r0ktpuc46pzjrm873ae8", + "consensus_pubkey": "cosmosvalconspub1zcjduepqg6y8magedjwr9p6s2c28zp28jdjtecxhn97ew6tnuzqklg63zgfspp9y3n", + "jailed": false, + "status": 2, + "tokens": "10377079380247", + "delegator_shares": "10377079378738.906130852393635459", + "description": { + "moniker": "Sikka", + "identity": "https://keybase.io/team/sikka", + "website": "sikka.tech", + "details": "Sunny Aggarwal (@sunnya97) and Dev Ojha (@ValarDragon)" + }, + "unbonding_height": "0", + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.030000000000000000", + "max_rate": "1.000000000000000000", + "max_change_rate": "1.000000000000000000" + }, + "update_time": "2019-11-01T04:08:08.548659287Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1et77usu8q2hargvyusl4qzryev8x8t9wwqkxfs", + "consensus_pubkey": "cosmosvalconspub1zcjduepqfx0p8s3gmxmaftkkazw5wag4sfau3vgcn20ut4dn5rv2nr8ddq2s59rnvq", + "jailed": false, + "status": 2, + "tokens": "15846947873", + "delegator_shares": "15846947873.000000000000000000", + "description": { + "moniker": "👾replicator.network", + "identity": "9203983F91296B66", + "website": "https://replicator.network", + "details": "" + }, + "unbonding_height": "1686743", + "unbonding_time": "2020-05-19T11:00:40.160158437Z", + "commission": { + "commission_rates": { + "rate": "0.050000000000000000", + "max_rate": "0.250000000000000000", + "max_change_rate": "0.050000000000000000" + }, + "update_time": "2020-04-28T19:23:18.063971937Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1e0plfg475phrsvrlzw8gwppeva0zk5yg9fgg8c", + "consensus_pubkey": "cosmosvalconspub1zcjduepqz83dmnt4g6w0w6syrf433mwpk86zejxnq6e336xtxd8pg9jtxkgq732tpu", + "jailed": false, + "status": 2, + "tokens": "331721337159", + "delegator_shares": "331721337159.000000000000000000", + "description": { + "moniker": "Easy 2 Stake", + "identity": "2C877AC873132C91", + "website": "www.easy2stake.com", + "details": "Easy.Stake.Trust. as easy and as simple as you would click next. Complete transparency and trust with a secure and stable validator. GoS winner, Never Jailed Crew" + }, + "unbonding_height": "0", + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.100000000000000000", + "max_rate": "0.300000000000000000", + "max_change_rate": "0.050000000000000000" + }, + "update_time": "2019-09-27T08:35:53.771679331Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1eh5mwu044gd5ntkkc2xgfg8247mgc56fz4sdg3", + "consensus_pubkey": "cosmosvalconspub1zcjduepq8hu49qdl5594rzxmdsww3hleu8phxrajjfsseqjere9mjrrrv9tq35mll4", + "jailed": false, + "status": 2, + "tokens": "2150370557522", + "delegator_shares": "2150370557522.000000000000000000", + "description": { + "moniker": "BouBouNode", + "identity": "", + "website": "https://boubounode.com", + "details": "AI-based Validator. #1 AI Validator on Game of Stakes. Fairly priced. Don't trust (humans), verify. Made with BouBou love." + }, + "unbonding_height": "0", + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.061000000000000000", + "max_rate": "1.000000000000000000", + "max_change_rate": "0.010000000000000000" + }, + "update_time": "2019-03-13T23:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1ehkfl7palwrh6w2hhr2yfrgrq8jetgucudztfe", + "consensus_pubkey": "cosmosvalconspub1zcjduepqvmmhug9hcmm26ce7we0n3esavn4c6tfcfd6zgnuj732ls7khjq4srpg0ft", + "jailed": false, + "status": 2, + "tokens": "1177437103283", + "delegator_shares": "1177437103283.000000000000000000", + "description": { + "moniker": "KalpaTech", + "identity": "B4AD06F0EB355573", + "website": "http://kalpatech.co", + "details": "KalpaTech | Genesis Validator | Game of Stakes winner | Services dedicated exclusively for Cosmos Hub | All resources put in one network" + }, + "unbonding_height": "0", + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.150000000000000000", + "max_rate": "0.200000000000000000", + "max_change_rate": "0.010000000000000000" + }, + "update_time": "2019-03-28T22:00:22.763748595Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1ec3p6a75mqwkv33zt543n6cnxqwun37rr5xlqv", + "consensus_pubkey": "cosmosvalconspub1zcjduepqd85nu5nelvcyyzcsrr0yaglh8rfvn6cv9pp3p0hgmwtk8hf3cazqc7vz5c", + "jailed": false, + "status": 2, + "tokens": "1016350149259", + "delegator_shares": "1016350149259.000000000000000000", + "description": { + "moniker": "lunamint", + "identity": "4F26823468DD7518", + "website": "https://lunamint.com", + "details": "Always adding value to Cosmos. Check out Lunagram, the Cosmos wallet built into Telegram." + }, + "unbonding_height": "0", + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.150000000000000000", + "max_rate": "1.000000000000000000", + "max_change_rate": "1.000000000000000000" + }, + "update_time": "2019-03-13T23:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1emaa7mwgpnpmc7yptm728ytp9quamsvu837nc0", + "consensus_pubkey": "cosmosvalconspub1zcjduepqfuxvufupnsm7v5anpwd7z8ec70z2k209j7xclnm25zz7vauhyc5qjgxx3h", + "jailed": false, + "status": 2, + "tokens": "525680707649", + "delegator_shares": "525680707649.000000000000000000", + "description": { + "moniker": "kochacolaj", + "identity": "1E9CE94FD0BA5CFEB901F90BC658D64D85B134D2", + "website": "https://blog.cosmos.network/game-of-stakes-closing-ceremonies-eddb71d3b114#147d", + "details": "Top 5 Game Of Stakes winner" + }, + "unbonding_height": "0", + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.200000000000000000", + "max_rate": "1.000000000000000000", + "max_change_rate": "1.000000000000000000" + }, + "update_time": "2020-04-25T14:55:05.718968098Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1eup5t8pp8jq354heck53qtama7vss9l354kh6r", + "consensus_pubkey": "cosmosvalconspub1zcjduepqxh4s2zj52uhfssu7u2xyhmnk5f7g9ty368twxkkcfllsq3fqaw9sdl6rj9", + "jailed": false, + "status": 2, + "tokens": "10436859212", + "delegator_shares": "10436859212.000000000000000000", + "description": { + "moniker": "IZ0", + "identity": "BF964D76855711CC", + "website": "www.izo.ro", + "details": "Izo Data Network ! Commission is 0% . Please join our [community](https://t.me/IzoData) or visit [website](https://www.izo.ro/)! " + }, + "unbonding_height": "0", + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.000000000000000000", + "max_rate": "0.100000000000000000", + "max_change_rate": "0.100000000000000000" + }, + "update_time": "2019-12-26T08:56:10.399933806Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper16qme5yxucnaj6snx35nmwze0wyxr8wfgqxsqfw", + "consensus_pubkey": "cosmosvalconspub1zcjduepqwnhw3azrlhnx9kaujvn0es9u26e4a3af6hye6e9j0pl2tlpx9k3s59zwh0", + "jailed": false, + "status": 2, + "tokens": "328202291816", + "delegator_shares": "328202291816.000000000000000000", + "description": { + "moniker": "KIRA Staking", + "identity": "C86C8FF08A5269DC", + "website": "https://kiraex.com", + "details": "Kira Core Staking Services - Sentry, KMS, HSM, High Availability \u0026 Double Sign Protection" + }, + "unbonding_height": "0", + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.020000000000000000", + "max_rate": "1.000000000000000000", + "max_change_rate": "1.000000000000000000" + }, + "update_time": "2020-05-01T18:39:34.037797682Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper16zgjnqxryhq2kftfuv8urp50x0xwt5dagemhfl", + "consensus_pubkey": "cosmosvalconspub1zcjduepqeumluaf7n7ss9qmaj43v4gd4dzj5jfw7cdnn6vngwd2m7gmu48lqsyy3wa", + "jailed": false, + "status": 2, + "tokens": "1000040000000", + "delegator_shares": "1000040000000.000000000000000000", + "description": { + "moniker": "Alphemy Capital", + "identity": "78DAB5C26CB56856", + "website": "https://alphemy.capital", + "details": "Institutional grade staking for clients of Alphemy Capital." + }, + "unbonding_height": "0", + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.200000000000000000", + "max_rate": "0.200000000000000000", + "max_change_rate": "0.010000000000000000" + }, + "update_time": "2020-04-20T19:33:55.395872948Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper16v3f95amtvpewuajjcdsvaekuuy4yyzups85ec", + "consensus_pubkey": "cosmosvalconspub1zcjduepqmgwzcm3aqmc8nln9u4q5ydsjwx6rzqrch6p243x2gtzetnx5l3ls432euv", + "jailed": false, + "status": 2, + "tokens": "293516903946", + "delegator_shares": "293516903946.000000000000000000", + "description": { + "moniker": "BlockPool", + "identity": "", + "website": "www.blockpool.com", + "details": "Power the staking economy" + }, + "unbonding_height": "0", + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.020000000000000000", + "max_rate": "0.030000000000000000", + "max_change_rate": "0.010000000000000000" + }, + "update_time": "2019-06-22T05:19:17.897735561Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1648ynlpdw7fqa2axt0w2yp3fk542junl7rsvq6", + "consensus_pubkey": "cosmosvalconspub1zcjduepqf8llkc4p43lksktsqzr5nmgmw4ln9pzym2vp4kqfrny8xrgnqrsq76djjc", + "jailed": false, + "status": 2, + "tokens": "955816857915", + "delegator_shares": "955912449090.690555765999702861", + "description": { + "moniker": "Any Labs", + "identity": "B2D07CA3CCC907CE", + "website": "https://anylabs.io", + "details": "Blockchain staking and consultancy based in Japan." + }, + "unbonding_height": "25880", + "unbonding_time": "2020-01-03T18:48:44.276425288Z", + "commission": { + "commission_rates": { + "rate": "0.000000000000000000", + "max_rate": "0.500000000000000000", + "max_change_rate": "0.010000000000000000" + }, + "update_time": "2019-05-08T11:30:02.004384504Z" + }, + "min_self_delegation": "100" + }, + { + "operator_address": "cosmosvaloper16k579jk6yt2cwmqx9dz5xvq9fug2tekvlu9qdv", + "consensus_pubkey": "cosmosvalconspub1zcjduepq55mjplg9gy979ua9r5qmk2wr5nysmputt28j0zsgadn933lyh32sh20cmm", + "jailed": false, + "status": 2, + "tokens": "931176202093", + "delegator_shares": "931269329007.764829857979365790", + "description": { + "moniker": "Cephalopod Equipment", + "identity": "6408AA029ADBE364", + "website": "https://cephalopod.equipment", + "details": "Cephalopod Equipment - infrastructure for decentralized intelligence" + }, + "unbonding_height": "0", + "unbonding_time": "2019-12-01T09:34:39.548038382Z", + "commission": { + "commission_rates": { + "rate": "0.081100000000000000", + "max_rate": "0.420000000000000000", + "max_change_rate": "0.011800000000000000" + }, + "update_time": "2019-09-19T12:26:43.48042061Z" + }, + "min_self_delegation": "100000" + }, + { + "operator_address": "cosmosvaloper1mykn77lkynl8fkwvl9tqg369u0zajzzcdhkptq", + "consensus_pubkey": "cosmosvalconspub1zcjduepqft6uxfmfjjce0p7ke4h0zc38x4d9d38wlmrgcc47flru92qq3ydq76mrsf", + "jailed": false, + "status": 2, + "tokens": "88053542555", + "delegator_shares": "88053542555.000000000000000000", + "description": { + "moniker": "Nodeasy.com", + "identity": "AB006A79DBD8FC57", + "website": "https://www.nodeasy.com", + "details": "Nodeasy.com,助你进入Staking时代!" + }, + "unbonding_height": "0", + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.100000000000000000", + "max_rate": "1.000000000000000000", + "max_change_rate": "1.000000000000000000" + }, + "update_time": "2019-10-28T13:02:55.182998044Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1m83cwjucw9nt8xm66u8xavvy6v9m7xfspcszc5", + "consensus_pubkey": "cosmosvalconspub1zcjduepq7qnf5r40z7esjc2utrjrvzxg9sfd683hw0805ek85ddchdcptthqjnzxxu", + "jailed": false, + "status": 2, + "tokens": "160362681331", + "delegator_shares": "160362681331.000000000000000000", + "description": { + "moniker": "Fenbushi US - Staked", + "identity": "CC4B238C8F9FB2BE", + "website": "https://fenbushi.vc", + "details": "Fenbushi Capital is the first and most active blockchain-focused venture capital firm in Asia. Staked is the leading provider of validation technology and services. We're bringing our combined skills to Cosmos." + }, + "unbonding_height": "0", + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.100000000000000000", + "max_rate": "0.200000000000000000", + "max_change_rate": "0.010000000000000000" + }, + "update_time": "2019-11-15T18:07:08.897219336Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1ma02nlc7lchu7caufyrrqt4r6v2mpsj90y9wzd", + "consensus_pubkey": "cosmosvalconspub1zcjduepqxtu8am2qmf0qnglqtvkar9gaclhccfn29tsp7n82vasrtnc8m2fsulp4h2", + "jailed": false, + "status": 2, + "tokens": "3441815546707", + "delegator_shares": "3441815546707.000000000000000000", + "description": { + "moniker": "hashtower", + "identity": "0BBBAE1FD11AEBAF", + "website": "http://hashtower.com", + "details": "Hashtower Actwo COSMOS Validator" + }, + "unbonding_height": "0", + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.030000000000000000", + "max_rate": "1.000000000000000000", + "max_change_rate": "0.200000000000000000" + }, + "update_time": "2019-07-16T08:46:06.560077744Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1uxh465053nq3at4dn0jywgwq3s9sme3la3drx6", + "consensus_pubkey": "cosmosvalconspub1zcjduepqc5y2du793cjut0cn6v7thp3xlvphggk6rt2dhw9ekjla5wtkm7nstmv5vy", + "jailed": false, + "status": 2, + "tokens": "520172159921", + "delegator_shares": "520172159921.000000000000000000", + "description": { + "moniker": "Bison Trails", + "identity": "A296556FF603197C", + "website": "https://bisontrails.co", + "details": "Bison Trails is the easiest way to run infrastructure on multiple blockchains." + }, + "unbonding_height": "0", + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.100000000000000000", + "max_rate": "0.500000000000000000", + "max_change_rate": "0.010000000000000000" + }, + "update_time": "2019-03-13T23:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1uhnsxv6m83jj3328mhrql7yax3nge5svrv6t6c", + "consensus_pubkey": "cosmosvalconspub1zcjduepql42t7mstnewp5rgweteuw95hawzystll7mq8dl24n5yh0th7q2jqetcy07", + "jailed": false, + "status": 2, + "tokens": "720894765456", + "delegator_shares": "720966862061.597270834863362006", + "description": { + "moniker": "Skystar Capital", + "identity": "", + "website": "", + "details": "" + }, + "unbonding_height": "1168707", + "unbonding_time": "2020-04-06T17:50:47.447745873Z", + "commission": { + "commission_rates": { + "rate": "0.100000000000000000", + "max_rate": "0.200000000000000000", + "max_change_rate": "0.010000000000000000" + }, + "update_time": "2019-03-13T23:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1u6ddcsjueax884l3tfrs66497c7g86skn7pa0u", + "consensus_pubkey": "cosmosvalconspub1zcjduepq87zcnf8sm4ewacjafqujfevt8rhwj5qk9uwtx4ef89ctuqmndkeq446ahw", + "jailed": false, + "status": 2, + "tokens": "809352867566", + "delegator_shares": "809352867566.000000000000000000", + "description": { + "moniker": "Sentinel", + "identity": "D54C8032CF19C407", + "website": "https://sentinel.co", + "details": "We are team Sentinel, developer of infrastructure tools on Cosmos \u0026 other networks.Winner in the Uptime category during GOS.Developed the first working version of the dVPN which runs on Ethereum \u0026 Sentinel's own Tendermint TestNet" + }, + "unbonding_height": "0", + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.200000000000000000", + "max_rate": "1.000000000000000000", + "max_change_rate": "0.100000000000000000" + }, + "update_time": "2020-04-29T05:17:01.930702784Z" + }, + "min_self_delegation": "1000000" + }, + { + "operator_address": "cosmosvaloper1uutuwrwt3z2a5z8z3uasml3rftlpmu25aga5c6", + "consensus_pubkey": "cosmosvalconspub1zcjduepqarrl0ppddzyczwvcqwf3jwd9qwkhxfy6lcv8ep4msk293mlxg39qgf77y3", + "jailed": false, + "status": 2, + "tokens": "908236212795", + "delegator_shares": "908236212795.000000000000000000", + "description": { + "moniker": "Delega Networks♾ ", + "identity": "1BED7C08416A619F", + "website": "https://delega.io", + "details": "Validador con énfasis en la comunidad de habla hispana, validando bloques en Cosmos desde el 2018. Mantenemos nuestra infraestructura segura y fiable el 99% del tiempo. Nodos manejados por Wimel.|N0∞D0|" + }, + "unbonding_height": "0", + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.200000000000000000", + "max_rate": "0.200000000000000000", + "max_change_rate": "0.010000000000000000" + }, + "update_time": "2020-05-06T03:25:11.392136982Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1ul2me6vukg2vac2p6ltxmqlaa7jywdgt8q76ag", + "consensus_pubkey": "cosmosvalconspub1zcjduepq0cet8ez89wj4yz8uencych7aldc5wyyrpx6jvh6n6kxxslumln5sxkq922", + "jailed": false, + "status": 2, + "tokens": "1219102963218", + "delegator_shares": "1219102963218.000000000000000000", + "description": { + "moniker": "HyperblocksPro", + "identity": "B073FA5BAD230585", + "website": "https://hyperblocks.pro/", + "details": "Secure the network and earn rewards with Hyperblocks.pro, one of the first companies in the world fully focused on Proof Of Stake protocols" + }, + "unbonding_height": "0", + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.100000000000000000", + "max_rate": "0.250000000000000000", + "max_change_rate": "0.010000000000000000" + }, + "update_time": "2019-04-05T23:57:19.320271237Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper17h2x3j7u44qkrq0sk8ul0r2qr440rwgjkfg0gh", + "consensus_pubkey": "cosmosvalconspub1zcjduepqc9ppxzktam9v39d9q07h6n98cdm7cgg4l65vq5yvtgruxp5h0yhs8tup68", + "jailed": false, + "status": 2, + "tokens": "572757556709", + "delegator_shares": "572757556709.000000000000000000", + "description": { + "moniker": "FRESHATOMS", + "identity": "63575EE3F0F9FAFC", + "website": "https://freshatoms.com", + "details": "FreshAtoms runs on bare metal in a SSAE16 SOC2 certified Tier 3 datacenter with geographically distributed private sentry nodes, YubiHSM2 hardware protected keys, with 24/7 monitoring, alerting, and analytics." + }, + "unbonding_height": "0", + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.000000000000000000", + "max_rate": "0.200000000000000000", + "max_change_rate": "0.010000000000000000" + }, + "update_time": "2019-09-23T20:29:05.781322875Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper17cy09npjq4sylkt56kwcuqcd74hlxj3fq4hwjd", + "consensus_pubkey": "cosmosvalconspub1zcjduepq4hwm4ev9d9cmg4v5sqkscmsy6g0qnhrskmhgacjux2l35lulfg8svx5ywk", + "jailed": false, + "status": 2, + "tokens": "13002678600", + "delegator_shares": "13006580000.000000000000000000", + "description": { + "moniker": "topool", + "identity": "9A866486C2AADA48", + "website": "http://topool.io", + "details": "The world's top PoS and Staking service providers in the future" + }, + "unbonding_height": "1840453", + "unbonding_time": "2020-06-01T00:43:55.825880187Z", + "commission": { + "commission_rates": { + "rate": "0.150000000000000000", + "max_rate": "1.000000000000000000", + "max_change_rate": "0.200000000000000000" + }, + "update_time": "2020-05-01T03:41:16.979171357Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper17mggn4znyeyg25wd7498qxl7r2jhgue8u4qjcq", + "consensus_pubkey": "cosmosvalconspub1zcjduepqlzmd0spn9m0m3eq9zp93d4w6e5tugamv44yqjzyacelnvra634fqnfec0r", + "jailed": false, + "status": 2, + "tokens": "1079735204356", + "delegator_shares": "1079735204356.000000000000000000", + "description": { + "moniker": "01node", + "identity": "22823CD59617B8E3", + "website": "https://01node.com", + "details": "01node Professional Staking Services for Cosmos, Iris, Terra, Solana, Kava, Polkadot, Skale" + }, + "unbonding_height": "0", + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.100000000000000000", + "max_rate": "0.200000000000000000", + "max_change_rate": "0.010000000000000000" + }, + "update_time": "2019-03-13T23:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1l9fwl9c77zx850htsr20pq3ltc379xt86ndelm", + "consensus_pubkey": "cosmosvalconspub1zcjduepqfjgjrj4heptaw6h9nhtkng8hw2zsq5c6e9xzwvnjjx2n6pc7x6yq4ny2qc", + "jailed": false, + "status": 2, + "tokens": "10466688923", + "delegator_shares": "10466688923.000000000000000000", + "description": { + "moniker": "CosmosLink", + "identity": "3F7807C66CE770B0", + "website": "cosmoslink.network", + "details": "Based on Cosmos network digital asset security value-added service provider" + }, + "unbonding_height": "1276519", + "unbonding_time": "2020-04-15T17:26:54.325724353Z", + "commission": { + "commission_rates": { + "rate": "0.000000000000000000", + "max_rate": "1.000000000000000000", + "max_change_rate": "0.010000000000000000" + }, + "update_time": "2020-03-18T16:46:59.079404223Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1lktjhnzkpkz3ehrg8psvmwhafg56kfss3q3t8m", + "consensus_pubkey": "cosmosvalconspub1zcjduepqelcwpat987h9yq0ck6g9fsc8t0mththk547gwvk0w4wnkpl0stnspr3hdc", + "jailed": false, + "status": 2, + "tokens": "1655592831912", + "delegator_shares": "1655592831912.000000000000000000", + "description": { + "moniker": "Umbrella ☔", + "identity": "A530AC4D75991FE2", + "website": "https://umbrellavalidator.com", + "details": "One of the winners of Cosmos Game of Stakes, and HackAtom3." + }, + "unbonding_height": "0", + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.070400000000000000", + "max_rate": "1.000000000000000000", + "max_change_rate": "0.100000000000000000" + }, + "update_time": "2019-08-05T07:10:23.689753607Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1lcwxu50rvvgf9v6jy6q5mrzyhlszwtjxhtscmp", + "consensus_pubkey": "cosmosvalconspub1zcjduepqh3jg5ld5xg5q5mcxrzn6fcuq696qqa3ut3azskphpdrty37ervjqcn8mfj", + "jailed": false, + "status": 2, + "tokens": "10717165430", + "delegator_shares": "10717165430.000000000000000000", + "description": { + "moniker": "stake.zone", + "identity": "0A888728046018EC", + "website": "http://stake.zone", + "details": "operated by nuevax" + }, + "unbonding_height": "0", + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.000000000000000000", + "max_rate": "0.200000000000000000", + "max_change_rate": "0.050000000000000000" + }, + "update_time": "2020-02-13T02:20:41.320594366Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1l6udzyaz8xaxv4hpagwauacm95jlcec3xlht2u", + "consensus_pubkey": "cosmosvalconspub1zcjduepq9t4r8jgr09rsscgacnaklxuf55pg0wq5zfwzw8ycawms5x0hrfhqks3dpe", + "jailed": false, + "status": 2, + "tokens": "12941250441", + "delegator_shares": "12941250441.000000000000000000", + "description": { + "moniker": "StakeHouse", + "identity": "A1AAB1D6D0E8F976", + "website": "stakehouse.org", + "details": "Low fees. No hassle. Enjoy your meal." + }, + "unbonding_height": "701066", + "unbonding_time": "2020-02-28T02:04:00.114690756Z", + "commission": { + "commission_rates": { + "rate": "0.010000000000000000", + "max_rate": "0.200000000000000000", + "max_change_rate": "0.010000000000000000" + }, + "update_time": "2020-02-11T07:24:35.723449554Z" + }, + "min_self_delegation": "1" + } + ] +} \ No newline at end of file diff --git a/mock/ext-api-data/cosmos-api_txs__limit_25_message.sender_cosmos1dx27g0kzhwej0ekcf2k9hsktcxnmpl7fcehcvq_page_1.json b/mock/ext-api-data/cosmos-api_txs__limit_25_message.sender_cosmos1dx27g0kzhwej0ekcf2k9hsktcxnmpl7fcehcvq_page_1.json new file mode 100644 index 000000000..5ea048ea1 --- /dev/null +++ b/mock/ext-api-data/cosmos-api_txs__limit_25_message.sender_cosmos1dx27g0kzhwej0ekcf2k9hsktcxnmpl7fcehcvq_page_1.json @@ -0,0 +1,308 @@ +{ + "total_count": "2", + "count": "2", + "page_number": "1", + "page_total": "1", + "limit": "25", + "txs": [ + { + "height": "26616", + "txhash": "3FEE8F10FBA5505DE2A8D3EF220D5CE900CA76B96208234BBF89B8075743A230", + "data": "0C0886C1BEF00510E7FFF6F801", + "raw_log": "[{\"msg_index\":0,\"success\":true,\"log\":\"\",\"events\":[{\"type\":\"message\",\"attributes\":[{\"key\":\"sender\",\"value\":\"cosmos1jv65s3grqf6v6jl3dp4t6c9t9rk99cd88lyufl\"},{\"key\":\"sender\",\"value\":\"cosmos1fl48vsnmsdzcv85q5d2q4z5ajdha8yu34mf0eh\"},{\"key\":\"module\",\"value\":\"staking\"},{\"key\":\"sender\",\"value\":\"cosmos1dx27g0kzhwej0ekcf2k9hsktcxnmpl7fcehcvq\"},{\"key\":\"action\",\"value\":\"begin_unbonding\"}]},{\"type\":\"transfer\",\"attributes\":[{\"key\":\"recipient\",\"value\":\"cosmos1dx27g0kzhwej0ekcf2k9hsktcxnmpl7fcehcvq\"},{\"key\":\"amount\",\"value\":\"1147uatom\"},{\"key\":\"recipient\",\"value\":\"cosmos1tygms3xhhs3yv487phx3dw4a95jn7t7lpm470r\"},{\"key\":\"amount\",\"value\":\"2203000uatom\"}]},{\"type\":\"unbond\",\"attributes\":[{\"key\":\"validator\",\"value\":\"cosmosvaloper1ptyzewnns2kn37ewtmv6ppsvhdnmeapvtfc9y5\"},{\"key\":\"amount\",\"value\":\"2203000\"},{\"key\":\"completion_time\",\"value\":\"2020-01-03T20:13:58Z\"}]}]}]", + "logs": [ + { + "msg_index": 0, + "success": true, + "log": "", + "events": [ + { + "type": "message", + "attributes": [ + { + "key": "sender", + "value": "cosmos1jv65s3grqf6v6jl3dp4t6c9t9rk99cd88lyufl" + }, + { + "key": "sender", + "value": "cosmos1fl48vsnmsdzcv85q5d2q4z5ajdha8yu34mf0eh" + }, + { + "key": "module", + "value": "staking" + }, + { + "key": "sender", + "value": "cosmos1dx27g0kzhwej0ekcf2k9hsktcxnmpl7fcehcvq" + }, + { + "key": "action", + "value": "begin_unbonding" + } + ] + }, + { + "type": "transfer", + "attributes": [ + { + "key": "recipient", + "value": "cosmos1dx27g0kzhwej0ekcf2k9hsktcxnmpl7fcehcvq" + }, + { + "key": "amount", + "value": "1147uatom" + }, + { + "key": "recipient", + "value": "cosmos1tygms3xhhs3yv487phx3dw4a95jn7t7lpm470r" + }, + { + "key": "amount", + "value": "2203000uatom" + } + ] + }, + { + "type": "unbond", + "attributes": [ + { + "key": "validator", + "value": "cosmosvaloper1ptyzewnns2kn37ewtmv6ppsvhdnmeapvtfc9y5" + }, + { + "key": "amount", + "value": "2203000" + }, + { + "key": "completion_time", + "value": "2020-01-03T20:13:58Z" + } + ] + } + ] + } + ], + "gas_wanted": "200000", + "gas_used": "127111", + "tx": { + "type": "cosmos-sdk/StdTx", + "value": { + "msg": [ + { + "type": "cosmos-sdk/MsgUndelegate", + "value": { + "delegator_address": "cosmos1dx27g0kzhwej0ekcf2k9hsktcxnmpl7fcehcvq", + "validator_address": "cosmosvaloper1ptyzewnns2kn37ewtmv6ppsvhdnmeapvtfc9y5", + "amount": { + "denom": "uatom", + "amount": "2203000" + } + } + } + ], + "fee": { + "amount": [ + { + "denom": "uatom", + "amount": "1000" + } + ], + "gas": "200000" + }, + "signatures": [ + { + "pub_key": { + "type": "tendermint/PubKeySecp256k1", + "value": "A782zo6TI2H3DfHJ7X1WHOJz6p4fUYVRYhb/XqMTcVQt" + }, + "signature": "fJkOgQX9FZz6UJJo48AA3qxc2v/vFrjxlMgq3iOhDmVUWjA2P6X+pPbPkSB1SHlBFlVbsNF/DDPB0pvP9LRPTg==" + } + ], + "memo": "" + } + }, + "timestamp": "2019-12-13T20:13:58Z", + "events": [ + { + "type": "message", + "attributes": [ + { + "key": "sender", + "value": "cosmos1jv65s3grqf6v6jl3dp4t6c9t9rk99cd88lyufl" + }, + { + "key": "sender", + "value": "cosmos1fl48vsnmsdzcv85q5d2q4z5ajdha8yu34mf0eh" + }, + { + "key": "module", + "value": "staking" + }, + { + "key": "sender", + "value": "cosmos1dx27g0kzhwej0ekcf2k9hsktcxnmpl7fcehcvq" + }, + { + "key": "action", + "value": "begin_unbonding" + } + ] + }, + { + "type": "transfer", + "attributes": [ + { + "key": "recipient", + "value": "cosmos1dx27g0kzhwej0ekcf2k9hsktcxnmpl7fcehcvq" + }, + { + "key": "amount", + "value": "1147uatom" + }, + { + "key": "recipient", + "value": "cosmos1tygms3xhhs3yv487phx3dw4a95jn7t7lpm470r" + }, + { + "key": "amount", + "value": "2203000uatom" + } + ] + }, + { + "type": "unbond", + "attributes": [ + { + "key": "validator", + "value": "cosmosvaloper1ptyzewnns2kn37ewtmv6ppsvhdnmeapvtfc9y5" + }, + { + "key": "amount", + "value": "2203000" + }, + { + "key": "completion_time", + "value": "2020-01-03T20:13:58Z" + } + ] + } + ] + }, + { + "height": "404179", + "txhash": "93E43518BAE4BC137605BBB7FD5D31FDAE6427ECE57EC299C43CE786FDAEBC63", + "raw_log": "[{\"msg_index\":0,\"success\":true,\"log\":\"\",\"events\":[{\"type\":\"delegate\",\"attributes\":[{\"key\":\"validator\",\"value\":\"cosmosvaloper17h2x3j7u44qkrq0sk8ul0r2qr440rwgjkfg0gh\"},{\"key\":\"amount\",\"value\":\"2211271\"}]},{\"type\":\"message\",\"attributes\":[{\"key\":\"module\",\"value\":\"staking\"},{\"key\":\"sender\",\"value\":\"cosmos1dx27g0kzhwej0ekcf2k9hsktcxnmpl7fcehcvq\"},{\"key\":\"action\",\"value\":\"delegate\"}]}]}]", + "logs": [ + { + "msg_index": 0, + "success": true, + "log": "", + "events": [ + { + "type": "delegate", + "attributes": [ + { + "key": "validator", + "value": "cosmosvaloper17h2x3j7u44qkrq0sk8ul0r2qr440rwgjkfg0gh" + }, + { + "key": "amount", + "value": "2211271" + } + ] + }, + { + "type": "message", + "attributes": [ + { + "key": "module", + "value": "staking" + }, + { + "key": "sender", + "value": "cosmos1dx27g0kzhwej0ekcf2k9hsktcxnmpl7fcehcvq" + }, + { + "key": "action", + "value": "delegate" + } + ] + } + ] + } + ], + "gas_wanted": "200000", + "gas_used": "93720", + "tx": { + "type": "cosmos-sdk/StdTx", + "value": { + "msg": [ + { + "type": "cosmos-sdk/MsgDelegate", + "value": { + "delegator_address": "cosmos1dx27g0kzhwej0ekcf2k9hsktcxnmpl7fcehcvq", + "validator_address": "cosmosvaloper17h2x3j7u44qkrq0sk8ul0r2qr440rwgjkfg0gh", + "amount": { + "denom": "uatom", + "amount": "2211271" + } + } + } + ], + "fee": { + "amount": [ + { + "denom": "uatom", + "amount": "1000" + } + ], + "gas": "200000" + }, + "signatures": [ + { + "pub_key": { + "type": "tendermint/PubKeySecp256k1", + "value": "A782zo6TI2H3DfHJ7X1WHOJz6p4fUYVRYhb/XqMTcVQt" + }, + "signature": "X1/NzRdb+HUxE7N9gMk39XI8TyHFobLRQtsX4QxZZbYeKmEYOOZ7FyNSGqgmipCkpuysBeh6fNnbXmo3IFzFEQ==" + } + ], + "memo": "" + } + }, + "timestamp": "2020-01-13T15:23:12Z", + "events": [ + { + "type": "delegate", + "attributes": [ + { + "key": "validator", + "value": "cosmosvaloper17h2x3j7u44qkrq0sk8ul0r2qr440rwgjkfg0gh" + }, + { + "key": "amount", + "value": "2211271" + } + ] + }, + { + "type": "message", + "attributes": [ + { + "key": "module", + "value": "staking" + }, + { + "key": "sender", + "value": "cosmos1dx27g0kzhwej0ekcf2k9hsktcxnmpl7fcehcvq" + }, + { + "key": "action", + "value": "delegate" + } + ] + } + ] + } + ] +} \ No newline at end of file diff --git a/mock/ext-api-data/cosmos-api_txs__limit_25_page_1_transfer.recipient_cosmos1dx27g0kzhwej0ekcf2k9hsktcxnmpl7fcehcvq.json b/mock/ext-api-data/cosmos-api_txs__limit_25_page_1_transfer.recipient_cosmos1dx27g0kzhwej0ekcf2k9hsktcxnmpl7fcehcvq.json new file mode 100644 index 000000000..ca5fac28d --- /dev/null +++ b/mock/ext-api-data/cosmos-api_txs__limit_25_page_1_transfer.recipient_cosmos1dx27g0kzhwej0ekcf2k9hsktcxnmpl7fcehcvq.json @@ -0,0 +1,192 @@ +{ + "total_count": "1", + "count": "1", + "page_number": "1", + "page_total": "1", + "limit": "25", + "txs": [ + { + "height": "26616", + "txhash": "3FEE8F10FBA5505DE2A8D3EF220D5CE900CA76B96208234BBF89B8075743A230", + "data": "0C0886C1BEF00510E7FFF6F801", + "raw_log": "[{\"msg_index\":0,\"success\":true,\"log\":\"\",\"events\":[{\"type\":\"message\",\"attributes\":[{\"key\":\"sender\",\"value\":\"cosmos1jv65s3grqf6v6jl3dp4t6c9t9rk99cd88lyufl\"},{\"key\":\"sender\",\"value\":\"cosmos1fl48vsnmsdzcv85q5d2q4z5ajdha8yu34mf0eh\"},{\"key\":\"module\",\"value\":\"staking\"},{\"key\":\"sender\",\"value\":\"cosmos1dx27g0kzhwej0ekcf2k9hsktcxnmpl7fcehcvq\"},{\"key\":\"action\",\"value\":\"begin_unbonding\"}]},{\"type\":\"transfer\",\"attributes\":[{\"key\":\"recipient\",\"value\":\"cosmos1dx27g0kzhwej0ekcf2k9hsktcxnmpl7fcehcvq\"},{\"key\":\"amount\",\"value\":\"1147uatom\"},{\"key\":\"recipient\",\"value\":\"cosmos1tygms3xhhs3yv487phx3dw4a95jn7t7lpm470r\"},{\"key\":\"amount\",\"value\":\"2203000uatom\"}]},{\"type\":\"unbond\",\"attributes\":[{\"key\":\"validator\",\"value\":\"cosmosvaloper1ptyzewnns2kn37ewtmv6ppsvhdnmeapvtfc9y5\"},{\"key\":\"amount\",\"value\":\"2203000\"},{\"key\":\"completion_time\",\"value\":\"2020-01-03T20:13:58Z\"}]}]}]", + "logs": [ + { + "msg_index": 0, + "success": true, + "log": "", + "events": [ + { + "type": "message", + "attributes": [ + { + "key": "sender", + "value": "cosmos1jv65s3grqf6v6jl3dp4t6c9t9rk99cd88lyufl" + }, + { + "key": "sender", + "value": "cosmos1fl48vsnmsdzcv85q5d2q4z5ajdha8yu34mf0eh" + }, + { + "key": "module", + "value": "staking" + }, + { + "key": "sender", + "value": "cosmos1dx27g0kzhwej0ekcf2k9hsktcxnmpl7fcehcvq" + }, + { + "key": "action", + "value": "begin_unbonding" + } + ] + }, + { + "type": "transfer", + "attributes": [ + { + "key": "recipient", + "value": "cosmos1dx27g0kzhwej0ekcf2k9hsktcxnmpl7fcehcvq" + }, + { + "key": "amount", + "value": "1147uatom" + }, + { + "key": "recipient", + "value": "cosmos1tygms3xhhs3yv487phx3dw4a95jn7t7lpm470r" + }, + { + "key": "amount", + "value": "2203000uatom" + } + ] + }, + { + "type": "unbond", + "attributes": [ + { + "key": "validator", + "value": "cosmosvaloper1ptyzewnns2kn37ewtmv6ppsvhdnmeapvtfc9y5" + }, + { + "key": "amount", + "value": "2203000" + }, + { + "key": "completion_time", + "value": "2020-01-03T20:13:58Z" + } + ] + } + ] + } + ], + "gas_wanted": "200000", + "gas_used": "127111", + "tx": { + "type": "cosmos-sdk/StdTx", + "value": { + "msg": [ + { + "type": "cosmos-sdk/MsgUndelegate", + "value": { + "delegator_address": "cosmos1dx27g0kzhwej0ekcf2k9hsktcxnmpl7fcehcvq", + "validator_address": "cosmosvaloper1ptyzewnns2kn37ewtmv6ppsvhdnmeapvtfc9y5", + "amount": { + "denom": "uatom", + "amount": "2203000" + } + } + } + ], + "fee": { + "amount": [ + { + "denom": "uatom", + "amount": "1000" + } + ], + "gas": "200000" + }, + "signatures": [ + { + "pub_key": { + "type": "tendermint/PubKeySecp256k1", + "value": "A782zo6TI2H3DfHJ7X1WHOJz6p4fUYVRYhb/XqMTcVQt" + }, + "signature": "fJkOgQX9FZz6UJJo48AA3qxc2v/vFrjxlMgq3iOhDmVUWjA2P6X+pPbPkSB1SHlBFlVbsNF/DDPB0pvP9LRPTg==" + } + ], + "memo": "" + } + }, + "timestamp": "2019-12-13T20:13:58Z", + "events": [ + { + "type": "message", + "attributes": [ + { + "key": "sender", + "value": "cosmos1jv65s3grqf6v6jl3dp4t6c9t9rk99cd88lyufl" + }, + { + "key": "sender", + "value": "cosmos1fl48vsnmsdzcv85q5d2q4z5ajdha8yu34mf0eh" + }, + { + "key": "module", + "value": "staking" + }, + { + "key": "sender", + "value": "cosmos1dx27g0kzhwej0ekcf2k9hsktcxnmpl7fcehcvq" + }, + { + "key": "action", + "value": "begin_unbonding" + } + ] + }, + { + "type": "transfer", + "attributes": [ + { + "key": "recipient", + "value": "cosmos1dx27g0kzhwej0ekcf2k9hsktcxnmpl7fcehcvq" + }, + { + "key": "amount", + "value": "1147uatom" + }, + { + "key": "recipient", + "value": "cosmos1tygms3xhhs3yv487phx3dw4a95jn7t7lpm470r" + }, + { + "key": "amount", + "value": "2203000uatom" + } + ] + }, + { + "type": "unbond", + "attributes": [ + { + "key": "validator", + "value": "cosmosvaloper1ptyzewnns2kn37ewtmv6ppsvhdnmeapvtfc9y5" + }, + { + "key": "amount", + "value": "2203000" + }, + { + "key": "completion_time", + "value": "2020-01-03T20:13:58Z" + } + ] + } + ] + } + ] +} \ No newline at end of file diff --git a/mock/ext-api-data/dash-api_v2_address_XrcbsQdrFYEzbqA9nCJi8zDtnRZzNKkCtG__details_txs.json b/mock/ext-api-data/dash-api_v2_address_XrcbsQdrFYEzbqA9nCJi8zDtnRZzNKkCtG__details_txs.json new file mode 100644 index 000000000..1780f71a1 --- /dev/null +++ b/mock/ext-api-data/dash-api_v2_address_XrcbsQdrFYEzbqA9nCJi8zDtnRZzNKkCtG__details_txs.json @@ -0,0 +1 @@ +{"page":1,"totalPages":73,"itemsOnPage":10,"address":"XrcbsQdrFYEzbqA9nCJi8zDtnRZzNKkCtG","balance":"32621341881","totalReceived":"146027501461","totalSent":"113406159580","unconfirmedBalance":"0","unconfirmedTxs":0,"txs":723,"transactions":[{"txid":"3db4dca70f007a6f9c20216d275a7817081f6ac0054c4080f42ec4a49ff9bd79","version":3,"vin":[{"sequence":4294967295,"n":0,"isAddress":false,"coinbase":"031772131a4d696e656420627920416e74506f6f6c347c002900202864bcf5865e0000ce290000"}],"vout":[{"value":"144313387","n":0,"hex":"76a914aeb4b16eb331e7be66082f1dc132ef245e722d7188ac","addresses":["XrcbsQdrFYEzbqA9nCJi8zDtnRZzNKkCtG"],"isAddress":true},{"value":"144313393","n":1,"hex":"76a91404dfe99f6dda028e4e6a90595096e63787a4a01c88ac","addresses":["Xb8cmjtK67y9T2haqrcDicoAMByDesLcAe"],"isAddress":true}],"blockHash":"0000000000000005db43b81ebbe8022ab3197b6ab4f75ff9fec25025181cb4eb","blockHeight":1274391,"confirmations":147,"blockTime":1590046619,"value":"288626780","valueIn":"0","fees":"0","hex":"03000500010000000000000000000000000000000000000000000000000000000000000000ffffffff27031772131a4d696e656420627920416e74506f6f6c347c002900202864bcf5865e0000ce290000ffffffff022b0c9a08000000001976a914aeb4b16eb331e7be66082f1dc132ef245e722d7188ac310c9a08000000001976a91404dfe99f6dda028e4e6a90595096e63787a4a01c88ac0000000046020017721300b486d6efc4d82a46ef1d7fc6d892b988c55fa758cf48cfb4d359c4a43a30bc46398c15d48d495949a7ed6d7d56f681f7268e59d9091c810f2063773f2d97bb0c"},{"txid":"17cabd36cf9308d70f603c00ed4d29c6d448ee26a27d7bff080df7d516b0629c","version":3,"vin":[{"sequence":4294967295,"n":0,"isAddress":false,"coinbase":"031672131a4d696e656420627920416e74506f6f6c35fd003d00202811e2c39b7a0000af040000"}],"vout":[{"value":"144262270","n":0,"hex":"76a914aeb4b16eb331e7be66082f1dc132ef245e722d7188ac","addresses":["XrcbsQdrFYEzbqA9nCJi8zDtnRZzNKkCtG"],"isAddress":true},{"value":"144262289","n":1,"hex":"76a91404dfe99f6dda028e4e6a90595096e63787a4a01c88ac","addresses":["Xb8cmjtK67y9T2haqrcDicoAMByDesLcAe"],"isAddress":true}],"blockHash":"0000000000000007e165a9ffee645c50b4456718ad39faace1632b9cb378e005","blockHeight":1274390,"confirmations":148,"blockTime":1590046566,"value":"288524559","valueIn":"0","fees":"0","hex":"03000500010000000000000000000000000000000000000000000000000000000000000000ffffffff27031672131a4d696e656420627920416e74506f6f6c35fd003d00202811e2c39b7a0000af040000ffffffff027e449908000000001976a914aeb4b16eb331e7be66082f1dc132ef245e722d7188ac91449908000000001976a91404dfe99f6dda028e4e6a90595096e63787a4a01c88ac0000000046020016721300b486d6efc4d82a46ef1d7fc6d892b988c55fa758cf48cfb4d359c4a43a30bc46398c15d48d495949a7ed6d7d56f681f7268e59d9091c810f2063773f2d97bb0c"},{"txid":"97a2fd473a553493b1ade2f68d013e32b67fdb140efa34c8ac95953bc1988bcf","version":3,"vin":[{"n":0,"isAddress":false,"coinbase":"03067213044524c65e08fabe6d6d000000002f6c6f6f5063746279432f0b00002eb26646e95f000000000000000101000000000000005fe9469e351e00000b2f4379627463506f6f6c2f"}],"vout":[{"value":"144236253","n":0,"hex":"76a914ed148451671949d7353471ee5ef203d424cfbc0a88ac","addresses":["XxJQZFhLtGYz97zH92Zs4QUSF8ej6K6Qwc"],"isAddress":true},{"value":"144236247","n":1,"hex":"76a914aeb4b16eb331e7be66082f1dc132ef245e722d7188ac","addresses":["XrcbsQdrFYEzbqA9nCJi8zDtnRZzNKkCtG"],"isAddress":true}],"blockHash":"000000000000000bea9a32a25b8b36b21d6e20a387a7b5c9189a57539290f8d7","blockHeight":1274374,"confirmations":164,"blockTime":1590043717,"value":"288472500","valueIn":"0","fees":"0","hex":"03000500010000000000000000000000000000000000000000000000000000000000000000ffffffff4a03067213044524c65e08fabe6d6d000000002f6c6f6f5063746279432f0b00002eb26646e95f000000000000000101000000000000005fe9469e351e00000b2f4379627463506f6f6c2f0000000002ddde9808000000001976a914ed148451671949d7353471ee5ef203d424cfbc0a88acd7de9808000000001976a914aeb4b16eb331e7be66082f1dc132ef245e722d7188ac0000000046020006721300b486d6efc4d82a46ef1d7fc6d892b988c55fa758cf48cfb4d359c4a43a30bc466316990da5dbe77116b1dcb017f680b8f7f75f81254a5a7830fc8dd96cf94f89"},{"txid":"b4a0cc5bd09002efb169cc915b962f2362818d82862b384d169252fdb74e6c8e","version":3,"vin":[{"n":0,"isAddress":false,"coinbase":"03e1701304d96ec55e08fabe6d6d000000011d1c1fbf717559b370b05f48978c7cf9bc8f41ea83d251fd2000000001000000000000005fe94eecf74c00000b2f4379627463506f6f6c2f"}],"vout":[{"value":"144236253","n":0,"hex":"76a914ed148451671949d7353471ee5ef203d424cfbc0a88ac","addresses":["XxJQZFhLtGYz97zH92Zs4QUSF8ej6K6Qwc"],"isAddress":true},{"value":"144236247","n":1,"hex":"76a914aeb4b16eb331e7be66082f1dc132ef245e722d7188ac","addresses":["XrcbsQdrFYEzbqA9nCJi8zDtnRZzNKkCtG"],"isAddress":true}],"blockHash":"00000000000000081d7638e9faaccbaa8a11a92381b420e3bd75f1267ad8c33d","blockHeight":1274081,"confirmations":457,"blockTime":1589997273,"value":"288472500","valueIn":"0","fees":"0","hex":"03000500010000000000000000000000000000000000000000000000000000000000000000ffffffff4a03e1701304d96ec55e08fabe6d6d000000011d1c1fbf717559b370b05f48978c7cf9bc8f41ea83d251fd2000000001000000000000005fe94eecf74c00000b2f4379627463506f6f6c2f0000000002ddde9808000000001976a914ed148451671949d7353471ee5ef203d424cfbc0a88acd7de9808000000001976a914aeb4b16eb331e7be66082f1dc132ef245e722d7188ac00000000460200e1701300eb6914c8accb8b7a0d350d0a70fd815d207c11dd2b8949d25cdae2c771b27e23209ee13c7e4ce98664264382e4041e6102dfe7c1441d375e5ae544b86ebcedbd"},{"txid":"4df67627b300f5dbfd59203fb17a7c606db089e77897cec0ec9bc973ab59ecdd","version":3,"vin":[{"sequence":4294967295,"n":0,"isAddress":false,"coinbase":"03a8701304184fc55e01000153aa2b000000000000"}],"vout":[{"value":"144548387","n":0,"hex":"76a914aeb4b16eb331e7be66082f1dc132ef245e722d7188ac","addresses":["XrcbsQdrFYEzbqA9nCJi8zDtnRZzNKkCtG"],"isAddress":true},{"value":"144548393","n":1,"hex":"76a91417158751f496276811c148495b28915314dd9fc088ac","addresses":["XcnuAVsG4pRCqxQmQB6PeTX8FJo2ssYPyB"],"isAddress":true}],"blockHash":"00000000000000114068e5f0b37266e8482d2fb61a2ffae5d4d02aeb8843ddd4","blockHeight":1274024,"confirmations":514,"blockTime":1589989156,"value":"289096780","valueIn":"0","fees":"0","hex":"03000500010000000000000000000000000000000000000000000000000000000000000000ffffffff1503a8701304184fc55e01000153aa2b000000000000ffffffff0223a29d08000000001976a914aeb4b16eb331e7be66082f1dc132ef245e722d7188ac29a29d08000000001976a91417158751f496276811c148495b28915314dd9fc088ac00000000460200a87013007aa39890eaa3d3ad98bcf87390534ef109340e16ce4d2fbed4502d833a703312fa56b0bcd3dabf298ff9fabd00e5a906439b7cdca43e84f9a35fc54e2300b398"},{"txid":"13456921c40297a1e7c22ac32864c8c93f6aa8033ec1a9cdda28769998e427ef","version":3,"vin":[{"n":0,"isAddress":false,"coinbase":"03c66f131b5c4c55584f525c00000000bdf779f74ec2dd6dfc4a387e8f040000"}],"vout":[{"value":"144263769","n":0,"spent":true,"hex":"76a9148bf9a55d3864e49d0bb9f8cc75b6ab3949526ab888ac","addresses":["XoSxpd5VYNQvKbXbEaDKt6P1aZANzAkXrJ"],"isAddress":true},{"value":"144263750","n":1,"hex":"76a914aeb4b16eb331e7be66082f1dc132ef245e722d7188ac","addresses":["XrcbsQdrFYEzbqA9nCJi8zDtnRZzNKkCtG"],"isAddress":true}],"blockHash":"0000000000000011516ab91ba1ecb91b72e59eb4277f53595c91a438624e00a0","blockHeight":1273798,"confirmations":740,"blockTime":1589954367,"value":"288527519","valueIn":"0","fees":"0","hex":"03000500010000000000000000000000000000000000000000000000000000000000000000ffffffff2003c66f131b5c4c55584f525c00000000bdf779f74ec2dd6dfc4a387e8f0400000000000002594a9908000000001976a9148bf9a55d3864e49d0bb9f8cc75b6ab3949526ab888ac464a9908000000001976a914aeb4b16eb331e7be66082f1dc132ef245e722d7188ac00000000460200c66f1300e8af15b313aaac73fe3b9fa249e138f50fee346803e2da15832d76eb851560d64fc1a256ba8f923ccda8a9a717b309208171399e34a5bb11ff16a52eaa5c8410"},{"txid":"18063c38154b6072e09be08293e0f4dc39379ae2c40bc09ee6b73b3bd4844dc5","version":3,"vin":[{"sequence":4294967295,"n":0,"isAddress":false,"coinbase":"03686f131d2f5669614254432f4d696e656420627920747275646f766f737475362f10303c2d0130a1ecf6892c72d6d4040000"}],"vout":[{"value":"144263186","n":0,"spent":true,"hex":"76a914bc89d6071dabc5b4494d303af761a052a5c70d5788ac","addresses":["XssjzLKgsfATYGqTQmiJURQzeKdpL5K1k3"],"isAddress":true},{"value":"144263181","n":1,"hex":"76a914aeb4b16eb331e7be66082f1dc132ef245e722d7188ac","addresses":["XrcbsQdrFYEzbqA9nCJi8zDtnRZzNKkCtG"],"isAddress":true}],"blockHash":"000000000000001f5a78354319984517bad7aba7aff7927e7bad64b2a1bf26f1","blockHeight":1273704,"confirmations":834,"blockTime":1589939700,"value":"288526367","valueIn":"0","fees":"0","hex":"03000500010000000000000000000000000000000000000000000000000000000000000000ffffffff3303686f131d2f5669614254432f4d696e656420627920747275646f766f737475362f10303c2d0130a1ecf6892c72d6d4040000ffffffff0212489908000000001976a914bc89d6071dabc5b4494d303af761a052a5c70d5788ac0d489908000000001976a914aeb4b16eb331e7be66082f1dc132ef245e722d7188ac00000000460200686f130050689b664f559996fc8775aca110b2f0ed9aec7f8fe3aab4f79ec0fc4f8a344dedd7620153e1668282952353c7e2eef6405ef7c82a683d3c7a4f4210a78992c3"},{"txid":"321dbd1768fb763c350d6dd40b1b43f9ac9caea041ff7f12c6002b2cc4fee3b4","version":3,"vin":[{"sequence":4294967295,"n":0,"isAddress":false,"coinbase":"03506f1312b49ba1e25427ee6dc100000000002f4e614e"}],"vout":[{"value":"144250048","n":0,"hex":"76a91408b6841935f55cb830d14ecc863ea93fb969c63c88ac","addresses":["XbUutDsgJbf7Sjjq4omhusNtkT8ih1d7oQ"],"isAddress":true},{"value":"144250030","n":1,"hex":"76a914aeb4b16eb331e7be66082f1dc132ef245e722d7188ac","addresses":["XrcbsQdrFYEzbqA9nCJi8zDtnRZzNKkCtG"],"isAddress":true}],"blockHash":"000000000000000b5e5c93abd129d43f144b86c90b6a3439ec631021267220f7","blockHeight":1273680,"confirmations":858,"blockTime":1589934555,"value":"288500078","valueIn":"0","fees":"0","hex":"03000500010000000000000000000000000000000000000000000000000000000000000000ffffffff1703506f1312b49ba1e25427ee6dc100000000002f4e614effffffff02c0149908000000001976a91408b6841935f55cb830d14ecc863ea93fb969c63c88acae149908000000001976a914aeb4b16eb331e7be66082f1dc132ef245e722d7188ac00000000460200506f1300e8a35551ae71fb9b09ecc86d8d728c832684ea2ad283e2b4d1ed31f6dd4bf11ac1c2e67062c1c299bd250c393058810a298e4ff291a529a5c93c477db90ebd64"},{"txid":"19686bf79281f204a3dc50ec2932a509f271577cecd844f7e27cc821aa433cab","version":3,"vin":[{"sequence":4294967295,"n":0,"isAddress":false,"coinbase":"033e6f131a4d696e656420627920416e74506f6f6c34fd004702207d54c8a01d770000bb0e0000"}],"vout":[{"value":"144444187","n":0,"hex":"76a914aeb4b16eb331e7be66082f1dc132ef245e722d7188ac","addresses":["XrcbsQdrFYEzbqA9nCJi8zDtnRZzNKkCtG"],"isAddress":true},{"value":"144444195","n":1,"hex":"76a91404dfe99f6dda028e4e6a90595096e63787a4a01c88ac","addresses":["Xb8cmjtK67y9T2haqrcDicoAMByDesLcAe"],"isAddress":true}],"blockHash":"000000000000000329e30b38a5fc07526b8f555b9514ae3102dee856e0f15c4a","blockHeight":1273662,"confirmations":876,"blockTime":1589932031,"value":"288888382","valueIn":"0","fees":"0","hex":"03000500010000000000000000000000000000000000000000000000000000000000000000ffffffff27033e6f131a4d696e656420627920416e74506f6f6c34fd004702207d54c8a01d770000bb0e0000ffffffff021b0b9c08000000001976a914aeb4b16eb331e7be66082f1dc132ef245e722d7188ac230b9c08000000001976a91404dfe99f6dda028e4e6a90595096e63787a4a01c88ac000000004602003e6f1300d8198f241d16116008d7b0892570e17f538ccd37a328f192037cc4aedffc1868f827bfb72d03894bf5851a2ccf433500bb2996c3f5b035c5bfe1fff01bbe0857"},{"txid":"c94c9bb63e9f2e9bbd181f1910f17e651822958445ea6cf9885860b1163da6d4","version":3,"vin":[{"n":0,"isAddress":false,"coinbase":"03cd6e1304312bc45e08fabe6d6d6011161d248f19d800136ecc00024600000000ac880c555103d01da67a4825d001000000000000005fe95aa02e1d00000b2f4379627463506f6f6c2f"}],"vout":[{"value":"144236253","n":0,"spent":true,"hex":"76a914ed148451671949d7353471ee5ef203d424cfbc0a88ac","addresses":["XxJQZFhLtGYz97zH92Zs4QUSF8ej6K6Qwc"],"isAddress":true},{"value":"144236247","n":1,"hex":"76a914aeb4b16eb331e7be66082f1dc132ef245e722d7188ac","addresses":["XrcbsQdrFYEzbqA9nCJi8zDtnRZzNKkCtG"],"isAddress":true}],"blockHash":"0000000000000000b904566cb38be8c8fcbb3ed833ac95301f40d8420b835b63","blockHeight":1273549,"confirmations":989,"blockTime":1589914417,"value":"288472500","valueIn":"0","fees":"0","hex":"03000500010000000000000000000000000000000000000000000000000000000000000000ffffffff4a03cd6e1304312bc45e08fabe6d6d6011161d248f19d800136ecc00024600000000ac880c555103d01da67a4825d001000000000000005fe95aa02e1d00000b2f4379627463506f6f6c2f0000000002ddde9808000000001976a914ed148451671949d7353471ee5ef203d424cfbc0a88acd7de9808000000001976a914aeb4b16eb331e7be66082f1dc132ef245e722d7188ac00000000460200cd6e1300d8198f241d16116008d7b0892570e17f538ccd37a328f192037cc4aedffc1868e36ee33703b2b2c01ab2296db5852004d07a8297ee0a2c87ed22ef2367a3eb4b"}]} diff --git a/mock/ext-api-data/dash-api_v2_xpub_xpub6CKAjCUKKPW7bzYEG5mzRsmzyTRp7XzauqFWNmpGVNqMqsSQpLMCN3ygEmD6ZEGVocNDrDhE7SeGot78noEWpwPDbJjfxREHC848sxNrUkD__details_txs.json b/mock/ext-api-data/dash-api_v2_xpub_xpub6CKAjCUKKPW7bzYEG5mzRsmzyTRp7XzauqFWNmpGVNqMqsSQpLMCN3ygEmD6ZEGVocNDrDhE7SeGot78noEWpwPDbJjfxREHC848sxNrUkD__details_txs.json new file mode 100644 index 000000000..cf76f04d8 --- /dev/null +++ b/mock/ext-api-data/dash-api_v2_xpub_xpub6CKAjCUKKPW7bzYEG5mzRsmzyTRp7XzauqFWNmpGVNqMqsSQpLMCN3ygEmD6ZEGVocNDrDhE7SeGot78noEWpwPDbJjfxREHC848sxNrUkD__details_txs.json @@ -0,0 +1 @@ +{"page":1,"totalPages":6,"itemsOnPage":10,"address":"xpub6CKAjCUKKPW7bzYEG5mzRsmzyTRp7XzauqFWNmpGVNqMqsSQpLMCN3ygEmD6ZEGVocNDrDhE7SeGot78noEWpwPDbJjfxREHC848sxNrUkD","balance":"2597761","totalReceived":"27175423","totalSent":"24577662","unconfirmedBalance":"0","unconfirmedTxs":0,"txs":52,"transactions":[{"txid":"2b67e2fbe6a212286243bc539cca3c1d877e85ffec7c925e34f2bfb7b6cc498c","version":1,"vin":[{"txid":"227f1995f5d0b0adcd4f014159710892fa4b66a02ff7ad1e0fc4c1b84ca27cb2","n":0,"addresses":["XyPpEePUKruNEVgdp5jWSakfvoQTnkZxhL"],"isAddress":true,"value":"34508","hex":"483045022100bebce18899214200115fbb2e3b16cd7a6b61cca2cf3e1ffc3b26872f66b714f702203316ce9f1cfb7cef751dbba46015ea76d3c409d6b913b6e434553ebe66680713012103f556051304c43ef031a17615fd8b056c1ac7b0a50926137bf918e72be002f606"}],"vout":[{"value":"10000","n":0,"hex":"76a9149b80787d880fd9f6a822fad78037c9563790a6fa88ac","addresses":["Xps4UHWgH1Ge9HAJijuJMA1i6Ybhq8JNkq"],"isAddress":true},{"value":"18858","n":1,"hex":"76a9149b80787d880fd9f6a822fad78037c9563790a6fa88ac","addresses":["Xps4UHWgH1Ge9HAJijuJMA1i6Ybhq8JNkq"],"isAddress":true}],"blockHash":"000000000000000b3e9287157ae29c1c19bbd1e65660a5bbe723261d0fc57737","blockHeight":1226578,"confirmations":47963,"blockTime":1582509671,"value":"28858","valueIn":"34508","fees":"5650","hex":"0100000001b27ca24cb8c1c40f1eadf72fa0664bfa9208715941014fcdadb0d0f595197f22000000006b483045022100bebce18899214200115fbb2e3b16cd7a6b61cca2cf3e1ffc3b26872f66b714f702203316ce9f1cfb7cef751dbba46015ea76d3c409d6b913b6e434553ebe66680713012103f556051304c43ef031a17615fd8b056c1ac7b0a50926137bf918e72be002f606000000000210270000000000001976a9149b80787d880fd9f6a822fad78037c9563790a6fa88acaa490000000000001976a9149b80787d880fd9f6a822fad78037c9563790a6fa88ac00000000"},{"txid":"dc8e1219da91a24c2eca773a6853d7a0602eed509a4b71afd553f8b4c218b309","version":1,"vin":[{"txid":"501c3c7ecaae272de760e81d284e44644a0475c42e3ee15ae16a125650211c8e","vout":1,"n":0,"addresses":["Xps4UHWgH1Ge9HAJijuJMA1i6Ybhq8JNkq"],"isAddress":true,"value":"768334","hex":"483045022100805ae010fb81b3659f687d1f9da9efa27fa220d34c0f9c54dde4f8e8358e7c2e022003c2c89eb0372616ad50b74f627097e3ccf2ecd940bad616b0bf7caaab58615c01210359d6639a8c603a3ecf0384373935c90a93477668c148929be3b5752fcdf64600"},{"txid":"501c3c7ecaae272de760e81d284e44644a0475c42e3ee15ae16a125650211c8e","n":1,"addresses":["Xps4UHWgH1Ge9HAJijuJMA1i6Ybhq8JNkq"],"isAddress":true,"value":"809686","hex":"483045022100ff644abb86e4272384e64de00d7ac2b1ed01e6848f59707f1bd93913b0f2ceeb02205ba0be94a02a2af3d7178977d828dda4268da4f83c00d2af1331e4274a5454a201210359d6639a8c603a3ecf0384373935c90a93477668c148929be3b5752fcdf64600"}],"vout":[{"value":"1000000","n":0,"hex":"76a9149b80787d880fd9f6a822fad78037c9563790a6fa88ac","addresses":["Xps4UHWgH1Ge9HAJijuJMA1i6Ybhq8JNkq"],"isAddress":true},{"value":"576150","n":1,"hex":"76a9149b80787d880fd9f6a822fad78037c9563790a6fa88ac","addresses":["Xps4UHWgH1Ge9HAJijuJMA1i6Ybhq8JNkq"],"isAddress":true}],"blockHash":"000000000000000f727266a1a157af489fec0a009938dadeca89bc3edd1bc017","blockHeight":1215128,"confirmations":59413,"blockTime":1580704472,"value":"1576150","valueIn":"1578020","fees":"1870","hex":"01000000028e1c215056126ae15ae13e2ec475044a64444e281de860e72d27aeca7e3c1c50010000006b483045022100805ae010fb81b3659f687d1f9da9efa27fa220d34c0f9c54dde4f8e8358e7c2e022003c2c89eb0372616ad50b74f627097e3ccf2ecd940bad616b0bf7caaab58615c01210359d6639a8c603a3ecf0384373935c90a93477668c148929be3b5752fcdf64600000000008e1c215056126ae15ae13e2ec475044a64444e281de860e72d27aeca7e3c1c50000000006b483045022100ff644abb86e4272384e64de00d7ac2b1ed01e6848f59707f1bd93913b0f2ceeb02205ba0be94a02a2af3d7178977d828dda4268da4f83c00d2af1331e4274a5454a201210359d6639a8c603a3ecf0384373935c90a93477668c148929be3b5752fcdf64600000000000240420f00000000001976a9149b80787d880fd9f6a822fad78037c9563790a6fa88ac96ca0800000000001976a9149b80787d880fd9f6a822fad78037c9563790a6fa88ac00000000"},{"txid":"6696dd6c84e58023ecfd5418c9b729e35d2a87235dd0c260f2195ed1810a50d0","version":1,"vin":[{"txid":"31bb6217e1fec3f0041e15e8e8878bbbe1169520ac42fc08a2bb3718946ee309","n":0,"addresses":["XdSr6KFsDGmUpKuG5jWzjZWCbhCtUeT9TZ"],"isAddress":true,"value":"1000000","hex":"473044022010420f86db6de28f66abc96fb474f602f5d90700297555a638851403e70f385102201bb76e34df895edfbb2188b0d293eddbd0434847bedebd21949f5bd42f5048e001210282c2c88e60a8aa55be2c3ff46975e2f79d8d208751b59d4943a59d0a002d5ad0"},{"txid":"f7bc5be43c4dd9c5a23dc88ba5ba823f5109c16a15d69a4fee668311facb72b0","vout":1,"n":1,"addresses":["XqRxi4Y91n6P24eAfymkwckaHE2463Mvxf"],"isAddress":true,"value":"1014267","hex":"47304402204b85b8549fcd6f028d620d4855b03fd900f4a2a70515c7a8d27164b5d3955afd02204569a163bec5e3ee693de7ea11ea7ae611ac8cd7de492c88d328a177f8e5ebba01210276c23ac6a5245e706be703db4d317ecf4b7f341e6a5b9f72a5b364b3dd8746c9"}],"vout":[{"value":"1609050","n":0,"spent":true,"hex":"76a9143f9f7dbf8c17f6c5d96ed20ca8ac3c65f97b898b88ac","addresses":["XgVFTyuPdzk4VpUTYDt5Hyc7WSDRFUczPg"],"isAddress":true},{"value":"403347","n":1,"hex":"76a9149b80787d880fd9f6a822fad78037c9563790a6fa88ac","addresses":["Xps4UHWgH1Ge9HAJijuJMA1i6Ybhq8JNkq"],"isAddress":true}],"blockHash":"00000000000000170e5fa8aa5da53048e697284b8c2c7c540db6b97136d0aedd","blockHeight":1213079,"confirmations":61462,"blockTime":1580381547,"value":"2012397","valueIn":"2014267","fees":"1870","hex":"010000000209e36e941837bba208fc42ac209516e1bb8b87e8e8151e04f0c3fee11762bb31000000006a473044022010420f86db6de28f66abc96fb474f602f5d90700297555a638851403e70f385102201bb76e34df895edfbb2188b0d293eddbd0434847bedebd21949f5bd42f5048e001210282c2c88e60a8aa55be2c3ff46975e2f79d8d208751b59d4943a59d0a002d5ad000000000b072cbfa118366ee4f9ad6156ac109513f82baa58bc83da2c5d94d3ce45bbcf7010000006a47304402204b85b8549fcd6f028d620d4855b03fd900f4a2a70515c7a8d27164b5d3955afd02204569a163bec5e3ee693de7ea11ea7ae611ac8cd7de492c88d328a177f8e5ebba01210276c23ac6a5245e706be703db4d317ecf4b7f341e6a5b9f72a5b364b3dd8746c900000000025a8d1800000000001976a9143f9f7dbf8c17f6c5d96ed20ca8ac3c65f97b898b88ac93270600000000001976a9149b80787d880fd9f6a822fad78037c9563790a6fa88ac00000000"},{"txid":"501c3c7ecaae272de760e81d284e44644a0475c42e3ee15ae16a125650211c8e","version":1,"vin":[{"txid":"d89f83e41cff574070841fb502e69be155ac38d3537047ab61ef597b0eeb9eb3","vout":1,"n":0,"addresses":["Xmt4GmF2Z8sSFtr4zQweZmwHXoEWAEjQjS"],"isAddress":true,"value":"1579150","hex":"473044022022fa02151b5a09be882b93fa1771f1fc9d2e1f3059d548f8afa7fa91d5474e5502200c9dc39c310103b4bcddf88cda6acac4151fd6164be63dff95baf63b306eb9710121022ceba3e32535678aa740a9ea4d333dcaf3cae9e5132586c149938a5d609dc837"}],"vout":[{"value":"809686","n":0,"spent":true,"hex":"76a9149b80787d880fd9f6a822fad78037c9563790a6fa88ac","addresses":["Xps4UHWgH1Ge9HAJijuJMA1i6Ybhq8JNkq"],"isAddress":true},{"value":"768334","n":1,"spent":true,"hex":"76a9149b80787d880fd9f6a822fad78037c9563790a6fa88ac","addresses":["Xps4UHWgH1Ge9HAJijuJMA1i6Ybhq8JNkq"],"isAddress":true}],"blockHash":"000000000000000f17a7d21440dc0980abac9f64a55d652a9e945a080b72c253","blockHeight":1213076,"confirmations":61465,"blockTime":1580381293,"value":"1578020","valueIn":"1579150","fees":"1130","hex":"0100000001b39eeb0e7b59ef61ab477053d338ac55e19be602b51f84704057ff1ce4839fd8010000006a473044022022fa02151b5a09be882b93fa1771f1fc9d2e1f3059d548f8afa7fa91d5474e5502200c9dc39c310103b4bcddf88cda6acac4151fd6164be63dff95baf63b306eb9710121022ceba3e32535678aa740a9ea4d333dcaf3cae9e5132586c149938a5d609dc8370000000002d65a0c00000000001976a9149b80787d880fd9f6a822fad78037c9563790a6fa88ac4eb90b00000000001976a9149b80787d880fd9f6a822fad78037c9563790a6fa88ac00000000"},{"txid":"c13e0718fdafa2a79153748092f978e63dfc8fd41b28bea23427e1d7c976c25b","version":1,"vin":[{"txid":"31bb6217e1fec3f0041e15e8e8878bbbe1169520ac42fc08a2bb3718946ee309","vout":1,"n":0,"addresses":["XgQ6GjrRACaU1ci8BGtALqwd3p7Z1W6m7p"],"isAddress":true,"value":"578870","hex":"483045022100b3683d1170e2e2395a7a35e5b0d0a674ff7b4e1660999893ae60d7e6bc841cbb022027e345eb9776b160260129f33ce6a404268f763d986cefb614573cdc12e7509201210372d1d3eb2c31f49510220dc2aaf32c6a363ed00827734d3713f7e72c8776def8"}],"vout":[{"value":"43000","n":0,"spent":true,"hex":"76a9144ad11db3087da53b67f56e87e9a53ecd89dde09b88ac","addresses":["XhWSM5qaV2dnuHPGzpogBGkhTBPMPjDXaG"],"isAddress":true},{"value":"534740","n":1,"hex":"76a9149b80787d880fd9f6a822fad78037c9563790a6fa88ac","addresses":["Xps4UHWgH1Ge9HAJijuJMA1i6Ybhq8JNkq"],"isAddress":true}],"blockHash":"00000000000000049439d5c7528b34e01643695735ef9db11696382f7c08f75a","blockHeight":1211620,"confirmations":62921,"blockTime":1580151375,"value":"577740","valueIn":"578870","fees":"1130","hex":"010000000109e36e941837bba208fc42ac209516e1bb8b87e8e8151e04f0c3fee11762bb31010000006b483045022100b3683d1170e2e2395a7a35e5b0d0a674ff7b4e1660999893ae60d7e6bc841cbb022027e345eb9776b160260129f33ce6a404268f763d986cefb614573cdc12e7509201210372d1d3eb2c31f49510220dc2aaf32c6a363ed00827734d3713f7e72c8776def80000000002f8a70000000000001976a9144ad11db3087da53b67f56e87e9a53ecd89dde09b88acd4280800000000001976a9149b80787d880fd9f6a822fad78037c9563790a6fa88ac00000000"},{"txid":"31bb6217e1fec3f0041e15e8e8878bbbe1169520ac42fc08a2bb3718946ee309","version":1,"vin":[{"txid":"d89f83e41cff574070841fb502e69be155ac38d3537047ab61ef597b0eeb9eb3","n":0,"addresses":["Xjt3PDPSWXNet3o52JTwgr656mtygDZead"],"isAddress":true,"value":"1580000","hex":"4830450221009b25b8c7f8e188d7c4f1afd98519493e4f68150c1ef674d962191b142aac60df02204c04a7552183e5a19e3e8f3b1b837bee389a30fb72c1ee2704490c204c1d156301210267be33f661018e638b648038b2d5dc6e6920ca9ff71451047e7c66294bedbbbf"}],"vout":[{"value":"1000000","n":0,"spent":true,"hex":"76a9141e42c54a5e1b5d9b18027ba2d97143a87e5c32bb88ac","addresses":["XdSr6KFsDGmUpKuG5jWzjZWCbhCtUeT9TZ"],"isAddress":true},{"value":"578870","n":1,"spent":true,"hex":"76a9143ea5bc9cfe132f64cb0c141d1ea86223666f9c1888ac","addresses":["XgQ6GjrRACaU1ci8BGtALqwd3p7Z1W6m7p"],"isAddress":true}],"blockHash":"000000000000000eb3032ddc1a92f3058dc04d315cedb022c4a30b6ba30ae60a","blockHeight":1207821,"confirmations":66720,"blockTime":1579553025,"value":"1578870","valueIn":"1580000","fees":"1130","hex":"0100000001b39eeb0e7b59ef61ab477053d338ac55e19be602b51f84704057ff1ce4839fd8000000006b4830450221009b25b8c7f8e188d7c4f1afd98519493e4f68150c1ef674d962191b142aac60df02204c04a7552183e5a19e3e8f3b1b837bee389a30fb72c1ee2704490c204c1d156301210267be33f661018e638b648038b2d5dc6e6920ca9ff71451047e7c66294bedbbbf000000000240420f00000000001976a9141e42c54a5e1b5d9b18027ba2d97143a87e5c32bb88ac36d50800000000001976a9143ea5bc9cfe132f64cb0c141d1ea86223666f9c1888ac00000000"},{"txid":"227f1995f5d0b0adcd4f014159710892fa4b66a02ff7ad1e0fc4c1b84ca27cb2","version":1,"vin":[{"txid":"f7bc5be43c4dd9c5a23dc88ba5ba823f5109c16a15d69a4fee668311facb72b0","n":0,"addresses":["Xe4pb7964mDz3j6T8qME8oNPn4Qq7rvfLx"],"isAddress":true,"value":"34700","hex":"47304402205525a79b5e00f718c7de2543de0192e8fed59d1e566383e54dfda688295b773602200c962fe59cfc860191a6d721b3dfe76b01d0a282f109c86d1d3e3991d32da5a6012103015b8c707ded30b2750ac31665335c7ff60db8d18ede940cb70070267bf88617"}],"vout":[{"value":"34508","n":0,"spent":true,"hex":"76a914f9127d23bd2b473d5a9fa45a6b8b27c18cbeab6e88ac","addresses":["XyPpEePUKruNEVgdp5jWSakfvoQTnkZxhL"],"isAddress":true}],"blockHash":"000000000000000e84ed0e94fa47767d5be5c421a239079449fd7899a5ce5578","blockHeight":1166949,"confirmations":107592,"blockTime":1573112576,"value":"34508","valueIn":"34700","fees":"192","hex":"0100000001b072cbfa118366ee4f9ad6156ac109513f82baa58bc83da2c5d94d3ce45bbcf7000000006a47304402205525a79b5e00f718c7de2543de0192e8fed59d1e566383e54dfda688295b773602200c962fe59cfc860191a6d721b3dfe76b01d0a282f109c86d1d3e3991d32da5a6012103015b8c707ded30b2750ac31665335c7ff60db8d18ede940cb70070267bf886170000000001cc860000000000001976a914f9127d23bd2b473d5a9fa45a6b8b27c18cbeab6e88ac00000000"},{"txid":"9547b79e41fb869994b839fcd8b8c5ea580aaabc6711146d389b09e6cf624f06","version":1,"vin":[{"txid":"78481c5218b6c6d3cc4d07e0c6e52082a8d235596394ea794782de4ed80abbcb","sequence":4294967291,"n":0,"addresses":["Xki96Js2mRv6rC63UokDVbRmE7RDc7ULPp"],"isAddress":true,"value":"44892","hex":"4830450221008dbdd31911231aad03aef6eded9230a55607405b0dc77977e43c2ec339f8a8e002201b62bb327dc725263de1e75931cd6642f49d98d49a6e0424587ea478343eab680121020440f808adf979ca45adf2db3c91701c378e99f9770f84102c0b16eed8a0e81e"}],"vout":[{"value":"10000","n":0,"hex":"76a91474ec52b284baa7bc0a5c554726f1e2b717e24c3b88ac","addresses":["XmM5KX1Zpepji5V6RF7iypCkXBi4hSronS"],"isAddress":true},{"value":"34666","n":1,"hex":"76a91412084b5792de33e02d99c555a956ccd32586838488ac","addresses":["XcLBw1EUz5HPDJ5pZrSbeyXYBWcVCabZ56"],"isAddress":true}],"blockHash":"0000000000000005f32905ffe9cb77f22e372256f6d2657124f8bafd36fbc8c0","blockHeight":1166519,"confirmations":108022,"blockTime":1573044962,"value":"44666","valueIn":"44892","fees":"226","hex":"0100000001cbbb0ad84ede824779ea94635935d2a88220e5c6e0074dccd3c6b618521c4878000000006b4830450221008dbdd31911231aad03aef6eded9230a55607405b0dc77977e43c2ec339f8a8e002201b62bb327dc725263de1e75931cd6642f49d98d49a6e0424587ea478343eab680121020440f808adf979ca45adf2db3c91701c378e99f9770f84102c0b16eed8a0e81efbffffff0210270000000000001976a91474ec52b284baa7bc0a5c554726f1e2b717e24c3b88ac6a870000000000001976a91412084b5792de33e02d99c555a956ccd32586838488ac00000000"},{"txid":"f7bc5be43c4dd9c5a23dc88ba5ba823f5109c16a15d69a4fee668311facb72b0","version":1,"vin":[{"txid":"78481c5218b6c6d3cc4d07e0c6e52082a8d235596394ea794782de4ed80abbcb","vout":1,"n":0,"addresses":["XeFnGkttzWebuQvPRQMsCZx8irRqZh9bXB"],"isAddress":true,"value":"1274967","hex":"47304402202666f9d9294ee1baa863722543400ed9286e771462212e7fd9252ecb55dc160102202983aab7fbcd63103350be226fc2c0a1fe8aa8a197bd20634976f10a5b5fef49012103a67eb8083b43cd54ac56a5c5361825e0e4681984b6ea2300b398fb736f279cc8"}],"vout":[{"value":"34700","n":0,"spent":true,"hex":"76a91425107d7a41d6e6167a19873ace2a977eabaf058688ac","addresses":["Xe4pb7964mDz3j6T8qME8oNPn4Qq7rvfLx"],"isAddress":true},{"value":"1014267","n":1,"spent":true,"hex":"76a914a1b9631afa751aa45b0af6b873e44a0461e84b5d88ac","addresses":["XqRxi4Y91n6P24eAfymkwckaHE2463Mvxf"],"isAddress":true}],"blockHash":"000000000000002522f2157367c56683a7a26dea3e6be7bca4fcef8ee068eb7b","blockHeight":1140065,"confirmations":134476,"blockTime":1568874528,"value":"1048967","valueIn":"1274967","fees":"226000","hex":"0100000001cbbb0ad84ede824779ea94635935d2a88220e5c6e0074dccd3c6b618521c4878010000006a47304402202666f9d9294ee1baa863722543400ed9286e771462212e7fd9252ecb55dc160102202983aab7fbcd63103350be226fc2c0a1fe8aa8a197bd20634976f10a5b5fef49012103a67eb8083b43cd54ac56a5c5361825e0e4681984b6ea2300b398fb736f279cc800000000028c870000000000001976a91425107d7a41d6e6167a19873ace2a977eabaf058688acfb790f00000000001976a914a1b9631afa751aa45b0af6b873e44a0461e84b5d88ac00000000"},{"txid":"78481c5218b6c6d3cc4d07e0c6e52082a8d235596394ea794782de4ed80abbcb","version":1,"vin":[{"txid":"93aa38b6e55c08f0dcb1423626e226a459baa68c3246c93bd5b08c131a180cb8","sequence":4294967291,"n":0,"addresses":["XkbgwRmm1SKoKgBp3QAbqY3fvRA1DJfEij"],"isAddress":true,"value":"1320085","hex":"473044022033ce7e907f87dd5d6c6faea76688e0ea9367e71cfda58d1205d4adad13250f0a022072aaf56cdc36b9adb91819f34733ad1d1b74518befd26e0cd77691169831989001210343355be8a2bac33d30e878996016603717931287764d277876960416558fbcc9"}],"vout":[{"value":"44892","n":0,"spent":true,"hex":"76a9146df014d476d6e737f8e70e1123859e94e297062a88ac","addresses":["Xki96Js2mRv6rC63UokDVbRmE7RDc7ULPp"],"isAddress":true},{"value":"1274967","n":1,"spent":true,"hex":"76a914272321d2e254c762b38dcffd027e5f5b84b3798088ac","addresses":["XeFnGkttzWebuQvPRQMsCZx8irRqZh9bXB"],"isAddress":true}],"blockHash":"0000000000000018a47bfd48e74bed20fe83298904e5a52971f4e8ad9d51d727","blockHeight":1136578,"confirmations":137963,"blockTime":1568325650,"value":"1319859","valueIn":"1320085","fees":"226","hex":"0100000001b80c181a138cb0d53bc946328ca6ba59a426e2263642b1dcf0085ce5b638aa93000000006a473044022033ce7e907f87dd5d6c6faea76688e0ea9367e71cfda58d1205d4adad13250f0a022072aaf56cdc36b9adb91819f34733ad1d1b74518befd26e0cd77691169831989001210343355be8a2bac33d30e878996016603717931287764d277876960416558fbcc9fbffffff025caf0000000000001976a9146df014d476d6e737f8e70e1123859e94e297062a88ac57741300000000001976a914272321d2e254c762b38dcffd027e5f5b84b3798088ac00000000"}],"usedTokens":47,"tokens":[{"type":"XPUBAddress","name":"Xps4UHWgH1Ge9HAJijuJMA1i6Ybhq8JNkq","path":"m/44'/5'/0'/0/0","transfers":13,"decimals":8,"balance":"2543095","totalReceived":"4275043","totalSent":"1731948"},{"type":"XPUBAddress","name":"XezMSYZ3ucD2tNGVME1j3A8tM5q3NvigKu","path":"m/44'/5'/0'/0/15","transfers":1,"decimals":8,"balance":"10000","totalReceived":"10000","totalSent":"0"},{"type":"XPUBAddress","name":"XmM5KX1Zpepji5V6RF7iypCkXBi4hSronS","path":"m/44'/5'/0'/0/18","transfers":1,"decimals":8,"balance":"10000","totalReceived":"10000","totalSent":"0"},{"type":"XPUBAddress","name":"XcLBw1EUz5HPDJ5pZrSbeyXYBWcVCabZ56","path":"m/44'/5'/0'/1/24","transfers":1,"decimals":8,"balance":"34666","totalReceived":"34666","totalSent":"0"}]} diff --git a/mock/ext-api-data/decred-api_v2_address_DsTxPUVFxXeNgu5fzozr4mTR4tqqMaKcvpY__details_txs.json b/mock/ext-api-data/decred-api_v2_address_DsTxPUVFxXeNgu5fzozr4mTR4tqqMaKcvpY__details_txs.json new file mode 100644 index 000000000..957dc2412 --- /dev/null +++ b/mock/ext-api-data/decred-api_v2_address_DsTxPUVFxXeNgu5fzozr4mTR4tqqMaKcvpY__details_txs.json @@ -0,0 +1,523 @@ +{ + "page": 1, + "totalPages": 1, + "itemsOnPage": 1000, + "address": "DsTxPUVFxXeNgu5fzozr4mTR4tqqMaKcvpY", + "balance": "19370607", + "totalReceived": "75347145", + "totalSent": "55976538", + "unconfirmedBalance": "0", + "unconfirmedTxs": 0, + "txs": 11, + "transactions": [ + { + "txid": "22009e6feb0ecbd29004f8a5273163da53c112d93ec5f9dbff46bc41a30f90f0", + "version": 1, + "vin": [ + { + "txid": "66e3d1622d4cb3337babf5e5a466f94b6a732e132c802cc219c6e26543d736e0", + "vout": 1, + "sequence": 4294967283, + "n": 0, + "addresses": [ + "DsTxPUVFxXeNgu5fzozr4mTR4tqqMaKcvpY" + ], + "isAddress": true, + "value": "489415", + "hex": "483045022100b67f278e9552abddde008a4d91e5c1044d8cf01248378f6b4ed94514b23dbf5e022025c96ea8974f40833287f91f5d7a2a672654950993322ec91b32caf45a9d9fc90121039b24b2073eef4835f226bb98ec9cb28b1cd0550c76077d3865a77870f119c344" + } + ], + "vout": [ + { + "value": "100000", + "n": 0, + "hex": "76a914f3fa335c33379fabe6d61c5491504d8d1ad6851c88ac", + "addresses": [ + "DsoCwRHkCHpR1Jvk9GnCT2M8hVgVjfyYAKE" + ], + "isAddress": true + }, + { + "value": "386875", + "n": 1, + "hex": "76a91420cf523034c462f8e09fc0fd35c47760b822398888ac", + "addresses": [ + "DsTxPUVFxXeNgu5fzozr4mTR4tqqMaKcvpY" + ], + "isAddress": true + } + ], + "blockHash": "00000000000000000d08b3d88676bc81defa76eeb6f1322dd68bca50f34a9e8b", + "blockHeight": 447041, + "confirmations": 2034, + "blockTime": 1588752334, + "value": "486875", + "valueIn": "489415", + "fees": "2540", + "hex": "0100000001e036d74365e2c619c22c802c132e736a4bf966a4e5f5ab7b33b34c2d62d1e3660100000000f3ffffff02a08601000000000000001976a914f3fa335c33379fabe6d61c5491504d8d1ad6851c88ac3be705000000000000001976a91420cf523034c462f8e09fc0fd35c47760b822398888ac000000000000000001c777070000000000298e0600030000006b483045022100b67f278e9552abddde008a4d91e5c1044d8cf01248378f6b4ed94514b23dbf5e022025c96ea8974f40833287f91f5d7a2a672654950993322ec91b32caf45a9d9fc90121039b24b2073eef4835f226bb98ec9cb28b1cd0550c76077d3865a77870f119c344" + }, + { + "txid": "66e3d1622d4cb3337babf5e5a466f94b6a732e132c802cc219c6e26543d736e0", + "version": 1, + "vin": [ + { + "txid": "2dc905f525885537310c8ab87f67dc175ca369af1fe7111a49a94451866aa019", + "sequence": 4294967291, + "n": 0, + "addresses": [ + "Dsjr1AbSRiZaN9PkCGaNyjfAVkbcPLozafq" + ], + "isAddress": true, + "value": "591955", + "hex": "473044022045cb71f2c6c446a69cdf77cc7beedf6f4616091a7fc4843ef74757475f5a95c402203609e095561a11e0ac32f51de870a597b39dce4596b5b253842c838b7c4c9953012102eefcb948122fad71682df1ed8c59a9852afeffea086650e3a86e8a1214c0a94f" + } + ], + "vout": [ + { + "value": "100000", + "n": 0, + "hex": "76a91420cf523034c462f8e09fc0fd35c47760b822398888ac", + "addresses": [ + "DsTxPUVFxXeNgu5fzozr4mTR4tqqMaKcvpY" + ], + "isAddress": true + }, + { + "value": "489415", + "n": 1, + "spent": true, + "hex": "76a91420cf523034c462f8e09fc0fd35c47760b822398888ac", + "addresses": [ + "DsTxPUVFxXeNgu5fzozr4mTR4tqqMaKcvpY" + ], + "isAddress": true + } + ], + "blockHash": "00000000000000000c12cb497e60470a3cf366d16705eaba303c2c4415cc7567", + "blockHeight": 429609, + "confirmations": 19466, + "blockTime": 1583516573, + "value": "589415", + "valueIn": "591955", + "fees": "2540", + "hex": "010000000119a06a865144a9491a11e71faf69a35c17dc677fb88a0c3137558825f505c92d0000000000fbffffff02a08601000000000000001976a91420cf523034c462f8e09fc0fd35c47760b822398888acc77707000000000000001976a91420cf523034c462f8e09fc0fd35c47760b822398888ac0000000000000000015308090000000000dbcc05000b0000006a473044022045cb71f2c6c446a69cdf77cc7beedf6f4616091a7fc4843ef74757475f5a95c402203609e095561a11e0ac32f51de870a597b39dce4596b5b253842c838b7c4c9953012102eefcb948122fad71682df1ed8c59a9852afeffea086650e3a86e8a1214c0a94f" + }, + { + "txid": "025abf340da79c4fc4de29667c08fc22cdafbded24c7c2a994a27f6fb4d5fa17", + "version": 1, + "vin": [ + { + "txid": "5a2a0d01ed8672d6bebd7dee447b2e0342bfc34fd4893bed58a4fa5aa87a4c42", + "n": 0, + "addresses": [ + "Dsf6WkLoiTcSGKmkXoSEdukqUfeRJMqUNJV" + ], + "isAddress": true, + "value": "19991980", + "hex": "483045022100dd6997eab2e2bed5b275af4f2511a62b90da430ecb67f960afe4e06ebf8f362b022017e62873f5bd86abe725ef8fa75d506235ef174e18a06305b889d207ca6194e70121039603af712bd8410ada5a3b6c99d536b2e91dfaf4aa27e488b118cf6a9920e769" + } + ], + "vout": [ + { + "value": "100000", + "n": 0, + "hex": "76a91420cf523034c462f8e09fc0fd35c47760b822398888ac", + "addresses": [ + "DsTxPUVFxXeNgu5fzozr4mTR4tqqMaKcvpY" + ], + "isAddress": true + }, + { + "value": "19889440", + "n": 1, + "hex": "76a914989b1aecabf1c24e213cc0f2d8a22ffee25dd4e188ac", + "addresses": [ + "Dsesp1V6DZDEtcq2behmBVKdYqKMdkh96hL" + ], + "isAddress": true + } + ], + "blockHash": "0000000000000000264c499f21a7ef95bffb37148fc099514b2407dfa28c3287", + "blockHeight": 429186, + "confirmations": 19889, + "blockTime": 1583384838, + "value": "19989440", + "valueIn": "19991980", + "fees": "2540", + "hex": "0100000001424c7aa85afaa458ed3b89d44fc3bf42032e7b44ee7dbdbed67286ed010d2a5a00000000000000000002a08601000000000000001976a91420cf523034c462f8e09fc0fd35c47760b822398888ac207d2f010000000000001976a914989b1aecabf1c24e213cc0f2d8a22ffee25dd4e188ac000000000000000001ac0d31010000000052630600050000006b483045022100dd6997eab2e2bed5b275af4f2511a62b90da430ecb67f960afe4e06ebf8f362b022017e62873f5bd86abe725ef8fa75d506235ef174e18a06305b889d207ca6194e70121039603af712bd8410ada5a3b6c99d536b2e91dfaf4aa27e488b118cf6a9920e769" + }, + { + "txid": "68dcb93e36879f33e741f5706463af10387aadeba193cb204453ec23ad1b1979", + "version": 1, + "vin": [ + { + "txid": "d1352a165c773fe22556219916c2dbd3e184cbf29d9be88b4d52b1c321131601", + "vout": 1, + "sequence": 4294967291, + "n": 0, + "addresses": [ + "DseafVVZGqk4VMCiEJoxRS6FkUjxofh2PXA" + ], + "isAddress": true, + "value": "150582", + "hex": "473044022028e6a72865dfb231b6a64cb3bacc5421dde842c57a169d13b753c36e96cacd9f022049e381c5e8a7e82d96b8996898c43baebbb1e5e5e9f51c15beb17e29e784c257012102fed4dd58683487545cc89c1fd779bf70b46067b863921b0e0c1b09bbe56d4345" + } + ], + "vout": [ + { + "value": "100000", + "n": 0, + "hex": "76a91420cf523034c462f8e09fc0fd35c47760b822398888ac", + "addresses": [ + "DsTxPUVFxXeNgu5fzozr4mTR4tqqMaKcvpY" + ], + "isAddress": true + }, + { + "value": "48042", + "n": 1, + "hex": "76a91420cf523034c462f8e09fc0fd35c47760b822398888ac", + "addresses": [ + "DsTxPUVFxXeNgu5fzozr4mTR4tqqMaKcvpY" + ], + "isAddress": true + } + ], + "blockHash": "0000000000000000025750e22134a74a8a5389c716b51dc4757bf213c7dfbb70", + "blockHeight": 427612, + "confirmations": 21463, + "blockTime": 1582902615, + "value": "148042", + "valueIn": "150582", + "fees": "2540", + "hex": "010000000101161321c3b1524d8be89b9df2cb84e1d3dbc21699215625e23f775c162a35d10100000000fbffffff02a08601000000000000001976a91420cf523034c462f8e09fc0fd35c47760b822398888acaabb00000000000000001976a91420cf523034c462f8e09fc0fd35c47760b822398888ac000000000000000001364c020000000000f4c80500070000006a473044022028e6a72865dfb231b6a64cb3bacc5421dde842c57a169d13b753c36e96cacd9f022049e381c5e8a7e82d96b8996898c43baebbb1e5e5e9f51c15beb17e29e784c257012102fed4dd58683487545cc89c1fd779bf70b46067b863921b0e0c1b09bbe56d4345" + }, + { + "txid": "70a5caffaac9105b47ff9b70213f3a9f8bbd28f09335dce763a99f1b39e74ccf", + "version": 1, + "vin": [ + { + "txid": "2c922ec02ec0bc86803290191198232183e903ea2e79f7f6ddb6c7c7c193b9db", + "vout": 1, + "sequence": 4294967287, + "n": 0, + "addresses": [ + "DsTxPUVFxXeNgu5fzozr4mTR4tqqMaKcvpY" + ], + "isAddress": true, + "value": "5292552", + "hex": "483045022100bc0999a9673f4f72b2bd79fd40c1b8a8398381edcc584f6ed868229e2ec5628b02205baab2c3b1cefdb41dc439782310931f15b31fd48544ca70f88c94940a3870800121039b24b2073eef4835f226bb98ec9cb28b1cd0550c76077d3865a77870f119c344" + } + ], + "vout": [ + { + "value": "1000000", + "n": 0, + "hex": "76a91420cf523034c462f8e09fc0fd35c47760b822398888ac", + "addresses": [ + "DsTxPUVFxXeNgu5fzozr4mTR4tqqMaKcvpY" + ], + "isAddress": true + }, + { + "value": "4290012", + "n": 1, + "hex": "76a91420cf523034c462f8e09fc0fd35c47760b822398888ac", + "addresses": [ + "DsTxPUVFxXeNgu5fzozr4mTR4tqqMaKcvpY" + ], + "isAddress": true + } + ], + "blockHash": "00000000000000001c196ac1e8e050a3d7bc600bcb87826dca4ff558ac280014", + "blockHeight": 427609, + "confirmations": 21466, + "blockTime": 1582901951, + "value": "5290012", + "valueIn": "5292552", + "fees": "2540", + "hex": "0100000001dbb993c1c7c7b6ddf6f7792eea03e983212398111990328086bcc02ec02e922c0100000000f7ffffff0240420f000000000000001976a91420cf523034c462f8e09fc0fd35c47760b822398888acdc7541000000000000001976a91420cf523034c462f8e09fc0fd35c47760b822398888ac00000000000000000108c2500000000000bc5d0600020000006b483045022100bc0999a9673f4f72b2bd79fd40c1b8a8398381edcc584f6ed868229e2ec5628b02205baab2c3b1cefdb41dc439782310931f15b31fd48544ca70f88c94940a3870800121039b24b2073eef4835f226bb98ec9cb28b1cd0550c76077d3865a77870f119c344" + }, + { + "txid": "2c922ec02ec0bc86803290191198232183e903ea2e79f7f6ddb6c7c7c193b9db", + "version": 1, + "vin": [ + { + "txid": "a81ab3f0d0744c42fcc8e5c3b0b77382323d0cf6ac73a55f982dcadc4fe604c7", + "vout": 1, + "n": 0, + "addresses": [ + "DseSHdQv3cZhuY3foizi3bbHHMw2o7RsNsu" + ], + "isAddress": true, + "value": "6295092", + "hex": "47304402206d190e10475b3dc57a9ec4aff060f1d9ee82e47b99d1f9cb2e926384ccdc04df022056040c8b364176c28876b597006faba7b0f1f74abcf0321e530520907b8ded8001210385ece82907d214f46db634a6326d99616ea022ec887991251215d1564120ac41" + } + ], + "vout": [ + { + "value": "1000000", + "n": 0, + "hex": "76a91420cf523034c462f8e09fc0fd35c47760b822398888ac", + "addresses": [ + "DsTxPUVFxXeNgu5fzozr4mTR4tqqMaKcvpY" + ], + "isAddress": true + }, + { + "value": "5292552", + "n": 1, + "spent": true, + "hex": "76a91420cf523034c462f8e09fc0fd35c47760b822398888ac", + "addresses": [ + "DsTxPUVFxXeNgu5fzozr4mTR4tqqMaKcvpY" + ], + "isAddress": true + } + ], + "blockHash": "0000000000000000008e3020d59db97a9e69b7b77697369cee0cd600a3e3c106", + "blockHeight": 417211, + "confirmations": 31864, + "blockTime": 1579769314, + "value": "6292552", + "valueIn": "6295092", + "fees": "2540", + "hex": "0100000001c704e64fdcca2d985fa573acf60c3d328273b7b0c3e5c8fc424c74d0f0b31aa80100000000000000000240420f000000000000001976a91420cf523034c462f8e09fc0fd35c47760b822398888ac08c250000000000000001976a91420cf523034c462f8e09fc0fd35c47760b822398888ac000000000000000001340e600000000000c0050600070000006a47304402206d190e10475b3dc57a9ec4aff060f1d9ee82e47b99d1f9cb2e926384ccdc04df022056040c8b364176c28876b597006faba7b0f1f74abcf0321e530520907b8ded8001210385ece82907d214f46db634a6326d99616ea022ec887991251215d1564120ac41" + }, + { + "txid": "a81ab3f0d0744c42fcc8e5c3b0b77382323d0cf6ac73a55f982dcadc4fe604c7", + "version": 1, + "vin": [ + { + "txid": "f901951a6552d84a047170534a17f176dddf3ff05046d94d5a4f60e951cb7814", + "vout": 1, + "n": 0, + "addresses": [ + "Dse6xFAU3LBzNeFZiPGJHuBRebHN74Sr2ry" + ], + "isAddress": true, + "value": "18643310", + "hex": "4830450221008d6be510c08e051ed4b1f4e00503595531f4800d042a438cb76681677e471b3c022072fb18f79fd673d86449b3ca77e846a9c8ffb87551ce3597b1b206f5d99fa3ab01210212d8d67fa0db8a51432cbbff4d29d5a2ec407f43958800e3770c277b6c22e4ca" + } + ], + "vout": [ + { + "value": "12345678", + "n": 0, + "hex": "76a91420cf523034c462f8e09fc0fd35c47760b822398888ac", + "addresses": [ + "DsTxPUVFxXeNgu5fzozr4mTR4tqqMaKcvpY" + ], + "isAddress": true + }, + { + "value": "6295092", + "n": 1, + "spent": true, + "hex": "76a91493c7588139797500ca13011a73e01a78da3092cd88ac", + "addresses": [ + "DseSHdQv3cZhuY3foizi3bbHHMw2o7RsNsu" + ], + "isAddress": true + } + ], + "blockHash": "000000000000000017871738a562ecfe28699613f578177c3d43c00124b65abe", + "blockHeight": 394687, + "confirmations": 54388, + "blockTime": 1573005579, + "value": "18640770", + "valueIn": "18643310", + "fees": "2540", + "hex": "01000000011478cb51e9604f5a4dd94650f03fdfdd76f1174a537071044ad852651a9501f9010000000000000000024e61bc000000000000001976a91420cf523034c462f8e09fc0fd35c47760b822398888ac340e60000000000000001976a91493c7588139797500ca13011a73e01a78da3092cd88ac0000000000000000016e791c0100000000d4cc0500010000006b4830450221008d6be510c08e051ed4b1f4e00503595531f4800d042a438cb76681677e471b3c022072fb18f79fd673d86449b3ca77e846a9c8ffb87551ce3597b1b206f5d99fa3ab01210212d8d67fa0db8a51432cbbff4d29d5a2ec407f43958800e3770c277b6c22e4ca" + }, + { + "txid": "ce314ec559ceae4d2a98ed4708848708c9cfde14b484b879838a2dc75c793910", + "version": 1, + "vin": [ + { + "txid": "6928795181bd951849bcdebab2f012b1f6a71f8f1993e573ee1b531207c61255", + "sequence": 4294967293, + "n": 0, + "addresses": [ + "DsTxPUVFxXeNgu5fzozr4mTR4tqqMaKcvpY" + ], + "isAddress": true, + "value": "194571", + "hex": "483045022100dd4fafb4a6d89f81b0602a3305aac956decad8e65182cd690eda70854eccc43a022055a23cd4eff950901494fe0f53d880a5c04ca23e822116d91a9ada83ba6baf010121039b24b2073eef4835f226bb98ec9cb28b1cd0550c76077d3865a77870f119c344" + } + ], + "vout": [ + { + "value": "19457", + "n": 0, + "hex": "76a914a0f82f406aa9ce69402d915f9e93312c9e5d796988ac", + "addresses": [ + "Dsfe2vHn1TVqHJWeD37BXL1y31nWeBQqB7c" + ], + "isAddress": true + }, + { + "value": "172574", + "n": 1, + "spent": true, + "hex": "76a914cf1c37327174a9eb957bc879320c405f7f678b7588ac", + "addresses": [ + "Dsjr1AbSRiZaN9PkCGaNyjfAVkbcPLozafq" + ], + "isAddress": true + } + ], + "blockHash": "000000000000000004f7b5a862dc2f9fa6acc037a743913056d2882856ba4314", + "blockHeight": 379022, + "confirmations": 70053, + "blockTime": 1568292291, + "value": "192031", + "valueIn": "194571", + "fees": "2540", + "hex": "01000000015512c60712531bee73e593198f1fa7f6b112f0b2badebc491895bd81517928690000000000fdffffff02014c00000000000000001976a914a0f82f406aa9ce69402d915f9e93312c9e5d796988ac1ea202000000000000001976a914cf1c37327174a9eb957bc879320c405f7f678b7588ac0000000000000000010bf80200000000008dc80500030000006b483045022100dd4fafb4a6d89f81b0602a3305aac956decad8e65182cd690eda70854eccc43a022055a23cd4eff950901494fe0f53d880a5c04ca23e822116d91a9ada83ba6baf010121039b24b2073eef4835f226bb98ec9cb28b1cd0550c76077d3865a77870f119c344" + }, + { + "txid": "6928795181bd951849bcdebab2f012b1f6a71f8f1993e573ee1b531207c61255", + "version": 1, + "vin": [ + { + "txid": "4510dd5fa05c5a8a1ab44a9b77315bf989a3749eb2ff2b651648313dc15c98f9", + "vout": 1, + "sequence": 4294967293, + "n": 0, + "addresses": [ + "DsmwaUbFCWoZCjGv2bYA8bmmXFarWgc6zHY" + ], + "isAddress": true, + "value": "19437456", + "hex": "483045022100a9bdbc46b9856b592d50fc718a818393a53c380fd08dae92a470293d0b7da5f102203e4addd7634bcc14546840cb80f13b6e994d4523a80a46dfd951b173d62a49d6012103bb6681dc8e643af1a54e94e7efe9089f4b9051b2e43803050d6b5a7de7991a11" + } + ], + "vout": [ + { + "value": "194571", + "n": 0, + "spent": true, + "hex": "76a91420cf523034c462f8e09fc0fd35c47760b822398888ac", + "addresses": [ + "DsTxPUVFxXeNgu5fzozr4mTR4tqqMaKcvpY" + ], + "isAddress": true + }, + { + "value": "19240345", + "n": 1, + "spent": true, + "hex": "76a914cf1c37327174a9eb957bc879320c405f7f678b7588ac", + "addresses": [ + "Dsjr1AbSRiZaN9PkCGaNyjfAVkbcPLozafq" + ], + "isAddress": true + } + ], + "blockHash": "00000000000000000bde3ce71634ce6fa7ed894c6d016fba61abb0a94d2c4afa", + "blockHeight": 379020, + "confirmations": 70055, + "blockTime": 1568292043, + "value": "19434916", + "valueIn": "19437456", + "fees": "2540", + "hex": "0100000001f9985cc13d314816652bffb29e74a389f95b31779b4ab41a8a5a5ca05fdd10450100000000fdffffff020bf802000000000000001976a91420cf523034c462f8e09fc0fd35c47760b822398888ac999525010000000000001976a914cf1c37327174a9eb957bc879320c405f7f678b7588ac0000000000000000019097280100000000bdc70500030000006b483045022100a9bdbc46b9856b592d50fc718a818393a53c380fd08dae92a470293d0b7da5f102203e4addd7634bcc14546840cb80f13b6e994d4523a80a46dfd951b173d62a49d6012103bb6681dc8e643af1a54e94e7efe9089f4b9051b2e43803050d6b5a7de7991a11" + }, + { + "txid": "5015d14dcfd78998cfa13e0325798a74d95bbe75f167a49467303f70dde9bffd", + "version": 1, + "vin": [ + { + "txid": "ac4b4b9af3e0b8cdb7918bb6bfdf9878ace398b92e6e5ef7844936c676041a26", + "vout": 1, + "sequence": 4294967295, + "n": 0, + "addresses": [ + "DsTxPUVFxXeNgu5fzozr4mTR4tqqMaKcvpY" + ], + "isAddress": true, + "value": "50000000", + "hex": "483045022100923900d86dfbfefa31c5789c0d142fd75d18dd91ea13930515c46e280b6f33fc022079fddaf46e6da7978b9226cc09c6d978bca89b37ec99becb65625ddb6d00f9180121039b24b2073eef4835f226bb98ec9cb28b1cd0550c76077d3865a77870f119c344" + } + ], + "vout": [ + { + "value": "39900000", + "n": 0, + "spent": true, + "hex": "76a914746462efaf7a648ccd1a46de4e2842f2b25f498588ac", + "addresses": [ + "DsbaL8f4Uu4bQ6wPpbjcLWxRDZQZo3Ncrrq" + ], + "isAddress": true + }, + { + "value": "10000000", + "n": 1, + "hex": "76a9145f6ef673184369f86779658d13f436a7d303276888ac", + "addresses": [ + "DsZfWcUeaTLtXz3roBmNCNP96srYmDFVZ1W" + ], + "isAddress": true + } + ], + "blockHash": "000000000000000008e0427a4b4e95d540d03fcc28a059861204a8674bdf7a64", + "blockHeight": 330617, + "confirmations": 118458, + "blockTime": 1553754509, + "value": "49900000", + "valueIn": "50000000", + "fees": "100000", + "hex": "0100000001261a0476c6364984f75e6e2eb998e3ac7898dfbfb68b91b7cdb8e0f39a4b4bac0100000000ffffffff0260d360020000000000001976a914746462efaf7a648ccd1a46de4e2842f2b25f498588ac809698000000000000001976a9145f6ef673184369f86779658d13f436a7d303276888ac00000000000000000180f0fa020000000035ef0400150000006b483045022100923900d86dfbfefa31c5789c0d142fd75d18dd91ea13930515c46e280b6f33fc022079fddaf46e6da7978b9226cc09c6d978bca89b37ec99becb65625ddb6d00f9180121039b24b2073eef4835f226bb98ec9cb28b1cd0550c76077d3865a77870f119c344" + }, + { + "txid": "ac4b4b9af3e0b8cdb7918bb6bfdf9878ace398b92e6e5ef7844936c676041a26", + "version": 1, + "vin": [ + { + "txid": "9ecec2fc079ebc6646de451b73231cf422f7ad761472b6482c7453a82c87a321", + "vout": 5, + "sequence": 4294967295, + "n": 0, + "addresses": [ + "DsfMzjYfieAwq2zpeCRyDMiSVDxfEFfRNui" + ], + "isAddress": true, + "value": "7078093729", + "hex": "483045022100fef9f8fd733a94ee691d1845442335a3693882e441078c5dc1220ce21ce93d0f0220308aed0bd8cb2e5a040f46426be0b25fdb3605bb6ae3ec8252055bc2cbd13738012102167188e52e860521bd21cc3548f4250c75309a70ec182f081b4d04f788a48914" + } + ], + "vout": [ + { + "value": "7028091199", + "n": 0, + "spent": true, + "hex": "76a914d3b1286986e589b0e819f98e2a2462e5a17f1ef288ac", + "addresses": [ + "DskGEJ3taowt2PxqopPLSUoVh9eq4nWqDXT" + ], + "isAddress": true + }, + { + "value": "50000000", + "n": 1, + "spent": true, + "hex": "76a91420cf523034c462f8e09fc0fd35c47760b822398888ac", + "addresses": [ + "DsTxPUVFxXeNgu5fzozr4mTR4tqqMaKcvpY" + ], + "isAddress": true + } + ], + "blockHash": "000000000000000016d937210760bb0fbde311d3bfb0719abeb6a2230c537817", + "blockHeight": 323381, + "confirmations": 125694, + "blockTime": 1551595302, + "value": "7078091199", + "valueIn": "7078093729", + "fees": "2530", + "hex": "010000000121a3872ca853742c48b6721476adf722f41c23731b45de4666bc9e07fcc2ce9e0500000001ffffffff023f29e8a20100000000001976a914d3b1286986e589b0e819f98e2a2462e5a17f1ef288ac80f0fa020000000000001976a91420cf523034c462f8e09fc0fd35c47760b822398888ac000000000000000001a123e3a501000000a6ea0400030000006b483045022100fef9f8fd733a94ee691d1845442335a3693882e441078c5dc1220ce21ce93d0f0220308aed0bd8cb2e5a040f46426be0b25fdb3605bb6ae3ec8252055bc2cbd13738012102167188e52e860521bd21cc3548f4250c75309a70ec182f081b4d04f788a48914" + } + ] +} diff --git a/mock/ext-api-data/decred-api_v2_xpub_dpubZFf1tYMxcku9nvDRxnYdE4yrEESrkuQFRq5RwA4KoYQKpDSRszN2emePTwLgfQpd4mZHGrHbQkKPZdjH1BcopomXRnr5Gt43rjpNEfeuJLN__details_txs.json b/mock/ext-api-data/decred-api_v2_xpub_dpubZFf1tYMxcku9nvDRxnYdE4yrEESrkuQFRq5RwA4KoYQKpDSRszN2emePTwLgfQpd4mZHGrHbQkKPZdjH1BcopomXRnr5Gt43rjpNEfeuJLN__details_txs.json new file mode 100644 index 000000000..083825a97 --- /dev/null +++ b/mock/ext-api-data/decred-api_v2_xpub_dpubZFf1tYMxcku9nvDRxnYdE4yrEESrkuQFRq5RwA4KoYQKpDSRszN2emePTwLgfQpd4mZHGrHbQkKPZdjH1BcopomXRnr5Gt43rjpNEfeuJLN__details_txs.json @@ -0,0 +1,1447 @@ +{ + "page": 1, + "totalPages": 1, + "itemsOnPage": 1000, + "address": "dpubZFf1tYMxcku9nvDRxnYdE4yrEESrkuQFRq5RwA4KoYQKpDSRszN2emePTwLgfQpd4mZHGrHbQkKPZdjH1BcopomXRnr5Gt43rjpNEfeuJLN", + "balance": "19514502", + "totalReceived": "376819168", + "totalSent": "357304666", + "unconfirmedBalance": "0", + "unconfirmedTxs": 0, + "txs": 29, + "transactions": [ + { + "txid": "22009e6feb0ecbd29004f8a5273163da53c112d93ec5f9dbff46bc41a30f90f0", + "version": 1, + "vin": [ + { + "txid": "66e3d1622d4cb3337babf5e5a466f94b6a732e132c802cc219c6e26543d736e0", + "vout": 1, + "sequence": 4294967283, + "n": 0, + "addresses": [ + "DsTxPUVFxXeNgu5fzozr4mTR4tqqMaKcvpY" + ], + "isAddress": true, + "value": "489415", + "hex": "483045022100b67f278e9552abddde008a4d91e5c1044d8cf01248378f6b4ed94514b23dbf5e022025c96ea8974f40833287f91f5d7a2a672654950993322ec91b32caf45a9d9fc90121039b24b2073eef4835f226bb98ec9cb28b1cd0550c76077d3865a77870f119c344" + } + ], + "vout": [ + { + "value": "100000", + "n": 0, + "hex": "76a914f3fa335c33379fabe6d61c5491504d8d1ad6851c88ac", + "addresses": [ + "DsoCwRHkCHpR1Jvk9GnCT2M8hVgVjfyYAKE" + ], + "isAddress": true + }, + { + "value": "386875", + "n": 1, + "hex": "76a91420cf523034c462f8e09fc0fd35c47760b822398888ac", + "addresses": [ + "DsTxPUVFxXeNgu5fzozr4mTR4tqqMaKcvpY" + ], + "isAddress": true + } + ], + "blockHash": "00000000000000000d08b3d88676bc81defa76eeb6f1322dd68bca50f34a9e8b", + "blockHeight": 447041, + "confirmations": 2034, + "blockTime": 1588752334, + "value": "486875", + "valueIn": "489415", + "fees": "2540", + "hex": "0100000001e036d74365e2c619c22c802c132e736a4bf966a4e5f5ab7b33b34c2d62d1e3660100000000f3ffffff02a08601000000000000001976a914f3fa335c33379fabe6d61c5491504d8d1ad6851c88ac3be705000000000000001976a91420cf523034c462f8e09fc0fd35c47760b822398888ac000000000000000001c777070000000000298e0600030000006b483045022100b67f278e9552abddde008a4d91e5c1044d8cf01248378f6b4ed94514b23dbf5e022025c96ea8974f40833287f91f5d7a2a672654950993322ec91b32caf45a9d9fc90121039b24b2073eef4835f226bb98ec9cb28b1cd0550c76077d3865a77870f119c344" + }, + { + "txid": "66e3d1622d4cb3337babf5e5a466f94b6a732e132c802cc219c6e26543d736e0", + "version": 1, + "vin": [ + { + "txid": "2dc905f525885537310c8ab87f67dc175ca369af1fe7111a49a94451866aa019", + "sequence": 4294967291, + "n": 0, + "addresses": [ + "Dsjr1AbSRiZaN9PkCGaNyjfAVkbcPLozafq" + ], + "isAddress": true, + "value": "591955", + "hex": "473044022045cb71f2c6c446a69cdf77cc7beedf6f4616091a7fc4843ef74757475f5a95c402203609e095561a11e0ac32f51de870a597b39dce4596b5b253842c838b7c4c9953012102eefcb948122fad71682df1ed8c59a9852afeffea086650e3a86e8a1214c0a94f" + } + ], + "vout": [ + { + "value": "100000", + "n": 0, + "hex": "76a91420cf523034c462f8e09fc0fd35c47760b822398888ac", + "addresses": [ + "DsTxPUVFxXeNgu5fzozr4mTR4tqqMaKcvpY" + ], + "isAddress": true + }, + { + "value": "489415", + "n": 1, + "spent": true, + "hex": "76a91420cf523034c462f8e09fc0fd35c47760b822398888ac", + "addresses": [ + "DsTxPUVFxXeNgu5fzozr4mTR4tqqMaKcvpY" + ], + "isAddress": true + } + ], + "blockHash": "00000000000000000c12cb497e60470a3cf366d16705eaba303c2c4415cc7567", + "blockHeight": 429609, + "confirmations": 19466, + "blockTime": 1583516573, + "value": "589415", + "valueIn": "591955", + "fees": "2540", + "hex": "010000000119a06a865144a9491a11e71faf69a35c17dc677fb88a0c3137558825f505c92d0000000000fbffffff02a08601000000000000001976a91420cf523034c462f8e09fc0fd35c47760b822398888acc77707000000000000001976a91420cf523034c462f8e09fc0fd35c47760b822398888ac0000000000000000015308090000000000dbcc05000b0000006a473044022045cb71f2c6c446a69cdf77cc7beedf6f4616091a7fc4843ef74757475f5a95c402203609e095561a11e0ac32f51de870a597b39dce4596b5b253842c838b7c4c9953012102eefcb948122fad71682df1ed8c59a9852afeffea086650e3a86e8a1214c0a94f" + }, + { + "txid": "025abf340da79c4fc4de29667c08fc22cdafbded24c7c2a994a27f6fb4d5fa17", + "version": 1, + "vin": [ + { + "txid": "5a2a0d01ed8672d6bebd7dee447b2e0342bfc34fd4893bed58a4fa5aa87a4c42", + "n": 0, + "addresses": [ + "Dsf6WkLoiTcSGKmkXoSEdukqUfeRJMqUNJV" + ], + "isAddress": true, + "value": "19991980", + "hex": "483045022100dd6997eab2e2bed5b275af4f2511a62b90da430ecb67f960afe4e06ebf8f362b022017e62873f5bd86abe725ef8fa75d506235ef174e18a06305b889d207ca6194e70121039603af712bd8410ada5a3b6c99d536b2e91dfaf4aa27e488b118cf6a9920e769" + } + ], + "vout": [ + { + "value": "100000", + "n": 0, + "hex": "76a91420cf523034c462f8e09fc0fd35c47760b822398888ac", + "addresses": [ + "DsTxPUVFxXeNgu5fzozr4mTR4tqqMaKcvpY" + ], + "isAddress": true + }, + { + "value": "19889440", + "n": 1, + "hex": "76a914989b1aecabf1c24e213cc0f2d8a22ffee25dd4e188ac", + "addresses": [ + "Dsesp1V6DZDEtcq2behmBVKdYqKMdkh96hL" + ], + "isAddress": true + } + ], + "blockHash": "0000000000000000264c499f21a7ef95bffb37148fc099514b2407dfa28c3287", + "blockHeight": 429186, + "confirmations": 19889, + "blockTime": 1583384838, + "value": "19989440", + "valueIn": "19991980", + "fees": "2540", + "hex": "0100000001424c7aa85afaa458ed3b89d44fc3bf42032e7b44ee7dbdbed67286ed010d2a5a00000000000000000002a08601000000000000001976a91420cf523034c462f8e09fc0fd35c47760b822398888ac207d2f010000000000001976a914989b1aecabf1c24e213cc0f2d8a22ffee25dd4e188ac000000000000000001ac0d31010000000052630600050000006b483045022100dd6997eab2e2bed5b275af4f2511a62b90da430ecb67f960afe4e06ebf8f362b022017e62873f5bd86abe725ef8fa75d506235ef174e18a06305b889d207ca6194e70121039603af712bd8410ada5a3b6c99d536b2e91dfaf4aa27e488b118cf6a9920e769" + }, + { + "txid": "68dcb93e36879f33e741f5706463af10387aadeba193cb204453ec23ad1b1979", + "version": 1, + "vin": [ + { + "txid": "d1352a165c773fe22556219916c2dbd3e184cbf29d9be88b4d52b1c321131601", + "vout": 1, + "sequence": 4294967291, + "n": 0, + "addresses": [ + "DseafVVZGqk4VMCiEJoxRS6FkUjxofh2PXA" + ], + "isAddress": true, + "value": "150582", + "hex": "473044022028e6a72865dfb231b6a64cb3bacc5421dde842c57a169d13b753c36e96cacd9f022049e381c5e8a7e82d96b8996898c43baebbb1e5e5e9f51c15beb17e29e784c257012102fed4dd58683487545cc89c1fd779bf70b46067b863921b0e0c1b09bbe56d4345" + } + ], + "vout": [ + { + "value": "100000", + "n": 0, + "hex": "76a91420cf523034c462f8e09fc0fd35c47760b822398888ac", + "addresses": [ + "DsTxPUVFxXeNgu5fzozr4mTR4tqqMaKcvpY" + ], + "isAddress": true + }, + { + "value": "48042", + "n": 1, + "hex": "76a91420cf523034c462f8e09fc0fd35c47760b822398888ac", + "addresses": [ + "DsTxPUVFxXeNgu5fzozr4mTR4tqqMaKcvpY" + ], + "isAddress": true + } + ], + "blockHash": "0000000000000000025750e22134a74a8a5389c716b51dc4757bf213c7dfbb70", + "blockHeight": 427612, + "confirmations": 21463, + "blockTime": 1582902615, + "value": "148042", + "valueIn": "150582", + "fees": "2540", + "hex": "010000000101161321c3b1524d8be89b9df2cb84e1d3dbc21699215625e23f775c162a35d10100000000fbffffff02a08601000000000000001976a91420cf523034c462f8e09fc0fd35c47760b822398888acaabb00000000000000001976a91420cf523034c462f8e09fc0fd35c47760b822398888ac000000000000000001364c020000000000f4c80500070000006a473044022028e6a72865dfb231b6a64cb3bacc5421dde842c57a169d13b753c36e96cacd9f022049e381c5e8a7e82d96b8996898c43baebbb1e5e5e9f51c15beb17e29e784c257012102fed4dd58683487545cc89c1fd779bf70b46067b863921b0e0c1b09bbe56d4345" + }, + { + "txid": "70a5caffaac9105b47ff9b70213f3a9f8bbd28f09335dce763a99f1b39e74ccf", + "version": 1, + "vin": [ + { + "txid": "2c922ec02ec0bc86803290191198232183e903ea2e79f7f6ddb6c7c7c193b9db", + "vout": 1, + "sequence": 4294967287, + "n": 0, + "addresses": [ + "DsTxPUVFxXeNgu5fzozr4mTR4tqqMaKcvpY" + ], + "isAddress": true, + "value": "5292552", + "hex": "483045022100bc0999a9673f4f72b2bd79fd40c1b8a8398381edcc584f6ed868229e2ec5628b02205baab2c3b1cefdb41dc439782310931f15b31fd48544ca70f88c94940a3870800121039b24b2073eef4835f226bb98ec9cb28b1cd0550c76077d3865a77870f119c344" + } + ], + "vout": [ + { + "value": "1000000", + "n": 0, + "hex": "76a91420cf523034c462f8e09fc0fd35c47760b822398888ac", + "addresses": [ + "DsTxPUVFxXeNgu5fzozr4mTR4tqqMaKcvpY" + ], + "isAddress": true + }, + { + "value": "4290012", + "n": 1, + "hex": "76a91420cf523034c462f8e09fc0fd35c47760b822398888ac", + "addresses": [ + "DsTxPUVFxXeNgu5fzozr4mTR4tqqMaKcvpY" + ], + "isAddress": true + } + ], + "blockHash": "00000000000000001c196ac1e8e050a3d7bc600bcb87826dca4ff558ac280014", + "blockHeight": 427609, + "confirmations": 21466, + "blockTime": 1582901951, + "value": "5290012", + "valueIn": "5292552", + "fees": "2540", + "hex": "0100000001dbb993c1c7c7b6ddf6f7792eea03e983212398111990328086bcc02ec02e922c0100000000f7ffffff0240420f000000000000001976a91420cf523034c462f8e09fc0fd35c47760b822398888acdc7541000000000000001976a91420cf523034c462f8e09fc0fd35c47760b822398888ac00000000000000000108c2500000000000bc5d0600020000006b483045022100bc0999a9673f4f72b2bd79fd40c1b8a8398381edcc584f6ed868229e2ec5628b02205baab2c3b1cefdb41dc439782310931f15b31fd48544ca70f88c94940a3870800121039b24b2073eef4835f226bb98ec9cb28b1cd0550c76077d3865a77870f119c344" + }, + { + "txid": "2c922ec02ec0bc86803290191198232183e903ea2e79f7f6ddb6c7c7c193b9db", + "version": 1, + "vin": [ + { + "txid": "a81ab3f0d0744c42fcc8e5c3b0b77382323d0cf6ac73a55f982dcadc4fe604c7", + "vout": 1, + "n": 0, + "addresses": [ + "DseSHdQv3cZhuY3foizi3bbHHMw2o7RsNsu" + ], + "isAddress": true, + "value": "6295092", + "hex": "47304402206d190e10475b3dc57a9ec4aff060f1d9ee82e47b99d1f9cb2e926384ccdc04df022056040c8b364176c28876b597006faba7b0f1f74abcf0321e530520907b8ded8001210385ece82907d214f46db634a6326d99616ea022ec887991251215d1564120ac41" + } + ], + "vout": [ + { + "value": "1000000", + "n": 0, + "hex": "76a91420cf523034c462f8e09fc0fd35c47760b822398888ac", + "addresses": [ + "DsTxPUVFxXeNgu5fzozr4mTR4tqqMaKcvpY" + ], + "isAddress": true + }, + { + "value": "5292552", + "n": 1, + "spent": true, + "hex": "76a91420cf523034c462f8e09fc0fd35c47760b822398888ac", + "addresses": [ + "DsTxPUVFxXeNgu5fzozr4mTR4tqqMaKcvpY" + ], + "isAddress": true + } + ], + "blockHash": "0000000000000000008e3020d59db97a9e69b7b77697369cee0cd600a3e3c106", + "blockHeight": 417211, + "confirmations": 31864, + "blockTime": 1579769314, + "value": "6292552", + "valueIn": "6295092", + "fees": "2540", + "hex": "0100000001c704e64fdcca2d985fa573acf60c3d328273b7b0c3e5c8fc424c74d0f0b31aa80100000000000000000240420f000000000000001976a91420cf523034c462f8e09fc0fd35c47760b822398888ac08c250000000000000001976a91420cf523034c462f8e09fc0fd35c47760b822398888ac000000000000000001340e600000000000c0050600070000006a47304402206d190e10475b3dc57a9ec4aff060f1d9ee82e47b99d1f9cb2e926384ccdc04df022056040c8b364176c28876b597006faba7b0f1f74abcf0321e530520907b8ded8001210385ece82907d214f46db634a6326d99616ea022ec887991251215d1564120ac41" + }, + { + "txid": "b23b63aff6fb5dbfef139f8e0ff0cb9a34b9dbe1b110278d8391b3713b6ca67c", + "version": 1, + "vin": [ + { + "txid": "2138de727f692d55e76f9cd9c1ce30203fe85d8fc64a72703fa0ad7b0a31ca6c", + "vout": 1, + "n": 0, + "addresses": [ + "DsmjpgebRNYbUtAc3KooGpM1pecV1ENJVUe" + ], + "isAddress": true, + "value": "87460", + "hex": "47304402202025782b52bb328a604b2a0c0458eda1c49b53e945cf9deb79627a8d6009cf64022057dcbbad19df5402309191d0ac1f8fc60b35e6ffe309e3c346bb69e5c46ebc6c012103ac7a88d60a68fd722e43a149cb50a7f05075e1192c4351df1dd244e1b38f5f05" + } + ], + "vout": [ + { + "value": "85300", + "n": 0, + "hex": "76a91479cf64f9c950f80da936b57a7d838ae4fd8b1d1388ac", + "addresses": [ + "Dsc4yhfEdqj31WCbtRgv2cXNCtdJNHFCg4o" + ], + "isAddress": true + } + ], + "blockHash": "0000000000000000118884be52c6ca7123b651a48dc1c3b9f069932a3694e7d0", + "blockHeight": 403824, + "confirmations": 45251, + "blockTime": 1575752600, + "value": "85300", + "valueIn": "87460", + "fees": "2160", + "hex": "01000000016cca310a7bada03f70724ac68f5de83f2030cec1d99c6fe7552d697f72de382101000000000000000001344d01000000000000001976a91479cf64f9c950f80da936b57a7d838ae4fd8b1d1388ac000000000000000001a45501000000000017c70500010000006a47304402202025782b52bb328a604b2a0c0458eda1c49b53e945cf9deb79627a8d6009cf64022057dcbbad19df5402309191d0ac1f8fc60b35e6ffe309e3c346bb69e5c46ebc6c012103ac7a88d60a68fd722e43a149cb50a7f05075e1192c4351df1dd244e1b38f5f05" + }, + { + "txid": "a81ab3f0d0744c42fcc8e5c3b0b77382323d0cf6ac73a55f982dcadc4fe604c7", + "version": 1, + "vin": [ + { + "txid": "f901951a6552d84a047170534a17f176dddf3ff05046d94d5a4f60e951cb7814", + "vout": 1, + "n": 0, + "addresses": [ + "Dse6xFAU3LBzNeFZiPGJHuBRebHN74Sr2ry" + ], + "isAddress": true, + "value": "18643310", + "hex": "4830450221008d6be510c08e051ed4b1f4e00503595531f4800d042a438cb76681677e471b3c022072fb18f79fd673d86449b3ca77e846a9c8ffb87551ce3597b1b206f5d99fa3ab01210212d8d67fa0db8a51432cbbff4d29d5a2ec407f43958800e3770c277b6c22e4ca" + } + ], + "vout": [ + { + "value": "12345678", + "n": 0, + "hex": "76a91420cf523034c462f8e09fc0fd35c47760b822398888ac", + "addresses": [ + "DsTxPUVFxXeNgu5fzozr4mTR4tqqMaKcvpY" + ], + "isAddress": true + }, + { + "value": "6295092", + "n": 1, + "spent": true, + "hex": "76a91493c7588139797500ca13011a73e01a78da3092cd88ac", + "addresses": [ + "DseSHdQv3cZhuY3foizi3bbHHMw2o7RsNsu" + ], + "isAddress": true + } + ], + "blockHash": "000000000000000017871738a562ecfe28699613f578177c3d43c00124b65abe", + "blockHeight": 394687, + "confirmations": 54388, + "blockTime": 1573005579, + "value": "18640770", + "valueIn": "18643310", + "fees": "2540", + "hex": "01000000011478cb51e9604f5a4dd94650f03fdfdd76f1174a537071044ad852651a9501f9010000000000000000024e61bc000000000000001976a91420cf523034c462f8e09fc0fd35c47760b822398888ac340e60000000000000001976a91493c7588139797500ca13011a73e01a78da3092cd88ac0000000000000000016e791c0100000000d4cc0500010000006b4830450221008d6be510c08e051ed4b1f4e00503595531f4800d042a438cb76681677e471b3c022072fb18f79fd673d86449b3ca77e846a9c8ffb87551ce3597b1b206f5d99fa3ab01210212d8d67fa0db8a51432cbbff4d29d5a2ec407f43958800e3770c277b6c22e4ca" + }, + { + "txid": "2dc905f525885537310c8ab87f67dc175ca369af1fe7111a49a94451866aa019", + "version": 1, + "vin": [ + { + "txid": "f901951a6552d84a047170534a17f176dddf3ff05046d94d5a4f60e951cb7814", + "sequence": 4294967294, + "n": 0, + "addresses": [ + "DsoCwRHkCHpR1Jvk9GnCT2M8hVgVjfyYAKE" + ], + "isAddress": true, + "value": "594495", + "hex": "483045022100fdc5b54189aaaa7c0e622dd5723ab3da9431ef84b38f6a7d5fc5285f07dbe7980220207b75cd3f047757e54812a711f38add03073e24f767cc04b4f784ce1a8e3913012103702335aa130d38e61b4444b5413febdb3cffc552ddffa97212882908662ae454" + } + ], + "vout": [ + { + "value": "591955", + "n": 0, + "spent": true, + "hex": "76a914cf1c37327174a9eb957bc879320c405f7f678b7588ac", + "addresses": [ + "Dsjr1AbSRiZaN9PkCGaNyjfAVkbcPLozafq" + ], + "isAddress": true + } + ], + "blockHash": "000000000000000017c392360a4bd7c3c184404d9f5c73abcf7aad990170948e", + "blockHeight": 380122, + "confirmations": 68953, + "blockTime": 1568625431, + "value": "591955", + "valueIn": "594495", + "fees": "2540", + "hex": "01000000011478cb51e9604f5a4dd94650f03fdfdd76f1174a537071044ad852651a9501f90000000000feffffff01530809000000000000001976a914cf1c37327174a9eb957bc879320c405f7f678b7588ac0000000000000000013f12090000000000d4cc0500010000006b483045022100fdc5b54189aaaa7c0e622dd5723ab3da9431ef84b38f6a7d5fc5285f07dbe7980220207b75cd3f047757e54812a711f38add03073e24f767cc04b4f784ce1a8e3913012103702335aa130d38e61b4444b5413febdb3cffc552ddffa97212882908662ae454" + }, + { + "txid": "f901951a6552d84a047170534a17f176dddf3ff05046d94d5a4f60e951cb7814", + "version": 1, + "vin": [ + { + "txid": "6928795181bd951849bcdebab2f012b1f6a71f8f1993e573ee1b531207c61255", + "vout": 1, + "sequence": 4294967293, + "n": 0, + "addresses": [ + "Dsjr1AbSRiZaN9PkCGaNyjfAVkbcPLozafq" + ], + "isAddress": true, + "value": "19240345", + "hex": "483045022100feace09f456985a5d1d8a44fea21282138799202a2a441542b44f38ad9cc24fd022045b87fa9869462465bbe605863c31243911dccadde4ffb4c853be7719b31d9b9012102eefcb948122fad71682df1ed8c59a9852afeffea086650e3a86e8a1214c0a94f" + } + ], + "vout": [ + { + "value": "594495", + "n": 0, + "spent": true, + "hex": "76a914f3fa335c33379fabe6d61c5491504d8d1ad6851c88ac", + "addresses": [ + "DsoCwRHkCHpR1Jvk9GnCT2M8hVgVjfyYAKE" + ], + "isAddress": true + }, + { + "value": "18643310", + "n": 1, + "spent": true, + "hex": "76a914901f43073875d802f83f19568407d3e4721ec6c688ac", + "addresses": [ + "Dse6xFAU3LBzNeFZiPGJHuBRebHN74Sr2ry" + ], + "isAddress": true + } + ], + "blockHash": "0000000000000000181a2cb9b30a08020e747f249fc6ab8b6fed7d467565c608", + "blockHeight": 380115, + "confirmations": 68960, + "blockTime": 1568621402, + "value": "19237805", + "valueIn": "19240345", + "fees": "2540", + "hex": "01000000015512c60712531bee73e593198f1fa7f6b112f0b2badebc491895bd81517928690100000000fdffffff023f1209000000000000001976a914f3fa335c33379fabe6d61c5491504d8d1ad6851c88ac6e791c010000000000001976a914901f43073875d802f83f19568407d3e4721ec6c688ac00000000000000000199952501000000008dc80500030000006b483045022100feace09f456985a5d1d8a44fea21282138799202a2a441542b44f38ad9cc24fd022045b87fa9869462465bbe605863c31243911dccadde4ffb4c853be7719b31d9b9012102eefcb948122fad71682df1ed8c59a9852afeffea086650e3a86e8a1214c0a94f" + }, + { + "txid": "d1352a165c773fe22556219916c2dbd3e184cbf29d9be88b4d52b1c321131601", + "version": 1, + "vin": [ + { + "txid": "ce314ec559ceae4d2a98ed4708848708c9cfde14b484b879838a2dc75c793910", + "vout": 1, + "sequence": 4294967291, + "n": 0, + "addresses": [ + "Dsjr1AbSRiZaN9PkCGaNyjfAVkbcPLozafq" + ], + "isAddress": true, + "value": "172574", + "hex": "47304402203e9fb2dd6e7105ea850fed2ae1d7073c1aaa27bc8bbff79d03edd3799ff854f702200910ba540373613bed8f108754fab7cf9d2f4ff3cc807d0cab33637641044b07012102eefcb948122fad71682df1ed8c59a9852afeffea086650e3a86e8a1214c0a94f" + } + ], + "vout": [ + { + "value": "19452", + "n": 0, + "hex": "76a9148e5323908a6d4869d4b85e45998a143ab4d0631a88ac", + "addresses": [ + "DsdwT3GGppDmuPSEetywszY7Y95jGpLopSU" + ], + "isAddress": true + }, + { + "value": "150582", + "n": 1, + "spent": true, + "hex": "76a914955cec92163c1b9b2469596948c1f4601955cc5688ac", + "addresses": [ + "DseafVVZGqk4VMCiEJoxRS6FkUjxofh2PXA" + ], + "isAddress": true + } + ], + "blockHash": "00000000000000000a7785b2e8916051e66db1f1fcaad299eb2a3c045b1d832d", + "blockHeight": 379124, + "confirmations": 69951, + "blockTime": 1568325197, + "value": "170034", + "valueIn": "172574", + "fees": "2540", + "hex": "01000000011039795cc72d8a8379b884b414decfc90887840847ed982a4daece59c54e31ce0100000000fbffffff02fc4b00000000000000001976a9148e5323908a6d4869d4b85e45998a143ab4d0631a88ac364c02000000000000001976a914955cec92163c1b9b2469596948c1f4601955cc5688ac0000000000000000011ea20200000000008ec80500080000006a47304402203e9fb2dd6e7105ea850fed2ae1d7073c1aaa27bc8bbff79d03edd3799ff854f702200910ba540373613bed8f108754fab7cf9d2f4ff3cc807d0cab33637641044b07012102eefcb948122fad71682df1ed8c59a9852afeffea086650e3a86e8a1214c0a94f" + }, + { + "txid": "ce314ec559ceae4d2a98ed4708848708c9cfde14b484b879838a2dc75c793910", + "version": 1, + "vin": [ + { + "txid": "6928795181bd951849bcdebab2f012b1f6a71f8f1993e573ee1b531207c61255", + "sequence": 4294967293, + "n": 0, + "addresses": [ + "DsTxPUVFxXeNgu5fzozr4mTR4tqqMaKcvpY" + ], + "isAddress": true, + "value": "194571", + "hex": "483045022100dd4fafb4a6d89f81b0602a3305aac956decad8e65182cd690eda70854eccc43a022055a23cd4eff950901494fe0f53d880a5c04ca23e822116d91a9ada83ba6baf010121039b24b2073eef4835f226bb98ec9cb28b1cd0550c76077d3865a77870f119c344" + } + ], + "vout": [ + { + "value": "19457", + "n": 0, + "hex": "76a914a0f82f406aa9ce69402d915f9e93312c9e5d796988ac", + "addresses": [ + "Dsfe2vHn1TVqHJWeD37BXL1y31nWeBQqB7c" + ], + "isAddress": true + }, + { + "value": "172574", + "n": 1, + "spent": true, + "hex": "76a914cf1c37327174a9eb957bc879320c405f7f678b7588ac", + "addresses": [ + "Dsjr1AbSRiZaN9PkCGaNyjfAVkbcPLozafq" + ], + "isAddress": true + } + ], + "blockHash": "000000000000000004f7b5a862dc2f9fa6acc037a743913056d2882856ba4314", + "blockHeight": 379022, + "confirmations": 70053, + "blockTime": 1568292291, + "value": "192031", + "valueIn": "194571", + "fees": "2540", + "hex": "01000000015512c60712531bee73e593198f1fa7f6b112f0b2badebc491895bd81517928690000000000fdffffff02014c00000000000000001976a914a0f82f406aa9ce69402d915f9e93312c9e5d796988ac1ea202000000000000001976a914cf1c37327174a9eb957bc879320c405f7f678b7588ac0000000000000000010bf80200000000008dc80500030000006b483045022100dd4fafb4a6d89f81b0602a3305aac956decad8e65182cd690eda70854eccc43a022055a23cd4eff950901494fe0f53d880a5c04ca23e822116d91a9ada83ba6baf010121039b24b2073eef4835f226bb98ec9cb28b1cd0550c76077d3865a77870f119c344" + }, + { + "txid": "6928795181bd951849bcdebab2f012b1f6a71f8f1993e573ee1b531207c61255", + "version": 1, + "vin": [ + { + "txid": "4510dd5fa05c5a8a1ab44a9b77315bf989a3749eb2ff2b651648313dc15c98f9", + "vout": 1, + "sequence": 4294967293, + "n": 0, + "addresses": [ + "DsmwaUbFCWoZCjGv2bYA8bmmXFarWgc6zHY" + ], + "isAddress": true, + "value": "19437456", + "hex": "483045022100a9bdbc46b9856b592d50fc718a818393a53c380fd08dae92a470293d0b7da5f102203e4addd7634bcc14546840cb80f13b6e994d4523a80a46dfd951b173d62a49d6012103bb6681dc8e643af1a54e94e7efe9089f4b9051b2e43803050d6b5a7de7991a11" + } + ], + "vout": [ + { + "value": "194571", + "n": 0, + "spent": true, + "hex": "76a91420cf523034c462f8e09fc0fd35c47760b822398888ac", + "addresses": [ + "DsTxPUVFxXeNgu5fzozr4mTR4tqqMaKcvpY" + ], + "isAddress": true + }, + { + "value": "19240345", + "n": 1, + "spent": true, + "hex": "76a914cf1c37327174a9eb957bc879320c405f7f678b7588ac", + "addresses": [ + "Dsjr1AbSRiZaN9PkCGaNyjfAVkbcPLozafq" + ], + "isAddress": true + } + ], + "blockHash": "00000000000000000bde3ce71634ce6fa7ed894c6d016fba61abb0a94d2c4afa", + "blockHeight": 379020, + "confirmations": 70055, + "blockTime": 1568292043, + "value": "19434916", + "valueIn": "19437456", + "fees": "2540", + "hex": "0100000001f9985cc13d314816652bffb29e74a389f95b31779b4ab41a8a5a5ca05fdd10450100000000fdffffff020bf802000000000000001976a91420cf523034c462f8e09fc0fd35c47760b822398888ac999525010000000000001976a914cf1c37327174a9eb957bc879320c405f7f678b7588ac0000000000000000019097280100000000bdc70500030000006b483045022100a9bdbc46b9856b592d50fc718a818393a53c380fd08dae92a470293d0b7da5f102203e4addd7634bcc14546840cb80f13b6e994d4523a80a46dfd951b173d62a49d6012103bb6681dc8e643af1a54e94e7efe9089f4b9051b2e43803050d6b5a7de7991a11" + }, + { + "txid": "4510dd5fa05c5a8a1ab44a9b77315bf989a3749eb2ff2b651648313dc15c98f9", + "version": 1, + "vin": [ + { + "txid": "cc227d117d0f7d9b8aaaee4ce11bd6eaafa62adbddea9428c9bc8f257b56b50c", + "vout": 1, + "sequence": 2147483646, + "n": 0, + "addresses": [ + "DshALmistThHv2qmXM5wF5ACqPLzSfk8Syf" + ], + "isAddress": true, + "value": "19467142", + "hex": "4830450221009b010fbaeedc912e82c2d864a0d359f4b0723b1f17403c05d050f823b3015cd702204533b28be9722798f5c180ee381345115e914c55422ecdf7b4a2003f8b1d657e01210234a89c9f685966ab79a095d65e3253cb6e2fc0d5d6fb18fef090a045a729b7aa" + } + ], + "vout": [ + { + "value": "19686", + "n": 0, + "hex": "76a914f57b7845ed8064ab991b23ebd49003a1e596ecda88ac", + "addresses": [ + "DsoLtxGAPidBykdxWkzRAmhgBwBeqLdJEXR" + ], + "isAddress": true + }, + { + "value": "19437456", + "n": 1, + "spent": true, + "hex": "76a914e61a5a5f5a70f22de8156a15a510e82369bc48de88ac", + "addresses": [ + "DsmwaUbFCWoZCjGv2bYA8bmmXFarWgc6zHY" + ], + "isAddress": true + } + ], + "blockHash": "00000000000000001c055f129cbd785708947616301cc4ec3cfe604c84be884f", + "blockHeight": 378812, + "confirmations": 70263, + "blockTime": 1568228155, + "value": "19457142", + "valueIn": "19467142", + "fees": "10000", + "hex": "01000000010cb5567b258fbcc92894eadddb2aa6afead61be14ceeaa8a9b7d0f7d117d22cc0100000000feffff7f02e64c00000000000000001976a914f57b7845ed8064ab991b23ebd49003a1e596ecda88ac909728010000000000001976a914e61a5a5f5a70f22de8156a15a510e82369bc48de88ac000000000000000001860b290100000000abc70500070000006b4830450221009b010fbaeedc912e82c2d864a0d359f4b0723b1f17403c05d050f823b3015cd702204533b28be9722798f5c180ee381345115e914c55422ecdf7b4a2003f8b1d657e01210234a89c9f685966ab79a095d65e3253cb6e2fc0d5d6fb18fef090a045a729b7aa" + }, + { + "txid": "cc227d117d0f7d9b8aaaee4ce11bd6eaafa62adbddea9428c9bc8f257b56b50c", + "version": 1, + "vin": [ + { + "txid": "ae12bcde96172c2953e27562a8ee0c0a3368ddfbca5f4d9562e866e965a5232b", + "sequence": 2147483644, + "n": 0, + "addresses": [ + "DsowaTuYHygWaxox11yKbRSoQhfpjLmbzuL" + ], + "isAddress": true, + "value": "193136", + "hex": "47304402204f2d922cc2b2f4fc31e9715369231ac622e6e018691c7187136cc6ab9918ce9702207c4925d14ac86f07a9e0300c7d1af3d4d18cc57fb90cde2c26f0230e4fcf6c860121025cc5f64fc451b54c56f044580a56c50b4fb3f4d4d69158e8898ddb8cf892de65" + }, + { + "txid": "8081de85157ca6cb5d12c3971e2cac6aa0e95370826a89307bfe144d3db33d1c", + "vout": 1, + "sequence": 2147483645, + "n": 1, + "addresses": [ + "DsRtQjGTkaBTyHqsTyN1Gv3N8QMkrnRg3yd" + ], + "isAddress": true, + "value": "19473775", + "hex": "483045022100f67c9e02ac7dbd58368c25c4b69ee6a4cfef77f0385677831c6f8625874917e102204e5e143fbc13c6187f4a02268cb53480ad6b10bafe74edb1fe67f72d608492850121034ebee1373499bec415fb9b6eabbf6d659fa4f5c06b93014c89c65777d7c3886c" + }, + { + "txid": "8081de85157ca6cb5d12c3971e2cac6aa0e95370826a89307bfe144d3db33d1c", + "sequence": 2147483646, + "n": 2, + "addresses": [ + "DsWmtukoGFxtrHUBoM7UnFVfnBANBRgZ22c" + ], + "isAddress": true, + "value": "19697", + "hex": "4730440220404be3f0940ad6d321b976e61802c15d9cfad4bff7bbdb58ffa81d044cfa085c02202257ab91ddde8b75f74785a850e71c0033dacf64aff194dd1f315e7121c1f5eb012102c6e0318938086b3b7164dabd33263de83a1c3e59cc6b4dde8853927dd0eb6853" + } + ], + "vout": [ + { + "value": "196866", + "n": 0, + "hex": "76a9140f685cce0b2c2825e4157c2af925f9cf21d691bd88ac", + "addresses": [ + "DsSNNeYSYA9VYNe9m1YBZPoUKmqmkts9moi" + ], + "isAddress": true + }, + { + "value": "19467142", + "n": 1, + "spent": true, + "hex": "76a914b1abb109bc360fdd86b8d1e728eb147164897c1f88ac", + "addresses": [ + "DshALmistThHv2qmXM5wF5ACqPLzSfk8Syf" + ], + "isAddress": true + } + ], + "blockHash": "00000000000000000f8c0b11a62d2df16039706c72d37c672cea8b02ea8b9393", + "blockHeight": 378794, + "confirmations": 70281, + "blockTime": 1568221848, + "value": "19664008", + "valueIn": "19686608", + "fees": "22600", + "hex": "01000000032b23a565e966e862954d5fcafbdd68330a0ceea86275e253292c1796debc12ae0000000000fcffff7f1c3db33d4d14fe7b30896a827053e9a06aac2c1e97c3125dcba67c1585de81800100000000fdffff7f1c3db33d4d14fe7b30896a827053e9a06aac2c1e97c3125dcba67c1585de81800000000000feffff7f02020103000000000000001976a9140f685cce0b2c2825e4157c2af925f9cf21d691bd88ac860b29010000000000001976a914b1abb109bc360fdd86b8d1e728eb147164897c1f88ac00000000000000000370f2020000000000a6c70500030000006a47304402204f2d922cc2b2f4fc31e9715369231ac622e6e018691c7187136cc6ab9918ce9702207c4925d14ac86f07a9e0300c7d1af3d4d18cc57fb90cde2c26f0230e4fcf6c860121025cc5f64fc451b54c56f044580a56c50b4fb3f4d4d69158e8898ddb8cf892de656f25290100000000a4c70500010000006b483045022100f67c9e02ac7dbd58368c25c4b69ee6a4cfef77f0385677831c6f8625874917e102204e5e143fbc13c6187f4a02268cb53480ad6b10bafe74edb1fe67f72d608492850121034ebee1373499bec415fb9b6eabbf6d659fa4f5c06b93014c89c65777d7c3886cf14c000000000000a4c70500010000006a4730440220404be3f0940ad6d321b976e61802c15d9cfad4bff7bbdb58ffa81d044cfa085c02202257ab91ddde8b75f74785a850e71c0033dacf64aff194dd1f315e7121c1f5eb012102c6e0318938086b3b7164dabd33263de83a1c3e59cc6b4dde8853927dd0eb6853" + }, + { + "txid": "ae12bcde96172c2953e27562a8ee0c0a3368ddfbca5f4d9562e866e965a5232b", + "version": 1, + "vin": [ + { + "txid": "374e7179bec21f341a648bd012a89863b8a262d3854c9e662837d2f32441bdef", + "sequence": 2147483646, + "n": 0, + "addresses": [ + "DshHAv8CmxHwdKUs1Dfddv8sv4o6hN8LpaQ" + ], + "isAddress": true, + "value": "196976", + "hex": "483045022100985710b5c20e407ac42b5c908c65408dc9118d040ee13e8cf1962df560956c2302202dc9c9ea10045380ba8ee402dff4832e66a28f9aa5f9dc8b0be080f9c1939d9e0121021224cf94a0455dcbfe727ea404e1ed174c112bbffb1d50dd383c50bc4d188406" + } + ], + "vout": [ + { + "value": "193136", + "n": 0, + "spent": true, + "hex": "76a914fc0a984061ba5819f7ab8a0ea7d546e691d1a50b88ac", + "addresses": [ + "DsowaTuYHygWaxox11yKbRSoQhfpjLmbzuL" + ], + "isAddress": true + } + ], + "blockHash": "00000000000000000db2a3d8ab366e7894d062919539dd92a05fb974731383af", + "blockHeight": 378790, + "confirmations": 70285, + "blockTime": 1568219847, + "value": "193136", + "valueIn": "196976", + "fees": "3840", + "hex": "0100000001efbd4124f3d23728669e4c85d362a2b86398a812d08b641a341fc2be79714e370000000000feffff7f0170f202000000000000001976a914fc0a984061ba5819f7ab8a0ea7d546e691d1a50b88ac0000000000000000017001030000000000a2c70500030000006b483045022100985710b5c20e407ac42b5c908c65408dc9118d040ee13e8cf1962df560956c2302202dc9c9ea10045380ba8ee402dff4832e66a28f9aa5f9dc8b0be080f9c1939d9e0121021224cf94a0455dcbfe727ea404e1ed174c112bbffb1d50dd383c50bc4d188406" + }, + { + "txid": "8081de85157ca6cb5d12c3971e2cac6aa0e95370826a89307bfe144d3db33d1c", + "version": 1, + "vin": [ + { + "txid": "374e7179bec21f341a648bd012a89863b8a262d3854c9e662837d2f32441bdef", + "vout": 1, + "sequence": 2147483646, + "n": 0, + "addresses": [ + "DsUg8xbvU9irDqtMmWxLHaXSByRGGFcbHs6" + ], + "isAddress": true, + "value": "19496184", + "hex": "483045022100a0fddf430dcd68754145d54b660064feca0d5fe173d6f76024f1e30ed856926402202314ab99f4e5b236458965038d6eea9b4e174ede6c3b122a7bb4554e84d54e63012102a3754902a372bee2b4f0946f3f4388d3b555ac77fde9360665d86f37ef3820f4" + } + ], + "vout": [ + { + "value": "19697", + "n": 0, + "spent": true, + "hex": "76a9143fbbb1c889263b06fc6383e77f87b30b865d507e88ac", + "addresses": [ + "DsWmtukoGFxtrHUBoM7UnFVfnBANBRgZ22c" + ], + "isAddress": true + }, + { + "value": "19473775", + "n": 1, + "spent": true, + "hex": "76a9140a1e73fe7705c2a5ca99e9caa309ad7fe22f318188ac", + "addresses": [ + "DsRtQjGTkaBTyHqsTyN1Gv3N8QMkrnRg3yd" + ], + "isAddress": true + } + ], + "blockHash": "000000000000000006af0cbcd6a0882fe41155e54343d2491a745f72c6e6cec1", + "blockHeight": 378787, + "confirmations": 70288, + "blockTime": 1568218744, + "value": "19493472", + "valueIn": "19496184", + "fees": "2712", + "hex": "0100000001efbd4124f3d23728669e4c85d362a2b86398a812d08b641a341fc2be79714e370100000000feffff7f02f14c00000000000000001976a9143fbbb1c889263b06fc6383e77f87b30b865d507e88ac6f2529010000000000001976a9140a1e73fe7705c2a5ca99e9caa309ad7fe22f318188ac000000000000000001f87c290100000000a2c70500030000006b483045022100a0fddf430dcd68754145d54b660064feca0d5fe173d6f76024f1e30ed856926402202314ab99f4e5b236458965038d6eea9b4e174ede6c3b122a7bb4554e84d54e63012102a3754902a372bee2b4f0946f3f4388d3b555ac77fde9360665d86f37ef3820f4" + }, + { + "txid": "374e7179bec21f341a648bd012a89863b8a262d3854c9e662837d2f32441bdef", + "version": 1, + "vin": [ + { + "txid": "0e127e2c47f2a8779c007ec092bb641c84fcfaad043578b85193372ce57647ca", + "vout": 1, + "sequence": 2147483645, + "n": 0, + "addresses": [ + "DsoUYJStadLjrvgTSL4AVHsP8f6uG7TXEYi" + ], + "isAddress": true, + "value": "19677983", + "hex": "47304402207f20ea5436abacbf2e846c2f7a17a70a69970240cc0aadcd06491880e3e19ccf022016f21eeafeaaec1ccb50119f6d6707cb175fe8d52d71cbe09a233010429ddbdf01210277aabb5d244665b771ebd3c59d6eda42b7a95f53b937e7d8c74f85f0f9c3346a" + }, + { + "txid": "0e127e2c47f2a8779c007ec092bb641c84fcfaad043578b85193372ce57647ca", + "sequence": 2147483646, + "n": 1, + "addresses": [ + "DsnrYbE1bZ5yPMphTuZ8C7bQyRjBi4pbGeX" + ], + "isAddress": true, + "value": "19697", + "hex": "483045022100f11a5745288e675c7225a50db44f46e8f626112abe1236403b2a7821fad06c97022049d2d7b75092279e3246a84641abbc70606439b2c3e93a79b56b26a32b241a9b0121025e52eafdbe47878d9e8c6954123c6bb6eb40d851d57e14bda352b25489654650" + } + ], + "vout": [ + { + "value": "196976", + "n": 0, + "spent": true, + "hex": "76a914b2f6606b247714118e2824d8377d430289bf8e9a88ac", + "addresses": [ + "DshHAv8CmxHwdKUs1Dfddv8sv4o6hN8LpaQ" + ], + "isAddress": true + }, + { + "value": "19496184", + "n": 1, + "spent": true, + "hex": "76a91428b4acba0ed858454846b70a4cdfe34b926efae288ac", + "addresses": [ + "DsUg8xbvU9irDqtMmWxLHaXSByRGGFcbHs6" + ], + "isAddress": true + } + ], + "blockHash": "00000000000000001a409bed8a0b608d015c15e8537387eb4bdb543b804874ee", + "blockHeight": 378786, + "confirmations": 70289, + "blockTime": 1568218103, + "value": "19693160", + "valueIn": "19697680", + "fees": "4520", + "hex": "0100000002ca4776e52c379351b8783504adfafc841c64bb92c07e009c77a8f2472c7e120e0100000000fdffff7fca4776e52c379351b8783504adfafc841c64bb92c07e009c77a8f2472c7e120e0000000000feffff7f02700103000000000000001976a914b2f6606b247714118e2824d8377d430289bf8e9a88acf87c29010000000000001976a91428b4acba0ed858454846b70a4cdfe34b926efae288ac0000000000000000021f432c01000000009ac70500010000006a47304402207f20ea5436abacbf2e846c2f7a17a70a69970240cc0aadcd06491880e3e19ccf022016f21eeafeaaec1ccb50119f6d6707cb175fe8d52d71cbe09a233010429ddbdf01210277aabb5d244665b771ebd3c59d6eda42b7a95f53b937e7d8c74f85f0f9c3346af14c0000000000009ac70500010000006b483045022100f11a5745288e675c7225a50db44f46e8f626112abe1236403b2a7821fad06c97022049d2d7b75092279e3246a84641abbc70606439b2c3e93a79b56b26a32b241a9b0121025e52eafdbe47878d9e8c6954123c6bb6eb40d851d57e14bda352b25489654650" + }, + { + "txid": "0e127e2c47f2a8779c007ec092bb641c84fcfaad043578b85193372ce57647ca", + "version": 1, + "vin": [ + { + "txid": "2138de727f692d55e76f9cd9c1ce30203fe85d8fc64a72703fa0ad7b0a31ca6c", + "sequence": 2147483643, + "n": 0, + "addresses": [ + "DspBxSac8FWcKWi1MfpZiYZeFPSWRznmBAT" + ], + "isAddress": true, + "value": "10000", + "hex": "4830450221008a34ff313ccb1facfa57a4fab181b1ff81ee1f3e8043d20524b4f909c8ae3440022021bd68bd9b6b13151de63194da93defcb78f605935060eebf3e453c0444e29da012102d77499b1b96917cde09a14f56972b9ce9a0a1d54ff4a8fb53cf661acc97e1947" + }, + { + "txid": "c416dd7cfb276aead083ea7bb3648f50902d6602d58624232dfc5035f1da8a88", + "vout": 1, + "sequence": 2147483644, + "n": 1, + "addresses": [ + "Dsn9CTECmGUK8uM8kKiTugmxiy16dh18pRZ" + ], + "isAddress": true, + "value": "897460", + "hex": "47304402205e34414797dec57016f7ac4ac9ab746fbe946150242a135f19b8d0ff3efcd5730220295e27becf1f67b3c6fa53977e54beef8abdc95a20f95c7639c6c801fba043280121039da1c8459eb5dcc38dede0f4caf9db65500136e385041e793695c4819d10a13b" + }, + { + "txid": "1a142ae8243b58062d63eefe3a9e824608ef4ad32fff00726a2ee66f08c165a5", + "vout": 1, + "sequence": 2147483645, + "n": 2, + "addresses": [ + "DsUz6RQnnhzhXphPe7wCRe1JE6Znn912VqC" + ], + "isAddress": true, + "value": "18690220", + "hex": "463043021f6ef23907add7ba3c03ac00ea02414e5cf9a1821eb19f71593d3e30e053bf2902201f95f1de74f94ab6e24372264cb4739fe47adb9c82b9b1abd14e7811587c91a10121023fb5b17d1eae140fe098877afab49d45f07509acf848bfb1311bf6cfb64ad8da" + }, + { + "txid": "076325760e3bdc16323b5de8ef5563ef10809568e13d9fc76e2ee8d523bb200c", + "sequence": 2147483646, + "n": 3, + "addresses": [ + "DsW4aSTWVaW1V6jPLu1K9PzSFWBCLJuexkm" + ], + "isAddress": true, + "value": "100000", + "hex": "483045022100d635b8214ee61095917956cdd2a1c0d35e7b135b280704a9db25f9d3a3a957d202204e45da95f8bf029be802c68aafb7f60ef820b194df2871a4a483499632002ca2012102a1608ef89e8b7a80531436eb05421a5dc427c1c1515f6ce8285df1bf20d59219" + } + ], + "vout": [ + { + "value": "19697", + "n": 0, + "spent": true, + "hex": "76a914f01ed3302c231e4ad30ad4965d058e68c1ef12ef88ac", + "addresses": [ + "DsnrYbE1bZ5yPMphTuZ8C7bQyRjBi4pbGeX" + ], + "isAddress": true + }, + { + "value": "19677983", + "n": 1, + "spent": true, + "hex": "76a914f6ed8edfe15349528b7e797fe64d5c032772627e88ac", + "addresses": [ + "DsoUYJStadLjrvgTSL4AVHsP8f6uG7TXEYi" + ], + "isAddress": true + } + ], + "blockHash": "00000000000000001598d3aed4e50f75ba4e3abea4629853d3cc60d5de07adcd", + "blockHeight": 378778, + "confirmations": 70297, + "blockTime": 1568214596, + "value": "19697680", + "valueIn": "19697680", + "fees": "0", + "hex": "01000000046cca310a7bada03f70724ac68f5de83f2030cec1d99c6fe7552d697f72de38210000000000fbffff7f888adaf13550fc2d232486d502662d90508f64b37bea83d0ea6a27fb7cdd16c40100000000fcffff7fa565c1086fe62e6a7200ff2fd34aef0846829e3afeee632d06583b24e82a141a0100000000fdffff7f0c20bb23d5e82e6ec79f3de168958010ef6355efe85d3b3216dc3b0e762563070000000000feffff7f02f14c00000000000000001976a914f01ed3302c231e4ad30ad4965d058e68c1ef12ef88ac1f432c010000000000001976a914f6ed8edfe15349528b7e797fe64d5c032772627e88ac000000000000000004102700000000000017c70500010000006b4830450221008a34ff313ccb1facfa57a4fab181b1ff81ee1f3e8043d20524b4f909c8ae3440022021bd68bd9b6b13151de63194da93defcb78f605935060eebf3e453c0444e29da012102d77499b1b96917cde09a14f56972b9ce9a0a1d54ff4a8fb53cf661acc97e1947b4b10d0000000000edc40500040000006a47304402205e34414797dec57016f7ac4ac9ab746fbe946150242a135f19b8d0ff3efcd5730220295e27becf1f67b3c6fa53977e54beef8abdc95a20f95c7639c6c801fba043280121039da1c8459eb5dcc38dede0f4caf9db65500136e385041e793695c4819d10a13bac301d01000000006dc305000200000069463043021f6ef23907add7ba3c03ac00ea02414e5cf9a1821eb19f71593d3e30e053bf2902201f95f1de74f94ab6e24372264cb4739fe47adb9c82b9b1abd14e7811587c91a10121023fb5b17d1eae140fe098877afab49d45f07509acf848bfb1311bf6cfb64ad8daa08601000000000026c30500060000006b483045022100d635b8214ee61095917956cdd2a1c0d35e7b135b280704a9db25f9d3a3a957d202204e45da95f8bf029be802c68aafb7f60ef820b194df2871a4a483499632002ca2012102a1608ef89e8b7a80531436eb05421a5dc427c1c1515f6ce8285df1bf20d59219" + }, + { + "txid": "2138de727f692d55e76f9cd9c1ce30203fe85d8fc64a72703fa0ad7b0a31ca6c", + "version": 1, + "vin": [ + { + "txid": "c416dd7cfb276aead083ea7bb3648f50902d6602d58624232dfc5035f1da8a88", + "n": 0, + "addresses": [ + "DscLqW7bs478sVUKzi3e3q11ogmF7mKwnmd" + ], + "isAddress": true, + "value": "100000", + "hex": "473044022032026f00e5012dabfa73821e6396eec427e6352b0f70a1463c032ba9965092e302205e1de3b0c019c25aef610153a90aa2a53845c4fb5af91b5fa32389c1ada295e4012102301f55ea3a582662bd6a87acf3bbedba5c2f8e55b870105cf2af720562eb1636" + } + ], + "vout": [ + { + "value": "10000", + "n": 0, + "spent": true, + "hex": "76a914fec2c387356e5d0a0b2754ef7158f06a4f85e91288ac", + "addresses": [ + "DspBxSac8FWcKWi1MfpZiYZeFPSWRznmBAT" + ], + "isAddress": true + }, + { + "value": "87460", + "n": 1, + "spent": true, + "hex": "76a914e3e138bc8b704663c3bfecc603549d0c795bef3288ac", + "addresses": [ + "DsmjpgebRNYbUtAc3KooGpM1pecV1ENJVUe" + ], + "isAddress": true + } + ], + "blockHash": "000000000000000000062626f17c08bee76c06d41438f6e996c0bfbbc1c2ed16", + "blockHeight": 378646, + "confirmations": 70429, + "blockTime": 1568179113, + "value": "97460", + "valueIn": "100000", + "fees": "2540", + "hex": "0100000001888adaf13550fc2d232486d502662d90508f64b37bea83d0ea6a27fb7cdd16c400000000000000000002102700000000000000001976a914fec2c387356e5d0a0b2754ef7158f06a4f85e91288aca45501000000000000001976a914e3e138bc8b704663c3bfecc603549d0c795bef3288ac000000000000000001a086010000000000edc40500040000006a473044022032026f00e5012dabfa73821e6396eec427e6352b0f70a1463c032ba9965092e302205e1de3b0c019c25aef610153a90aa2a53845c4fb5af91b5fa32389c1ada295e4012102301f55ea3a582662bd6a87acf3bbedba5c2f8e55b870105cf2af720562eb1636" + }, + { + "txid": "c416dd7cfb276aead083ea7bb3648f50902d6602d58624232dfc5035f1da8a88", + "version": 1, + "vin": [ + { + "txid": "1a142ae8243b58062d63eefe3a9e824608ef4ad32fff00726a2ee66f08c165a5", + "n": 0, + "addresses": [ + "DsU58J9shjqUh8QsEYn9N9xdq19SQRnw1WP" + ], + "isAddress": true, + "value": "1000000", + "hex": "4730440220769fd7bcbdf23848258688e60e6be15c16eed200f8c3d92e1e1e0af35f76f5d202200a69bdeba50dfcafeacee8acba1b8ae6608b786861310af6e2faef946d1aa8a0012103308b19c0e8e51700acebce494cd22fe5b2a5723279ecb90cb4e0ecd7c95f4141" + } + ], + "vout": [ + { + "value": "100000", + "n": 0, + "spent": true, + "hex": "76a9147ccf34a1e67d66714f0c162d0e84b9edaad895c688ac", + "addresses": [ + "DscLqW7bs478sVUKzi3e3q11ogmF7mKwnmd" + ], + "isAddress": true + }, + { + "value": "897460", + "n": 1, + "spent": true, + "hex": "76a914e84cf5d4407038a0e0f360dce5799f9882303cef88ac", + "addresses": [ + "Dsn9CTECmGUK8uM8kKiTugmxiy16dh18pRZ" + ], + "isAddress": true + } + ], + "blockHash": "00000000000000001051551adf3ecba1cc7abbe16ae6c534664620dea0a15c92", + "blockHeight": 378093, + "confirmations": 70982, + "blockTime": 1568020338, + "value": "997460", + "valueIn": "1000000", + "fees": "2540", + "hex": "0100000001a565c1086fe62e6a7200ff2fd34aef0846829e3afeee632d06583b24e82a141a00000000000000000002a08601000000000000001976a9147ccf34a1e67d66714f0c162d0e84b9edaad895c688acb4b10d000000000000001976a914e84cf5d4407038a0e0f360dce5799f9882303cef88ac00000000000000000140420f00000000006dc30500020000006a4730440220769fd7bcbdf23848258688e60e6be15c16eed200f8c3d92e1e1e0af35f76f5d202200a69bdeba50dfcafeacee8acba1b8ae6608b786861310af6e2faef946d1aa8a0012103308b19c0e8e51700acebce494cd22fe5b2a5723279ecb90cb4e0ecd7c95f4141" + }, + { + "txid": "1a142ae8243b58062d63eefe3a9e824608ef4ad32fff00726a2ee66f08c165a5", + "version": 1, + "vin": [ + { + "txid": "076325760e3bdc16323b5de8ef5563ef10809568e13d9fc76e2ee8d523bb200c", + "vout": 1, + "n": 0, + "addresses": [ + "DsXJ2WL3RJggGuzdb14ngsZBsovbjJU3vfZ" + ], + "isAddress": true, + "value": "19692760", + "hex": "47304402200363d79ad40b72722a469469ec7af1c8d1d52c48b9acdbc47c542547db091d2f0220312dca3dfd741b461a3dee74e64b6d1d851a8c234253c4226240108eeeb60654012103b8f0e579be248f58d56310e839d0cd0433517a83dc20916ee18e7e3ec2120c84" + } + ], + "vout": [ + { + "value": "1000000", + "n": 0, + "spent": true, + "hex": "76a9142215900ba09320357c5c01b3397cfcbbbc88de6388ac", + "addresses": [ + "DsU58J9shjqUh8QsEYn9N9xdq19SQRnw1WP" + ], + "isAddress": true + }, + { + "value": "18690220", + "n": 1, + "spent": true, + "hex": "76a9142c1a0b285426b6c050a32cc3ef7dc6c6c418aa1288ac", + "addresses": [ + "DsUz6RQnnhzhXphPe7wCRe1JE6Znn912VqC" + ], + "isAddress": true + } + ], + "blockHash": "000000000000000002d73723a283859923c3147c38e0084e6fd5f713234549d1", + "blockHeight": 377709, + "confirmations": 71366, + "blockTime": 1567896183, + "value": "19690220", + "valueIn": "19692760", + "fees": "2540", + "hex": "01000000010c20bb23d5e82e6ec79f3de168958010ef6355efe85d3b3216dc3b0e762563070100000000000000000240420f000000000000001976a9142215900ba09320357c5c01b3397cfcbbbc88de6388acac301d010000000000001976a9142c1a0b285426b6c050a32cc3ef7dc6c6c418aa1288ac000000000000000001d87c2c010000000026c30500060000006a47304402200363d79ad40b72722a469469ec7af1c8d1d52c48b9acdbc47c542547db091d2f0220312dca3dfd741b461a3dee74e64b6d1d851a8c234253c4226240108eeeb60654012103b8f0e579be248f58d56310e839d0cd0433517a83dc20916ee18e7e3ec2120c84" + }, + { + "txid": "076325760e3bdc16323b5de8ef5563ef10809568e13d9fc76e2ee8d523bb200c", + "version": 1, + "vin": [ + { + "txid": "29521bf9516d976364d5dbbda9dfa35229aa52fcc6a3ad3c7d4b11ebe4008620", + "n": 0, + "addresses": [ + "DsesW1sQL9wkP9E3xnxRggR8uWbcyHv9mU2" + ], + "isAddress": true, + "value": "19795300", + "hex": "47304402207c29e0ee6f364841150fffe229ef48f77a8c8fee2e3a11b31aaa69ed1433e6c502204f9b426569ee04ef5319b53f6cd66f7999ba7bd92a8e41c7e95cd7b29ce3090d0121035bb46ab10dde3874cdb079be42261f31144a8ac568307b26e18d9db51aa8ac90" + } + ], + "vout": [ + { + "value": "100000", + "n": 0, + "spent": true, + "hex": "76a91437eb38b48e9113dc0d9a4f020aef3c708823cb2d88ac", + "addresses": [ + "DsW4aSTWVaW1V6jPLu1K9PzSFWBCLJuexkm" + ], + "isAddress": true + }, + { + "value": "19692760", + "n": 1, + "spent": true, + "hex": "76a914456e83a3a589cf1c3547a41f8246a8a5a60624c188ac", + "addresses": [ + "DsXJ2WL3RJggGuzdb14ngsZBsovbjJU3vfZ" + ], + "isAddress": true + } + ], + "blockHash": "000000000000000019d72034c4f14e35f90640c34e4c1ba8c05283ef47f83c99", + "blockHeight": 377637, + "confirmations": 71438, + "blockTime": 1567871358, + "value": "19792760", + "valueIn": "19795300", + "fees": "2540", + "hex": "0100000001208600e4eb114b7d3cada3c6fc52aa2952a3dfa9bddbd56463976d51f91b522900000000000000000002a08601000000000000001976a91437eb38b48e9113dc0d9a4f020aef3c708823cb2d88acd87c2c010000000000001976a914456e83a3a589cf1c3547a41f8246a8a5a60624c188ac000000000000000001640d2e0100000000d4bc0500070000006a47304402207c29e0ee6f364841150fffe229ef48f77a8c8fee2e3a11b31aaa69ed1433e6c502204f9b426569ee04ef5319b53f6cd66f7999ba7bd92a8e41c7e95cd7b29ce3090d0121035bb46ab10dde3874cdb079be42261f31144a8ac568307b26e18d9db51aa8ac90" + }, + { + "txid": "29521bf9516d976364d5dbbda9dfa35229aa52fcc6a3ad3c7d4b11ebe4008620", + "version": 1, + "vin": [ + { + "txid": "4103946f2742b5f9bb5fd348c4722d0479861c4c0a9191d1e7578a7032f01f63", + "n": 0, + "addresses": [ + "DsSpq2ZoacCfmPqz1jtiQ881UsyxYFg3noz" + ], + "isAddress": true, + "value": "28561300", + "hex": "47304402206bc169542469496bcb667b14bbb36b5c14a86b33f3bd23ec2eaa2eb58feb5f3d02206517cc07ee54d148d7932d3c55ac60a28fe4d0dcad50118e8f63cbe764f33ddd01210264de4a69d3486f3fbe51fc422da7d482262e31c140fe2a3122d68ecb6d62a1a2" + } + ], + "vout": [ + { + "value": "19795300", + "n": 0, + "spent": true, + "hex": "76a914988c15c6f686270745e2fa320b5bf522ec0c0d5988ac", + "addresses": [ + "DsesW1sQL9wkP9E3xnxRggR8uWbcyHv9mU2" + ], + "isAddress": true + }, + { + "value": "8763460", + "n": 1, + "spent": true, + "hex": "76a91405392c56a7f131fc28a76f8b20b75ba3f52b767b88ac", + "addresses": [ + "DsRSXMrRri1Pt8qxP7YpR8qcMUxQiSgWkno" + ], + "isAddress": true + } + ], + "blockHash": "00000000000000000e7e8796398f4b9f59b1aa86987d002ce882ec231aa000ee", + "blockHeight": 376019, + "confirmations": 73056, + "blockTime": 1567390537, + "value": "28558760", + "valueIn": "28561300", + "fees": "2540", + "hex": "0100000001631ff032708a57e7d191910a4c1c8679042d72c448d35fbbf9b542276f94034100000000000000000002640d2e010000000000001976a914988c15c6f686270745e2fa320b5bf522ec0c0d5988ac44b885000000000000001976a91405392c56a7f131fc28a76f8b20b75ba3f52b767b88ac00000000000000000194cfb30100000000d2bc0500190000006a47304402206bc169542469496bcb667b14bbb36b5c14a86b33f3bd23ec2eaa2eb58feb5f3d02206517cc07ee54d148d7932d3c55ac60a28fe4d0dcad50118e8f63cbe764f33ddd01210264de4a69d3486f3fbe51fc422da7d482262e31c140fe2a3122d68ecb6d62a1a2" + }, + { + "txid": "4103946f2742b5f9bb5fd348c4722d0479861c4c0a9191d1e7578a7032f01f63", + "version": 1, + "vin": [ + { + "txid": "810cfe2b27d14f6ab7111afa53044c4e7d673f1626004c539e89cc118f9625be", + "vout": 1, + "n": 0, + "addresses": [ + "DsVoRmLjjFPVNTYjkwAM81KCNfhoPFJnFTR" + ], + "isAddress": true, + "value": "28563460", + "hex": "483045022100ec9f9ccfa8cd46c88abac0f9a7322c2ae6818a0bac87926f6acf39aaaf7d214d022005f2389507722c2b984d6a110a89b46141aed3e90fec5f829d7254a3e2e0dcf601210382f288c0618670d925727de89445e38fcef4f5b076b68c73affa9c812e092cdc" + } + ], + "vout": [ + { + "value": "28561300", + "n": 0, + "spent": true, + "hex": "76a914146932bd6eaa9b9c8e249334bc0aaf74147b31c588ac", + "addresses": [ + "DsSpq2ZoacCfmPqz1jtiQ881UsyxYFg3noz" + ], + "isAddress": true + } + ], + "blockHash": "000000000000000001aa65c110419f3d53c56c511b327dc5600063b15f35df5f", + "blockHeight": 376017, + "confirmations": 73058, + "blockTime": 1567389612, + "value": "28561300", + "valueIn": "28563460", + "fees": "2160", + "hex": "0100000001be25968f11cc899e534c0026163f677d4e4c0453fa1a11b76a4fd1272bfe0c810100000000000000000194cfb3010000000000001976a914146932bd6eaa9b9c8e249334bc0aaf74147b31c588ac00000000000000000104d8b30100000000d1bc0500080000006b483045022100ec9f9ccfa8cd46c88abac0f9a7322c2ae6818a0bac87926f6acf39aaaf7d214d022005f2389507722c2b984d6a110a89b46141aed3e90fec5f829d7254a3e2e0dcf601210382f288c0618670d925727de89445e38fcef4f5b076b68c73affa9c812e092cdc" + }, + { + "txid": "810cfe2b27d14f6ab7111afa53044c4e7d673f1626004c539e89cc118f9625be", + "version": 1, + "vin": [ + { + "txid": "bcc5228e9d956918984d1853c31d7edcd862f8a7fca20ded114d93f8a74ad32a", + "vout": 1, + "n": 0, + "addresses": [ + "DsUoWCAxprdGNtKQqambFbTcSBgH1SHn9Gp" + ], + "isAddress": true, + "value": "29800000", + "hex": "483045022100daeed849e3a7d53ac2469cda56487598b4af6f32502b6ec17d2bf046671b8f6d022011f16ade4b20c11ce48bb910cebc19656e668e119071ac3fbeeb3fe411d1b6070121020dcb5dc1d90cb05e23350f2ede85746ec934a3b31a8a520907d47ebc8abeb1e1" + } + ], + "vout": [ + { + "value": "1234000", + "n": 0, + "spent": true, + "hex": "76a914146932bd6eaa9b9c8e249334bc0aaf74147b31c588ac", + "addresses": [ + "DsSpq2ZoacCfmPqz1jtiQ881UsyxYFg3noz" + ], + "isAddress": true + }, + { + "value": "28563460", + "n": 1, + "spent": true, + "hex": "76a914350dbdb43bc1e78bdad96522156fda5378a6c9be88ac", + "addresses": [ + "DsVoRmLjjFPVNTYjkwAM81KCNfhoPFJnFTR" + ], + "isAddress": true + } + ], + "blockHash": "00000000000000000af6dcbafdc58a4aa17a62d99e037a859c86791629f74c90", + "blockHeight": 376016, + "confirmations": 73059, + "blockTime": 1567387305, + "value": "29797460", + "valueIn": "29800000", + "fees": "2540", + "hex": "01000000012ad34aa7f8934d11ed0da2fca7f862d8dc7e1dc353184d981869959d8e22c5bc0100000000000000000250d412000000000000001976a914146932bd6eaa9b9c8e249334bc0aaf74147b31c588ac04d8b3010000000000001976a914350dbdb43bc1e78bdad96522156fda5378a6c9be88ac00000000000000000140b6c60100000000fbb90500030000006b483045022100daeed849e3a7d53ac2469cda56487598b4af6f32502b6ec17d2bf046671b8f6d022011f16ade4b20c11ce48bb910cebc19656e668e119071ac3fbeeb3fe411d1b6070121020dcb5dc1d90cb05e23350f2ede85746ec934a3b31a8a520907d47ebc8abeb1e1" + }, + { + "txid": "bcc5228e9d956918984d1853c31d7edcd862f8a7fca20ded114d93f8a74ad32a", + "version": 1, + "vin": [ + { + "txid": "5015d14dcfd78998cfa13e0325798a74d95bbe75f167a49467303f70dde9bffd", + "n": 0, + "addresses": [ + "DsbaL8f4Uu4bQ6wPpbjcLWxRDZQZo3Ncrrq" + ], + "isAddress": true, + "value": "39900000", + "hex": "47304402206e87253e8eb7629f3529934b831ed251d27bb429dec52cc96eedf2f7b1fa080002203682e702ab885ef2ecf0ec4a524288a1560b3e055550a767d10fb79483a18ba4012102b811228759df7b31eb5a219c4be0841c0341cd1e05a723d0dcba462d2aae0bfd" + } + ], + "vout": [ + { + "value": "10000000", + "n": 0, + "spent": true, + "hex": "76a914989b1aecabf1c24e213cc0f2d8a22ffee25dd4e188ac", + "addresses": [ + "Dsesp1V6DZDEtcq2behmBVKdYqKMdkh96hL" + ], + "isAddress": true + }, + { + "value": "29800000", + "n": 1, + "spent": true, + "hex": "76a9142a194fc92e27fef9cc2b057bc9060c580cbb484888ac", + "addresses": [ + "DsUoWCAxprdGNtKQqambFbTcSBgH1SHn9Gp" + ], + "isAddress": true + } + ], + "blockHash": "000000000000000012f24e779cca63028a7dfae179182feabb065ae40e449199", + "blockHeight": 375290, + "confirmations": 73785, + "blockTime": 1567173553, + "value": "39800000", + "valueIn": "39900000", + "fees": "100000", + "hex": "0100000001fdbfe9dd703f306794a467f175be5bd9748a7925033ea1cf9889d7cf4dd1155000000000000000000002809698000000000000001976a914989b1aecabf1c24e213cc0f2d8a22ffee25dd4e188ac40b6c6010000000000001976a9142a194fc92e27fef9cc2b057bc9060c580cbb484888ac00000000000000000160d3600200000000790b0500030000006a47304402206e87253e8eb7629f3529934b831ed251d27bb429dec52cc96eedf2f7b1fa080002203682e702ab885ef2ecf0ec4a524288a1560b3e055550a767d10fb79483a18ba4012102b811228759df7b31eb5a219c4be0841c0341cd1e05a723d0dcba462d2aae0bfd" + }, + { + "txid": "5015d14dcfd78998cfa13e0325798a74d95bbe75f167a49467303f70dde9bffd", + "version": 1, + "vin": [ + { + "txid": "ac4b4b9af3e0b8cdb7918bb6bfdf9878ace398b92e6e5ef7844936c676041a26", + "vout": 1, + "sequence": 4294967295, + "n": 0, + "addresses": [ + "DsTxPUVFxXeNgu5fzozr4mTR4tqqMaKcvpY" + ], + "isAddress": true, + "value": "50000000", + "hex": "483045022100923900d86dfbfefa31c5789c0d142fd75d18dd91ea13930515c46e280b6f33fc022079fddaf46e6da7978b9226cc09c6d978bca89b37ec99becb65625ddb6d00f9180121039b24b2073eef4835f226bb98ec9cb28b1cd0550c76077d3865a77870f119c344" + } + ], + "vout": [ + { + "value": "39900000", + "n": 0, + "spent": true, + "hex": "76a914746462efaf7a648ccd1a46de4e2842f2b25f498588ac", + "addresses": [ + "DsbaL8f4Uu4bQ6wPpbjcLWxRDZQZo3Ncrrq" + ], + "isAddress": true + }, + { + "value": "10000000", + "n": 1, + "hex": "76a9145f6ef673184369f86779658d13f436a7d303276888ac", + "addresses": [ + "DsZfWcUeaTLtXz3roBmNCNP96srYmDFVZ1W" + ], + "isAddress": true + } + ], + "blockHash": "000000000000000008e0427a4b4e95d540d03fcc28a059861204a8674bdf7a64", + "blockHeight": 330617, + "confirmations": 118458, + "blockTime": 1553754509, + "value": "49900000", + "valueIn": "50000000", + "fees": "100000", + "hex": "0100000001261a0476c6364984f75e6e2eb998e3ac7898dfbfb68b91b7cdb8e0f39a4b4bac0100000000ffffffff0260d360020000000000001976a914746462efaf7a648ccd1a46de4e2842f2b25f498588ac809698000000000000001976a9145f6ef673184369f86779658d13f436a7d303276888ac00000000000000000180f0fa020000000035ef0400150000006b483045022100923900d86dfbfefa31c5789c0d142fd75d18dd91ea13930515c46e280b6f33fc022079fddaf46e6da7978b9226cc09c6d978bca89b37ec99becb65625ddb6d00f9180121039b24b2073eef4835f226bb98ec9cb28b1cd0550c76077d3865a77870f119c344" + }, + { + "txid": "ac4b4b9af3e0b8cdb7918bb6bfdf9878ace398b92e6e5ef7844936c676041a26", + "version": 1, + "vin": [ + { + "txid": "9ecec2fc079ebc6646de451b73231cf422f7ad761472b6482c7453a82c87a321", + "vout": 5, + "sequence": 4294967295, + "n": 0, + "addresses": [ + "DsfMzjYfieAwq2zpeCRyDMiSVDxfEFfRNui" + ], + "isAddress": true, + "value": "7078093729", + "hex": "483045022100fef9f8fd733a94ee691d1845442335a3693882e441078c5dc1220ce21ce93d0f0220308aed0bd8cb2e5a040f46426be0b25fdb3605bb6ae3ec8252055bc2cbd13738012102167188e52e860521bd21cc3548f4250c75309a70ec182f081b4d04f788a48914" + } + ], + "vout": [ + { + "value": "7028091199", + "n": 0, + "spent": true, + "hex": "76a914d3b1286986e589b0e819f98e2a2462e5a17f1ef288ac", + "addresses": [ + "DskGEJ3taowt2PxqopPLSUoVh9eq4nWqDXT" + ], + "isAddress": true + }, + { + "value": "50000000", + "n": 1, + "spent": true, + "hex": "76a91420cf523034c462f8e09fc0fd35c47760b822398888ac", + "addresses": [ + "DsTxPUVFxXeNgu5fzozr4mTR4tqqMaKcvpY" + ], + "isAddress": true + } + ], + "blockHash": "000000000000000016d937210760bb0fbde311d3bfb0719abeb6a2230c537817", + "blockHeight": 323381, + "confirmations": 125694, + "blockTime": 1551595302, + "value": "7078091199", + "valueIn": "7078093729", + "fees": "2530", + "hex": "010000000121a3872ca853742c48b6721476adf722f41c23731b45de4666bc9e07fcc2ce9e0500000001ffffffff023f29e8a20100000000001976a914d3b1286986e589b0e819f98e2a2462e5a17f1ef288ac80f0fa020000000000001976a91420cf523034c462f8e09fc0fd35c47760b822398888ac000000000000000001a123e3a501000000a6ea0400030000006b483045022100fef9f8fd733a94ee691d1845442335a3693882e441078c5dc1220ce21ce93d0f0220308aed0bd8cb2e5a040f46426be0b25fdb3605bb6ae3ec8252055bc2cbd13738012102167188e52e860521bd21cc3548f4250c75309a70ec182f081b4d04f788a48914" + } + ], + "usedTokens": 27, + "tokens": [ + { + "type": "XPUBAddress", + "name": "DsTxPUVFxXeNgu5fzozr4mTR4tqqMaKcvpY", + "path": "m/44'/42'/0'/0/0", + "transfers": 11, + "decimals": 8, + "balance": "19370607", + "totalReceived": "75347145", + "totalSent": "55976538" + }, + { + "type": "XPUBAddress", + "name": "Dsfe2vHn1TVqHJWeD37BXL1y31nWeBQqB7c", + "path": "m/44'/42'/0'/0/8", + "transfers": 1, + "decimals": 8, + "balance": "19457", + "totalReceived": "19457", + "totalSent": "0" + }, + { + "type": "XPUBAddress", + "name": "DsdwT3GGppDmuPSEetywszY7Y95jGpLopSU", + "path": "m/44'/42'/0'/0/9", + "transfers": 1, + "decimals": 8, + "balance": "19452", + "totalReceived": "19452", + "totalSent": "0" + }, + { + "type": "XPUBAddress", + "name": "Dsc4yhfEdqj31WCbtRgv2cXNCtdJNHFCg4o", + "path": "m/44'/42'/0'/0/10", + "transfers": 1, + "decimals": 8, + "balance": "85300", + "totalReceived": "85300", + "totalSent": "0" + }, + { + "type": "XPUBAddress", + "name": "DsoLtxGAPidBykdxWkzRAmhgBwBeqLdJEXR", + "path": "m/44'/42'/0'/0/23", + "transfers": 1, + "decimals": 8, + "balance": "19686", + "totalReceived": "19686", + "totalSent": "0" + } + ] +} diff --git a/mock/ext-api-data/digibyte-api_v2_address_DEs1RJKuASSjfphFJdxX9eidrjWewMZgAi__details_txs.json b/mock/ext-api-data/digibyte-api_v2_address_DEs1RJKuASSjfphFJdxX9eidrjWewMZgAi__details_txs.json new file mode 100644 index 000000000..cdc77c86e --- /dev/null +++ b/mock/ext-api-data/digibyte-api_v2_address_DEs1RJKuASSjfphFJdxX9eidrjWewMZgAi__details_txs.json @@ -0,0 +1 @@ +{"page":1,"totalPages":384,"itemsOnPage":10,"address":"DEs1RJKuASSjfphFJdxX9eidrjWewMZgAi","balance":"0","totalReceived":"244615238234","totalSent":"244615238234","unconfirmedBalance":"0","unconfirmedTxs":0,"txs":3840,"transactions":[{"txid":"52618b3146251b767d6e9d0f4076da68d2af5b780be52eb34cf1c45188954acb","version":1,"vin":[{"txid":"9843f6b1c966663f6942061207b4fd549a23bcd0844827eea397dc2fc299e74f","sequence":4294967295,"n":0,"addresses":["DEs1RJKuASSjfphFJdxX9eidrjWewMZgAi"],"isAddress":true,"value":"62143000","hex":"47304402207bd05f2a4487ebca7d722427497370a5cdcae44fb2e9a314d24a548c03261f2e02205883efc76c704dd67492adbb27a9d049d254f367e6b34c06de4b742dc59bdc5f0141041dd9c41a6c1a3ea6c9fd53eecc0314c79386eb56f380552d46644d106bdbc4dfd389027e1498313480441bbf5130461af785656deaea87348dd7ac523eaeff48"}],"vout":[{"value":"62142000","n":0,"spent":true,"hex":"76a914562e330d8879eeaf17c72c8ad7f3acb4ebb6262c88ac","addresses":["DCzmzkMBqEz2tLn47W9YuNAV9cFzuWCydW"],"isAddress":true},{"value":"0","n":1,"hex":"6a45524d555453422e41432e544800000000000029bfa398bee3241347368c2d4d758575c7fe00d60c05f90d1e6ddc36f99ef2f27683c59e41bb4c803c710e33ed63faefb68089","addresses":["OP_RETURN 524d555453422e41432e544800000000000029bfa398bee3241347368c2d4d758575c7fe00d60c05f90d1e6ddc36f99ef2f27683c59e41bb4c803c710e33ed63faefb68089"],"isAddress":false}],"blockHash":"9c082ff8666f530e114f9c07f564211a43d2809c6248e0b896c3787e69e1d963","blockHeight":10869003,"confirmations":3488,"blockTime":1590017999,"value":"62142000","valueIn":"62143000","fees":"1000","hex":"01000000014fe799c22fdc97a3ee274884d0bc239a54fdb407120642693f6666c9b1f64398000000008a47304402207bd05f2a4487ebca7d722427497370a5cdcae44fb2e9a314d24a548c03261f2e02205883efc76c704dd67492adbb27a9d049d254f367e6b34c06de4b742dc59bdc5f0141041dd9c41a6c1a3ea6c9fd53eecc0314c79386eb56f380552d46644d106bdbc4dfd389027e1498313480441bbf5130461af785656deaea87348dd7ac523eaeff48ffffffff023036b403000000001976a914562e330d8879eeaf17c72c8ad7f3acb4ebb6262c88ac0000000000000000476a45524d555453422e41432e544800000000000029bfa398bee3241347368c2d4d758575c7fe00d60c05f90d1e6ddc36f99ef2f27683c59e41bb4c803c710e33ed63faefb6808900000000"},{"txid":"9843f6b1c966663f6942061207b4fd549a23bcd0844827eea397dc2fc299e74f","version":1,"vin":[{"txid":"b178d6584fe3b37d978f29f0fff899e6d36be05486e8a75b9d5b41bb3edaafcb","sequence":4294967295,"n":0,"addresses":["DCzmzkMBqEz2tLn47W9YuNAV9cFzuWCydW"],"isAddress":true,"value":"62144000","hex":"473044022030312758b634855268aecd2b006c5ae8951723dbb76bac4af98b128f61b83aff022016069738e950590202c6d705d67da443848c05d4bf8ae0071856a8dff548b9ab012102aa3f5da884ab5654137cf660576e590830f6ec177ca84629d5a0264a1e494057"}],"vout":[{"value":"62143000","n":0,"spent":true,"hex":"76a9146aa65418d9de46d678eb71db1d2616f5a96acdc588ac","addresses":["DEs1RJKuASSjfphFJdxX9eidrjWewMZgAi"],"isAddress":true},{"value":"0","n":1,"hex":"6a45524d555453422e41432e544800000000000029bfa398bee3241347368c2d4d758575c7fe00d60c05f90d1e6ddc36f99ef2f27683c59e41bb4c803c710e33ed63faefb68089","addresses":["OP_RETURN 524d555453422e41432e544800000000000029bfa398bee3241347368c2d4d758575c7fe00d60c05f90d1e6ddc36f99ef2f27683c59e41bb4c803c710e33ed63faefb68089"],"isAddress":false}],"blockHash":"e3e584e9072be121b3b1e94d2495a3c3974e0df1cfedc136936b70a5a5cac801","blockHeight":10869002,"confirmations":3489,"blockTime":1590017991,"value":"62143000","valueIn":"62144000","fees":"1000","hex":"0100000001cbafda3ebb415b9d5ba7e88654e06bd3e699f8fff0298f977db3e34f58d678b1000000006a473044022030312758b634855268aecd2b006c5ae8951723dbb76bac4af98b128f61b83aff022016069738e950590202c6d705d67da443848c05d4bf8ae0071856a8dff548b9ab012102aa3f5da884ab5654137cf660576e590830f6ec177ca84629d5a0264a1e494057ffffffff02183ab403000000001976a9146aa65418d9de46d678eb71db1d2616f5a96acdc588ac0000000000000000476a45524d555453422e41432e544800000000000029bfa398bee3241347368c2d4d758575c7fe00d60c05f90d1e6ddc36f99ef2f27683c59e41bb4c803c710e33ed63faefb6808900000000"},{"txid":"9d880c73ad1682b03339e884b97b022f408d90597d4c00a716b954724fed8e5e","version":1,"vin":[{"txid":"9e0487ae145d698e1eae57bf5a5c9bfbd2a8cb2a41dabefef822c9da976c5ecc","sequence":4294967295,"n":0,"addresses":["DEs1RJKuASSjfphFJdxX9eidrjWewMZgAi"],"isAddress":true,"value":"61627000","hex":"47304402207eb214458be2185d7aa3d329995a9041ec29deef17ea9c2d1b34951c3582e3f302207415b095de42a5ad7b0e1cfa6006ec67ebe7c075e124d47c08f99daad60bb7010141041dd9c41a6c1a3ea6c9fd53eecc0314c79386eb56f380552d46644d106bdbc4dfd389027e1498313480441bbf5130461af785656deaea87348dd7ac523eaeff48"}],"vout":[{"value":"61626000","n":0,"spent":true,"hex":"76a914562e330d8879eeaf17c72c8ad7f3acb4ebb6262c88ac","addresses":["DCzmzkMBqEz2tLn47W9YuNAV9cFzuWCydW"],"isAddress":true},{"value":"0","n":1,"hex":"6a45524d555453422e41432e54480000000000002998a398bee3241347368c2d4d758575c7fe00ba8e9832f5eadcfc68d11b1417f1787de6ae95a47b0830c527be09ff693a17eb","addresses":["OP_RETURN 524d555453422e41432e54480000000000002998a398bee3241347368c2d4d758575c7fe00ba8e9832f5eadcfc68d11b1417f1787de6ae95a47b0830c527be09ff693a17eb"],"isAddress":false}],"blockHash":"847a223814159f3b0670c15742b778688aa381883cedc59456ab66ef4ab78811","blockHeight":10863931,"confirmations":8560,"blockTime":1589942553,"value":"61626000","valueIn":"61627000","fees":"1000","hex":"0100000001cc5e6c97dac922f8febeda412acba8d2fb9b5c5abf57ae1e8e695d14ae87049e000000008a47304402207eb214458be2185d7aa3d329995a9041ec29deef17ea9c2d1b34951c3582e3f302207415b095de42a5ad7b0e1cfa6006ec67ebe7c075e124d47c08f99daad60bb7010141041dd9c41a6c1a3ea6c9fd53eecc0314c79386eb56f380552d46644d106bdbc4dfd389027e1498313480441bbf5130461af785656deaea87348dd7ac523eaeff48ffffffff029056ac03000000001976a914562e330d8879eeaf17c72c8ad7f3acb4ebb6262c88ac0000000000000000476a45524d555453422e41432e54480000000000002998a398bee3241347368c2d4d758575c7fe00ba8e9832f5eadcfc68d11b1417f1787de6ae95a47b0830c527be09ff693a17eb00000000"},{"txid":"9e0487ae145d698e1eae57bf5a5c9bfbd2a8cb2a41dabefef822c9da976c5ecc","version":1,"vin":[{"txid":"b215c706e32c44a1a30e110a1b60221c30c578d11d42142734803c90ced368df","sequence":4294967295,"n":0,"addresses":["DCzmzkMBqEz2tLn47W9YuNAV9cFzuWCydW"],"isAddress":true,"value":"61628000","hex":"473044022059d09606a6e4ad6c854cba45e9b13d7be52641c705fee95637c90c7f6001ecd802204fb5b67f02fe9df02e89011ff808e17fbb9f406e1290739820ae438ead9e7069012102aa3f5da884ab5654137cf660576e590830f6ec177ca84629d5a0264a1e494057"}],"vout":[{"value":"61627000","n":0,"spent":true,"hex":"76a9146aa65418d9de46d678eb71db1d2616f5a96acdc588ac","addresses":["DEs1RJKuASSjfphFJdxX9eidrjWewMZgAi"],"isAddress":true},{"value":"0","n":1,"hex":"6a45524d555453422e41432e54480000000000002998a398bee3241347368c2d4d758575c7fe00ba8e9832f5eadcfc68d11b1417f1787de6ae95a47b0830c527be09ff693a17eb","addresses":["OP_RETURN 524d555453422e41432e54480000000000002998a398bee3241347368c2d4d758575c7fe00ba8e9832f5eadcfc68d11b1417f1787de6ae95a47b0830c527be09ff693a17eb"],"isAddress":false}],"blockHash":"847a223814159f3b0670c15742b778688aa381883cedc59456ab66ef4ab78811","blockHeight":10863931,"confirmations":8560,"blockTime":1589942553,"value":"61627000","valueIn":"61628000","fees":"1000","hex":"0100000001df68d3ce903c80342714421dd178c5301c22601b0a110ea3a1442ce306c715b2000000006a473044022059d09606a6e4ad6c854cba45e9b13d7be52641c705fee95637c90c7f6001ecd802204fb5b67f02fe9df02e89011ff808e17fbb9f406e1290739820ae438ead9e7069012102aa3f5da884ab5654137cf660576e590830f6ec177ca84629d5a0264a1e494057ffffffff02785aac03000000001976a9146aa65418d9de46d678eb71db1d2616f5a96acdc588ac0000000000000000476a45524d555453422e41432e54480000000000002998a398bee3241347368c2d4d758575c7fe00ba8e9832f5eadcfc68d11b1417f1787de6ae95a47b0830c527be09ff693a17eb00000000"},{"txid":"565a6acc5b6e0832844a6cf1fb3a84330a57021256aebd667a99fddecde76ea7","version":1,"vin":[{"txid":"d32d7c65d4fdd8b7f77379e3c2f13dafc38ac4ba5bad391a8271305674be5deb","sequence":4294967295,"n":0,"addresses":["DEs1RJKuASSjfphFJdxX9eidrjWewMZgAi"],"isAddress":true,"value":"61733000","hex":"473044022046232395d40a79d525972cf35962c6b082bf7e562315ffe20092371ce167010f022001d24738b76ae32b422465f2f8d2e7609c8243ac2d9f5698d4e795d973383f040141041dd9c41a6c1a3ea6c9fd53eecc0314c79386eb56f380552d46644d106bdbc4dfd389027e1498313480441bbf5130461af785656deaea87348dd7ac523eaeff48"}],"vout":[{"value":"61732000","n":0,"spent":true,"hex":"76a914562e330d8879eeaf17c72c8ad7f3acb4ebb6262c88ac","addresses":["DCzmzkMBqEz2tLn47W9YuNAV9cFzuWCydW"],"isAddress":true},{"value":"0","n":1,"hex":"6a45524d555453422e41432e5448000000000000297fa398bee3241347368c2d4d758575c7fe00b2bcd12aa47cd973e773af9d10317ca9d8d0210a141ffe684c7fef9a2477b7e8","addresses":["OP_RETURN 524d555453422e41432e5448000000000000297fa398bee3241347368c2d4d758575c7fe00b2bcd12aa47cd973e773af9d10317ca9d8d0210a141ffe684c7fef9a2477b7e8"],"isAddress":false}],"blockHash":"0000000000000000824fa33e16a642fb8a79e5507b64e4aa0534f766bf974978","blockHeight":10863924,"confirmations":8567,"blockTime":1589942406,"value":"61732000","valueIn":"61733000","fees":"1000","hex":"0100000001eb5dbe74563071821a39ad5bbac48ac3af3df1c2e37973f7b7d8fdd4657c2dd3000000008a473044022046232395d40a79d525972cf35962c6b082bf7e562315ffe20092371ce167010f022001d24738b76ae32b422465f2f8d2e7609c8243ac2d9f5698d4e795d973383f040141041dd9c41a6c1a3ea6c9fd53eecc0314c79386eb56f380552d46644d106bdbc4dfd389027e1498313480441bbf5130461af785656deaea87348dd7ac523eaeff48ffffffff02a0f4ad03000000001976a914562e330d8879eeaf17c72c8ad7f3acb4ebb6262c88ac0000000000000000476a45524d555453422e41432e5448000000000000297fa398bee3241347368c2d4d758575c7fe00b2bcd12aa47cd973e773af9d10317ca9d8d0210a141ffe684c7fef9a2477b7e800000000"},{"txid":"d32d7c65d4fdd8b7f77379e3c2f13dafc38ac4ba5bad391a8271305674be5deb","version":1,"vin":[{"txid":"aca9b244d37d027233d37c9d8e83dcb0ced0bd5adda0d1eb2b10ade2e830117e","sequence":4294967295,"n":0,"addresses":["DCzmzkMBqEz2tLn47W9YuNAV9cFzuWCydW"],"isAddress":true,"value":"61734000","hex":"47304402204a563a55460ce140c98a02c78cc926ea4fa0980963a5e1ad3806b066fcf3c79f02207a31e1604fd04996fd36344dcc70f2fd76412118dde4353e599711de5c5850ef012102aa3f5da884ab5654137cf660576e590830f6ec177ca84629d5a0264a1e494057"}],"vout":[{"value":"61733000","n":0,"spent":true,"hex":"76a9146aa65418d9de46d678eb71db1d2616f5a96acdc588ac","addresses":["DEs1RJKuASSjfphFJdxX9eidrjWewMZgAi"],"isAddress":true},{"value":"0","n":1,"hex":"6a45524d555453422e41432e5448000000000000297fa398bee3241347368c2d4d758575c7fe00b2bcd12aa47cd973e773af9d10317ca9d8d0210a141ffe684c7fef9a2477b7e8","addresses":["OP_RETURN 524d555453422e41432e5448000000000000297fa398bee3241347368c2d4d758575c7fe00b2bcd12aa47cd973e773af9d10317ca9d8d0210a141ffe684c7fef9a2477b7e8"],"isAddress":false}],"blockHash":"0000000000000000824fa33e16a642fb8a79e5507b64e4aa0534f766bf974978","blockHeight":10863924,"confirmations":8567,"blockTime":1589942406,"value":"61733000","valueIn":"61734000","fees":"1000","hex":"01000000017e1130e8e2ad102bebd1a0dd5abdd0ceb0dc838e9d7cd33372027dd344b2a9ac000000006a47304402204a563a55460ce140c98a02c78cc926ea4fa0980963a5e1ad3806b066fcf3c79f02207a31e1604fd04996fd36344dcc70f2fd76412118dde4353e599711de5c5850ef012102aa3f5da884ab5654137cf660576e590830f6ec177ca84629d5a0264a1e494057ffffffff0288f8ad03000000001976a9146aa65418d9de46d678eb71db1d2616f5a96acdc588ac0000000000000000476a45524d555453422e41432e5448000000000000297fa398bee3241347368c2d4d758575c7fe00b2bcd12aa47cd973e773af9d10317ca9d8d0210a141ffe684c7fef9a2477b7e800000000"},{"txid":"aa8f2b0289f48a46521273f5b0664f5c8b4d62516be5a3ae9d09c2a8d0082a72","version":1,"vin":[{"txid":"083c2562fdc327c0f4d2a595b4858cd8b2abc07204dc118c8cf1d123ea2c8708","sequence":4294967295,"n":0,"addresses":["DEs1RJKuASSjfphFJdxX9eidrjWewMZgAi"],"isAddress":true,"value":"61739000","hex":"473044022043b9d64b14a9132004d46871e3e9ecadb189a05f3b60cc92d75c59fb3668fa980220186a7e0af36bda79438502af16ad2980c86a2e923ba549ac5fa0dbbac77a5d6a0141041dd9c41a6c1a3ea6c9fd53eecc0314c79386eb56f380552d46644d106bdbc4dfd389027e1498313480441bbf5130461af785656deaea87348dd7ac523eaeff48"}],"vout":[{"value":"61738000","n":0,"spent":true,"hex":"76a914562e330d8879eeaf17c72c8ad7f3acb4ebb6262c88ac","addresses":["DCzmzkMBqEz2tLn47W9YuNAV9cFzuWCydW"],"isAddress":true},{"value":"0","n":1,"hex":"6a45524d555453422e41432e5448000000000000297ea398bee3241347368c2d4d758575c7fe002b23ecc5a066a8f952dbc9079ff75b3b2ae6650325c287a0ffb8677a1137ce36","addresses":["OP_RETURN 524d555453422e41432e5448000000000000297ea398bee3241347368c2d4d758575c7fe002b23ecc5a066a8f952dbc9079ff75b3b2ae6650325c287a0ffb8677a1137ce36"],"isAddress":false}],"blockHash":"0000000000000000437bee40996add8cf12f928f8d610dce4a3836cb499fdc27","blockHeight":10863919,"confirmations":8572,"blockTime":1589942373,"value":"61738000","valueIn":"61739000","fees":"1000","hex":"010000000108872cea23d1f18c8c11dc0472c0abb2d88c85b495a5d2f4c027c3fd62253c08000000008a473044022043b9d64b14a9132004d46871e3e9ecadb189a05f3b60cc92d75c59fb3668fa980220186a7e0af36bda79438502af16ad2980c86a2e923ba549ac5fa0dbbac77a5d6a0141041dd9c41a6c1a3ea6c9fd53eecc0314c79386eb56f380552d46644d106bdbc4dfd389027e1498313480441bbf5130461af785656deaea87348dd7ac523eaeff48ffffffff02100cae03000000001976a914562e330d8879eeaf17c72c8ad7f3acb4ebb6262c88ac0000000000000000476a45524d555453422e41432e5448000000000000297ea398bee3241347368c2d4d758575c7fe002b23ecc5a066a8f952dbc9079ff75b3b2ae6650325c287a0ffb8677a1137ce3600000000"},{"txid":"083c2562fdc327c0f4d2a595b4858cd8b2abc07204dc118c8cf1d123ea2c8708","version":1,"vin":[{"txid":"b48316c1c90f0f107c884391a458e32d4353a6efa2d86f365ea2ae6325225c48","sequence":4294967295,"n":0,"addresses":["DCzmzkMBqEz2tLn47W9YuNAV9cFzuWCydW"],"isAddress":true,"value":"61740000","hex":"47304402205110c23ef48578efeb572e5222e564261b699bfeb47d39644838dc22a7fbcab902206229983ac8734619759383e927f61139c2f4d36af4be9da385eb8787075673a9012102aa3f5da884ab5654137cf660576e590830f6ec177ca84629d5a0264a1e494057"}],"vout":[{"value":"61739000","n":0,"spent":true,"hex":"76a9146aa65418d9de46d678eb71db1d2616f5a96acdc588ac","addresses":["DEs1RJKuASSjfphFJdxX9eidrjWewMZgAi"],"isAddress":true},{"value":"0","n":1,"hex":"6a45524d555453422e41432e5448000000000000297ea398bee3241347368c2d4d758575c7fe002b23ecc5a066a8f952dbc9079ff75b3b2ae6650325c287a0ffb8677a1137ce36","addresses":["OP_RETURN 524d555453422e41432e5448000000000000297ea398bee3241347368c2d4d758575c7fe002b23ecc5a066a8f952dbc9079ff75b3b2ae6650325c287a0ffb8677a1137ce36"],"isAddress":false}],"blockHash":"0000000000000000437bee40996add8cf12f928f8d610dce4a3836cb499fdc27","blockHeight":10863919,"confirmations":8572,"blockTime":1589942373,"value":"61739000","valueIn":"61740000","fees":"1000","hex":"0100000001485c222563aea25e366fd8a2efa653432de358a49143887c100f0fc9c11683b4000000006a47304402205110c23ef48578efeb572e5222e564261b699bfeb47d39644838dc22a7fbcab902206229983ac8734619759383e927f61139c2f4d36af4be9da385eb8787075673a9012102aa3f5da884ab5654137cf660576e590830f6ec177ca84629d5a0264a1e494057ffffffff02f80fae03000000001976a9146aa65418d9de46d678eb71db1d2616f5a96acdc588ac0000000000000000476a45524d555453422e41432e5448000000000000297ea398bee3241347368c2d4d758575c7fe002b23ecc5a066a8f952dbc9079ff75b3b2ae6650325c287a0ffb8677a1137ce3600000000"},{"txid":"aa6e59af4733d5de78a80f342de5c86cfd29ece94a240a34f9c03ee351907f40","version":1,"vin":[{"txid":"30508fb951fdd4feefab4e0ce0d169657a9922a5a87c8840e8a25222db2c9f16","sequence":4294967295,"n":0,"addresses":["DEs1RJKuASSjfphFJdxX9eidrjWewMZgAi"],"isAddress":true,"value":"61775000","hex":"47304402205a24ed8a11b7d9a3b0125513cd96546a38260f04b844d974082798b17039628102203fb48a3c1c54a436218afe5ea022074c8a6e07f329c5fef7ccf1186feda96aee0141041dd9c41a6c1a3ea6c9fd53eecc0314c79386eb56f380552d46644d106bdbc4dfd389027e1498313480441bbf5130461af785656deaea87348dd7ac523eaeff48"}],"vout":[{"value":"61774000","n":0,"spent":true,"hex":"76a914562e330d8879eeaf17c72c8ad7f3acb4ebb6262c88ac","addresses":["DCzmzkMBqEz2tLn47W9YuNAV9cFzuWCydW"],"isAddress":true},{"value":"0","n":1,"hex":"6a45524d555453422e41432e544800000000000029aba398bee3241347368c2d4d758575c7fe0001299f8ab6e5ea61c29b366468451b067604214eb037811a7d67c4d785a9d956","addresses":["OP_RETURN 524d555453422e41432e544800000000000029aba398bee3241347368c2d4d758575c7fe0001299f8ab6e5ea61c29b366468451b067604214eb037811a7d67c4d785a9d956"],"isAddress":false}],"blockHash":"00000000000000005f8107124e967386137af8c6ae9cb7603711bccfbedd9fa9","blockHeight":10863261,"confirmations":9230,"blockTime":1589932487,"value":"61774000","valueIn":"61775000","fees":"1000","hex":"0100000001169f2cdb2252a2e840887ca8a522997a6569d1e00c4eabeffed4fd51b98f5030000000008a47304402205a24ed8a11b7d9a3b0125513cd96546a38260f04b844d974082798b17039628102203fb48a3c1c54a436218afe5ea022074c8a6e07f329c5fef7ccf1186feda96aee0141041dd9c41a6c1a3ea6c9fd53eecc0314c79386eb56f380552d46644d106bdbc4dfd389027e1498313480441bbf5130461af785656deaea87348dd7ac523eaeff48ffffffff02b098ae03000000001976a914562e330d8879eeaf17c72c8ad7f3acb4ebb6262c88ac0000000000000000476a45524d555453422e41432e544800000000000029aba398bee3241347368c2d4d758575c7fe0001299f8ab6e5ea61c29b366468451b067604214eb037811a7d67c4d785a9d95600000000"},{"txid":"30508fb951fdd4feefab4e0ce0d169657a9922a5a87c8840e8a25222db2c9f16","version":1,"vin":[{"txid":"28cc8cf9a2d1012843cb11236b1ad118b3f8467ff76317242cab0c5c9f2821cb","sequence":4294967295,"n":0,"addresses":["DCzmzkMBqEz2tLn47W9YuNAV9cFzuWCydW"],"isAddress":true,"value":"61776000","hex":"4730440220491a71aa59efd0a71754a52e0bbb5791581c30fa5c4f1760b1bc33da45d1358002207476d8ff39997599de89f28ae3188b7f26b19a15a6530079bfcf707eb91a04af012102aa3f5da884ab5654137cf660576e590830f6ec177ca84629d5a0264a1e494057"}],"vout":[{"value":"61775000","n":0,"spent":true,"hex":"76a9146aa65418d9de46d678eb71db1d2616f5a96acdc588ac","addresses":["DEs1RJKuASSjfphFJdxX9eidrjWewMZgAi"],"isAddress":true},{"value":"0","n":1,"hex":"6a45524d555453422e41432e544800000000000029aba398bee3241347368c2d4d758575c7fe0001299f8ab6e5ea61c29b366468451b067604214eb037811a7d67c4d785a9d956","addresses":["OP_RETURN 524d555453422e41432e544800000000000029aba398bee3241347368c2d4d758575c7fe0001299f8ab6e5ea61c29b366468451b067604214eb037811a7d67c4d785a9d956"],"isAddress":false}],"blockHash":"00000000000000005f8107124e967386137af8c6ae9cb7603711bccfbedd9fa9","blockHeight":10863261,"confirmations":9230,"blockTime":1589932487,"value":"61775000","valueIn":"61776000","fees":"1000","hex":"0100000001cb21289f5c0cab2c241763f77f46f8b318d11a6b2311cb432801d1a2f98ccc28000000006a4730440220491a71aa59efd0a71754a52e0bbb5791581c30fa5c4f1760b1bc33da45d1358002207476d8ff39997599de89f28ae3188b7f26b19a15a6530079bfcf707eb91a04af012102aa3f5da884ab5654137cf660576e590830f6ec177ca84629d5a0264a1e494057ffffffff02989cae03000000001976a9146aa65418d9de46d678eb71db1d2616f5a96acdc588ac0000000000000000476a45524d555453422e41432e544800000000000029aba398bee3241347368c2d4d758575c7fe0001299f8ab6e5ea61c29b366468451b067604214eb037811a7d67c4d785a9d95600000000"}]} diff --git a/mock/ext-api-data/digibyte-api_v2_xpub_zpub6ricE56nzsDeTAVo4w68vQQ3tRvR6C18JjKVsgbiRFjEawGV9SuS2gfkpm5qFxjbTNPPuvAA3cqRsxNHxFwVnpYD2Lawjtb3wowbFdwmjow__details_txs.json b/mock/ext-api-data/digibyte-api_v2_xpub_zpub6ricE56nzsDeTAVo4w68vQQ3tRvR6C18JjKVsgbiRFjEawGV9SuS2gfkpm5qFxjbTNPPuvAA3cqRsxNHxFwVnpYD2Lawjtb3wowbFdwmjow__details_txs.json new file mode 100644 index 000000000..575335381 --- /dev/null +++ b/mock/ext-api-data/digibyte-api_v2_xpub_zpub6ricE56nzsDeTAVo4w68vQQ3tRvR6C18JjKVsgbiRFjEawGV9SuS2gfkpm5qFxjbTNPPuvAA3cqRsxNHxFwVnpYD2Lawjtb3wowbFdwmjow__details_txs.json @@ -0,0 +1,389 @@ +{ + "page": 1, + "totalPages": 1, + "itemsOnPage": 1000, + "address": "zpub6ricE56nzsDeTAVo4w68vQQ3tRvR6C18JjKVsgbiRFjEawGV9SuS2gfkpm5qFxjbTNPPuvAA3cqRsxNHxFwVnpYD2Lawjtb3wowbFdwmjow", + "balance": "2599896040", + "totalReceived": "6895667780", + "totalSent": "4295771740", + "unconfirmedBalance": "0", + "unconfirmedTxs": 0, + "txs": 7, + "transactions": [ + { + "txid": "e13c81f4450e43ef8ef10dea8f4f9d53f357266563462df32a7fd61eb71bd190", + "version": 1, + "vin": [ + { + "txid": "34fac508c701939ac0fcb62bc436281cc28588d7986c5aa51de99e9835b9217b", + "vout": 1, + "n": 0, + "addresses": [ + "dgb1qxxdszsfkv4uvw8kzzl2wfatts5r9zex69x6076" + ], + "isAddress": true, + "value": "598908696" + } + ], + "vout": [ + { + "value": "10000000", + "n": 0, + "hex": "0014428a3010eb79c4d32478404200dbd41042e61fce", + "addresses": [ + "dgb1qg29rqy8t08zdxfrcgppqpk75zppwv87wknuder" + ], + "isAddress": true + }, + { + "value": "588896040", + "n": 1, + "hex": "00146542b8b7859994b18df4b71c72c4a72ed113662e", + "addresses": [ + "dgb1qv4pt3du9nx2trr05kuw893989mg3xe3w322vy7" + ], + "isAddress": true + } + ], + "blockHash": "000000000000000733a44ab2efd51c9485b05d905d2ba9092f716dcc0083116c", + "blockHeight": 9763292, + "confirmations": 1062143, + "blockTime": 1573501957, + "value": "598896040", + "valueIn": "598908696", + "fees": "12656", + "hex": "010000000001017b21b935989ee91da55a6c98d78885c21c2836c42bb6fcc09a9301c708c5fa34010000000000000000028096980000000000160014428a3010eb79c4d32478404200dbd41042e61fce28d71923000000001600146542b8b7859994b18df4b71c72c4a72ed113662e02473044022023b050ed97c4c7e334fec8efa3f27754e65c1e66a60ce142b2f8e2c16a1c847b02204a2e7d8a470a8978735a0b6d0f3649da6489612256f7cacd52e95034cc05365e012102cc9d7c2383e8f7c18e5af1852ddc35c5c4355a262a68b9d499ba173f6200ff9500000000" + }, + { + "txid": "303aa433530cb32762f8068ae14022e9a759b6c40bb69cee7e77abca333db317", + "version": 1, + "vin": [ + { + "txid": "d8d05cee8623257853b90cb1b0ff6c8e4bf5509818e812510f6715015fac1599", + "sequence": 4294967295, + "n": 0, + "addresses": [ + "DTVYvQYvoXQjsiZQdvT9AaBjyQJr8TjAWu" + ], + "isAddress": true, + "value": "48587940518800", + "hex": "483045022100de758903643db73bc56bcd6b3e1e4bdafb3bd9b7a844286f66317de7c90b868702207eba0eeb32c817df9e79df2aad5f192808941ccb5d18430f9ee7ea18b8b1abad0121038f47ad4221aa24dbefe2b439f644b3af71428a7eb9e837517a162710fe631cf7" + } + ], + "vout": [ + { + "value": "48585940500900", + "n": 0, + "spent": true, + "hex": "76a914c30c2dd0e7b7f6506259f11e956d0f1085ca437588ac", + "addresses": [ + "DNvQtshdnrehs8MNRx6Mh9XDPz4UZucfEv" + ], + "isAddress": true + }, + { + "value": "2000000000", + "n": 1, + "hex": "00147ad8c91046724785f78b48d4ae606a3556ddf9b4", + "addresses": [ + "dgb1q0tvvjyzxwfrctautfr22ucr2x4tdm7d5va4lr6" + ], + "isAddress": true + } + ], + "blockHash": "311aa13d66a4cf6be602209601d7b54bc715320d9255d1abc822ad20a7e01a20", + "blockHeight": 9756845, + "confirmations": 1068590, + "blockTime": 1573405513, + "value": "48587940500900", + "valueIn": "48587940518800", + "fees": "17900", + "hex": "01000000019915ac5f0115670f5112e8189850f54b8e6cffb0b10cb95378252386ee5cd0d8000000006b483045022100de758903643db73bc56bcd6b3e1e4bdafb3bd9b7a844286f66317de7c90b868702207eba0eeb32c817df9e79df2aad5f192808941ccb5d18430f9ee7ea18b8b1abad0121038f47ad4221aa24dbefe2b439f644b3af71428a7eb9e837517a162710fe631cf7ffffffff02a481b94b302c00001976a914c30c2dd0e7b7f6506259f11e956d0f1085ca437588ac00943577000000001600147ad8c91046724785f78b48d4ae606a3556ddf9b400000000" + }, + { + "txid": "34fac508c701939ac0fcb62bc436281cc28588d7986c5aa51de99e9835b9217b", + "version": 1, + "vin": [ + { + "txid": "ac7b8ce8ceea74cfc5c9d6f64b9943a1f30747c8b5adad6e6a21bc715efb18e7", + "vout": 1, + "n": 0, + "addresses": [ + "dgb1qakdslehzre7rhfzwea93pkar95f3yxm73lyxp6" + ], + "isAddress": true, + "value": "798931522" + } + ], + "vout": [ + { + "value": "200000000", + "n": 0, + "spent": true, + "hex": "0014af765ac1eeb3b4ceb768994474288807d4624b24", + "addresses": [ + "dgb1q4am94s0wkw6vadmgn9z8g2ygql2xyjeyee6m6d" + ], + "isAddress": true + }, + { + "value": "598908696", + "n": 1, + "spent": true, + "hex": "0014319b0141366578c71ec217d4e4f56b85065164da", + "addresses": [ + "dgb1qxxdszsfkv4uvw8kzzl2wfatts5r9zex69x6076" + ], + "isAddress": true + } + ], + "blockHash": "9fef191db549b2ce895d1629b69be93d8fcd2eae74497ef43c4f1d13b807fb90", + "blockHeight": 9755214, + "confirmations": 1070221, + "blockTime": 1573381024, + "value": "798908696", + "valueIn": "798931522", + "fees": "22826", + "hex": "01000000000101e718fb5e71bc216a6eadadb5c84707f3a143994bf6d6c9c5cf74eacee88c7bac0100000000000000000200c2eb0b00000000160014af765ac1eeb3b4ceb768994474288807d4624b24189fb22300000000160014319b0141366578c71ec217d4e4f56b85065164da0247304402205602f6b4d6372eb954a89e9713789f6428ff4b3d023b8831f8e4d07ce51d725d02203c9608b45124b6233090250a59091f426c37d4df3c2563c758dbf95ae072c9ba012102d068173f4ca0b0c388fad24d262737615f0015498c2a09ff952249750d70f48300000000" + }, + { + "txid": "ac7b8ce8ceea74cfc5c9d6f64b9943a1f30747c8b5adad6e6a21bc715efb18e7", + "version": 1, + "vin": [ + { + "txid": "e1094c583bfbafe974ec819351a0491e44b6982ac4b37d859cec771df6c6dbe3", + "vout": 1, + "n": 0, + "addresses": [ + "dgb1qw97rz5cr7r3axm64pl9uefmvgw006gpjslsxzd" + ], + "isAddress": true, + "value": "898954348" + } + ], + "vout": [ + { + "value": "100000000", + "n": 0, + "spent": true, + "hex": "001406f9f37f7ad63d990c4d3f2ec6276b78acef3805", + "addresses": [ + "dgb1qqmulxlm66c7ejrzd8uhvvfmt0zkw7wq9u2yd4y" + ], + "isAddress": true + }, + { + "value": "798931522", + "n": 1, + "spent": true, + "hex": "0014ed9b0fe6e21e7c3ba44ecf4b10dba32d13121b7e", + "addresses": [ + "dgb1qakdslehzre7rhfzwea93pkar95f3yxm73lyxp6" + ], + "isAddress": true + } + ], + "blockHash": "0000000000000008a2e821f32358ac50b7f4856ba09ad0aaad54b8dc6ac21483", + "blockHeight": 9755127, + "confirmations": 1070308, + "blockTime": 1573379763, + "value": "898931522", + "valueIn": "898954348", + "fees": "22826", + "hex": "01000000000101e3dbc6f61d77ec9c857db3c42a98b6441e49a0519381ec74e9affb3b584c09e10100000000000000000200e1f5050000000016001406f9f37f7ad63d990c4d3f2ec6276b78acef380542ba9e2f00000000160014ed9b0fe6e21e7c3ba44ecf4b10dba32d13121b7e0247304402206f5b728f7489fa8571ee0deb80afd7eb3bb547cd1bd39849814c2d717c5593f302207f3aa1ddf3d49da1da354f6873cf0e2194b3eef685b0cce79be9c1cc4a9a7d2d012103978ec321da1421cf9e871732d06b4fbd15697fb3f0204348aa481b7899a584e600000000" + }, + { + "txid": "e1094c583bfbafe974ec819351a0491e44b6982ac4b37d859cec771df6c6dbe3", + "version": 1, + "vin": [ + { + "txid": "76256e4f59a2135e76ea87a513dcafc9803c64cb81848135bcef3fed60abb862", + "vout": 1, + "n": 0, + "addresses": [ + "dgb1qfnzgdpa76576kngxlh2zda0t2r5kh29mjd50l3" + ], + "isAddress": true, + "value": "998977174" + } + ], + "vout": [ + { + "value": "100000000", + "n": 0, + "spent": true, + "hex": "76a91497421a26ae55a8c01ba339a0b65ab6a5f935a50488ac", + "addresses": [ + "DJvsm5mCp4a3YsJXxxiLk9MDWVwvrFDPm3" + ], + "isAddress": true + }, + { + "value": "898954348", + "n": 1, + "spent": true, + "hex": "0014717c315303f0e3d36f550fcbcca76c439efd2032", + "addresses": [ + "dgb1qw97rz5cr7r3axm64pl9uefmvgw006gpjslsxzd" + ], + "isAddress": true + } + ], + "blockHash": "5b6636f66d6ef37c4281bdf3088e48c9d22ca6c423cabaa18320fc303c861c71", + "blockHeight": 9755040, + "confirmations": 1070395, + "blockTime": 1573378521, + "value": "998954348", + "valueIn": "998977174", + "fees": "22826", + "hex": "0100000000010162b8ab60ed3fefbc35818481cb643c80c9afdc13a587ea765e13a2594f6e25760100000000000000000200e1f505000000001976a91497421a26ae55a8c01ba339a0b65ab6a5f935a50488ac6cf4943500000000160014717c315303f0e3d36f550fcbcca76c439efd20320248304502210084ebc948a2fa88ca2c893faa160a7f8340fcf057d764c898562206cb97eda44202201e7d790b34b9bdd946b1fbacbae02b5e9add3a2f11d2182cf76e83697c5e88e0012103cb1f31320481fea72f8f5a378578ca440ee2db3ebade1cea6e9ec15ee99c365600000000" + }, + { + "txid": "76256e4f59a2135e76ea87a513dcafc9803c64cb81848135bcef3fed60abb862", + "version": 1, + "vin": [ + { + "txid": "96c223272fce4e105cca3f2c9c966742c03f76b07aa5cfca514b890e90c46dc3", + "vout": 1, + "n": 0, + "addresses": [ + "dgb1q0tvvjyzxwfrctautfr22ucr2x4tdm7d5va4lr6" + ], + "isAddress": true, + "value": "1000000000" + } + ], + "vout": [ + { + "value": "1000000", + "n": 0, + "hex": "0014d1900052a23df4ba9e8c2adf0c7d815adb6de80e", + "addresses": [ + "dgb1q6xgqq54z8h6t485v9t0sclvpttdkm6qwp4292e" + ], + "isAddress": true + }, + { + "value": "998977174", + "n": 1, + "spent": true, + "hex": "00144cc48687bed53dab4d06fdd426f5eb50e96ba8bb", + "addresses": [ + "dgb1qfnzgdpa76576kngxlh2zda0t2r5kh29mjd50l3" + ], + "isAddress": true + } + ], + "blockHash": "d8122b3b73b70d8f78bded86562d9fd649b73209681ea5a7d3a0e14fb339e37d", + "blockHeight": 9755022, + "confirmations": 1070413, + "blockTime": 1573378224, + "value": "999977174", + "valueIn": "1000000000", + "fees": "22826", + "hex": "01000000000101c36dc4900e894b51cacfa57ab0763fc04267969c2c3fca5c104ece2f2723c2960100000000000000000240420f0000000000160014d1900052a23df4ba9e8c2adf0c7d815adb6de80e962e8b3b000000001600144cc48687bed53dab4d06fdd426f5eb50e96ba8bb02483045022100f09aeeb5dd360d691bf729f206fd24fb6aba185388ce387a7c7757bb88aa3cb80220203a4ca385ab6f21cc4606e83d492efb2b0a844294ab63773f5f4f8601cb54ef0121029df0ec50608f69a7e05097f33b731f2d4bf112001d25072f7a8ab065de5985ab00000000" + }, + { + "txid": "96c223272fce4e105cca3f2c9c966742c03f76b07aa5cfca514b890e90c46dc3", + "version": 1, + "vin": [ + { + "txid": "ce3d1d4de8c32659bd6329c516fbe348af53823236b4918f3f243d924a872354", + "vout": 50, + "sequence": 4294967295, + "n": 0, + "addresses": [ + "DJvsm5mCp4a3YsJXxxiLk9MDWVwvrFDPm3" + ], + "isAddress": true, + "value": "2936876555", + "hex": "473044022037c4cfbba57c9a9ac4b728e006e585d8b4422460ee714b21b9e0f9a4bd8dc04e02205ddfdc6dba325229406b57e6622d5f141e9c2dfb704db4e30be2e1e3dc0e16ee012103161f2325217e38461d71745e8652851a90285eb89e4344e48b804f3c943b5433" + }, + { + "txid": "ae2e1b22567da28d3a90f6920193cb4b5c3d32b921db80cd2859bc2eaccc0110", + "sequence": 4294967295, + "n": 1, + "addresses": [ + "DJvsm5mCp4a3YsJXxxiLk9MDWVwvrFDPm3" + ], + "isAddress": true, + "value": "1000000000", + "hex": "483045022100f43f677961c5cf4ad9df2351523e64e963f2e34082dde6ff2162e76f3ba2deed0220430bbfae4ee22884011c88db890848f0b880e6e6d3335fc1c93bd13f9a986b19012103161f2325217e38461d71745e8652851a90285eb89e4344e48b804f3c943b5433" + } + ], + "vout": [ + { + "value": "2936875555", + "n": 0, + "spent": true, + "hex": "0014f78aa1ee8590fad304450b732416ecbface4ea6b", + "addresses": [ + "dgb1q7792rm59jradxpz9pdejg9hvh7kwf6ntd8w0qq" + ], + "isAddress": true + }, + { + "value": "1000000000", + "n": 1, + "spent": true, + "hex": "00147ad8c91046724785f78b48d4ae606a3556ddf9b4", + "addresses": [ + "dgb1q0tvvjyzxwfrctautfr22ucr2x4tdm7d5va4lr6" + ], + "isAddress": true + } + ], + "blockHash": "102c0f5d2b8ad6db93419fb607127f482e0b2e2809970ee90479eb1158b15669", + "blockHeight": 9754963, + "confirmations": 1070472, + "blockTime": 1573377240, + "value": "3936875555", + "valueIn": "3936876555", + "fees": "1000", + "hex": "01000000025423874a923d243f8f91b436328253af48e3fb16c52963bd5926c3e84d1d3dce320000006a473044022037c4cfbba57c9a9ac4b728e006e585d8b4422460ee714b21b9e0f9a4bd8dc04e02205ddfdc6dba325229406b57e6622d5f141e9c2dfb704db4e30be2e1e3dc0e16ee012103161f2325217e38461d71745e8652851a90285eb89e4344e48b804f3c943b5433ffffffff1001ccac2ebc5928cd80db21b9323d5c4bcb930192f6903a8da27d56221b2eae000000006b483045022100f43f677961c5cf4ad9df2351523e64e963f2e34082dde6ff2162e76f3ba2deed0220430bbfae4ee22884011c88db890848f0b880e6e6d3335fc1c93bd13f9a986b19012103161f2325217e38461d71745e8652851a90285eb89e4344e48b804f3c943b5433ffffffff02232a0daf00000000160014f78aa1ee8590fad304450b732416ecbface4ea6b00ca9a3b000000001600147ad8c91046724785f78b48d4ae606a3556ddf9b400000000" + } + ], + "usedTokens": 8, + "tokens": [ + { + "type": "XPUBAddress", + "name": "dgb1q0tvvjyzxwfrctautfr22ucr2x4tdm7d5va4lr6", + "path": "m/84'/20'/0'/0/0", + "transfers": 3, + "decimals": 8, + "balance": "2000000000", + "totalReceived": "3000000000", + "totalSent": "1000000000" + }, + { + "type": "XPUBAddress", + "name": "dgb1q6xgqq54z8h6t485v9t0sclvpttdkm6qwp4292e", + "path": "m/84'/20'/0'/0/1", + "transfers": 1, + "decimals": 8, + "balance": "1000000", + "totalReceived": "1000000", + "totalSent": "0" + }, + { + "type": "XPUBAddress", + "name": "dgb1qg29rqy8t08zdxfrcgppqpk75zppwv87wknuder", + "path": "m/84'/20'/0'/0/2", + "transfers": 1, + "decimals": 8, + "balance": "10000000", + "totalReceived": "10000000", + "totalSent": "0" + }, + { + "type": "XPUBAddress", + "name": "dgb1qv4pt3du9nx2trr05kuw893989mg3xe3w322vy7", + "path": "m/84'/20'/0'/1/4", + "transfers": 1, + "decimals": 8, + "balance": "588896040", + "totalReceived": "588896040", + "totalSent": "0" + } + ] +} diff --git a/mock/ext-api-data/doge-api_v2_address_D5dAUAx3Ezg1q4dRgzKTBsxp4VJietWkDh__details_txs.json b/mock/ext-api-data/doge-api_v2_address_D5dAUAx3Ezg1q4dRgzKTBsxp4VJietWkDh__details_txs.json new file mode 100644 index 000000000..1028b577a --- /dev/null +++ b/mock/ext-api-data/doge-api_v2_address_D5dAUAx3Ezg1q4dRgzKTBsxp4VJietWkDh__details_txs.json @@ -0,0 +1,568 @@ +{ + "page": 1, + "totalPages": 1, + "itemsOnPage": 1000, + "address": "D5dAUAx3Ezg1q4dRgzKTBsxp4VJietWkDh", + "balance": "50394795942", + "totalReceived": "160202987826", + "totalSent": "109808191884", + "unconfirmedBalance": "0", + "unconfirmedTxs": 0, + "txs": 12, + "transactions": [ + { + "txid": "fee8381fed7406a48a8ea9e62328a3134064210626e81489ed8906e18c433bdf", + "version": 1, + "vin": [ + { + "txid": "c6a51ed2d4bb163c324f58659d98142b3fbe44503289eb6c7749414e63111dfb", + "n": 0, + "addresses": [ + "D5dAUAx3Ezg1q4dRgzKTBsxp4VJietWkDh" + ], + "isAddress": true, + "value": "1000000000", + "hex": "47304402200833c3184e768e5b6da836d9824f98b65704a24229a02e572ac760bb304ab9fb022068d102da9400afaeee3a6b42930a966ff107f5c68affde4a0239dab9fa21123d012102cc82e0824da5cc96d5967cfc06d4b82e29c44ce10cb86028d15b5e67ceb1b6ca" + } + ], + "vout": [ + { + "value": "134700000", + "n": 0, + "hex": "76a9142ba977acdb30bc18d350df32f38a777313ae86b088ac", + "addresses": [ + "D97xcKB9EAPmgNExbB5nAXDAQ9s5ZJ91J4" + ], + "isAddress": true + }, + { + "value": "707100000", + "n": 1, + "hex": "76a914b358390833fd8371733c1d11477bdb2d185e61e988ac", + "addresses": [ + "DMVPBRTD6bgqr3fk2yTdz97hS4AA2gzj8g" + ], + "isAddress": true + } + ], + "blockHash": "b94fd58d99710000ff0991ebf82c85330ed706ea18bcd4265e1f22747b91ddfe", + "blockHeight": 3170421, + "confirmations": 56768, + "blockTime": 1585794154, + "value": "841800000", + "valueIn": "1000000000", + "fees": "158200000", + "hex": "0100000001fb1d11634e4149776ceb89325044be3f2b14989d65584f323c16bbd4d21ea5c6000000006a47304402200833c3184e768e5b6da836d9824f98b65704a24229a02e572ac760bb304ab9fb022068d102da9400afaeee3a6b42930a966ff107f5c68affde4a0239dab9fa21123d012102cc82e0824da5cc96d5967cfc06d4b82e29c44ce10cb86028d15b5e67ceb1b6ca0000000002e05b0708000000001976a9142ba977acdb30bc18d350df32f38a777313ae86b088ac607d252a000000001976a914b358390833fd8371733c1d11477bdb2d185e61e988ac00000000" + }, + { + "txid": "8d5fc1e686ff042b4811cb6b2df406b98b2484e973cd663b442c296f2d2f78b9", + "version": 1, + "vin": [ + { + "txid": "f60da53d80e50e4aef26e58ca89cbbe90b554baefcf67c54b0a2648420907498", + "vout": 1, + "sequence": 4294967288, + "n": 0, + "addresses": [ + "DF5TedCytjJRQdvTbMPJuMwbMWoveWZYp3" + ], + "isAddress": true, + "value": "533600000", + "hex": "483045022100f357d4cb4fbef56bc76de9894e330ce485085c3cbe58dc9680db2a35dcf99dbf02204d7ef785782d75025c117c5e70ae009104b7cdd7cd1554d5cf4cb884958c06be01210391c22d3c06172377ff770f0832a4decf91ee38b975eb65451c38faa6bef861b5" + } + ], + "vout": [ + { + "value": "100000000", + "n": 0, + "hex": "76a914054eed59ece5b6aa1ef15f3713765e708cf3d5f688ac", + "addresses": [ + "D5dAUAx3Ezg1q4dRgzKTBsxp4VJietWkDh" + ], + "isAddress": true + }, + { + "value": "275400000", + "n": 1, + "hex": "76a9149ff8db746d4f6b11acab2bda9288dde3b8428d8e88ac", + "addresses": [ + "DKix6fTygojRpBFbADfkYKDX9nZ2Y7Huqq" + ], + "isAddress": true + } + ], + "blockHash": "ece2c433edfaf7143ba79f381ea40ac8b7e38ce6c4ff0771ae1e3dda9246824a", + "blockHeight": 3099770, + "confirmations": 127419, + "blockTime": 1581351126, + "value": "375400000", + "valueIn": "533600000", + "fees": "158200000", + "hex": "0100000001987490208464a2b0547cf6fcae4b550be9bb9ca88ce526ef4a0ee5803da50df6010000006b483045022100f357d4cb4fbef56bc76de9894e330ce485085c3cbe58dc9680db2a35dcf99dbf02204d7ef785782d75025c117c5e70ae009104b7cdd7cd1554d5cf4cb884958c06be01210391c22d3c06172377ff770f0832a4decf91ee38b975eb65451c38faa6bef861b5f8ffffff0200e1f505000000001976a914054eed59ece5b6aa1ef15f3713765e708cf3d5f688ac40456a10000000001976a9149ff8db746d4f6b11acab2bda9288dde3b8428d8e88ac00000000" + }, + { + "txid": "f60da53d80e50e4aef26e58ca89cbbe90b554baefcf67c54b0a2648420907498", + "version": 1, + "vin": [ + { + "txid": "c6a51ed2d4bb163c324f58659d98142b3fbe44503289eb6c7749414e63111dfb", + "vout": 1, + "sequence": 4294967291, + "n": 0, + "addresses": [ + "D5dAUAx3Ezg1q4dRgzKTBsxp4VJietWkDh" + ], + "isAddress": true, + "value": "841800000", + "hex": "483045022100f80b337309fcefc7886364f9a87ff9afcadf876542a5a36b543547f7e9d43ef10220397d6aaa649814b68dc98a1ed1027de34c8aa06cbe480e34bbe5a7ba5f282402012102cc82e0824da5cc96d5967cfc06d4b82e29c44ce10cb86028d15b5e67ceb1b6ca" + } + ], + "vout": [ + { + "value": "150000000", + "n": 0, + "hex": "76a914e82178c73b5744342916f6a7a944af4fa37aebff88ac", + "addresses": [ + "DSJVQRY3wyVPrXbEDMSeoFufWNSsMeKEuj" + ], + "isAddress": true + }, + { + "value": "533600000", + "n": 1, + "spent": true, + "hex": "76a9146d01372d8c138cddcc142ade8a7ebc84948b87df88ac", + "addresses": [ + "DF5TedCytjJRQdvTbMPJuMwbMWoveWZYp3" + ], + "isAddress": true + } + ], + "blockHash": "d4a57feed1683117d412944fc6581eace1bc3a8be5ebab93cf2dd99f5918374d", + "blockHeight": 3088989, + "confirmations": 138200, + "blockTime": 1580673745, + "value": "683600000", + "valueIn": "841800000", + "fees": "158200000", + "hex": "0100000001fb1d11634e4149776ceb89325044be3f2b14989d65584f323c16bbd4d21ea5c6010000006b483045022100f80b337309fcefc7886364f9a87ff9afcadf876542a5a36b543547f7e9d43ef10220397d6aaa649814b68dc98a1ed1027de34c8aa06cbe480e34bbe5a7ba5f282402012102cc82e0824da5cc96d5967cfc06d4b82e29c44ce10cb86028d15b5e67ceb1b6cafbffffff0280d1f008000000001976a914e82178c73b5744342916f6a7a944af4fa37aebff88ac0017ce1f000000001976a9146d01372d8c138cddcc142ade8a7ebc84948b87df88ac00000000" + }, + { + "txid": "17e7d6371140eba1d57a2461a8d646534ff0c8044aff83b90c49f9d74aad0a8e", + "version": 1, + "vin": [ + { + "txid": "eaead3019d3a76858d7c106cdf3324595b8c1f06ae3ecf668327c997bb584f33", + "vout": 1, + "n": 0, + "addresses": [ + "D5dAUAx3Ezg1q4dRgzKTBsxp4VJietWkDh" + ], + "isAddress": true, + "value": "483600000", + "hex": "4730440220336f743b7030ac993705d48a4e64d1bb5a7c2fbddeabdc4fdb33f7f41c7addc502202c723805658115ae148b9211b25987813c848949a3cd835b942de0b248168e7c012102cc82e0824da5cc96d5967cfc06d4b82e29c44ce10cb86028d15b5e67ceb1b6ca" + } + ], + "vout": [ + { + "value": "134700000", + "n": 0, + "spent": true, + "hex": "76a9147e2cd472834c324ead9cc333c50c55117e07525a88ac", + "addresses": [ + "DGeFPGDgmxcuVFS4WGKQ4cqEgJSAnz6tpt" + ], + "isAddress": true + }, + { + "value": "190700000", + "n": 1, + "hex": "76a914054eed59ece5b6aa1ef15f3713765e708cf3d5f688ac", + "addresses": [ + "D5dAUAx3Ezg1q4dRgzKTBsxp4VJietWkDh" + ], + "isAddress": true + } + ], + "blockHash": "03a3c4216bf64a38dac9ca5c34722f79ec67e0b3de9ba8a58108fced2b782374", + "blockHeight": 3082655, + "confirmations": 144534, + "blockTime": 1580277168, + "value": "325400000", + "valueIn": "483600000", + "fees": "158200000", + "hex": "0100000001334f58bb97c9278366cf3eae061f8c5b592433df6c107c8d85763a9d01d3eaea010000006a4730440220336f743b7030ac993705d48a4e64d1bb5a7c2fbddeabdc4fdb33f7f41c7addc502202c723805658115ae148b9211b25987813c848949a3cd835b942de0b248168e7c012102cc82e0824da5cc96d5967cfc06d4b82e29c44ce10cb86028d15b5e67ceb1b6ca0000000002e05b0708000000001976a9147e2cd472834c324ead9cc333c50c55117e07525a88ace0d95d0b000000001976a914054eed59ece5b6aa1ef15f3713765e708cf3d5f688ac00000000" + }, + { + "txid": "c6a51ed2d4bb163c324f58659d98142b3fbe44503289eb6c7749414e63111dfb", + "version": 1, + "vin": [ + { + "txid": "44941f1d6b3bf0361f00a00d8e503ce8d0289b0990c5b4a6d13de00fa4eec1cd", + "n": 0, + "addresses": [ + "D5dAUAx3Ezg1q4dRgzKTBsxp4VJietWkDh" + ], + "isAddress": true, + "value": "2000000000", + "hex": "473044022027ca75c9763fa154134343a46d8ea35c28d1231d2a0e6857564773866f5a91fe02206ec5af0e55730bfbbf53eb0eb3fccfcace7b051af973a176d8d8d096675772b2012102cc82e0824da5cc96d5967cfc06d4b82e29c44ce10cb86028d15b5e67ceb1b6ca" + } + ], + "vout": [ + { + "value": "1000000000", + "n": 0, + "spent": true, + "hex": "76a914054eed59ece5b6aa1ef15f3713765e708cf3d5f688ac", + "addresses": [ + "D5dAUAx3Ezg1q4dRgzKTBsxp4VJietWkDh" + ], + "isAddress": true + }, + { + "value": "841800000", + "n": 1, + "spent": true, + "hex": "76a914054eed59ece5b6aa1ef15f3713765e708cf3d5f688ac", + "addresses": [ + "D5dAUAx3Ezg1q4dRgzKTBsxp4VJietWkDh" + ], + "isAddress": true + } + ], + "blockHash": "4701d7cf8b274af55ddddfbe76527f9b616fc69325c08b79ed35da5183be37c3", + "blockHeight": 3081510, + "confirmations": 145679, + "blockTime": 1580204896, + "value": "1841800000", + "valueIn": "2000000000", + "fees": "158200000", + "hex": "0100000001cdc1eea40fe03dd1a6b4c590099b28d0e83c508e0da0001f36f03b6b1d1f9444000000006a473044022027ca75c9763fa154134343a46d8ea35c28d1231d2a0e6857564773866f5a91fe02206ec5af0e55730bfbbf53eb0eb3fccfcace7b051af973a176d8d8d096675772b2012102cc82e0824da5cc96d5967cfc06d4b82e29c44ce10cb86028d15b5e67ceb1b6ca000000000200ca9a3b000000001976a914054eed59ece5b6aa1ef15f3713765e708cf3d5f688ac40d92c32000000001976a914054eed59ece5b6aa1ef15f3713765e708cf3d5f688ac00000000" + }, + { + "txid": "eaead3019d3a76858d7c106cdf3324595b8c1f06ae3ecf668327c997bb584f33", + "version": 1, + "vin": [ + { + "txid": "a369bf2cee39e406b04d3782385f76956241b5ac1774db13f166c8e8a0172d36", + "vout": 1, + "n": 0, + "addresses": [ + "DAth3nj1fUStB8UHxxuE4uFfjg8Aze4S8v" + ], + "isAddress": true, + "value": "741800000", + "hex": "47304402202377dc80bcc0d43a2996ec3057056730489cc3b138f504c6be5229d5441246c202201c7bdfed8a8388336b754b7a21ec631e8f5bbfcfa3ebb68cfb5d5cea60971ec30121029f274c032269ab70b7a1bed45068f6e97f0b865ae652a98054fdd25e04af267a" + } + ], + "vout": [ + { + "value": "100000000", + "n": 0, + "hex": "76a914054eed59ece5b6aa1ef15f3713765e708cf3d5f688ac", + "addresses": [ + "D5dAUAx3Ezg1q4dRgzKTBsxp4VJietWkDh" + ], + "isAddress": true + }, + { + "value": "483600000", + "n": 1, + "spent": true, + "hex": "76a914054eed59ece5b6aa1ef15f3713765e708cf3d5f688ac", + "addresses": [ + "D5dAUAx3Ezg1q4dRgzKTBsxp4VJietWkDh" + ], + "isAddress": true + } + ], + "blockHash": "fab26df4f935751512760217249335c9a4218bd84766152bd1d1b47f7cdfe33e", + "blockHeight": 3079034, + "confirmations": 148155, + "blockTime": 1580049813, + "value": "583600000", + "valueIn": "741800000", + "fees": "158200000", + "hex": "0100000001362d17a0e8c866f113db7417acb5416295765f3882374db006e439ee2cbf69a3010000006a47304402202377dc80bcc0d43a2996ec3057056730489cc3b138f504c6be5229d5441246c202201c7bdfed8a8388336b754b7a21ec631e8f5bbfcfa3ebb68cfb5d5cea60971ec30121029f274c032269ab70b7a1bed45068f6e97f0b865ae652a98054fdd25e04af267a000000000200e1f505000000001976a914054eed59ece5b6aa1ef15f3713765e708cf3d5f688ac8026d31c000000001976a914054eed59ece5b6aa1ef15f3713765e708cf3d5f688ac00000000" + }, + { + "txid": "44941f1d6b3bf0361f00a00d8e503ce8d0289b0990c5b4a6d13de00fa4eec1cd", + "version": 1, + "vin": [ + { + "txid": "2b59988ab83317341e9ee48a0ba80abf4399254089037dc7660d000de53565e7", + "vout": 1, + "n": 0, + "addresses": [ + "D5dAUAx3Ezg1q4dRgzKTBsxp4VJietWkDh" + ], + "isAddress": true, + "value": "51162295942", + "hex": "4830450221009bd7a6e5d664c57b7c994fe2bba3fc14db41e3b961b52f6da46ea517f0a765bf022028a695add7d1f0e948a492ba196f6266cc7cafc9628a9ac4518cd7fceb1e1f54012102cc82e0824da5cc96d5967cfc06d4b82e29c44ce10cb86028d15b5e67ceb1b6ca" + } + ], + "vout": [ + { + "value": "2000000000", + "n": 0, + "spent": true, + "hex": "76a914054eed59ece5b6aa1ef15f3713765e708cf3d5f688ac", + "addresses": [ + "D5dAUAx3Ezg1q4dRgzKTBsxp4VJietWkDh" + ], + "isAddress": true + }, + { + "value": "49004095942", + "n": 1, + "hex": "76a914054eed59ece5b6aa1ef15f3713765e708cf3d5f688ac", + "addresses": [ + "D5dAUAx3Ezg1q4dRgzKTBsxp4VJietWkDh" + ], + "isAddress": true + } + ], + "blockHash": "a6ebe4f81737b59699c7a3a59f21b93280c7d2a88c9e84dd90b4326226074f4f", + "blockHeight": 3074554, + "confirmations": 152635, + "blockTime": 1579769000, + "value": "51004095942", + "valueIn": "51162295942", + "fees": "158200000", + "hex": "0100000001e76535e50d000d66c77d038940259943bf0aa80b8ae49e1e341733b88a98592b010000006b4830450221009bd7a6e5d664c57b7c994fe2bba3fc14db41e3b961b52f6da46ea517f0a765bf022028a695add7d1f0e948a492ba196f6266cc7cafc9628a9ac4518cd7fceb1e1f54012102cc82e0824da5cc96d5967cfc06d4b82e29c44ce10cb86028d15b5e67ceb1b6ca000000000200943577000000001976a914054eed59ece5b6aa1ef15f3713765e708cf3d5f688acc629df680b0000001976a914054eed59ece5b6aa1ef15f3713765e708cf3d5f688ac00000000" + }, + { + "txid": "a369bf2cee39e406b04d3782385f76956241b5ac1774db13f166c8e8a0172d36", + "version": 1, + "vin": [ + { + "txid": "2b59988ab83317341e9ee48a0ba80abf4399254089037dc7660d000de53565e7", + "sequence": 4294967291, + "n": 0, + "addresses": [ + "D5dAUAx3Ezg1q4dRgzKTBsxp4VJietWkDh" + ], + "isAddress": true, + "value": "1000000000", + "hex": "4730440220348d03905d720f7bf4adf247195dcb30f4e581a88ca611ad2c336665acb10e73022034926b1fadbe03078c3210502f76cc34340b9e5a906ba1deb9ee9fc3c2a5b20d012102cc82e0824da5cc96d5967cfc06d4b82e29c44ce10cb86028d15b5e67ceb1b6ca" + } + ], + "vout": [ + { + "value": "100000000", + "n": 0, + "hex": "76a9149fc4e4b3c5a1331b93b26bcb290c7fa2633e304688ac", + "addresses": [ + "DKhsr9gcxfZ1EPGz7YK4BwWAPDeATwT94o" + ], + "isAddress": true + }, + { + "value": "741800000", + "n": 1, + "spent": true, + "hex": "76a9143f175272c8685646337257fdd4ff9837b3b37d0d88ac", + "addresses": [ + "DAth3nj1fUStB8UHxxuE4uFfjg8Aze4S8v" + ], + "isAddress": true + } + ], + "blockHash": "d677e3585338c456ba1c84e5ac360dba7b972840ece88b59b7977cab32fe697d", + "blockHeight": 3073761, + "confirmations": 153428, + "blockTime": 1579719400, + "value": "841800000", + "valueIn": "1000000000", + "fees": "158200000", + "hex": "0100000001e76535e50d000d66c77d038940259943bf0aa80b8ae49e1e341733b88a98592b000000006a4730440220348d03905d720f7bf4adf247195dcb30f4e581a88ca611ad2c336665acb10e73022034926b1fadbe03078c3210502f76cc34340b9e5a906ba1deb9ee9fc3c2a5b20d012102cc82e0824da5cc96d5967cfc06d4b82e29c44ce10cb86028d15b5e67ceb1b6cafbffffff0200e1f505000000001976a9149fc4e4b3c5a1331b93b26bcb290c7fa2633e304688ac40f8362c000000001976a9143f175272c8685646337257fdd4ff9837b3b37d0d88ac00000000" + }, + { + "txid": "2b59988ab83317341e9ee48a0ba80abf4399254089037dc7660d000de53565e7", + "version": 1, + "vin": [ + { + "txid": "a5ea8e1bfcad3f860d8e2876486213d9448f14d0b4fae2d5f4c6f7ad9fd187bf", + "vout": 1, + "n": 0, + "addresses": [ + "D5dAUAx3Ezg1q4dRgzKTBsxp4VJietWkDh" + ], + "isAddress": true, + "value": "52320495942", + "hex": "4830450221008e5dd501d7a6b0c9babca2f5d8b11ada06fb2918303c5f281b1fe8e64cde7b4802206f86df1d40eb42108ade7cad36226f9e1ba75cb282cab75ed12fcb387f4970b2012102cc82e0824da5cc96d5967cfc06d4b82e29c44ce10cb86028d15b5e67ceb1b6ca" + } + ], + "vout": [ + { + "value": "1000000000", + "n": 0, + "spent": true, + "hex": "76a914054eed59ece5b6aa1ef15f3713765e708cf3d5f688ac", + "addresses": [ + "D5dAUAx3Ezg1q4dRgzKTBsxp4VJietWkDh" + ], + "isAddress": true + }, + { + "value": "51162295942", + "n": 1, + "spent": true, + "hex": "76a914054eed59ece5b6aa1ef15f3713765e708cf3d5f688ac", + "addresses": [ + "D5dAUAx3Ezg1q4dRgzKTBsxp4VJietWkDh" + ], + "isAddress": true + } + ], + "blockHash": "0c13cea0560ccf100ccfa2b484aaf6639f4a75fe9029708728abbf42423981bf", + "blockHeight": 3070556, + "confirmations": 156633, + "blockTime": 1579517965, + "value": "52162295942", + "valueIn": "52320495942", + "fees": "158200000", + "hex": "0100000001bf87d19fadf7c6f4d5e2fab4d0148f44d913624876288e0d863fadfc1b8eeaa5010000006b4830450221008e5dd501d7a6b0c9babca2f5d8b11ada06fb2918303c5f281b1fe8e64cde7b4802206f86df1d40eb42108ade7cad36226f9e1ba75cb282cab75ed12fcb387f4970b2012102cc82e0824da5cc96d5967cfc06d4b82e29c44ce10cb86028d15b5e67ceb1b6ca000000000200ca9a3b000000001976a914054eed59ece5b6aa1ef15f3713765e708cf3d5f688ac86ae82e90b0000001976a914054eed59ece5b6aa1ef15f3713765e708cf3d5f688ac00000000" + }, + { + "txid": "a5ea8e1bfcad3f860d8e2876486213d9448f14d0b4fae2d5f4c6f7ad9fd187bf", + "version": 1, + "vin": [ + { + "txid": "0a43e6297dc2c63527bc0138e199cfe41b6b41c4877ba60a425bd425a7eafec9", + "vout": 1, + "n": 0, + "addresses": [ + "DLKFsc4PWe6KSGbeXZPv9kgCrQQBycf6nc" + ], + "isAddress": true, + "value": "53478695942", + "hex": "483045022100db69f1b5966a47c20de9fcf9891ff6bda8f9ccd28336acd51276a4134290bd9002200c33d0c4bb76c8c0596a68fb715a8e7cc47ac98a65266f9ef40ea2de36ca3a9b012102debf9eb33094bbbf385e118614f4e8d67c946067677dd85de913415800148c5f" + } + ], + "vout": [ + { + "value": "1000000000", + "n": 0, + "hex": "76a914054eed59ece5b6aa1ef15f3713765e708cf3d5f688ac", + "addresses": [ + "D5dAUAx3Ezg1q4dRgzKTBsxp4VJietWkDh" + ], + "isAddress": true + }, + { + "value": "52320495942", + "n": 1, + "spent": true, + "hex": "76a914054eed59ece5b6aa1ef15f3713765e708cf3d5f688ac", + "addresses": [ + "D5dAUAx3Ezg1q4dRgzKTBsxp4VJietWkDh" + ], + "isAddress": true + } + ], + "blockHash": "336481816fe09f284657ebe3c98fca8fab4c3edd7e15ddbb5f8c19bd00326f9c", + "blockHeight": 3070538, + "confirmations": 156651, + "blockTime": 1579516786, + "value": "53320495942", + "valueIn": "53478695942", + "fees": "158200000", + "hex": "0100000001c9feeaa725d45b420aa67b87c4416b1be4cf99e13801bc2735c6c27d29e6430a010000006b483045022100db69f1b5966a47c20de9fcf9891ff6bda8f9ccd28336acd51276a4134290bd9002200c33d0c4bb76c8c0596a68fb715a8e7cc47ac98a65266f9ef40ea2de36ca3a9b012102debf9eb33094bbbf385e118614f4e8d67c946067677dd85de913415800148c5f000000000200ca9a3b000000001976a914054eed59ece5b6aa1ef15f3713765e708cf3d5f688ac46698b2e0c0000001976a914054eed59ece5b6aa1ef15f3713765e708cf3d5f688ac00000000" + }, + { + "txid": "e71cf261f87ee49397315d77722e53b9bee1fd8ea2a4676386c3555151b6f722", + "version": 1, + "vin": [ + { + "txid": "535b9feb13c603f8bceaa79665fd03bd0f088080f4ea299b0cca7cce3632ad07", + "n": 0, + "addresses": [ + "D5dAUAx3Ezg1q4dRgzKTBsxp4VJietWkDh" + ], + "isAddress": true, + "value": "1000000000", + "hex": "483045022100a684b77c1875ab28357fef968c045cab2e58f1a22f0e98260a84290177cf538002202c509b3a44bc0dec7f921f8c94f3dd114f5be037b2ff0b9981548c37eebf010a012102cc82e0824da5cc96d5967cfc06d4b82e29c44ce10cb86028d15b5e67ceb1b6ca" + } + ], + "vout": [ + { + "value": "100000000", + "n": 0, + "spent": true, + "hex": "76a914f333c40dfb29e23867fe8dbd73627e0740de84ed88ac", + "addresses": [ + "DTK2kdJb313M5rUEtDZvBDXcDtutZo7dWT" + ], + "isAddress": true + }, + { + "value": "779950382", + "n": 1, + "spent": true, + "hex": "76a9143e03a905771cb71314952a02462d03e01a6c399288ac", + "addresses": [ + "DAnzpUCmzUU1QtGsoASw54jSphpxsm1Apa" + ], + "isAddress": true + } + ], + "blockHash": "c6e007320b2bbab17086a2b76ad823d976b5bb1b6c95a31ed43268d6db0744c8", + "blockHeight": 2679141, + "confirmations": 548048, + "blockTime": 1555034899, + "value": "879950382", + "valueIn": "1000000000", + "fees": "120049618", + "hex": "010000000107ad3236ce7cca0c9b29eaf48080080fbd03fd6596a7eabcf803c613eb9f5b53000000006b483045022100a684b77c1875ab28357fef968c045cab2e58f1a22f0e98260a84290177cf538002202c509b3a44bc0dec7f921f8c94f3dd114f5be037b2ff0b9981548c37eebf010a012102cc82e0824da5cc96d5967cfc06d4b82e29c44ce10cb86028d15b5e67ceb1b6ca000000000200e1f505000000001976a914f333c40dfb29e23867fe8dbd73627e0740de84ed88ac2e197d2e000000001976a9143e03a905771cb71314952a02462d03e01a6c399288ac00000000" + }, + { + "txid": "535b9feb13c603f8bceaa79665fd03bd0f088080f4ea299b0cca7cce3632ad07", + "version": 1, + "vin": [ + { + "txid": "89e57e06ee263f1dcfaf7da712b073ac8db0472314f8da74c37782843b836b00", + "vout": 1, + "sequence": 4294967295, + "n": 0, + "addresses": [ + "A5ozMKvBJhMi5sMgwzbfVLs1WZ1t4c7JKB" + ], + "isAddress": true, + "value": "297501351695", + "hex": "00483045022100ee88f81596f41103023e210369b1ff06dbcbec3480e06641b897f566fbfe3082022027ec2cc39cfadbfb38ad4833061014d381dc74e29204dabc9079d87626b0752e01483045022100faa61e1cbd295cae9a3347a82b46014daa3f5aba3058632c9ec03be8fa3e764802201427b682f7e99ea6cac888239399ec6cd58305304a3dd950149e5bacb5b0e30301475221032a6ddebdac7ca3f832d6a7124002a7d3d9fc7ee05c29cf566502b9a84c2ab70221036c8ffa92f159c02d49a2149f9901ad624aa65e05a33f0ffa0e1a0a3c163e065552ae" + } + ], + "vout": [ + { + "value": "1000000000", + "n": 0, + "spent": true, + "hex": "76a914054eed59ece5b6aa1ef15f3713765e708cf3d5f688ac", + "addresses": [ + "D5dAUAx3Ezg1q4dRgzKTBsxp4VJietWkDh" + ], + "isAddress": true + }, + { + "value": "296301351695", + "n": 1, + "spent": true, + "hex": "a91492b52b95d25a130ccbb077703596b26e9be3c84587", + "addresses": [ + "A5ozMKvBJhMi5sMgwzbfVLs1WZ1t4c7JKB" + ], + "isAddress": true + } + ], + "blockHash": "1addc60124792f9abed8bb39aa0cd63a81911e3c361e2c313b56083cc306de2b", + "blockHeight": 2677741, + "confirmations": 549448, + "blockTime": 1554946628, + "value": "297301351695", + "valueIn": "297501351695", + "fees": "200000000", + "hex": "0100000001006b833b848277c374daf8142347b08dac73b012a77dafcf1d3f26ee067ee58901000000db00483045022100ee88f81596f41103023e210369b1ff06dbcbec3480e06641b897f566fbfe3082022027ec2cc39cfadbfb38ad4833061014d381dc74e29204dabc9079d87626b0752e01483045022100faa61e1cbd295cae9a3347a82b46014daa3f5aba3058632c9ec03be8fa3e764802201427b682f7e99ea6cac888239399ec6cd58305304a3dd950149e5bacb5b0e30301475221032a6ddebdac7ca3f832d6a7124002a7d3d9fc7ee05c29cf566502b9a84c2ab70221036c8ffa92f159c02d49a2149f9901ad624aa65e05a33f0ffa0e1a0a3c163e065552aeffffffff0200ca9a3b000000001976a914054eed59ece5b6aa1ef15f3713765e708cf3d5f688ac0fd3effc4400000017a91492b52b95d25a130ccbb077703596b26e9be3c8458700000000" + } + ] +} diff --git a/mock/ext-api-data/doge-api_v2_xpub_dgub8rceyfsEvGDexmvJcBqiKBrmuxWGgYJxHjtbouHTwTfQrCQcMjxyNf6vUPY4dUp23QtReFy6WGedutBk9XUaYNupUqVAZcweqGhfsudUELN__details_txs.json b/mock/ext-api-data/doge-api_v2_xpub_dgub8rceyfsEvGDexmvJcBqiKBrmuxWGgYJxHjtbouHTwTfQrCQcMjxyNf6vUPY4dUp23QtReFy6WGedutBk9XUaYNupUqVAZcweqGhfsudUELN__details_txs.json new file mode 100644 index 000000000..2ecb2d52d --- /dev/null +++ b/mock/ext-api-data/doge-api_v2_xpub_dgub8rceyfsEvGDexmvJcBqiKBrmuxWGgYJxHjtbouHTwTfQrCQcMjxyNf6vUPY4dUp23QtReFy6WGedutBk9XUaYNupUqVAZcweqGhfsudUELN__details_txs.json @@ -0,0 +1 @@ +{"page":1,"totalPages":12,"itemsOnPage":10,"address":"dgub8rceyfsEvGDexmvJcBqiKBrmuxWGgYJxHjtbouHTwTfQrCQcMjxyNf6vUPY4dUp23QtReFy6WGedutBk9XUaYNupUqVAZcweqGhfsudUELN","balance":"53244505232","totalReceived":"2702075149752","totalSent":"2648830644520","unconfirmedBalance":"0","unconfirmedTxs":0,"txs":112,"transactions":[{"txid":"fee8381fed7406a48a8ea9e62328a3134064210626e81489ed8906e18c433bdf","version":1,"vin":[{"txid":"c6a51ed2d4bb163c324f58659d98142b3fbe44503289eb6c7749414e63111dfb","n":0,"addresses":["D5dAUAx3Ezg1q4dRgzKTBsxp4VJietWkDh"],"isAddress":true,"value":"1000000000","hex":"47304402200833c3184e768e5b6da836d9824f98b65704a24229a02e572ac760bb304ab9fb022068d102da9400afaeee3a6b42930a966ff107f5c68affde4a0239dab9fa21123d012102cc82e0824da5cc96d5967cfc06d4b82e29c44ce10cb86028d15b5e67ceb1b6ca"}],"vout":[{"value":"134700000","n":0,"hex":"76a9142ba977acdb30bc18d350df32f38a777313ae86b088ac","addresses":["D97xcKB9EAPmgNExbB5nAXDAQ9s5ZJ91J4"],"isAddress":true},{"value":"707100000","n":1,"hex":"76a914b358390833fd8371733c1d11477bdb2d185e61e988ac","addresses":["DMVPBRTD6bgqr3fk2yTdz97hS4AA2gzj8g"],"isAddress":true}],"blockHash":"b94fd58d99710000ff0991ebf82c85330ed706ea18bcd4265e1f22747b91ddfe","blockHeight":3170421,"confirmations":67953,"blockTime":1585794154,"value":"841800000","valueIn":"1000000000","fees":"158200000","hex":"0100000001fb1d11634e4149776ceb89325044be3f2b14989d65584f323c16bbd4d21ea5c6000000006a47304402200833c3184e768e5b6da836d9824f98b65704a24229a02e572ac760bb304ab9fb022068d102da9400afaeee3a6b42930a966ff107f5c68affde4a0239dab9fa21123d012102cc82e0824da5cc96d5967cfc06d4b82e29c44ce10cb86028d15b5e67ceb1b6ca0000000002e05b0708000000001976a9142ba977acdb30bc18d350df32f38a777313ae86b088ac607d252a000000001976a914b358390833fd8371733c1d11477bdb2d185e61e988ac00000000"},{"txid":"8d5fc1e686ff042b4811cb6b2df406b98b2484e973cd663b442c296f2d2f78b9","version":1,"vin":[{"txid":"f60da53d80e50e4aef26e58ca89cbbe90b554baefcf67c54b0a2648420907498","vout":1,"sequence":4294967288,"n":0,"addresses":["DF5TedCytjJRQdvTbMPJuMwbMWoveWZYp3"],"isAddress":true,"value":"533600000","hex":"483045022100f357d4cb4fbef56bc76de9894e330ce485085c3cbe58dc9680db2a35dcf99dbf02204d7ef785782d75025c117c5e70ae009104b7cdd7cd1554d5cf4cb884958c06be01210391c22d3c06172377ff770f0832a4decf91ee38b975eb65451c38faa6bef861b5"}],"vout":[{"value":"100000000","n":0,"hex":"76a914054eed59ece5b6aa1ef15f3713765e708cf3d5f688ac","addresses":["D5dAUAx3Ezg1q4dRgzKTBsxp4VJietWkDh"],"isAddress":true},{"value":"275400000","n":1,"hex":"76a9149ff8db746d4f6b11acab2bda9288dde3b8428d8e88ac","addresses":["DKix6fTygojRpBFbADfkYKDX9nZ2Y7Huqq"],"isAddress":true}],"blockHash":"ece2c433edfaf7143ba79f381ea40ac8b7e38ce6c4ff0771ae1e3dda9246824a","blockHeight":3099770,"confirmations":138604,"blockTime":1581351126,"value":"375400000","valueIn":"533600000","fees":"158200000","hex":"0100000001987490208464a2b0547cf6fcae4b550be9bb9ca88ce526ef4a0ee5803da50df6010000006b483045022100f357d4cb4fbef56bc76de9894e330ce485085c3cbe58dc9680db2a35dcf99dbf02204d7ef785782d75025c117c5e70ae009104b7cdd7cd1554d5cf4cb884958c06be01210391c22d3c06172377ff770f0832a4decf91ee38b975eb65451c38faa6bef861b5f8ffffff0200e1f505000000001976a914054eed59ece5b6aa1ef15f3713765e708cf3d5f688ac40456a10000000001976a9149ff8db746d4f6b11acab2bda9288dde3b8428d8e88ac00000000"},{"txid":"f60da53d80e50e4aef26e58ca89cbbe90b554baefcf67c54b0a2648420907498","version":1,"vin":[{"txid":"c6a51ed2d4bb163c324f58659d98142b3fbe44503289eb6c7749414e63111dfb","vout":1,"sequence":4294967291,"n":0,"addresses":["D5dAUAx3Ezg1q4dRgzKTBsxp4VJietWkDh"],"isAddress":true,"value":"841800000","hex":"483045022100f80b337309fcefc7886364f9a87ff9afcadf876542a5a36b543547f7e9d43ef10220397d6aaa649814b68dc98a1ed1027de34c8aa06cbe480e34bbe5a7ba5f282402012102cc82e0824da5cc96d5967cfc06d4b82e29c44ce10cb86028d15b5e67ceb1b6ca"}],"vout":[{"value":"150000000","n":0,"hex":"76a914e82178c73b5744342916f6a7a944af4fa37aebff88ac","addresses":["DSJVQRY3wyVPrXbEDMSeoFufWNSsMeKEuj"],"isAddress":true},{"value":"533600000","n":1,"spent":true,"hex":"76a9146d01372d8c138cddcc142ade8a7ebc84948b87df88ac","addresses":["DF5TedCytjJRQdvTbMPJuMwbMWoveWZYp3"],"isAddress":true}],"blockHash":"d4a57feed1683117d412944fc6581eace1bc3a8be5ebab93cf2dd99f5918374d","blockHeight":3088989,"confirmations":149385,"blockTime":1580673745,"value":"683600000","valueIn":"841800000","fees":"158200000","hex":"0100000001fb1d11634e4149776ceb89325044be3f2b14989d65584f323c16bbd4d21ea5c6010000006b483045022100f80b337309fcefc7886364f9a87ff9afcadf876542a5a36b543547f7e9d43ef10220397d6aaa649814b68dc98a1ed1027de34c8aa06cbe480e34bbe5a7ba5f282402012102cc82e0824da5cc96d5967cfc06d4b82e29c44ce10cb86028d15b5e67ceb1b6cafbffffff0280d1f008000000001976a914e82178c73b5744342916f6a7a944af4fa37aebff88ac0017ce1f000000001976a9146d01372d8c138cddcc142ade8a7ebc84948b87df88ac00000000"},{"txid":"17e7d6371140eba1d57a2461a8d646534ff0c8044aff83b90c49f9d74aad0a8e","version":1,"vin":[{"txid":"eaead3019d3a76858d7c106cdf3324595b8c1f06ae3ecf668327c997bb584f33","vout":1,"n":0,"addresses":["D5dAUAx3Ezg1q4dRgzKTBsxp4VJietWkDh"],"isAddress":true,"value":"483600000","hex":"4730440220336f743b7030ac993705d48a4e64d1bb5a7c2fbddeabdc4fdb33f7f41c7addc502202c723805658115ae148b9211b25987813c848949a3cd835b942de0b248168e7c012102cc82e0824da5cc96d5967cfc06d4b82e29c44ce10cb86028d15b5e67ceb1b6ca"}],"vout":[{"value":"134700000","n":0,"spent":true,"hex":"76a9147e2cd472834c324ead9cc333c50c55117e07525a88ac","addresses":["DGeFPGDgmxcuVFS4WGKQ4cqEgJSAnz6tpt"],"isAddress":true},{"value":"190700000","n":1,"hex":"76a914054eed59ece5b6aa1ef15f3713765e708cf3d5f688ac","addresses":["D5dAUAx3Ezg1q4dRgzKTBsxp4VJietWkDh"],"isAddress":true}],"blockHash":"03a3c4216bf64a38dac9ca5c34722f79ec67e0b3de9ba8a58108fced2b782374","blockHeight":3082655,"confirmations":155719,"blockTime":1580277168,"value":"325400000","valueIn":"483600000","fees":"158200000","hex":"0100000001334f58bb97c9278366cf3eae061f8c5b592433df6c107c8d85763a9d01d3eaea010000006a4730440220336f743b7030ac993705d48a4e64d1bb5a7c2fbddeabdc4fdb33f7f41c7addc502202c723805658115ae148b9211b25987813c848949a3cd835b942de0b248168e7c012102cc82e0824da5cc96d5967cfc06d4b82e29c44ce10cb86028d15b5e67ceb1b6ca0000000002e05b0708000000001976a9147e2cd472834c324ead9cc333c50c55117e07525a88ace0d95d0b000000001976a914054eed59ece5b6aa1ef15f3713765e708cf3d5f688ac00000000"},{"txid":"c6a51ed2d4bb163c324f58659d98142b3fbe44503289eb6c7749414e63111dfb","version":1,"vin":[{"txid":"44941f1d6b3bf0361f00a00d8e503ce8d0289b0990c5b4a6d13de00fa4eec1cd","n":0,"addresses":["D5dAUAx3Ezg1q4dRgzKTBsxp4VJietWkDh"],"isAddress":true,"value":"2000000000","hex":"473044022027ca75c9763fa154134343a46d8ea35c28d1231d2a0e6857564773866f5a91fe02206ec5af0e55730bfbbf53eb0eb3fccfcace7b051af973a176d8d8d096675772b2012102cc82e0824da5cc96d5967cfc06d4b82e29c44ce10cb86028d15b5e67ceb1b6ca"}],"vout":[{"value":"1000000000","n":0,"spent":true,"hex":"76a914054eed59ece5b6aa1ef15f3713765e708cf3d5f688ac","addresses":["D5dAUAx3Ezg1q4dRgzKTBsxp4VJietWkDh"],"isAddress":true},{"value":"841800000","n":1,"spent":true,"hex":"76a914054eed59ece5b6aa1ef15f3713765e708cf3d5f688ac","addresses":["D5dAUAx3Ezg1q4dRgzKTBsxp4VJietWkDh"],"isAddress":true}],"blockHash":"4701d7cf8b274af55ddddfbe76527f9b616fc69325c08b79ed35da5183be37c3","blockHeight":3081510,"confirmations":156864,"blockTime":1580204896,"value":"1841800000","valueIn":"2000000000","fees":"158200000","hex":"0100000001cdc1eea40fe03dd1a6b4c590099b28d0e83c508e0da0001f36f03b6b1d1f9444000000006a473044022027ca75c9763fa154134343a46d8ea35c28d1231d2a0e6857564773866f5a91fe02206ec5af0e55730bfbbf53eb0eb3fccfcace7b051af973a176d8d8d096675772b2012102cc82e0824da5cc96d5967cfc06d4b82e29c44ce10cb86028d15b5e67ceb1b6ca000000000200ca9a3b000000001976a914054eed59ece5b6aa1ef15f3713765e708cf3d5f688ac40d92c32000000001976a914054eed59ece5b6aa1ef15f3713765e708cf3d5f688ac00000000"},{"txid":"eaead3019d3a76858d7c106cdf3324595b8c1f06ae3ecf668327c997bb584f33","version":1,"vin":[{"txid":"a369bf2cee39e406b04d3782385f76956241b5ac1774db13f166c8e8a0172d36","vout":1,"n":0,"addresses":["DAth3nj1fUStB8UHxxuE4uFfjg8Aze4S8v"],"isAddress":true,"value":"741800000","hex":"47304402202377dc80bcc0d43a2996ec3057056730489cc3b138f504c6be5229d5441246c202201c7bdfed8a8388336b754b7a21ec631e8f5bbfcfa3ebb68cfb5d5cea60971ec30121029f274c032269ab70b7a1bed45068f6e97f0b865ae652a98054fdd25e04af267a"}],"vout":[{"value":"100000000","n":0,"hex":"76a914054eed59ece5b6aa1ef15f3713765e708cf3d5f688ac","addresses":["D5dAUAx3Ezg1q4dRgzKTBsxp4VJietWkDh"],"isAddress":true},{"value":"483600000","n":1,"spent":true,"hex":"76a914054eed59ece5b6aa1ef15f3713765e708cf3d5f688ac","addresses":["D5dAUAx3Ezg1q4dRgzKTBsxp4VJietWkDh"],"isAddress":true}],"blockHash":"fab26df4f935751512760217249335c9a4218bd84766152bd1d1b47f7cdfe33e","blockHeight":3079034,"confirmations":159340,"blockTime":1580049813,"value":"583600000","valueIn":"741800000","fees":"158200000","hex":"0100000001362d17a0e8c866f113db7417acb5416295765f3882374db006e439ee2cbf69a3010000006a47304402202377dc80bcc0d43a2996ec3057056730489cc3b138f504c6be5229d5441246c202201c7bdfed8a8388336b754b7a21ec631e8f5bbfcfa3ebb68cfb5d5cea60971ec30121029f274c032269ab70b7a1bed45068f6e97f0b865ae652a98054fdd25e04af267a000000000200e1f505000000001976a914054eed59ece5b6aa1ef15f3713765e708cf3d5f688ac8026d31c000000001976a914054eed59ece5b6aa1ef15f3713765e708cf3d5f688ac00000000"},{"txid":"44941f1d6b3bf0361f00a00d8e503ce8d0289b0990c5b4a6d13de00fa4eec1cd","version":1,"vin":[{"txid":"2b59988ab83317341e9ee48a0ba80abf4399254089037dc7660d000de53565e7","vout":1,"n":0,"addresses":["D5dAUAx3Ezg1q4dRgzKTBsxp4VJietWkDh"],"isAddress":true,"value":"51162295942","hex":"4830450221009bd7a6e5d664c57b7c994fe2bba3fc14db41e3b961b52f6da46ea517f0a765bf022028a695add7d1f0e948a492ba196f6266cc7cafc9628a9ac4518cd7fceb1e1f54012102cc82e0824da5cc96d5967cfc06d4b82e29c44ce10cb86028d15b5e67ceb1b6ca"}],"vout":[{"value":"2000000000","n":0,"spent":true,"hex":"76a914054eed59ece5b6aa1ef15f3713765e708cf3d5f688ac","addresses":["D5dAUAx3Ezg1q4dRgzKTBsxp4VJietWkDh"],"isAddress":true},{"value":"49004095942","n":1,"hex":"76a914054eed59ece5b6aa1ef15f3713765e708cf3d5f688ac","addresses":["D5dAUAx3Ezg1q4dRgzKTBsxp4VJietWkDh"],"isAddress":true}],"blockHash":"a6ebe4f81737b59699c7a3a59f21b93280c7d2a88c9e84dd90b4326226074f4f","blockHeight":3074554,"confirmations":163820,"blockTime":1579769000,"value":"51004095942","valueIn":"51162295942","fees":"158200000","hex":"0100000001e76535e50d000d66c77d038940259943bf0aa80b8ae49e1e341733b88a98592b010000006b4830450221009bd7a6e5d664c57b7c994fe2bba3fc14db41e3b961b52f6da46ea517f0a765bf022028a695add7d1f0e948a492ba196f6266cc7cafc9628a9ac4518cd7fceb1e1f54012102cc82e0824da5cc96d5967cfc06d4b82e29c44ce10cb86028d15b5e67ceb1b6ca000000000200943577000000001976a914054eed59ece5b6aa1ef15f3713765e708cf3d5f688acc629df680b0000001976a914054eed59ece5b6aa1ef15f3713765e708cf3d5f688ac00000000"},{"txid":"a369bf2cee39e406b04d3782385f76956241b5ac1774db13f166c8e8a0172d36","version":1,"vin":[{"txid":"2b59988ab83317341e9ee48a0ba80abf4399254089037dc7660d000de53565e7","sequence":4294967291,"n":0,"addresses":["D5dAUAx3Ezg1q4dRgzKTBsxp4VJietWkDh"],"isAddress":true,"value":"1000000000","hex":"4730440220348d03905d720f7bf4adf247195dcb30f4e581a88ca611ad2c336665acb10e73022034926b1fadbe03078c3210502f76cc34340b9e5a906ba1deb9ee9fc3c2a5b20d012102cc82e0824da5cc96d5967cfc06d4b82e29c44ce10cb86028d15b5e67ceb1b6ca"}],"vout":[{"value":"100000000","n":0,"hex":"76a9149fc4e4b3c5a1331b93b26bcb290c7fa2633e304688ac","addresses":["DKhsr9gcxfZ1EPGz7YK4BwWAPDeATwT94o"],"isAddress":true},{"value":"741800000","n":1,"spent":true,"hex":"76a9143f175272c8685646337257fdd4ff9837b3b37d0d88ac","addresses":["DAth3nj1fUStB8UHxxuE4uFfjg8Aze4S8v"],"isAddress":true}],"blockHash":"d677e3585338c456ba1c84e5ac360dba7b972840ece88b59b7977cab32fe697d","blockHeight":3073761,"confirmations":164613,"blockTime":1579719400,"value":"841800000","valueIn":"1000000000","fees":"158200000","hex":"0100000001e76535e50d000d66c77d038940259943bf0aa80b8ae49e1e341733b88a98592b000000006a4730440220348d03905d720f7bf4adf247195dcb30f4e581a88ca611ad2c336665acb10e73022034926b1fadbe03078c3210502f76cc34340b9e5a906ba1deb9ee9fc3c2a5b20d012102cc82e0824da5cc96d5967cfc06d4b82e29c44ce10cb86028d15b5e67ceb1b6cafbffffff0200e1f505000000001976a9149fc4e4b3c5a1331b93b26bcb290c7fa2633e304688ac40f8362c000000001976a9143f175272c8685646337257fdd4ff9837b3b37d0d88ac00000000"},{"txid":"2b59988ab83317341e9ee48a0ba80abf4399254089037dc7660d000de53565e7","version":1,"vin":[{"txid":"a5ea8e1bfcad3f860d8e2876486213d9448f14d0b4fae2d5f4c6f7ad9fd187bf","vout":1,"n":0,"addresses":["D5dAUAx3Ezg1q4dRgzKTBsxp4VJietWkDh"],"isAddress":true,"value":"52320495942","hex":"4830450221008e5dd501d7a6b0c9babca2f5d8b11ada06fb2918303c5f281b1fe8e64cde7b4802206f86df1d40eb42108ade7cad36226f9e1ba75cb282cab75ed12fcb387f4970b2012102cc82e0824da5cc96d5967cfc06d4b82e29c44ce10cb86028d15b5e67ceb1b6ca"}],"vout":[{"value":"1000000000","n":0,"spent":true,"hex":"76a914054eed59ece5b6aa1ef15f3713765e708cf3d5f688ac","addresses":["D5dAUAx3Ezg1q4dRgzKTBsxp4VJietWkDh"],"isAddress":true},{"value":"51162295942","n":1,"spent":true,"hex":"76a914054eed59ece5b6aa1ef15f3713765e708cf3d5f688ac","addresses":["D5dAUAx3Ezg1q4dRgzKTBsxp4VJietWkDh"],"isAddress":true}],"blockHash":"0c13cea0560ccf100ccfa2b484aaf6639f4a75fe9029708728abbf42423981bf","blockHeight":3070556,"confirmations":167818,"blockTime":1579517965,"value":"52162295942","valueIn":"52320495942","fees":"158200000","hex":"0100000001bf87d19fadf7c6f4d5e2fab4d0148f44d913624876288e0d863fadfc1b8eeaa5010000006b4830450221008e5dd501d7a6b0c9babca2f5d8b11ada06fb2918303c5f281b1fe8e64cde7b4802206f86df1d40eb42108ade7cad36226f9e1ba75cb282cab75ed12fcb387f4970b2012102cc82e0824da5cc96d5967cfc06d4b82e29c44ce10cb86028d15b5e67ceb1b6ca000000000200ca9a3b000000001976a914054eed59ece5b6aa1ef15f3713765e708cf3d5f688ac86ae82e90b0000001976a914054eed59ece5b6aa1ef15f3713765e708cf3d5f688ac00000000"},{"txid":"a5ea8e1bfcad3f860d8e2876486213d9448f14d0b4fae2d5f4c6f7ad9fd187bf","version":1,"vin":[{"txid":"0a43e6297dc2c63527bc0138e199cfe41b6b41c4877ba60a425bd425a7eafec9","vout":1,"n":0,"addresses":["DLKFsc4PWe6KSGbeXZPv9kgCrQQBycf6nc"],"isAddress":true,"value":"53478695942","hex":"483045022100db69f1b5966a47c20de9fcf9891ff6bda8f9ccd28336acd51276a4134290bd9002200c33d0c4bb76c8c0596a68fb715a8e7cc47ac98a65266f9ef40ea2de36ca3a9b012102debf9eb33094bbbf385e118614f4e8d67c946067677dd85de913415800148c5f"}],"vout":[{"value":"1000000000","n":0,"hex":"76a914054eed59ece5b6aa1ef15f3713765e708cf3d5f688ac","addresses":["D5dAUAx3Ezg1q4dRgzKTBsxp4VJietWkDh"],"isAddress":true},{"value":"52320495942","n":1,"spent":true,"hex":"76a914054eed59ece5b6aa1ef15f3713765e708cf3d5f688ac","addresses":["D5dAUAx3Ezg1q4dRgzKTBsxp4VJietWkDh"],"isAddress":true}],"blockHash":"336481816fe09f284657ebe3c98fca8fab4c3edd7e15ddbb5f8c19bd00326f9c","blockHeight":3070538,"confirmations":167836,"blockTime":1579516786,"value":"53320495942","valueIn":"53478695942","fees":"158200000","hex":"0100000001c9feeaa725d45b420aa67b87c4416b1be4cf99e13801bc2735c6c27d29e6430a010000006b483045022100db69f1b5966a47c20de9fcf9891ff6bda8f9ccd28336acd51276a4134290bd9002200c33d0c4bb76c8c0596a68fb715a8e7cc47ac98a65266f9ef40ea2de36ca3a9b012102debf9eb33094bbbf385e118614f4e8d67c946067677dd85de913415800148c5f000000000200ca9a3b000000001976a914054eed59ece5b6aa1ef15f3713765e708cf3d5f688ac46698b2e0c0000001976a914054eed59ece5b6aa1ef15f3713765e708cf3d5f688ac00000000"}],"usedTokens":111,"tokens":[{"type":"XPUBAddress","name":"D5dAUAx3Ezg1q4dRgzKTBsxp4VJietWkDh","path":"m/44'/3'/0'/0/0","transfers":12,"decimals":8,"balance":"50394795942","totalReceived":"160202987826","totalSent":"109808191884"},{"type":"XPUBAddress","name":"DAmfSJjQsNhZhG9ofHPVmBoycaVCsGyedt","path":"m/44'/3'/0'/0/6","transfers":3,"decimals":8,"balance":"55000000","totalReceived":"305000000","totalSent":"250000000"},{"type":"XPUBAddress","name":"DAzJEmCZXWWji8fjhKwA2WXZjbLNpbAbNa","path":"m/44'/3'/0'/0/7","transfers":1,"decimals":8,"balance":"77500000","totalReceived":"77500000","totalSent":"0"},{"type":"XPUBAddress","name":"DTUsUEgauBsHowJe2nuQMwVZ2irqhENJ6Y","path":"m/44'/3'/0'/0/8","transfers":1,"decimals":8,"balance":"66500000","totalReceived":"66500000","totalSent":"0"},{"type":"XPUBAddress","name":"DEcqrwwRs6gYH4YSvHhmiaPpd3DyQYa2uR","path":"m/44'/3'/0'/0/9","transfers":1,"decimals":8,"balance":"8454000","totalReceived":"8454000","totalSent":"0"},{"type":"XPUBAddress","name":"DGVDyBSb7NMzYna2V8u8exUecgUz2m4xXQ","path":"m/44'/3'/0'/0/10","transfers":1,"decimals":8,"balance":"3350000","totalReceived":"3350000","totalSent":"0"},{"type":"XPUBAddress","name":"DPdHGVnuP2k2CyY2zp4goS9EqQGD6hUzBR","path":"m/44'/3'/0'/0/11","transfers":1,"decimals":8,"balance":"5577000","totalReceived":"5577000","totalSent":"0"},{"type":"XPUBAddress","name":"DCKFrLUWqydYnX1Fs8iSzDqkskzATUoxpT","path":"m/44'/3'/0'/0/12","transfers":1,"decimals":8,"balance":"6688550","totalReceived":"6688550","totalSent":"0"},{"type":"XPUBAddress","name":"DBmCuiHwpBrGwFVRoKbpatCFFGQt5pxJ3T","path":"m/44'/3'/0'/0/14","transfers":1,"decimals":8,"balance":"90000000","totalReceived":"90000000","totalSent":"0"},{"type":"XPUBAddress","name":"DGy5ZmuRmF7qdhPnrNX6avTDYjABnS5xDk","path":"m/44'/3'/0'/0/17","transfers":1,"decimals":8,"balance":"5000","totalReceived":"5000","totalSent":"0"},{"type":"XPUBAddress","name":"DEnxVnyWxHCi64BwHDWHRuCnkTajMWzNQ6","path":"m/44'/3'/0'/0/19","transfers":1,"decimals":8,"balance":"100000000","totalReceived":"100000000","totalSent":"0"},{"type":"XPUBAddress","name":"DCtJGsdVMrr1MkXjHNq7JEw8g3wkV2Vucv","path":"m/44'/3'/0'/0/21","transfers":3,"decimals":8,"balance":"1000000","totalReceived":"2501000000","totalSent":"2500000000"},{"type":"XPUBAddress","name":"DMXSG11oMpiEXGVPFef22Gm3t6n5M3iC44","path":"m/44'/3'/0'/0/24","transfers":1,"decimals":8,"balance":"100000","totalReceived":"100000","totalSent":"0"},{"type":"XPUBAddress","name":"D9aUm1ghFCGAdf3A2F9yrfy7n8KcPUdQMP","path":"m/44'/3'/0'/0/25","transfers":1,"decimals":8,"balance":"100000000","totalReceived":"100000000","totalSent":"0"},{"type":"XPUBAddress","name":"DHBX9Bi3zPqypTuiTWyhwJofaYr57RkoCp","path":"m/44'/3'/0'/0/26","transfers":1,"decimals":8,"balance":"368650","totalReceived":"368650","totalSent":"0"},{"type":"XPUBAddress","name":"DSVfFWXDHk3X55egkvXALHy83XYz3xBDro","path":"m/44'/3'/0'/0/27","transfers":1,"decimals":8,"balance":"100300000","totalReceived":"100300000","totalSent":"0"},{"type":"XPUBAddress","name":"D9cgiTxGYh6aMveGG5Bu4HqHuujH7H1mYt","path":"m/44'/3'/0'/0/29","transfers":3,"decimals":8,"balance":"212600000","totalReceived":"54554702722","totalSent":"54342102722"},{"type":"XPUBAddress","name":"DUAqwidnicCws1SRyENmMJo2KekJmB72ZH","path":"m/44'/3'/0'/0/30","transfers":1,"decimals":8,"balance":"100000000","totalReceived":"100000000","totalSent":"0"},{"type":"XPUBAddress","name":"DTFB8Mf5zLx6fuEwheBUZmNUmyubQZkn8F","path":"m/44'/3'/0'/0/31","transfers":1,"decimals":8,"balance":"100000000","totalReceived":"100000000","totalSent":"0"},{"type":"XPUBAddress","name":"DKhsr9gcxfZ1EPGz7YK4BwWAPDeATwT94o","path":"m/44'/3'/0'/0/32","transfers":1,"decimals":8,"balance":"100000000","totalReceived":"100000000","totalSent":"0"},{"type":"XPUBAddress","name":"DSJVQRY3wyVPrXbEDMSeoFufWNSsMeKEuj","path":"m/44'/3'/0'/0/33","transfers":1,"decimals":8,"balance":"150000000","totalReceived":"150000000","totalSent":"0"},{"type":"XPUBAddress","name":"D6GBtZ7eWgeb9mWnewXzxJZFTBdp9wxkWP","path":"m/44'/3'/0'/1/14","transfers":1,"decimals":8,"balance":"53594096","totalReceived":"53594096","totalSent":"0"},{"type":"XPUBAddress","name":"DEWNmicZTDghQDGgBysziWnkQX7SJTTLB8","path":"m/44'/3'/0'/1/16","transfers":3,"decimals":8,"balance":"44999774","totalReceived":"590469146","totalSent":"545469372"},{"type":"XPUBAddress","name":"D9NnFbEq5xCqBa8HUx7nEdfcdazNqWMsJT","path":"m/44'/3'/0'/1/18","transfers":1,"decimals":8,"balance":"39281934","totalReceived":"39281934","totalSent":"0"},{"type":"XPUBAddress","name":"DHxauYh42gVDAuFzx5NjNDcNu5BqniTTwK","path":"m/44'/3'/0'/1/21","transfers":1,"decimals":8,"balance":"7807718","totalReceived":"7807718","totalSent":"0"},{"type":"XPUBAddress","name":"DEnByJTQuE5qW9LecZeUeqB8TShWRDpWhE","path":"m/44'/3'/0'/1/23","transfers":1,"decimals":8,"balance":"19811382","totalReceived":"19811382","totalSent":"0"},{"type":"XPUBAddress","name":"DDjudCpuaPaoi2FyiAVFu2vaxsAkJu5fxi","path":"m/44'/3'/0'/1/24","transfers":1,"decimals":8,"balance":"100175758","totalReceived":"100175758","totalSent":"0"},{"type":"XPUBAddress","name":"DDyapoohdiTuM5R8jjnpsnHsfW1NcSMrSL","path":"m/44'/3'/0'/1/27","transfers":1,"decimals":8,"balance":"75155276","totalReceived":"75155276","totalSent":"0"},{"type":"XPUBAddress","name":"DQwQAPehMc8B9cXTyHR852T73jKTpzttck","path":"m/44'/3'/0'/1/31","transfers":1,"decimals":8,"balance":"57559726","totalReceived":"57559726","totalSent":"0"},{"type":"XPUBAddress","name":"D98VNKCWrfxNnFRyTL5GnG81QrDhHa5oJb","path":"m/44'/3'/0'/1/37","transfers":3,"decimals":8,"balance":"100000000","totalReceived":"76212237584","totalSent":"76112237584"},{"type":"XPUBAddress","name":"DH8voVMkSxoyyLnd9TFvBEcbTRwk7DNqH1","path":"m/44'/3'/0'/1/49","transfers":1,"decimals":8,"balance":"580426","totalReceived":"580426","totalSent":"0"},{"type":"XPUBAddress","name":"DLEDSw71Emp4yJtp7q2HLXBapjVs7eSY42","path":"m/44'/3'/0'/1/58","transfers":1,"decimals":8,"balance":"90800000","totalReceived":"90800000","totalSent":"0"},{"type":"XPUBAddress","name":"DKix6fTygojRpBFbADfkYKDX9nZ2Y7Huqq","path":"m/44'/3'/0'/1/75","transfers":1,"decimals":8,"balance":"275400000","totalReceived":"275400000","totalSent":"0"},{"type":"XPUBAddress","name":"DMVPBRTD6bgqr3fk2yTdz97hS4AA2gzj8g","path":"m/44'/3'/0'/1/76","transfers":1,"decimals":8,"balance":"707100000","totalReceived":"707100000","totalSent":"0"}]} diff --git a/mock/ext-api-data/eth-api_tokens__address_0x0875BCab22dE3d02402bc38aEe4104e1239374a7.json b/mock/ext-api-data/eth-api_tokens__address_0x0875BCab22dE3d02402bc38aEe4104e1239374a7.json new file mode 100644 index 000000000..d0c420cca --- /dev/null +++ b/mock/ext-api-data/eth-api_tokens__address_0x0875BCab22dE3d02402bc38aEe4104e1239374a7.json @@ -0,0 +1,107 @@ +{ + "total": 17, + "docs": [ + { + "address": "0xdd974D5C2e2928deA5F71b9825b8b646686BD200", + "name": "Kyber Network Crystal", + "decimals": 18, + "symbol": "KNC" + }, + { + "address": "0xB8c77482e45F1F44dE1745F52C74426C631bDD52", + "name": "BNB", + "decimals": 18, + "symbol": "BNB" + }, + { + "address": "0x0D8775F648430679A709E98d2b0Cb6250d2887EF", + "name": "Basic Attention Token", + "decimals": 18, + "symbol": "BAT" + }, + { + "address": "0x226bb599a12C826476e3A771454697EA52E9E220", + "name": "Propy", + "decimals": 8, + "symbol": "PRO" + }, + { + "address": "0xf3Db5Fa2C66B7aF3Eb0C0b782510816cbe4813b8", + "name": "Everex", + "decimals": 4, + "symbol": "EVX" + }, + { + "address": "0x85e076361cc813A908Ff672F9BAd1541474402b2", + "name": "Telcoin", + "decimals": 2, + "symbol": "TEL" + }, + { + "address": "0xD73bE539d6B2076BaB83CA6Ba62DfE189aBC6Bbe", + "name": "BlockchainCuties", + "decimals": 0, + "symbol": "BC" + }, + { + "address": "0x0000000000085d4780B73119b644AE5ecd22b376", + "name": "TrueUSD", + "decimals": 18, + "symbol": "TUSD" + }, + { + "address": "0xFBeef911Dc5821886e1dda71586d90eD28174B7d", + "name": "KnownOriginDigitalAsset", + "decimals": 0, + "symbol": "KODA" + }, + { + "address": "0xc3761EB917CD790B30dAD99f6Cc5b4Ff93C4F9eA", + "name": "ERC20", + "decimals": 18, + "symbol": "ERC20" + }, + { + "address": "0x77FE30b2cf39245267C0a5084B66a560f1cF9E1f", + "name": "Azbit", + "decimals": 18, + "symbol": "AZ" + }, + { + "address": "0x7f3EaB3491Ed282197038F1B89CA33D7e5ADffBa", + "name": "Coin-coin coinslot.com", + "decimals": 8, + "symbol": "CC coinslot.com" + }, + { + "address": "0xdAC17F958D2ee523a2206206994597C13D831ec7", + "name": "Tether USD", + "decimals": 6, + "symbol": "USDT" + }, + { + "address": "0xE1Ac9Eb7cDDAbfd9e5CA49c23bd521aFcDF8BE49", + "name": "Mycion", + "decimals": 18, + "symbol": "MYC" + }, + { + "address": "0xF629cBd94d3791C9250152BD8dfBDF380E2a3B9c", + "name": "Enjin Coin", + "decimals": 18, + "symbol": "ENJ" + }, + { + "address": "0x467Bccd9d29f223BcE8043b84E8C8B282827790F", + "name": "Telcoin", + "decimals": 2, + "symbol": "TEL" + }, + { + "address": "0xC12D1c73eE7DC3615BA4e37E4ABFdbDDFA38907E", + "name": "KickToken", + "decimals": 8, + "symbol": "KICK" + } + ] +} diff --git a/mock/ext-api-data/eth-api_transactions__address_0x0875BCab22dE3d02402bc38aEe4104e1239374a7.json b/mock/ext-api-data/eth-api_transactions__address_0x0875BCab22dE3d02402bc38aEe4104e1239374a7.json new file mode 100644 index 000000000..6b0295a70 --- /dev/null +++ b/mock/ext-api-data/eth-api_transactions__address_0x0875BCab22dE3d02402bc38aEe4104e1239374a7.json @@ -0,0 +1,58 @@ +{ + "docs": [ + { + "operations": [], + "contract": null, + "_id": "0x2a9fd94735e273526a2cde57c6a19b9d488e0c9a960565c3e19be5e12d4b4b47", + "blockNumber": 9551915, + "time": 1582624428, + "nonce": 227, + "from": "0x0875BCab22dE3d02402bc38aEe4104e1239374a7", + "to": "0x1717f94202c126ef71d6C562de253Fe95eEbDD5f", + "value": "17635730000000000", + "gas": "21000", + "gasPrice": "4320000000", + "gasUsed": "21000", + "input": "0x", + "error": "", + "id": "0x2a9fd94735e273526a2cde57c6a19b9d488e0c9a960565c3e19be5e12d4b4b47", + "timeStamp": "1582624428" + }, + { + "operations": [ + { + "transactionId": "0xb669b69afee75c6ef073a603600041d3708d54da8d43cab7b35ee66baa7510d3-0", + "contract": { + "address": "0x0d8775f648430679a709e98d2b0cb6250d2887ef", + "symbol": "BAT", + "decimals": 18, + "totalSupply": "1500000000000000000000000000", + "name": "Basic Attention Token", + "updatedAt": "2020-03-23T06:01:25.975Z" + }, + "from": "0xeCe114137b2e9Dbf29712BDC39639EB0B72B41b8", + "to": "0x0875BCab22dE3d02402bc38aEe4104e1239374a7", + "type": "token_transfer", + "value": "400000000000000000", + "id": null + } + ], + "contract": null, + "_id": "0xb669b69afee75c6ef073a603600041d3708d54da8d43cab7b35ee66baa7510d3", + "blockNumber": 9519169, + "time": 1582189159, + "nonce": 16, + "from": "0xeCe114137b2e9Dbf29712BDC39639EB0B72B41b8", + "to": "0x0D8775F648430679A709E98d2b0Cb6250d2887EF", + "value": "0", + "gas": "51839", + "gasPrice": "11500000000", + "gasUsed": "37028", + "input": "0xa9059cbb0000000000000000000000000875bcab22de3d02402bc38aee4104e1239374a7000000000000000000000000000000000000000000000000058d15e176280000", + "error": "", + "id": "0xb669b69afee75c6ef073a603600041d3708d54da8d43cab7b35ee66baa7510d3", + "timeStamp": "1582189159" + } + ], + "total": 2 +} \ No newline at end of file diff --git a/mock/ext-api-data/eth-blockbook-api_v2_address_0x0875BCab22dE3d02402bc38aEe4104e1239374a7__details_tokenBalances.json b/mock/ext-api-data/eth-blockbook-api_v2_address_0x0875BCab22dE3d02402bc38aEe4104e1239374a7__details_tokenBalances.json new file mode 100644 index 000000000..11ea43845 --- /dev/null +++ b/mock/ext-api-data/eth-blockbook-api_v2_address_0x0875BCab22dE3d02402bc38aEe4104e1239374a7__details_tokenBalances.json @@ -0,0 +1,38 @@ +{ + "address": "0x0875BCab22dE3d02402bc38aEe4104e1239374a7", + "balance": "182976771756327797", + "unconfirmedBalance": "0", + "unconfirmedTxs": 0, + "txs": 263, + "nonTokenTxs": 243, + "nonce": "231", + "tokens": [ + { + "type": "ERC20", + "name": "Kyber Network Crystal", + "contract": "0xdd974D5C2e2928deA5F71b9825b8b646686BD200", + "transfers": 13, + "symbol": "KNC", + "decimals": 18, + "balance": "41100" + }, + { + "type": "ERC20", + "name": "BNB", + "contract": "0xB8c77482e45F1F44dE1745F52C74426C631bDD52", + "transfers": 4, + "symbol": "BNB", + "decimals": 18, + "balance": "100500" + }, + { + "type": "ERC20", + "name": "BNB", + "contract": "0xB8c77482e45F1F44dE1745F52C74426C631bDD52", + "transfers": 4, + "symbol": "BNB", + "decimals": 18, + "balance": "0" + } + ] +} \ No newline at end of file diff --git a/mock/ext-api-data/eth-blockbook-api_v2_address_0x0875BCab22dE3d02402bc38aEe4104e1239374a7__details_txs.json b/mock/ext-api-data/eth-blockbook-api_v2_address_0x0875BCab22dE3d02402bc38aEe4104e1239374a7__details_txs.json new file mode 100644 index 000000000..38e87a47f --- /dev/null +++ b/mock/ext-api-data/eth-blockbook-api_v2_address_0x0875BCab22dE3d02402bc38aEe4104e1239374a7__details_txs.json @@ -0,0 +1,97 @@ +{ + "page": 1, + "totalPages": 11, + "itemsOnPage": 25, + "address": "0x0875BCab22dE3d02402bc38aEe4104e1239374a7", + "balance": "185659745674589722", + "unconfirmedBalance": "0", + "unconfirmedTxs": 0, + "txs": 259, + "nonTokenTxs": 240, + "transactions": [ + { + "txid": "0x2a9fd94735e273526a2cde57c6a19b9d488e0c9a960565c3e19be5e12d4b4b47", + "vin": [ + { + "n": 0, + "addresses": [ + "0x0875BCab22dE3d02402bc38aEe4104e1239374a7" + ], + "isAddress": true + } + ], + "vout": [ + { + "value": "17635730000000000", + "n": 0, + "addresses": [ + "0x1717f94202c126ef71d6C562de253Fe95eEbDD5f" + ], + "isAddress": true + } + ], + "blockHash": "0x5b8b39099d025a8feeed7575ebff6d0b2508e0542d6279c1b3b4f8b893e74296", + "blockHeight": 9551915, + "confirmations": 231227, + "blockTime": 1582624428, + "value": "17635730000000000", + "fees": "90720000000000", + "ethereumSpecific": { + "status": 1, + "nonce": 227, + "gasLimit": 21000, + "gasUsed": 21000, + "gasPrice": "4320000000" + } + }, + { + "txid": "0xb669b69afee75c6ef073a603600041d3708d54da8d43cab7b35ee66baa7510d3", + "vin": [ + { + "n": 0, + "addresses": [ + "0xeCe114137b2e9Dbf29712BDC39639EB0B72B41b8" + ], + "isAddress": true + } + ], + "vout": [ + { + "value": "0", + "n": 0, + "addresses": [ + "0x0D8775F648430679A709E98d2b0Cb6250d2887EF" + ], + "isAddress": true + } + ], + "blockHash": "0x770332c9b4ea42e518f8c5a0178ca5732fd5edfe5e8e011e1362e6598de262d5", + "blockHeight": 9519169, + "confirmations": 263973, + "blockTime": 1582189159, + "value": "0", + "fees": "425822000000000", + "tokenTransfers": [ + { + "type": "ERC20", + "from": "0xeCe114137b2e9Dbf29712BDC39639EB0B72B41b8", + "to": "0x0875BCab22dE3d02402bc38aEe4104e1239374a7", + "token": "0x0D8775F648430679A709E98d2b0Cb6250d2887EF", + "name": "Basic Attention Token", + "symbol": "BAT", + "decimals": 18, + "value": "400000000000000000" + } + ], + "ethereumSpecific": { + "status": 1, + "nonce": 16, + "gasLimit": 51839, + "gasUsed": 37028, + "gasPrice": "11500000000" + } + } + ], + "nonce": "228", + "tokens": [] +} \ No newline at end of file diff --git a/mock/ext-api-data/eth-rpc__eth_call_data_0x0178b8bf2337fcf9521666fd5114df2902fa9e6da5a6b004b5a192a0f55d2d9fab4f1047.json b/mock/ext-api-data/eth-rpc__eth_call_data_0x0178b8bf2337fcf9521666fd5114df2902fa9e6da5a6b004b5a192a0f55d2d9fab4f1047.json new file mode 100644 index 000000000..55019963b --- /dev/null +++ b/mock/ext-api-data/eth-rpc__eth_call_data_0x0178b8bf2337fcf9521666fd5114df2902fa9e6da5a6b004b5a192a0f55d2d9fab4f1047.json @@ -0,0 +1 @@ +{"jsonrpc":"2.0","id":257,"result":"0x0000000000000000000000001da022710df5002339274aadee8d58218e9d6ab5"} diff --git a/mock/ext-api-data/eth-rpc__eth_call_data_0x0178b8bf2337fcf9521666fd5114df2902fa9e6da5a6b004b5a192a0f55d2d9fab4f1047.request_json b/mock/ext-api-data/eth-rpc__eth_call_data_0x0178b8bf2337fcf9521666fd5114df2902fa9e6da5a6b004b5a192a0f55d2d9fab4f1047.request_json new file mode 100644 index 000000000..9fb2aae12 --- /dev/null +++ b/mock/ext-api-data/eth-rpc__eth_call_data_0x0178b8bf2337fcf9521666fd5114df2902fa9e6da5a6b004b5a192a0f55d2d9fab4f1047.request_json @@ -0,0 +1 @@ +{"jsonrpc":"2.0","method":"eth_call","params":[{"data":"0x0178b8bf2337fcf9521666fd5114df2902fa9e6da5a6b004b5a192a0f55d2d9fab4f1047","to":"0x00000000000C2E074eC69A0dFb2997BA6C7d2e1e"},"latest"],"id":257} diff --git a/mock/ext-api-data/eth-rpc__eth_call_data_0x0178b8bfa538cd174de170e8062c97c25c40a7ceb56aca81b12e6f5afc46f5a429999aa4.json b/mock/ext-api-data/eth-rpc__eth_call_data_0x0178b8bfa538cd174de170e8062c97c25c40a7ceb56aca81b12e6f5afc46f5a429999aa4.json new file mode 100644 index 000000000..95c58c4b8 --- /dev/null +++ b/mock/ext-api-data/eth-rpc__eth_call_data_0x0178b8bfa538cd174de170e8062c97c25c40a7ceb56aca81b12e6f5afc46f5a429999aa4.json @@ -0,0 +1 @@ +{"jsonrpc":"2.0","id":251,"result":"0x000000000000000000000000bd5f5ec7ed5f19b53726344540296c02584a5237"} diff --git a/mock/ext-api-data/eth-rpc__eth_call_data_0x0178b8bfa538cd174de170e8062c97c25c40a7ceb56aca81b12e6f5afc46f5a429999aa4.request_json b/mock/ext-api-data/eth-rpc__eth_call_data_0x0178b8bfa538cd174de170e8062c97c25c40a7ceb56aca81b12e6f5afc46f5a429999aa4.request_json new file mode 100644 index 000000000..234ab5a89 --- /dev/null +++ b/mock/ext-api-data/eth-rpc__eth_call_data_0x0178b8bfa538cd174de170e8062c97c25c40a7ceb56aca81b12e6f5afc46f5a429999aa4.request_json @@ -0,0 +1 @@ +{"jsonrpc":"2.0","method":"eth_call","params":[{"data":"0x0178b8bfa538cd174de170e8062c97c25c40a7ceb56aca81b12e6f5afc46f5a429999aa4","to":"0x00000000000C2E074eC69A0dFb2997BA6C7d2e1e"},"latest"],"id":251} diff --git a/mock/ext-api-data/eth-rpc__eth_call_data_0x0178b8bfee6c4522aab0003e8d14cd40a6af439055fd2577951148c14b6cea9a53475835.json b/mock/ext-api-data/eth-rpc__eth_call_data_0x0178b8bfee6c4522aab0003e8d14cd40a6af439055fd2577951148c14b6cea9a53475835.json new file mode 100644 index 000000000..7e6d9178d --- /dev/null +++ b/mock/ext-api-data/eth-rpc__eth_call_data_0x0178b8bfee6c4522aab0003e8d14cd40a6af439055fd2577951148c14b6cea9a53475835.json @@ -0,0 +1 @@ +{"jsonrpc":"2.0","id":249,"result":"0x000000000000000000000000226159d592e2b063810a10ebf6dcbada94ed68b8"} diff --git a/mock/ext-api-data/eth-rpc__eth_call_data_0x0178b8bfee6c4522aab0003e8d14cd40a6af439055fd2577951148c14b6cea9a53475835.request_json b/mock/ext-api-data/eth-rpc__eth_call_data_0x0178b8bfee6c4522aab0003e8d14cd40a6af439055fd2577951148c14b6cea9a53475835.request_json new file mode 100644 index 000000000..eb0df06e4 --- /dev/null +++ b/mock/ext-api-data/eth-rpc__eth_call_data_0x0178b8bfee6c4522aab0003e8d14cd40a6af439055fd2577951148c14b6cea9a53475835.request_json @@ -0,0 +1 @@ +{"jsonrpc":"2.0","method":"eth_call","params":[{"data":"0x0178b8bfee6c4522aab0003e8d14cd40a6af439055fd2577951148c14b6cea9a53475835","to":"0x00000000000C2E074eC69A0dFb2997BA6C7d2e1e"},"latest"],"id":249} diff --git a/mock/ext-api-data/eth-rpc__eth_call_data_0x3b3b57de2337fcf9521666fd5114df2902fa9e6da5a6b004b5a192a0f55d2d9fab4f1047.json b/mock/ext-api-data/eth-rpc__eth_call_data_0x3b3b57de2337fcf9521666fd5114df2902fa9e6da5a6b004b5a192a0f55d2d9fab4f1047.json new file mode 100644 index 000000000..8e3f357e6 --- /dev/null +++ b/mock/ext-api-data/eth-rpc__eth_call_data_0x3b3b57de2337fcf9521666fd5114df2902fa9e6da5a6b004b5a192a0f55d2d9fab4f1047.json @@ -0,0 +1 @@ +{"jsonrpc":"2.0","id":259,"result":"0x0000000000000000000000000c54eead78d555be3cbcd451424f9a27a7843935"} diff --git a/mock/ext-api-data/eth-rpc__eth_call_data_0x3b3b57de2337fcf9521666fd5114df2902fa9e6da5a6b004b5a192a0f55d2d9fab4f1047.request_json b/mock/ext-api-data/eth-rpc__eth_call_data_0x3b3b57de2337fcf9521666fd5114df2902fa9e6da5a6b004b5a192a0f55d2d9fab4f1047.request_json new file mode 100644 index 000000000..a9fda4132 --- /dev/null +++ b/mock/ext-api-data/eth-rpc__eth_call_data_0x3b3b57de2337fcf9521666fd5114df2902fa9e6da5a6b004b5a192a0f55d2d9fab4f1047.request_json @@ -0,0 +1 @@ +{"jsonrpc":"2.0","method":"eth_call","params":[{"data":"0x3b3b57de2337fcf9521666fd5114df2902fa9e6da5a6b004b5a192a0f55d2d9fab4f1047","to":"0x1da022710df5002339274aadee8d58218e9d6ab5"},"latest"],"id":259} diff --git a/mock/ext-api-data/eth-rpc__eth_call_data_0x3b3b57dea538cd174de170e8062c97c25c40a7ceb56aca81b12e6f5afc46f5a429999aa4.json b/mock/ext-api-data/eth-rpc__eth_call_data_0x3b3b57dea538cd174de170e8062c97c25c40a7ceb56aca81b12e6f5afc46f5a429999aa4.json new file mode 100644 index 000000000..06c0e5496 --- /dev/null +++ b/mock/ext-api-data/eth-rpc__eth_call_data_0x3b3b57dea538cd174de170e8062c97c25c40a7ceb56aca81b12e6f5afc46f5a429999aa4.json @@ -0,0 +1 @@ +{"jsonrpc":"2.0","id":253,"result":"0x000000000000000000000000d8a667312d5260f12a306ae7730c754d938da86c"} diff --git a/mock/ext-api-data/eth-rpc__eth_call_data_0x3b3b57dea538cd174de170e8062c97c25c40a7ceb56aca81b12e6f5afc46f5a429999aa4.request_json b/mock/ext-api-data/eth-rpc__eth_call_data_0x3b3b57dea538cd174de170e8062c97c25c40a7ceb56aca81b12e6f5afc46f5a429999aa4.request_json new file mode 100644 index 000000000..7af97c924 --- /dev/null +++ b/mock/ext-api-data/eth-rpc__eth_call_data_0x3b3b57dea538cd174de170e8062c97c25c40a7ceb56aca81b12e6f5afc46f5a429999aa4.request_json @@ -0,0 +1 @@ +{"jsonrpc":"2.0","method":"eth_call","params":[{"data":"0x3b3b57dea538cd174de170e8062c97c25c40a7ceb56aca81b12e6f5afc46f5a429999aa4","to":"0xbd5f5ec7ed5f19b53726344540296c02584a5237"},"latest"],"id":253} diff --git a/mock/ext-api-data/eth-rpc__eth_call_data_0xf1cb7e062337fcf9521666fd5114df2902fa9e6da5a6b004b5a192a0f55d2d9fab4f1047000000000000000000000000000000000000000000000000000000000000003c.json b/mock/ext-api-data/eth-rpc__eth_call_data_0xf1cb7e062337fcf9521666fd5114df2902fa9e6da5a6b004b5a192a0f55d2d9fab4f1047000000000000000000000000000000000000000000000000000000000000003c.json new file mode 100644 index 000000000..4033b5220 --- /dev/null +++ b/mock/ext-api-data/eth-rpc__eth_call_data_0xf1cb7e062337fcf9521666fd5114df2902fa9e6da5a6b004b5a192a0f55d2d9fab4f1047000000000000000000000000000000000000000000000000000000000000003c.json @@ -0,0 +1 @@ +{"jsonrpc":"2.0","id":258,"result":"0x"} diff --git a/mock/ext-api-data/eth-rpc__eth_call_data_0xf1cb7e062337fcf9521666fd5114df2902fa9e6da5a6b004b5a192a0f55d2d9fab4f1047000000000000000000000000000000000000000000000000000000000000003c.request_json b/mock/ext-api-data/eth-rpc__eth_call_data_0xf1cb7e062337fcf9521666fd5114df2902fa9e6da5a6b004b5a192a0f55d2d9fab4f1047000000000000000000000000000000000000000000000000000000000000003c.request_json new file mode 100644 index 000000000..f5ebff997 --- /dev/null +++ b/mock/ext-api-data/eth-rpc__eth_call_data_0xf1cb7e062337fcf9521666fd5114df2902fa9e6da5a6b004b5a192a0f55d2d9fab4f1047000000000000000000000000000000000000000000000000000000000000003c.request_json @@ -0,0 +1 @@ +{"jsonrpc":"2.0","method":"eth_call","params":[{"data":"0xf1cb7e062337fcf9521666fd5114df2902fa9e6da5a6b004b5a192a0f55d2d9fab4f1047000000000000000000000000000000000000000000000000000000000000003c","to":"0x1da022710df5002339274aadee8d58218e9d6ab5"},"latest"],"id":258} diff --git a/mock/ext-api-data/eth-rpc__eth_call_data_0xf1cb7e06a538cd174de170e8062c97c25c40a7ceb56aca81b12e6f5afc46f5a429999aa4000000000000000000000000000000000000000000000000000000000000003c.json b/mock/ext-api-data/eth-rpc__eth_call_data_0xf1cb7e06a538cd174de170e8062c97c25c40a7ceb56aca81b12e6f5afc46f5a429999aa4000000000000000000000000000000000000000000000000000000000000003c.json new file mode 100644 index 000000000..46be200fc --- /dev/null +++ b/mock/ext-api-data/eth-rpc__eth_call_data_0xf1cb7e06a538cd174de170e8062c97c25c40a7ceb56aca81b12e6f5afc46f5a429999aa4000000000000000000000000000000000000000000000000000000000000003c.json @@ -0,0 +1 @@ +{"jsonrpc":"2.0","id":252,"result":"0x"} diff --git a/mock/ext-api-data/eth-rpc__eth_call_data_0xf1cb7e06a538cd174de170e8062c97c25c40a7ceb56aca81b12e6f5afc46f5a429999aa4000000000000000000000000000000000000000000000000000000000000003c.request_json b/mock/ext-api-data/eth-rpc__eth_call_data_0xf1cb7e06a538cd174de170e8062c97c25c40a7ceb56aca81b12e6f5afc46f5a429999aa4000000000000000000000000000000000000000000000000000000000000003c.request_json new file mode 100644 index 000000000..cac40fda0 --- /dev/null +++ b/mock/ext-api-data/eth-rpc__eth_call_data_0xf1cb7e06a538cd174de170e8062c97c25c40a7ceb56aca81b12e6f5afc46f5a429999aa4000000000000000000000000000000000000000000000000000000000000003c.request_json @@ -0,0 +1 @@ +{"jsonrpc":"2.0","method":"eth_call","params":[{"data":"0xf1cb7e06a538cd174de170e8062c97c25c40a7ceb56aca81b12e6f5afc46f5a429999aa4000000000000000000000000000000000000000000000000000000000000003c","to":"0xbd5f5ec7ed5f19b53726344540296c02584a5237"},"latest"],"id":252} diff --git a/mock/ext-api-data/eth-rpc__eth_call_data_0xf1cb7e06ee6c4522aab0003e8d14cd40a6af439055fd2577951148c14b6cea9a53475835000000000000000000000000000000000000000000000000000000000000003c.json b/mock/ext-api-data/eth-rpc__eth_call_data_0xf1cb7e06ee6c4522aab0003e8d14cd40a6af439055fd2577951148c14b6cea9a53475835000000000000000000000000000000000000000000000000000000000000003c.json new file mode 100644 index 000000000..92a7224b7 --- /dev/null +++ b/mock/ext-api-data/eth-rpc__eth_call_data_0xf1cb7e06ee6c4522aab0003e8d14cd40a6af439055fd2577951148c14b6cea9a53475835000000000000000000000000000000000000000000000000000000000000003c.json @@ -0,0 +1 @@ +{"jsonrpc":"2.0","id":328,"result":"0x00000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000014d8da6bf26964af9d7eed9e03e53415d37aa96045000000000000000000000000"} diff --git a/mock/ext-api-data/eth-rpc__eth_call_data_0xf1cb7e06ee6c4522aab0003e8d14cd40a6af439055fd2577951148c14b6cea9a53475835000000000000000000000000000000000000000000000000000000000000003c.request_json b/mock/ext-api-data/eth-rpc__eth_call_data_0xf1cb7e06ee6c4522aab0003e8d14cd40a6af439055fd2577951148c14b6cea9a53475835000000000000000000000000000000000000000000000000000000000000003c.request_json new file mode 100644 index 000000000..456e91dcb --- /dev/null +++ b/mock/ext-api-data/eth-rpc__eth_call_data_0xf1cb7e06ee6c4522aab0003e8d14cd40a6af439055fd2577951148c14b6cea9a53475835000000000000000000000000000000000000000000000000000000000000003c.request_json @@ -0,0 +1 @@ +{"jsonrpc":"2.0","method":"eth_call","params":[{"data":"0xf1cb7e06ee6c4522aab0003e8d14cd40a6af439055fd2577951148c14b6cea9a53475835000000000000000000000000000000000000000000000000000000000000003c","to":"0x226159d592e2b063810a10ebf6dcbada94ed68b8"},"latest"],"id":328} diff --git a/mock/ext-api-data/ethclassic-api_tokens__address_0xa12105efa0663147bddee178f6a741ac15676b79.json b/mock/ext-api-data/ethclassic-api_tokens__address_0xa12105efa0663147bddee178f6a741ac15676b79.json new file mode 100644 index 000000000..b815fdb14 --- /dev/null +++ b/mock/ext-api-data/ethclassic-api_tokens__address_0xa12105efa0663147bddee178f6a741ac15676b79.json @@ -0,0 +1 @@ +{"total":2,"docs":[{"address":"0xCA68fE57A0E9987F940Ebcc65fe5F96E7bC30128","name":"Litecoin Classic Token","decimals":8,"symbol":"LCT"},{"address":"0x2B682bd9d5c31E67a95cbdF0292017C02E51923C","name":"Ether Klown","decimals":6,"symbol":"KLOWN2"}]} \ No newline at end of file diff --git a/mock/ext-api-data/ethclassic-api_transactions__address_0x7d2d0e153026fb428b885d86de50768d4cfeac37.json b/mock/ext-api-data/ethclassic-api_transactions__address_0x7d2d0e153026fb428b885d86de50768d4cfeac37.json new file mode 100644 index 000000000..096e71054 --- /dev/null +++ b/mock/ext-api-data/ethclassic-api_transactions__address_0x7d2d0e153026fb428b885d86de50768d4cfeac37.json @@ -0,0 +1 @@ +{"docs":[{"operations":[],"contract":null,"_id":"0x8439b360732a43b4bbebe4f00b9f8b2dbe14c6bd52d70598ab7fe6c8503383fe","blockNumber":9833329,"time":1582237362,"nonce":7071,"from":"0x2d4BeCA01fDE8963b3A2DBf8a838e0F2EBaB0FF9","to":"0x7D2D0E153026fB428B885D86De50768D4cFeaC37","value":"18529160000000000","gas":"21000","gasPrice":"1000000000","gasUsed":"21000","input":"0x","error":"","id":"0x8439b360732a43b4bbebe4f00b9f8b2dbe14c6bd52d70598ab7fe6c8503383fe","timeStamp":"1582237362"},{"operations":[],"contract":null,"_id":"0x524fb5fedace7bee35c165ac7f641d689122cb21390db7f7384507473a5ba058","blockNumber":9804290,"time":1581854371,"nonce":6918,"from":"0x2d4BeCA01fDE8963b3A2DBf8a838e0F2EBaB0FF9","to":"0x7D2D0E153026fB428B885D86De50768D4cFeaC37","value":"16208400000000000","gas":"21000","gasPrice":"1000000000","gasUsed":"21000","input":"0x","error":"","id":"0x524fb5fedace7bee35c165ac7f641d689122cb21390db7f7384507473a5ba058","timeStamp":"1581854371"},{"operations":[],"contract":null,"_id":"0xdafbb42223d0896d594b0d71e609bdb0ca88e9366dacb5b75936ea0314f24644","blockNumber":9800797,"time":1581807897,"nonce":6906,"from":"0x2d4BeCA01fDE8963b3A2DBf8a838e0F2EBaB0FF9","to":"0x7D2D0E153026fB428B885D86De50768D4cFeaC37","value":"15707220000000000","gas":"21000","gasPrice":"8750000000","gasUsed":"21000","input":"0x","error":"","id":"0xdafbb42223d0896d594b0d71e609bdb0ca88e9366dacb5b75936ea0314f24644","timeStamp":"1581807897"},{"operations":[],"contract":null,"_id":"0x7eae8a772f4cd047cb2fb6e51a97e6ec7330841893356faef9f1d27fc6863a13","blockNumber":9767819,"time":1581371768,"nonce":6760,"from":"0x2d4BeCA01fDE8963b3A2DBf8a838e0F2EBaB0FF9","to":"0x7D2D0E153026fB428B885D86De50768D4cFeaC37","value":"12382380000000000","gas":"21000","gasPrice":"1000000000","gasUsed":"21000","input":"0x","error":"","id":"0x7eae8a772f4cd047cb2fb6e51a97e6ec7330841893356faef9f1d27fc6863a13","timeStamp":"1581371768"},{"operations":[],"contract":null,"_id":"0x793030d8fefd7c8eab29b69f273c01be8a3f48dc7a729d492f0a534209a9f56f","blockNumber":9759207,"time":1581259513,"nonce":6725,"from":"0x2d4BeCA01fDE8963b3A2DBf8a838e0F2EBaB0FF9","to":"0x7D2D0E153026fB428B885D86De50768D4cFeaC37","value":"12243450000000000","gas":"21000","gasPrice":"1250000000","gasUsed":"21000","input":"0x","error":"","id":"0x793030d8fefd7c8eab29b69f273c01be8a3f48dc7a729d492f0a534209a9f56f","timeStamp":"1581259513"},{"operations":[],"contract":null,"_id":"0x4cd49c1cb015e1b2dbbe84b24028c03df4fd5267590ef8caa8771d84bbab6237","blockNumber":9753262,"time":1581181423,"nonce":6694,"from":"0x2d4BeCA01fDE8963b3A2DBf8a838e0F2EBaB0FF9","to":"0x7D2D0E153026fB428B885D86De50768D4cFeaC37","value":"12051340000000000","gas":"21000","gasPrice":"1000000000","gasUsed":"21000","input":"0x","error":"","id":"0x4cd49c1cb015e1b2dbbe84b24028c03df4fd5267590ef8caa8771d84bbab6237","timeStamp":"1581181423"}],"total":6} \ No newline at end of file diff --git a/mock/ext-api-data/fio-api_v1_chain_get_pub_address.0001.json b/mock/ext-api-data/fio-api_v1_chain_get_pub_address.0001.json new file mode 100644 index 000000000..8e3369b1e --- /dev/null +++ b/mock/ext-api-data/fio-api_v1_chain_get_pub_address.0001.json @@ -0,0 +1 @@ +{"public_address":"0xce5cB6c92Da37bbBa91Bd40D4C9D4D724A3a0001"} \ No newline at end of file diff --git a/mock/ext-api-data/fio-api_v1_chain_get_pub_address.0001.request_json b/mock/ext-api-data/fio-api_v1_chain_get_pub_address.0001.request_json new file mode 100644 index 000000000..9d14efd43 --- /dev/null +++ b/mock/ext-api-data/fio-api_v1_chain_get_pub_address.0001.request_json @@ -0,0 +1,5 @@ +{ + fio_address: 'trust@trustwallet', + token_code: 'ETH', + chain_code: 'ETH' +} diff --git a/mock/ext-api-data/fio-api_v1_chain_get_pub_address.0002.json b/mock/ext-api-data/fio-api_v1_chain_get_pub_address.0002.json new file mode 100644 index 000000000..cfe58ca56 --- /dev/null +++ b/mock/ext-api-data/fio-api_v1_chain_get_pub_address.0002.json @@ -0,0 +1 @@ +{"public_address":"0xce5cB6c92Da37bbBa91Bd40D4C9D4D724A3a0002"} \ No newline at end of file diff --git a/mock/ext-api-data/fio-api_v1_chain_get_pub_address.0002.request_json b/mock/ext-api-data/fio-api_v1_chain_get_pub_address.0002.request_json new file mode 100644 index 000000000..bed84d8a8 --- /dev/null +++ b/mock/ext-api-data/fio-api_v1_chain_get_pub_address.0002.request_json @@ -0,0 +1,5 @@ +{ + fio_address: 'name@somefiodomain', + token_code: 'ETH', + chain_code: 'ETH' +} diff --git a/mock/ext-api-data/fio-api_v1_chain_get_pub_address.json b/mock/ext-api-data/fio-api_v1_chain_get_pub_address.json new file mode 100644 index 000000000..337fd29a2 --- /dev/null +++ b/mock/ext-api-data/fio-api_v1_chain_get_pub_address.json @@ -0,0 +1 @@ +{"public_address":"0xce5cB6c92Da37bbBa91Bd40D4C9D4D724A3a8F51"} \ No newline at end of file diff --git a/mock/ext-api-data/fio-api_v1_chain_get_pub_address.request_json b/mock/ext-api-data/fio-api_v1_chain_get_pub_address.request_json new file mode 100644 index 000000000..519b92947 --- /dev/null +++ b/mock/ext-api-data/fio-api_v1_chain_get_pub_address.request_json @@ -0,0 +1 @@ +{fio_address: "trust@trust", token_code: "ETH", chain_code: "ETH"} diff --git a/mock/ext-api-data/fio-api_v1_history_get_actions.0001.json b/mock/ext-api-data/fio-api_v1_history_get_actions.0001.json new file mode 100644 index 000000000..e27154ff8 --- /dev/null +++ b/mock/ext-api-data/fio-api_v1_history_get_actions.0001.json @@ -0,0 +1,1100 @@ +{ + "actions": [ + { + "global_action_seq": 8085061, + "account_action_seq": 180, + "block_num": 7865147, + "block_time": "2020-05-09T13:01:02.500", + "action_trace": { + "receipt": { + "receiver": "fio.treasury", + "response": "{\"status\": \"OK\",\"amount\":0}", + "act_digest": "cd645ad840c51edccb89bf75e1e035f88c4b7a8d2a608bfb262176185b61fc85", + "global_sequence": 8085061, + "recv_sequence": 75973, + "auth_sequence": [ + [ + "gmdncuvoqxfn", + 132 + ] + ], + "code_sequence": 2, + "abi_sequence": 1 + }, + "receiver": "fio.treasury", + "act": { + "account": "fio.treasury", + "name": "bpclaim", + "authorization": [ + { + "actor": "gmdncuvoqxfn", + "permission": "fioclaim" + } + ], + "data": { + "fio_address": "maltablockbp@maltablock", + "actor": "gmdncuvoqxfn" + }, + "hex_data": "176d616c7461626c6f636b6270406d616c7461626c6f636b3057b7746b349364" + }, + "context_free": false, + "elapsed": 3210, + "console": "", + "trx_id": "4224701156c93156bd287df4a2ff61484e00ce7bb1cb65c815e96ef725b4759a", + "block_num": 7865147, + "block_time": "2020-05-09T13:01:02.500", + "producer_block_id": "0078033b7e5ce84f17ac23d33981386f218a4186626108a70a4e712b2f37ea3e", + "account_ram_deltas": [], + "except": null, + "error_code": null, + "action_ordinal": 1, + "creator_action_ordinal": 0, + "closest_unnotified_ancestor_action_ordinal": 0 + } + }, + { + "global_action_seq": 8143375, + "account_action_seq": 181, + "block_num": 7922745, + "block_time": "2020-05-09T21:01:01.500", + "action_trace": { + "receipt": { + "receiver": "fio.treasury", + "response": "{\"status\": \"OK\",\"amount\":208382292046}", + "act_digest": "cd645ad840c51edccb89bf75e1e035f88c4b7a8d2a608bfb262176185b61fc85", + "global_sequence": 8143375, + "recv_sequence": 76058, + "auth_sequence": [ + [ + "gmdncuvoqxfn", + 133 + ] + ], + "code_sequence": 2, + "abi_sequence": 1 + }, + "receiver": "fio.treasury", + "act": { + "account": "fio.treasury", + "name": "bpclaim", + "authorization": [ + { + "actor": "gmdncuvoqxfn", + "permission": "fioclaim" + } + ], + "data": { + "fio_address": "maltablockbp@maltablock", + "actor": "gmdncuvoqxfn" + }, + "hex_data": "176d616c7461626c6f636b6270406d616c7461626c6f636b3057b7746b349364" + }, + "context_free": false, + "elapsed": 3832, + "console": "", + "trx_id": "4139ca4a56cef1ea04a751d7b4ce37c195793a1b1b05fa6017db55feb52c3204", + "block_num": 7922745, + "block_time": "2020-05-09T21:01:01.500", + "producer_block_id": "0078e439ac0f97d125d850ab6dfa190c15778ef4b1067e3adf5fbbc47e4baac6", + "account_ram_deltas": [ + { + "account": "fio.treasury", + "delta": -144 + }, + { + "account": "p5fi5ywnitjc", + "delta": -128 + } + ], + "except": null, + "error_code": null, + "action_ordinal": 1, + "creator_action_ordinal": 0, + "closest_unnotified_ancestor_action_ordinal": 0 + } + }, + { + "global_action_seq": 8143379, + "account_action_seq": 182, + "block_num": 7922745, + "block_time": "2020-05-09T21:01:01.500", + "action_trace": { + "receipt": { + "receiver": "gmdncuvoqxfn", + "response": "", + "act_digest": "57cf1dae328832d3ccb2defa00c1f2bfcd494de88d9bed51443e1083d256f450", + "global_sequence": 8143379, + "recv_sequence": 47, + "auth_sequence": [ + [ + "fio.treasury", + 6266 + ] + ], + "code_sequence": 1, + "abi_sequence": 1 + }, + "receiver": "gmdncuvoqxfn", + "act": { + "account": "fio.token", + "name": "transfer", + "authorization": [ + { + "actor": "fio.treasury", + "permission": "active" + } + ], + "data": { + "from": "fio.treasury", + "to": "gmdncuvoqxfn", + "quantity": "208.382292046 FIO", + "memo": "Paying producer from treasury." + }, + "hex_data": "e0afc646dd0ca85b3057b7746b3493644e708d84300000000946494f000000001e506179696e672070726f64756365722066726f6d2074726561737572792e" + }, + "context_free": false, + "elapsed": 11, + "console": "", + "trx_id": "4139ca4a56cef1ea04a751d7b4ce37c195793a1b1b05fa6017db55feb52c3204", + "block_num": 7922745, + "block_time": "2020-05-09T21:01:01.500", + "producer_block_id": "0078e439ac0f97d125d850ab6dfa190c15778ef4b1067e3adf5fbbc47e4baac6", + "account_ram_deltas": [], + "except": null, + "error_code": null, + "action_ordinal": 6, + "creator_action_ordinal": 3, + "closest_unnotified_ancestor_action_ordinal": 3 + } + }, + { + "global_action_seq": 8201636, + "account_action_seq": 183, + "block_num": 7980333, + "block_time": "2020-05-10T05:01:01.500", + "action_trace": { + "receipt": { + "receiver": "fio.treasury", + "response": "{\"status\": \"OK\",\"amount\":0}", + "act_digest": "cd645ad840c51edccb89bf75e1e035f88c4b7a8d2a608bfb262176185b61fc85", + "global_sequence": 8201636, + "recv_sequence": 76107, + "auth_sequence": [ + [ + "gmdncuvoqxfn", + 134 + ] + ], + "code_sequence": 2, + "abi_sequence": 1 + }, + "receiver": "fio.treasury", + "act": { + "account": "fio.treasury", + "name": "bpclaim", + "authorization": [ + { + "actor": "gmdncuvoqxfn", + "permission": "fioclaim" + } + ], + "data": { + "fio_address": "maltablockbp@maltablock", + "actor": "gmdncuvoqxfn" + }, + "hex_data": "176d616c7461626c6f636b6270406d616c7461626c6f636b3057b7746b349364" + }, + "context_free": false, + "elapsed": 3244, + "console": "", + "trx_id": "7f19f1cb309e871899777c7ff9c17a6874b4cbf33c74983a93e88711c975dff8", + "block_num": 7980333, + "block_time": "2020-05-10T05:01:01.500", + "producer_block_id": "0079c52dd5cf8c7376bdc775fc1200e9f9e1c91607df66179eca3784cb7d48c3", + "account_ram_deltas": [], + "except": null, + "error_code": null, + "action_ordinal": 1, + "creator_action_ordinal": 0, + "closest_unnotified_ancestor_action_ordinal": 0 + } + }, + { + "global_action_seq": 8259758, + "account_action_seq": 184, + "block_num": 8037933, + "block_time": "2020-05-10T13:01:01.500", + "action_trace": { + "receipt": { + "receiver": "fio.treasury", + "response": "{\"status\": \"OK\",\"amount\":0}", + "act_digest": "cd645ad840c51edccb89bf75e1e035f88c4b7a8d2a608bfb262176185b61fc85", + "global_sequence": 8259758, + "recv_sequence": 76131, + "auth_sequence": [ + [ + "gmdncuvoqxfn", + 135 + ] + ], + "code_sequence": 2, + "abi_sequence": 1 + }, + "receiver": "fio.treasury", + "act": { + "account": "fio.treasury", + "name": "bpclaim", + "authorization": [ + { + "actor": "gmdncuvoqxfn", + "permission": "fioclaim" + } + ], + "data": { + "fio_address": "maltablockbp@maltablock", + "actor": "gmdncuvoqxfn" + }, + "hex_data": "176d616c7461626c6f636b6270406d616c7461626c6f636b3057b7746b349364" + }, + "context_free": false, + "elapsed": 3120, + "console": "", + "trx_id": "bd0e433db980b3c89942e1bcf136375cddf14feb3b407a3eca7510415d2f22c4", + "block_num": 8037933, + "block_time": "2020-05-10T13:01:01.500", + "producer_block_id": "007aa62dd1433e0f3e095b3e5a247a0a54472a8502c7365cf5b0371456e50a6d", + "account_ram_deltas": [], + "except": null, + "error_code": null, + "action_ordinal": 1, + "creator_action_ordinal": 0, + "closest_unnotified_ancestor_action_ordinal": 0 + } + }, + { + "global_action_seq": 8318046, + "account_action_seq": 185, + "block_num": 8095533, + "block_time": "2020-05-10T21:01:01.500", + "action_trace": { + "receipt": { + "receiver": "fio.treasury", + "response": "{\"status\": \"OK\",\"amount\":208379396046}", + "act_digest": "cd645ad840c51edccb89bf75e1e035f88c4b7a8d2a608bfb262176185b61fc85", + "global_sequence": 8318046, + "recv_sequence": 76198, + "auth_sequence": [ + [ + "gmdncuvoqxfn", + 136 + ] + ], + "code_sequence": 2, + "abi_sequence": 1 + }, + "receiver": "fio.treasury", + "act": { + "account": "fio.treasury", + "name": "bpclaim", + "authorization": [ + { + "actor": "gmdncuvoqxfn", + "permission": "fioclaim" + } + ], + "data": { + "fio_address": "maltablockbp@maltablock", + "actor": "gmdncuvoqxfn" + }, + "hex_data": "176d616c7461626c6f636b6270406d616c7461626c6f636b3057b7746b349364" + }, + "context_free": false, + "elapsed": 3783, + "console": "", + "trx_id": "783a4ce87c415501967685985a0e9315dd36f415261faa08e76f06cc37bb547c", + "block_num": 8095533, + "block_time": "2020-05-10T21:01:01.500", + "producer_block_id": "007b872de3c104dafd36fb5cd565113c4d61a3ec0b72b357486787e270b2cfb3", + "account_ram_deltas": [ + { + "account": "akfxqn52fx3a", + "delta": -128 + }, + { + "account": "fio.treasury", + "delta": -144 + } + ], + "except": null, + "error_code": null, + "action_ordinal": 1, + "creator_action_ordinal": 0, + "closest_unnotified_ancestor_action_ordinal": 0 + } + }, + { + "global_action_seq": 8318050, + "account_action_seq": 186, + "block_num": 8095533, + "block_time": "2020-05-10T21:01:01.500", + "action_trace": { + "receipt": { + "receiver": "gmdncuvoqxfn", + "response": "", + "act_digest": "1b7603066e70507a0962daa66c534a5a80a370e91fa839687f3e0bac002b3d2f", + "global_sequence": 8318050, + "recv_sequence": 48, + "auth_sequence": [ + [ + "fio.treasury", + 6460 + ] + ], + "code_sequence": 1, + "abi_sequence": 1 + }, + "receiver": "gmdncuvoqxfn", + "act": { + "account": "fio.token", + "name": "transfer", + "authorization": [ + { + "actor": "fio.treasury", + "permission": "active" + } + ], + "data": { + "from": "fio.treasury", + "to": "gmdncuvoqxfn", + "quantity": "208.379396046 FIO", + "memo": "Paying producer from treasury." + }, + "hex_data": "e0afc646dd0ca85b3057b7746b349364ce3f6184300000000946494f000000001e506179696e672070726f64756365722066726f6d2074726561737572792e" + }, + "context_free": false, + "elapsed": 7, + "console": "", + "trx_id": "783a4ce87c415501967685985a0e9315dd36f415261faa08e76f06cc37bb547c", + "block_num": 8095533, + "block_time": "2020-05-10T21:01:01.500", + "producer_block_id": "007b872de3c104dafd36fb5cd565113c4d61a3ec0b72b357486787e270b2cfb3", + "account_ram_deltas": [], + "except": null, + "error_code": null, + "action_ordinal": 6, + "creator_action_ordinal": 3, + "closest_unnotified_ancestor_action_ordinal": 3 + } + }, + { + "global_action_seq": 8376209, + "account_action_seq": 187, + "block_num": 8153133, + "block_time": "2020-05-11T05:01:02.000", + "action_trace": { + "receipt": { + "receiver": "fio.treasury", + "response": "{\"status\": \"OK\",\"amount\":0}", + "act_digest": "cd645ad840c51edccb89bf75e1e035f88c4b7a8d2a608bfb262176185b61fc85", + "global_sequence": 8376209, + "recv_sequence": 76232, + "auth_sequence": [ + [ + "gmdncuvoqxfn", + 137 + ] + ], + "code_sequence": 2, + "abi_sequence": 1 + }, + "receiver": "fio.treasury", + "act": { + "account": "fio.treasury", + "name": "bpclaim", + "authorization": [ + { + "actor": "gmdncuvoqxfn", + "permission": "fioclaim" + } + ], + "data": { + "fio_address": "maltablockbp@maltablock", + "actor": "gmdncuvoqxfn" + }, + "hex_data": "176d616c7461626c6f636b6270406d616c7461626c6f636b3057b7746b349364" + }, + "context_free": false, + "elapsed": 1915, + "console": "", + "trx_id": "006b36840fcaabe6acca50c4f03e343b8eb6692e2e4a41609213f8d5845d4be9", + "block_num": 8153133, + "block_time": "2020-05-11T05:01:02.000", + "producer_block_id": "007c682d1169d963428ba9ac05f99230b4618251d8c200d158df7af219b8e419", + "account_ram_deltas": [], + "except": null, + "error_code": null, + "action_ordinal": 1, + "creator_action_ordinal": 0, + "closest_unnotified_ancestor_action_ordinal": 0 + } + }, + { + "global_action_seq": 8434344, + "account_action_seq": 188, + "block_num": 8210732, + "block_time": "2020-05-11T13:01:01.500", + "action_trace": { + "receipt": { + "receiver": "fio.treasury", + "response": "{\"status\": \"OK\",\"amount\":0}", + "act_digest": "cd645ad840c51edccb89bf75e1e035f88c4b7a8d2a608bfb262176185b61fc85", + "global_sequence": 8434344, + "recv_sequence": 76259, + "auth_sequence": [ + [ + "gmdncuvoqxfn", + 138 + ] + ], + "code_sequence": 2, + "abi_sequence": 1 + }, + "receiver": "fio.treasury", + "act": { + "account": "fio.treasury", + "name": "bpclaim", + "authorization": [ + { + "actor": "gmdncuvoqxfn", + "permission": "fioclaim" + } + ], + "data": { + "fio_address": "maltablockbp@maltablock", + "actor": "gmdncuvoqxfn" + }, + "hex_data": "176d616c7461626c6f636b6270406d616c7461626c6f636b3057b7746b349364" + }, + "context_free": false, + "elapsed": 2863, + "console": "", + "trx_id": "159867ae812d839bd273f5147fc08e1eec2d74cfc2f9643d2be95c9c39909cc2", + "block_num": 8210732, + "block_time": "2020-05-11T13:01:01.500", + "producer_block_id": "007d492c5e2c34cfce5c12a6d5d10c4a71a185f1119bd130a12b23786f2f4fb2", + "account_ram_deltas": [], + "except": null, + "error_code": null, + "action_ordinal": 1, + "creator_action_ordinal": 0, + "closest_unnotified_ancestor_action_ordinal": 0 + } + }, + { + "global_action_seq": 8492674, + "account_action_seq": 189, + "block_num": 8268320, + "block_time": "2020-05-11T21:01:01.500", + "action_trace": { + "receipt": { + "receiver": "fio.treasury", + "response": "{\"status\": \"OK\",\"amount\":208378161259}", + "act_digest": "cd645ad840c51edccb89bf75e1e035f88c4b7a8d2a608bfb262176185b61fc85", + "global_sequence": 8492674, + "recv_sequence": 76327, + "auth_sequence": [ + [ + "gmdncuvoqxfn", + 139 + ] + ], + "code_sequence": 2, + "abi_sequence": 1 + }, + "receiver": "fio.treasury", + "act": { + "account": "fio.treasury", + "name": "bpclaim", + "authorization": [ + { + "actor": "gmdncuvoqxfn", + "permission": "fioclaim" + } + ], + "data": { + "fio_address": "maltablockbp@maltablock", + "actor": "gmdncuvoqxfn" + }, + "hex_data": "176d616c7461626c6f636b6270406d616c7461626c6f636b3057b7746b349364" + }, + "context_free": false, + "elapsed": 2561, + "console": "", + "trx_id": "cbee2abb5a39c0f4218b60375935c35cb85f7210a6b39327439a134f10f9194e", + "block_num": 8268320, + "block_time": "2020-05-11T21:01:01.500", + "producer_block_id": "007e2a201791b43ea14f07c76aade167046a432476ea8dbe940f0f266e51da01", + "account_ram_deltas": [ + { + "account": "akfxqn52fx3a", + "delta": -128 + }, + { + "account": "fio.treasury", + "delta": -144 + } + ], + "except": null, + "error_code": null, + "action_ordinal": 1, + "creator_action_ordinal": 0, + "closest_unnotified_ancestor_action_ordinal": 0 + } + }, + { + "global_action_seq": 8492678, + "account_action_seq": 190, + "block_num": 8268320, + "block_time": "2020-05-11T21:01:01.500", + "action_trace": { + "receipt": { + "receiver": "gmdncuvoqxfn", + "response": "", + "act_digest": "5c551fda3bffb5289db2114907c8c520519ef3fd2d5149827fcf35e7ab4452a5", + "global_sequence": 8492678, + "recv_sequence": 49, + "auth_sequence": [ + [ + "fio.treasury", + 6648 + ] + ], + "code_sequence": 1, + "abi_sequence": 1 + }, + "receiver": "gmdncuvoqxfn", + "act": { + "account": "fio.token", + "name": "transfer", + "authorization": [ + { + "actor": "fio.treasury", + "permission": "active" + } + ], + "data": { + "from": "fio.treasury", + "to": "gmdncuvoqxfn", + "quantity": "208.378161259 FIO", + "memo": "Paying producer from treasury." + }, + "hex_data": "e0afc646dd0ca85b3057b7746b3493646b684e84300000000946494f000000001e506179696e672070726f64756365722066726f6d2074726561737572792e" + }, + "context_free": false, + "elapsed": 6, + "console": "", + "trx_id": "cbee2abb5a39c0f4218b60375935c35cb85f7210a6b39327439a134f10f9194e", + "block_num": 8268320, + "block_time": "2020-05-11T21:01:01.500", + "producer_block_id": "007e2a201791b43ea14f07c76aade167046a432476ea8dbe940f0f266e51da01", + "account_ram_deltas": [], + "except": null, + "error_code": null, + "action_ordinal": 6, + "creator_action_ordinal": 3, + "closest_unnotified_ancestor_action_ordinal": 3 + } + }, + { + "global_action_seq": 8550775, + "account_action_seq": 191, + "block_num": 8325920, + "block_time": "2020-05-12T05:01:01.500", + "action_trace": { + "receipt": { + "receiver": "fio.treasury", + "response": "{\"status\": \"OK\",\"amount\":0}", + "act_digest": "cd645ad840c51edccb89bf75e1e035f88c4b7a8d2a608bfb262176185b61fc85", + "global_sequence": 8550775, + "recv_sequence": 76347, + "auth_sequence": [ + [ + "gmdncuvoqxfn", + 140 + ] + ], + "code_sequence": 2, + "abi_sequence": 1 + }, + "receiver": "fio.treasury", + "act": { + "account": "fio.treasury", + "name": "bpclaim", + "authorization": [ + { + "actor": "gmdncuvoqxfn", + "permission": "fioclaim" + } + ], + "data": { + "fio_address": "maltablockbp@maltablock", + "actor": "gmdncuvoqxfn" + }, + "hex_data": "176d616c7461626c6f636b6270406d616c7461626c6f636b3057b7746b349364" + }, + "context_free": false, + "elapsed": 1596, + "console": "", + "trx_id": "18e740da12cdbce1287d18a2678f4a8e63ace3f9743e7f33e11fc629c684ca63", + "block_num": 8325920, + "block_time": "2020-05-12T05:01:01.500", + "producer_block_id": "007f0b20a791a1fb42f07038ddbc4c25f80bef7d6e393932e04d5be1678d3192", + "account_ram_deltas": [], + "except": null, + "error_code": null, + "action_ordinal": 1, + "creator_action_ordinal": 0, + "closest_unnotified_ancestor_action_ordinal": 0 + } + }, + { + "global_action_seq": 8608936, + "account_action_seq": 192, + "block_num": 8383519, + "block_time": "2020-05-12T13:01:02.000", + "action_trace": { + "receipt": { + "receiver": "fio.treasury", + "response": "{\"status\": \"OK\",\"amount\":0}", + "act_digest": "cd645ad840c51edccb89bf75e1e035f88c4b7a8d2a608bfb262176185b61fc85", + "global_sequence": 8608936, + "recv_sequence": 76380, + "auth_sequence": [ + [ + "gmdncuvoqxfn", + 141 + ] + ], + "code_sequence": 2, + "abi_sequence": 1 + }, + "receiver": "fio.treasury", + "act": { + "account": "fio.treasury", + "name": "bpclaim", + "authorization": [ + { + "actor": "gmdncuvoqxfn", + "permission": "fioclaim" + } + ], + "data": { + "fio_address": "maltablockbp@maltablock", + "actor": "gmdncuvoqxfn" + }, + "hex_data": "176d616c7461626c6f636b6270406d616c7461626c6f636b3057b7746b349364" + }, + "context_free": false, + "elapsed": 2402, + "console": "", + "trx_id": "badf5275adb7c766418b2f5676298a22c2dbef20f35f13d980a7316a205325b2", + "block_num": 8383519, + "block_time": "2020-05-12T13:01:02.000", + "producer_block_id": "007fec1f5ecac875ef78e4034a3684b42edcfe18f774b39ca0478fd995d4a09d", + "account_ram_deltas": [], + "except": null, + "error_code": null, + "action_ordinal": 1, + "creator_action_ordinal": 0, + "closest_unnotified_ancestor_action_ordinal": 0 + } + }, + { + "global_action_seq": 8667271, + "account_action_seq": 193, + "block_num": 8441119, + "block_time": "2020-05-12T21:01:02.000", + "action_trace": { + "receipt": { + "receiver": "fio.treasury", + "response": "{\"status\": \"OK\",\"amount\":209426142191}", + "act_digest": "cd645ad840c51edccb89bf75e1e035f88c4b7a8d2a608bfb262176185b61fc85", + "global_sequence": 8667271, + "recv_sequence": 76454, + "auth_sequence": [ + [ + "gmdncuvoqxfn", + 142 + ] + ], + "code_sequence": 2, + "abi_sequence": 1 + }, + "receiver": "fio.treasury", + "act": { + "account": "fio.treasury", + "name": "bpclaim", + "authorization": [ + { + "actor": "gmdncuvoqxfn", + "permission": "fioclaim" + } + ], + "data": { + "fio_address": "maltablockbp@maltablock", + "actor": "gmdncuvoqxfn" + }, + "hex_data": "176d616c7461626c6f636b6270406d616c7461626c6f636b3057b7746b349364" + }, + "context_free": false, + "elapsed": 3145, + "console": "", + "trx_id": "a160133574bd5775dec7fe60ce42542b9a4fdf58fb69525af7ed15a12c23661a", + "block_num": 8441119, + "block_time": "2020-05-12T21:01:02.000", + "producer_block_id": "0080cd1f4b1c6b2a607e5574131b1c94f63f935b6fe73f0a597cc9fb9fdbb3c2", + "account_ram_deltas": [ + { + "account": "fio.treasury", + "delta": -144 + }, + { + "account": "wrcjejslfplp", + "delta": -128 + } + ], + "except": null, + "error_code": null, + "action_ordinal": 1, + "creator_action_ordinal": 0, + "closest_unnotified_ancestor_action_ordinal": 0 + } + }, + { + "global_action_seq": 8667275, + "account_action_seq": 194, + "block_num": 8441119, + "block_time": "2020-05-12T21:01:02.000", + "action_trace": { + "receipt": { + "receiver": "gmdncuvoqxfn", + "response": "", + "act_digest": "082f7056a955ced42388f8d2b9148d90dd73e6696d8cb56102abc69aae902d5e", + "global_sequence": 8667275, + "recv_sequence": 50, + "auth_sequence": [ + [ + "fio.treasury", + 6826 + ] + ], + "code_sequence": 1, + "abi_sequence": 1 + }, + "receiver": "gmdncuvoqxfn", + "act": { + "account": "fio.token", + "name": "transfer", + "authorization": [ + { + "actor": "fio.treasury", + "permission": "active" + } + ], + "data": { + "from": "fio.treasury", + "to": "gmdncuvoqxfn", + "quantity": "209.426142191 FIO", + "memo": "Paying producer from treasury." + }, + "hex_data": "e0afc646dd0ca85b3057b7746b349364ef53c5c2300000000946494f000000001e506179696e672070726f64756365722066726f6d2074726561737572792e" + }, + "context_free": false, + "elapsed": 6, + "console": "", + "trx_id": "a160133574bd5775dec7fe60ce42542b9a4fdf58fb69525af7ed15a12c23661a", + "block_num": 8441119, + "block_time": "2020-05-12T21:01:02.000", + "producer_block_id": "0080cd1f4b1c6b2a607e5574131b1c94f63f935b6fe73f0a597cc9fb9fdbb3c2", + "account_ram_deltas": [], + "except": null, + "error_code": null, + "action_ordinal": 6, + "creator_action_ordinal": 3, + "closest_unnotified_ancestor_action_ordinal": 3 + } + }, + { + "global_action_seq": 8725478, + "account_action_seq": 195, + "block_num": 8498718, + "block_time": "2020-05-13T05:01:01.500", + "action_trace": { + "receipt": { + "receiver": "fio.treasury", + "response": "{\"status\": \"OK\",\"amount\":0}", + "act_digest": "cd645ad840c51edccb89bf75e1e035f88c4b7a8d2a608bfb262176185b61fc85", + "global_sequence": 8725478, + "recv_sequence": 76496, + "auth_sequence": [ + [ + "gmdncuvoqxfn", + 143 + ] + ], + "code_sequence": 2, + "abi_sequence": 1 + }, + "receiver": "fio.treasury", + "act": { + "account": "fio.treasury", + "name": "bpclaim", + "authorization": [ + { + "actor": "gmdncuvoqxfn", + "permission": "fioclaim" + } + ], + "data": { + "fio_address": "maltablockbp@maltablock", + "actor": "gmdncuvoqxfn" + }, + "hex_data": "176d616c7461626c6f636b6270406d616c7461626c6f636b3057b7746b349364" + }, + "context_free": false, + "elapsed": 1511, + "console": "", + "trx_id": "d81ea2da0f4733805bed6af8f3229d94056f6b341d75f89ce9d2c29f62a8b139", + "block_num": 8498718, + "block_time": "2020-05-13T05:01:01.500", + "producer_block_id": "0081ae1e2015b6fd525449a794cb24724afd0eec80a2fb90f312307ec76773ee", + "account_ram_deltas": [], + "except": null, + "error_code": null, + "action_ordinal": 1, + "creator_action_ordinal": 0, + "closest_unnotified_ancestor_action_ordinal": 0 + } + }, + { + "global_action_seq": 8783826, + "account_action_seq": 196, + "block_num": 8556319, + "block_time": "2020-05-13T13:01:02.000", + "action_trace": { + "receipt": { + "receiver": "fio.treasury", + "response": "{\"status\": \"OK\",\"amount\":0}", + "act_digest": "cd645ad840c51edccb89bf75e1e035f88c4b7a8d2a608bfb262176185b61fc85", + "global_sequence": 8783826, + "recv_sequence": 76581, + "auth_sequence": [ + [ + "gmdncuvoqxfn", + 144 + ] + ], + "code_sequence": 2, + "abi_sequence": 1 + }, + "receiver": "fio.treasury", + "act": { + "account": "fio.treasury", + "name": "bpclaim", + "authorization": [ + { + "actor": "gmdncuvoqxfn", + "permission": "fioclaim" + } + ], + "data": { + "fio_address": "maltablockbp@maltablock", + "actor": "gmdncuvoqxfn" + }, + "hex_data": "176d616c7461626c6f636b6270406d616c7461626c6f636b3057b7746b349364" + }, + "context_free": false, + "elapsed": 3262, + "console": "", + "trx_id": "7a3939b6e6e7a9a4e02b248a5652a406c3b039651eb3ae7af97360fc0ccb4207", + "block_num": 8556319, + "block_time": "2020-05-13T13:01:02.000", + "producer_block_id": "00828f1f9d548ecad56f7a4d693da6cd5bdd941c70c91e028f0f3119a11daf32", + "account_ram_deltas": [], + "except": null, + "error_code": null, + "action_ordinal": 1, + "creator_action_ordinal": 0, + "closest_unnotified_ancestor_action_ordinal": 0 + } + }, + { + "global_action_seq": 8842416, + "account_action_seq": 197, + "block_num": 8613919, + "block_time": "2020-05-13T21:01:02.000", + "action_trace": { + "receipt": { + "receiver": "fio.treasury", + "response": "{\"status\": \"OK\",\"amount\":209423408688}", + "act_digest": "cd645ad840c51edccb89bf75e1e035f88c4b7a8d2a608bfb262176185b61fc85", + "global_sequence": 8842416, + "recv_sequence": 76714, + "auth_sequence": [ + [ + "gmdncuvoqxfn", + 145 + ] + ], + "code_sequence": 2, + "abi_sequence": 1 + }, + "receiver": "fio.treasury", + "act": { + "account": "fio.treasury", + "name": "bpclaim", + "authorization": [ + { + "actor": "gmdncuvoqxfn", + "permission": "fioclaim" + } + ], + "data": { + "fio_address": "maltablockbp@maltablock", + "actor": "gmdncuvoqxfn" + }, + "hex_data": "176d616c7461626c6f636b6270406d616c7461626c6f636b3057b7746b349364" + }, + "context_free": false, + "elapsed": 3535, + "console": "", + "trx_id": "4c846201239987c42d087a6acc0b702b553656a269f0f95e23a5499d3f7f21c0", + "block_num": 8613919, + "block_time": "2020-05-13T21:01:02.000", + "producer_block_id": "0083701f4a7339d51d9e295ebf6fa84d4b7b8fa5b69c55392328b641b8f6b652", + "account_ram_deltas": [ + { + "account": "akfxqn52fx3a", + "delta": -128 + }, + { + "account": "fio.treasury", + "delta": -144 + } + ], + "except": null, + "error_code": null, + "action_ordinal": 1, + "creator_action_ordinal": 0, + "closest_unnotified_ancestor_action_ordinal": 0 + } + }, + { + "global_action_seq": 8842420, + "account_action_seq": 198, + "block_num": 8613919, + "block_time": "2020-05-13T21:01:02.000", + "action_trace": { + "receipt": { + "receiver": "gmdncuvoqxfn", + "response": "", + "act_digest": "b3c0bd3b7c26fbab994d4b9a263d1a85e958546c201e0a89d6d43f4bb3f19fcb", + "global_sequence": 8842420, + "recv_sequence": 51, + "auth_sequence": [ + [ + "fio.treasury", + 7047 + ] + ], + "code_sequence": 1, + "abi_sequence": 1 + }, + "receiver": "gmdncuvoqxfn", + "act": { + "account": "fio.token", + "name": "transfer", + "authorization": [ + { + "actor": "fio.treasury", + "permission": "active" + } + ], + "data": { + "from": "fio.treasury", + "to": "gmdncuvoqxfn", + "quantity": "209.423408688 FIO", + "memo": "Paying producer from treasury." + }, + "hex_data": "e0afc646dd0ca85b3057b7746b349364309e9bc2300000000946494f000000001e506179696e672070726f64756365722066726f6d2074726561737572792e" + }, + "context_free": false, + "elapsed": 5, + "console": "", + "trx_id": "4c846201239987c42d087a6acc0b702b553656a269f0f95e23a5499d3f7f21c0", + "block_num": 8613919, + "block_time": "2020-05-13T21:01:02.000", + "producer_block_id": "0083701f4a7339d51d9e295ebf6fa84d4b7b8fa5b69c55392328b641b8f6b652", + "account_ram_deltas": [], + "except": null, + "error_code": null, + "action_ordinal": 6, + "creator_action_ordinal": 3, + "closest_unnotified_ancestor_action_ordinal": 3 + } + }, + { + "global_action_seq": 8900745, + "account_action_seq": 199, + "block_num": 8671519, + "block_time": "2020-05-14T05:01:02.000", + "action_trace": { + "receipt": { + "receiver": "fio.treasury", + "response": "{\"status\": \"OK\",\"amount\":0}", + "act_digest": "cd645ad840c51edccb89bf75e1e035f88c4b7a8d2a608bfb262176185b61fc85", + "global_sequence": 8900745, + "recv_sequence": 76795, + "auth_sequence": [ + [ + "gmdncuvoqxfn", + 146 + ] + ], + "code_sequence": 2, + "abi_sequence": 1 + }, + "receiver": "fio.treasury", + "act": { + "account": "fio.treasury", + "name": "bpclaim", + "authorization": [ + { + "actor": "gmdncuvoqxfn", + "permission": "fioclaim" + } + ], + "data": { + "fio_address": "maltablockbp@maltablock", + "actor": "gmdncuvoqxfn" + }, + "hex_data": "176d616c7461626c6f636b6270406d616c7461626c6f636b3057b7746b349364" + }, + "context_free": false, + "elapsed": 2845, + "console": "", + "trx_id": "afa96e24b429c5b22cc95c6f70452b059f589fe544f9ef4aed9bc58cbe829e97", + "block_num": 8671519, + "block_time": "2020-05-14T05:01:02.000", + "producer_block_id": "0084511f80b3c3529fc78b1813da0d9f2665ac5f563e6cc6cdb1dbe1b095dc1d", + "account_ram_deltas": [], + "except": null, + "error_code": null, + "action_ordinal": 1, + "creator_action_ordinal": 0, + "closest_unnotified_ancestor_action_ordinal": 0 + } + } + ], + "last_irreversible_block": 8724218 +} \ No newline at end of file diff --git a/mock/ext-api-data/fio-api_v1_history_get_actions.0001.request_json b/mock/ext-api-data/fio-api_v1_history_get_actions.0001.request_json new file mode 100644 index 000000000..3e7f4e4f7 --- /dev/null +++ b/mock/ext-api-data/fio-api_v1_history_get_actions.0001.request_json @@ -0,0 +1,3 @@ +{ + "account_name": "gmdncuvoqxfn" +} \ No newline at end of file diff --git a/mock/ext-api-data/fio-api_v1_history_get_actions.0002.json b/mock/ext-api-data/fio-api_v1_history_get_actions.0002.json new file mode 100644 index 000000000..9e9b5f825 --- /dev/null +++ b/mock/ext-api-data/fio-api_v1_history_get_actions.0002.json @@ -0,0 +1,1029 @@ +{ + "actions": [ + { + "global_action_seq": 8951703, + "account_action_seq": 82966, + "block_num": 8721919, + "block_time": "2020-05-14T12:01:02.000", + "action_trace": { + "receipt": { + "receiver": "fio.treasury", + "response": "{\"status\": \"OK\",\"amount\":0}", + "act_digest": "74ee42c53faf81069621ed0e2f04aaf6fa08a8955553368fa4a742b8f08839be", + "global_sequence": 8951703, + "recv_sequence": 76835, + "auth_sequence": [ + [ + "akfxqn52fx3a", + 144 + ] + ], + "code_sequence": 2, + "abi_sequence": 1 + }, + "receiver": "fio.treasury", + "act": { + "account": "fio.treasury", + "name": "bpclaim", + "authorization": [ + { + "actor": "akfxqn52fx3a", + "permission": "claim" + } + ], + "data": { + "fio_address": "bp@everstake", + "actor": "akfxqn52fx3a" + }, + "hex_data": "0c627040657665727374616b6560465fa24cdb1734" + }, + "context_free": false, + "elapsed": 1955, + "console": "", + "trx_id": "2b8b2b3c99b8ffaff57505fa25289a7cfda33e40ab899e7a9f8d7cea9e33a529", + "block_num": 8721919, + "block_time": "2020-05-14T12:01:02.000", + "producer_block_id": "008515ffc1812cffae3d181369733b03884658e8b718b4c9734b0a62727f3fa6", + "account_ram_deltas": [], + "except": null, + "error_code": null, + "action_ordinal": 1, + "creator_action_ordinal": 0, + "closest_unnotified_ancestor_action_ordinal": 0 + } + }, + { + "global_action_seq": 8951704, + "account_action_seq": 82967, + "block_num": 8721919, + "block_time": "2020-05-14T12:01:02.000", + "action_trace": { + "receipt": { + "receiver": "eosio", + "response": "", + "act_digest": "7a3f646478a6b56858310974646a3ccdeed4b24522f5158f725a08c95e804c26", + "global_sequence": 8951704, + "recv_sequence": 8772433, + "auth_sequence": [ + [ + "fio.treasury", + 7127 + ] + ], + "code_sequence": 3, + "abi_sequence": 2 + }, + "receiver": "eosio", + "act": { + "account": "eosio", + "name": "updlbpclaim", + "authorization": [ + { + "actor": "fio.treasury", + "permission": "active" + } + ], + "data": { + "producer": "akfxqn52fx3a" + }, + "hex_data": "60465fa24cdb1734" + }, + "context_free": false, + "elapsed": 265, + "console": "", + "trx_id": "2b8b2b3c99b8ffaff57505fa25289a7cfda33e40ab899e7a9f8d7cea9e33a529", + "block_num": 8721919, + "block_time": "2020-05-14T12:01:02.000", + "producer_block_id": "008515ffc1812cffae3d181369733b03884658e8b718b4c9734b0a62727f3fa6", + "account_ram_deltas": [], + "except": null, + "error_code": null, + "action_ordinal": 2, + "creator_action_ordinal": 1, + "closest_unnotified_ancestor_action_ordinal": 1 + } + }, + { + "global_action_seq": 8952911, + "account_action_seq": 82968, + "block_num": 8723112, + "block_time": "2020-05-14T12:10:58.500", + "action_trace": { + "receipt": { + "receiver": "fio.treasury", + "response": "", + "act_digest": "ab8ebb262909897219d717e0bebc0f93e95f67c90ccf6fb4f7ac7e1cca23d091", + "global_sequence": 8952911, + "recv_sequence": 76837, + "auth_sequence": [ + [ + "fio.reqobt", + 762 + ] + ], + "code_sequence": 2, + "abi_sequence": 1 + }, + "receiver": "fio.treasury", + "act": { + "account": "fio.treasury", + "name": "fdtnrwdupdat", + "authorization": [ + { + "actor": "fio.reqobt", + "permission": "active" + } + ], + "data": "80c3c90100000000" + }, + "context_free": false, + "elapsed": 72, + "console": "", + "trx_id": "a5d4f68f7de799655612baff3d74db6f1468fbe819c6f59468d8c4cd80342beb", + "block_num": 8723112, + "block_time": "2020-05-14T12:10:58.500", + "producer_block_id": "00851aa8133288ec60424e05e1901ff66a15e96cc2bfc8bf6bdcbcc623becfe2", + "account_ram_deltas": [], + "except": null, + "error_code": null, + "action_ordinal": 3, + "creator_action_ordinal": 1, + "closest_unnotified_ancestor_action_ordinal": 1 + } + }, + { + "global_action_seq": 8952912, + "account_action_seq": 82969, + "block_num": 8723112, + "block_time": "2020-05-14T12:10:58.500", + "action_trace": { + "receipt": { + "receiver": "fio.token", + "response": "", + "act_digest": "506b33f30557b821c4e08fd99512c17dba04e5e6222dd0b2a041739747606f71", + "global_sequence": 8952912, + "recv_sequence": 4386, + "auth_sequence": [ + [ + "fio.treasury", + 7128 + ] + ], + "code_sequence": 1, + "abi_sequence": 1 + }, + "receiver": "fio.token", + "act": { + "account": "fio.token", + "name": "mintfio", + "authorization": [ + { + "actor": "fio.treasury", + "permission": "active" + } + ], + "data": { + "to": "fio.treasury", + "amount": 240000000 + }, + "hex_data": "e0afc646dd0ca85b001c4e0e00000000" + }, + "context_free": false, + "elapsed": 82, + "console": "", + "trx_id": "a5d4f68f7de799655612baff3d74db6f1468fbe819c6f59468d8c4cd80342beb", + "block_num": 8723112, + "block_time": "2020-05-14T12:10:58.500", + "producer_block_id": "00851aa8133288ec60424e05e1901ff66a15e96cc2bfc8bf6bdcbcc623becfe2", + "account_ram_deltas": [], + "except": null, + "error_code": null, + "action_ordinal": 4, + "creator_action_ordinal": 1, + "closest_unnotified_ancestor_action_ordinal": 1 + } + }, + { + "global_action_seq": 8952917, + "account_action_seq": 82970, + "block_num": 8723112, + "block_time": "2020-05-14T12:10:58.500", + "action_trace": { + "receipt": { + "receiver": "fio.tpid", + "response": "", + "act_digest": "829e00f2391396a0af7a6cd1cf62d7d9b93212d47b0efcadd8cbf8bfeae89505", + "global_sequence": 8952917, + "recv_sequence": 885, + "auth_sequence": [ + [ + "fio.treasury", + 7129 + ] + ], + "code_sequence": 1, + "abi_sequence": 1 + }, + "receiver": "fio.tpid", + "act": { + "account": "fio.tpid", + "name": "updatebounty", + "authorization": [ + { + "actor": "fio.treasury", + "permission": "active" + } + ], + "data": { + "amount": 240000000 + }, + "hex_data": "001c4e0e00000000" + }, + "context_free": false, + "elapsed": 53, + "console": "", + "trx_id": "a5d4f68f7de799655612baff3d74db6f1468fbe819c6f59468d8c4cd80342beb", + "block_num": 8723112, + "block_time": "2020-05-14T12:10:58.500", + "producer_block_id": "00851aa8133288ec60424e05e1901ff66a15e96cc2bfc8bf6bdcbcc623becfe2", + "account_ram_deltas": [], + "except": null, + "error_code": null, + "action_ordinal": 5, + "creator_action_ordinal": 1, + "closest_unnotified_ancestor_action_ordinal": 1 + } + }, + { + "global_action_seq": 8952919, + "account_action_seq": 82971, + "block_num": 8723112, + "block_time": "2020-05-14T12:10:58.500", + "action_trace": { + "receipt": { + "receiver": "fio.treasury", + "response": "", + "act_digest": "1320ccc32ac047b301aa7a327cdc3815bea933ac691562b72666920144152587", + "global_sequence": 8952919, + "recv_sequence": 76839, + "auth_sequence": [ + [ + "fio.reqobt", + 764 + ] + ], + "code_sequence": 2, + "abi_sequence": 1 + }, + "receiver": "fio.treasury", + "act": { + "account": "fio.treasury", + "name": "bprewdupdate", + "authorization": [ + { + "actor": "fio.reqobt", + "permission": "active" + } + ], + "data": "80fb651e00000000" + }, + "context_free": false, + "elapsed": 63, + "console": "", + "trx_id": "a5d4f68f7de799655612baff3d74db6f1468fbe819c6f59468d8c4cd80342beb", + "block_num": 8723112, + "block_time": "2020-05-14T12:10:58.500", + "producer_block_id": "00851aa8133288ec60424e05e1901ff66a15e96cc2bfc8bf6bdcbcc623becfe2", + "account_ram_deltas": [], + "except": null, + "error_code": null, + "action_ordinal": 7, + "creator_action_ordinal": 1, + "closest_unnotified_ancestor_action_ordinal": 1 + } + }, + { + "global_action_seq": 8952910, + "account_action_seq": 82972, + "block_num": 8723112, + "block_time": "2020-05-14T12:10:58.500", + "action_trace": { + "receipt": { + "receiver": "fio.treasury", + "response": "", + "act_digest": "9056c596a1ae40734409b7a81e3e793999a639b51b500aac8dc7555516704054", + "global_sequence": 8952910, + "recv_sequence": 76836, + "auth_sequence": [ + [ + "eosio", + 8858043 + ] + ], + "code_sequence": 1, + "abi_sequence": 1 + }, + "receiver": "fio.treasury", + "act": { + "account": "fio.token", + "name": "transfer", + "authorization": [ + { + "actor": "eosio", + "permission": "active" + } + ], + "data": { + "from": "nvqpp5a3qmgh", + "to": "fio.treasury", + "quantity": "0.600000000 FIO", + "memo": "FIO API fees. Thank you." + }, + "hex_data": "d098b4c3945aed9ee0afc646dd0ca85b0046c323000000000946494f000000001846494f2041504920666565732e205468616e6b20796f752e" + }, + "context_free": false, + "elapsed": 20, + "console": "", + "trx_id": "a5d4f68f7de799655612baff3d74db6f1468fbe819c6f59468d8c4cd80342beb", + "block_num": 8723112, + "block_time": "2020-05-14T12:10:58.500", + "producer_block_id": "00851aa8133288ec60424e05e1901ff66a15e96cc2bfc8bf6bdcbcc623becfe2", + "account_ram_deltas": [], + "except": null, + "error_code": null, + "action_ordinal": 11, + "creator_action_ordinal": 2, + "closest_unnotified_ancestor_action_ordinal": 2 + } + }, + { + "global_action_seq": 8952916, + "account_action_seq": 82973, + "block_num": 8723112, + "block_time": "2020-05-14T12:10:58.500", + "action_trace": { + "receipt": { + "receiver": "fio.treasury", + "response": "", + "act_digest": "849eb5345ce7236ee40490bbffe754a8c6ba150f8e55bed1e37164079fd5c8c7", + "global_sequence": 8952916, + "recv_sequence": 76838, + "auth_sequence": [ + [ + "eosio", + 8858047 + ] + ], + "code_sequence": 1, + "abi_sequence": 1 + }, + "receiver": "fio.treasury", + "act": { + "account": "fio.token", + "name": "transfer", + "authorization": [ + { + "actor": "eosio", + "permission": "active" + } + ], + "data": { + "from": "eosio", + "to": "fio.treasury", + "quantity": "0.240000000 FIO", + "memo": "New tokens produced from reserves" + }, + "hex_data": "0000000000ea3055e0afc646dd0ca85b001c4e0e000000000946494f00000000214e657720746f6b656e732070726f64756365642066726f6d207265736572766573" + }, + "context_free": false, + "elapsed": 13, + "console": "", + "trx_id": "a5d4f68f7de799655612baff3d74db6f1468fbe819c6f59468d8c4cd80342beb", + "block_num": 8723112, + "block_time": "2020-05-14T12:10:58.500", + "producer_block_id": "00851aa8133288ec60424e05e1901ff66a15e96cc2bfc8bf6bdcbcc623becfe2", + "account_ram_deltas": [], + "except": null, + "error_code": null, + "action_ordinal": 15, + "creator_action_ordinal": 13, + "closest_unnotified_ancestor_action_ordinal": 13 + } + }, + { + "global_action_seq": 8953166, + "account_action_seq": 82974, + "block_num": 8723344, + "block_time": "2020-05-14T12:12:54.500", + "action_trace": { + "receipt": { + "receiver": "fio.treasury", + "response": "", + "act_digest": "791e180b4f3a4a3ada178be99836ca9733969cae3316307162f534bb7869b6da", + "global_sequence": 8953166, + "recv_sequence": 76841, + "auth_sequence": [ + [ + "fio.token", + 3830 + ] + ], + "code_sequence": 2, + "abi_sequence": 1 + }, + "receiver": "fio.treasury", + "act": { + "account": "fio.treasury", + "name": "fdtnrwdupdat", + "authorization": [ + { + "actor": "fio.token", + "permission": "active" + } + ], + "data": "00e1f50500000000" + }, + "context_free": false, + "elapsed": 118, + "console": "", + "trx_id": "81220b549e832fcff40d7e9a6995eae0ab008bcf5a5814438643b5ae224a9281", + "block_num": 8723344, + "block_time": "2020-05-14T12:12:54.500", + "producer_block_id": "00851b900c2ef952df5034b123c7c0a2f4754ea45e9386cc6e9a3bcad1b72e77", + "account_ram_deltas": [], + "except": null, + "error_code": null, + "action_ordinal": 5, + "creator_action_ordinal": 1, + "closest_unnotified_ancestor_action_ordinal": 1 + } + }, + { + "global_action_seq": 8953167, + "account_action_seq": 82975, + "block_num": 8723344, + "block_time": "2020-05-14T12:12:54.500", + "action_trace": { + "receipt": { + "receiver": "fio.token", + "response": "", + "act_digest": "fe397612c8c79fcd6ca4b6210d31e2b8fdc9b856d8bbd994bc6963dde6e52028", + "global_sequence": 8953167, + "recv_sequence": 4391, + "auth_sequence": [ + [ + "fio.treasury", + 7130 + ] + ], + "code_sequence": 1, + "abi_sequence": 1 + }, + "receiver": "fio.token", + "act": { + "account": "fio.token", + "name": "mintfio", + "authorization": [ + { + "actor": "fio.treasury", + "permission": "active" + } + ], + "data": { + "to": "fio.treasury", + "amount": 800000000 + }, + "hex_data": "e0afc646dd0ca85b0008af2f00000000" + }, + "context_free": false, + "elapsed": 188, + "console": "", + "trx_id": "81220b549e832fcff40d7e9a6995eae0ab008bcf5a5814438643b5ae224a9281", + "block_num": 8723344, + "block_time": "2020-05-14T12:12:54.500", + "producer_block_id": "00851b900c2ef952df5034b123c7c0a2f4754ea45e9386cc6e9a3bcad1b72e77", + "account_ram_deltas": [], + "except": null, + "error_code": null, + "action_ordinal": 6, + "creator_action_ordinal": 1, + "closest_unnotified_ancestor_action_ordinal": 1 + } + }, + { + "global_action_seq": 8953172, + "account_action_seq": 82976, + "block_num": 8723344, + "block_time": "2020-05-14T12:12:54.500", + "action_trace": { + "receipt": { + "receiver": "fio.tpid", + "response": "", + "act_digest": "1cdbbde4ed1d2950d721038c722d2b1e0712bf845c238d39fdafdbb7e4d976d7", + "global_sequence": 8953172, + "recv_sequence": 887, + "auth_sequence": [ + [ + "fio.treasury", + 7131 + ] + ], + "code_sequence": 1, + "abi_sequence": 1 + }, + "receiver": "fio.tpid", + "act": { + "account": "fio.tpid", + "name": "updatebounty", + "authorization": [ + { + "actor": "fio.treasury", + "permission": "active" + } + ], + "data": { + "amount": 800000000 + }, + "hex_data": "0008af2f00000000" + }, + "context_free": false, + "elapsed": 83, + "console": "", + "trx_id": "81220b549e832fcff40d7e9a6995eae0ab008bcf5a5814438643b5ae224a9281", + "block_num": 8723344, + "block_time": "2020-05-14T12:12:54.500", + "producer_block_id": "00851b900c2ef952df5034b123c7c0a2f4754ea45e9386cc6e9a3bcad1b72e77", + "account_ram_deltas": [], + "except": null, + "error_code": null, + "action_ordinal": 7, + "creator_action_ordinal": 1, + "closest_unnotified_ancestor_action_ordinal": 1 + } + }, + { + "global_action_seq": 8953174, + "account_action_seq": 82977, + "block_num": 8723344, + "block_time": "2020-05-14T12:12:54.500", + "action_trace": { + "receipt": { + "receiver": "fio.treasury", + "response": "", + "act_digest": "5d78739015f359116070fbc500329c607e0714e4c1ad46c19799db45fdc3f29d", + "global_sequence": 8953174, + "recv_sequence": 76843, + "auth_sequence": [ + [ + "fio.token", + 3832 + ] + ], + "code_sequence": 2, + "abi_sequence": 1 + }, + "receiver": "fio.treasury", + "act": { + "account": "fio.treasury", + "name": "bprewdupdate", + "authorization": [ + { + "actor": "fio.token", + "permission": "active" + } + ], + "data": "00f1536500000000" + }, + "context_free": false, + "elapsed": 133, + "console": "", + "trx_id": "81220b549e832fcff40d7e9a6995eae0ab008bcf5a5814438643b5ae224a9281", + "block_num": 8723344, + "block_time": "2020-05-14T12:12:54.500", + "producer_block_id": "00851b900c2ef952df5034b123c7c0a2f4754ea45e9386cc6e9a3bcad1b72e77", + "account_ram_deltas": [], + "except": null, + "error_code": null, + "action_ordinal": 9, + "creator_action_ordinal": 1, + "closest_unnotified_ancestor_action_ordinal": 1 + } + }, + { + "global_action_seq": 8953165, + "account_action_seq": 82978, + "block_num": 8723344, + "block_time": "2020-05-14T12:12:54.500", + "action_trace": { + "receipt": { + "receiver": "fio.treasury", + "response": "", + "act_digest": "ffbff6c9eda3ca64334e03dbbaba2e13185f50027c2105a004e92f9482bec8b0", + "global_sequence": 8953165, + "recv_sequence": 76840, + "auth_sequence": [ + [ + "eosio", + 8858286 + ] + ], + "code_sequence": 1, + "abi_sequence": 1 + }, + "receiver": "fio.treasury", + "act": { + "account": "fio.token", + "name": "transfer", + "authorization": [ + { + "actor": "eosio", + "permission": "active" + } + ], + "data": { + "from": "5p35rb3vhqgp", + "to": "fio.treasury", + "quantity": "2.000000000 FIO", + "memo": "FIO API fees. Thank you." + }, + "hex_data": "50996d7b9c5b462de0afc646dd0ca85b00943577000000000946494f000000001846494f2041504920666565732e205468616e6b20796f752e" + }, + "context_free": false, + "elapsed": 28, + "console": "", + "trx_id": "81220b549e832fcff40d7e9a6995eae0ab008bcf5a5814438643b5ae224a9281", + "block_num": 8723344, + "block_time": "2020-05-14T12:12:54.500", + "producer_block_id": "00851b900c2ef952df5034b123c7c0a2f4754ea45e9386cc6e9a3bcad1b72e77", + "account_ram_deltas": [], + "except": null, + "error_code": null, + "action_ordinal": 15, + "creator_action_ordinal": 4, + "closest_unnotified_ancestor_action_ordinal": 4 + } + }, + { + "global_action_seq": 8953171, + "account_action_seq": 82979, + "block_num": 8723344, + "block_time": "2020-05-14T12:12:54.500", + "action_trace": { + "receipt": { + "receiver": "fio.treasury", + "response": "", + "act_digest": "86bde9bb7482c4b8eda73331a5aa9805b028fd7837e5c727347fdf05078839ce", + "global_sequence": 8953171, + "recv_sequence": 76842, + "auth_sequence": [ + [ + "eosio", + 8858290 + ] + ], + "code_sequence": 1, + "abi_sequence": 1 + }, + "receiver": "fio.treasury", + "act": { + "account": "fio.token", + "name": "transfer", + "authorization": [ + { + "actor": "eosio", + "permission": "active" + } + ], + "data": { + "from": "eosio", + "to": "fio.treasury", + "quantity": "0.800000000 FIO", + "memo": "New tokens produced from reserves" + }, + "hex_data": "0000000000ea3055e0afc646dd0ca85b0008af2f000000000946494f00000000214e657720746f6b656e732070726f64756365642066726f6d207265736572766573" + }, + "context_free": false, + "elapsed": 27, + "console": "", + "trx_id": "81220b549e832fcff40d7e9a6995eae0ab008bcf5a5814438643b5ae224a9281", + "block_num": 8723344, + "block_time": "2020-05-14T12:12:54.500", + "producer_block_id": "00851b900c2ef952df5034b123c7c0a2f4754ea45e9386cc6e9a3bcad1b72e77", + "account_ram_deltas": [], + "except": null, + "error_code": null, + "action_ordinal": 19, + "creator_action_ordinal": 17, + "closest_unnotified_ancestor_action_ordinal": 17 + } + }, + { + "global_action_seq": 8953253, + "account_action_seq": 82980, + "block_num": 8723412, + "block_time": "2020-05-14T12:13:28.500", + "action_trace": { + "receipt": { + "receiver": "fio.treasury", + "response": "", + "act_digest": "791e180b4f3a4a3ada178be99836ca9733969cae3316307162f534bb7869b6da", + "global_sequence": 8953253, + "recv_sequence": 76845, + "auth_sequence": [ + [ + "fio.token", + 3837 + ] + ], + "code_sequence": 2, + "abi_sequence": 1 + }, + "receiver": "fio.treasury", + "act": { + "account": "fio.treasury", + "name": "fdtnrwdupdat", + "authorization": [ + { + "actor": "fio.token", + "permission": "active" + } + ], + "data": "00e1f50500000000" + }, + "context_free": false, + "elapsed": 132, + "console": "", + "trx_id": "db59cebb03c7b1b27a4223258c5750bdf6619533ffde66d45282f4e4e9d807a5", + "block_num": 8723412, + "block_time": "2020-05-14T12:13:28.500", + "producer_block_id": "00851bd4b9678b6e93d59da45b9ea3daf473592a698125755f72a06959066aa9", + "account_ram_deltas": [], + "except": null, + "error_code": null, + "action_ordinal": 5, + "creator_action_ordinal": 1, + "closest_unnotified_ancestor_action_ordinal": 1 + } + }, + { + "global_action_seq": 8953254, + "account_action_seq": 82981, + "block_num": 8723412, + "block_time": "2020-05-14T12:13:28.500", + "action_trace": { + "receipt": { + "receiver": "fio.token", + "response": "", + "act_digest": "fe397612c8c79fcd6ca4b6210d31e2b8fdc9b856d8bbd994bc6963dde6e52028", + "global_sequence": 8953254, + "recv_sequence": 4396, + "auth_sequence": [ + [ + "fio.treasury", + 7132 + ] + ], + "code_sequence": 1, + "abi_sequence": 1 + }, + "receiver": "fio.token", + "act": { + "account": "fio.token", + "name": "mintfio", + "authorization": [ + { + "actor": "fio.treasury", + "permission": "active" + } + ], + "data": { + "to": "fio.treasury", + "amount": 800000000 + }, + "hex_data": "e0afc646dd0ca85b0008af2f00000000" + }, + "context_free": false, + "elapsed": 163, + "console": "", + "trx_id": "db59cebb03c7b1b27a4223258c5750bdf6619533ffde66d45282f4e4e9d807a5", + "block_num": 8723412, + "block_time": "2020-05-14T12:13:28.500", + "producer_block_id": "00851bd4b9678b6e93d59da45b9ea3daf473592a698125755f72a06959066aa9", + "account_ram_deltas": [], + "except": null, + "error_code": null, + "action_ordinal": 6, + "creator_action_ordinal": 1, + "closest_unnotified_ancestor_action_ordinal": 1 + } + }, + { + "global_action_seq": 8953259, + "account_action_seq": 82982, + "block_num": 8723412, + "block_time": "2020-05-14T12:13:28.500", + "action_trace": { + "receipt": { + "receiver": "fio.tpid", + "response": "", + "act_digest": "1cdbbde4ed1d2950d721038c722d2b1e0712bf845c238d39fdafdbb7e4d976d7", + "global_sequence": 8953259, + "recv_sequence": 889, + "auth_sequence": [ + [ + "fio.treasury", + 7133 + ] + ], + "code_sequence": 1, + "abi_sequence": 1 + }, + "receiver": "fio.tpid", + "act": { + "account": "fio.tpid", + "name": "updatebounty", + "authorization": [ + { + "actor": "fio.treasury", + "permission": "active" + } + ], + "data": { + "amount": 800000000 + }, + "hex_data": "0008af2f00000000" + }, + "context_free": false, + "elapsed": 48, + "console": "", + "trx_id": "db59cebb03c7b1b27a4223258c5750bdf6619533ffde66d45282f4e4e9d807a5", + "block_num": 8723412, + "block_time": "2020-05-14T12:13:28.500", + "producer_block_id": "00851bd4b9678b6e93d59da45b9ea3daf473592a698125755f72a06959066aa9", + "account_ram_deltas": [], + "except": null, + "error_code": null, + "action_ordinal": 7, + "creator_action_ordinal": 1, + "closest_unnotified_ancestor_action_ordinal": 1 + } + }, + { + "global_action_seq": 8953261, + "account_action_seq": 82983, + "block_num": 8723412, + "block_time": "2020-05-14T12:13:28.500", + "action_trace": { + "receipt": { + "receiver": "fio.treasury", + "response": "", + "act_digest": "5d78739015f359116070fbc500329c607e0714e4c1ad46c19799db45fdc3f29d", + "global_sequence": 8953261, + "recv_sequence": 76847, + "auth_sequence": [ + [ + "fio.token", + 3839 + ] + ], + "code_sequence": 2, + "abi_sequence": 1 + }, + "receiver": "fio.treasury", + "act": { + "account": "fio.treasury", + "name": "bprewdupdate", + "authorization": [ + { + "actor": "fio.token", + "permission": "active" + } + ], + "data": "00f1536500000000" + }, + "context_free": false, + "elapsed": 62, + "console": "", + "trx_id": "db59cebb03c7b1b27a4223258c5750bdf6619533ffde66d45282f4e4e9d807a5", + "block_num": 8723412, + "block_time": "2020-05-14T12:13:28.500", + "producer_block_id": "00851bd4b9678b6e93d59da45b9ea3daf473592a698125755f72a06959066aa9", + "account_ram_deltas": [], + "except": null, + "error_code": null, + "action_ordinal": 9, + "creator_action_ordinal": 1, + "closest_unnotified_ancestor_action_ordinal": 1 + } + }, + { + "global_action_seq": 8953252, + "account_action_seq": 82984, + "block_num": 8723412, + "block_time": "2020-05-14T12:13:28.500", + "action_trace": { + "receipt": { + "receiver": "fio.treasury", + "response": "", + "act_digest": "7c4342041fc654cd686584243a81e5b535d49fa448435e9882348ab1778f8da2", + "global_sequence": 8953252, + "recv_sequence": 76844, + "auth_sequence": [ + [ + "eosio", + 8858362 + ] + ], + "code_sequence": 1, + "abi_sequence": 1 + }, + "receiver": "fio.treasury", + "act": { + "account": "fio.token", + "name": "transfer", + "authorization": [ + { + "actor": "eosio", + "permission": "active" + } + ], + "data": { + "from": "nvqpp5a3qmgh", + "to": "fio.treasury", + "quantity": "2.000000000 FIO", + "memo": "FIO API fees. Thank you." + }, + "hex_data": "d098b4c3945aed9ee0afc646dd0ca85b00943577000000000946494f000000001846494f2041504920666565732e205468616e6b20796f752e" + }, + "context_free": false, + "elapsed": 39, + "console": "", + "trx_id": "db59cebb03c7b1b27a4223258c5750bdf6619533ffde66d45282f4e4e9d807a5", + "block_num": 8723412, + "block_time": "2020-05-14T12:13:28.500", + "producer_block_id": "00851bd4b9678b6e93d59da45b9ea3daf473592a698125755f72a06959066aa9", + "account_ram_deltas": [], + "except": null, + "error_code": null, + "action_ordinal": 15, + "creator_action_ordinal": 4, + "closest_unnotified_ancestor_action_ordinal": 4 + } + }, + { + "global_action_seq": 8953258, + "account_action_seq": 82985, + "block_num": 8723412, + "block_time": "2020-05-14T12:13:28.500", + "action_trace": { + "receipt": { + "receiver": "fio.treasury", + "response": "", + "act_digest": "86bde9bb7482c4b8eda73331a5aa9805b028fd7837e5c727347fdf05078839ce", + "global_sequence": 8953258, + "recv_sequence": 76846, + "auth_sequence": [ + [ + "eosio", + 8858366 + ] + ], + "code_sequence": 1, + "abi_sequence": 1 + }, + "receiver": "fio.treasury", + "act": { + "account": "fio.token", + "name": "transfer", + "authorization": [ + { + "actor": "eosio", + "permission": "active" + } + ], + "data": { + "from": "eosio", + "to": "fio.treasury", + "quantity": "0.800000000 FIO", + "memo": "New tokens produced from reserves" + }, + "hex_data": "0000000000ea3055e0afc646dd0ca85b0008af2f000000000946494f00000000214e657720746f6b656e732070726f64756365642066726f6d207265736572766573" + }, + "context_free": false, + "elapsed": 14, + "console": "", + "trx_id": "db59cebb03c7b1b27a4223258c5750bdf6619533ffde66d45282f4e4e9d807a5", + "block_num": 8723412, + "block_time": "2020-05-14T12:13:28.500", + "producer_block_id": "00851bd4b9678b6e93d59da45b9ea3daf473592a698125755f72a06959066aa9", + "account_ram_deltas": [], + "except": null, + "error_code": null, + "action_ordinal": 19, + "creator_action_ordinal": 17, + "closest_unnotified_ancestor_action_ordinal": 17 + } + } + ], + "last_irreversible_block": 8724218 +} \ No newline at end of file diff --git a/mock/ext-api-data/fio-api_v1_history_get_actions.0002.request_json b/mock/ext-api-data/fio-api_v1_history_get_actions.0002.request_json new file mode 100644 index 000000000..6ad980f4e --- /dev/null +++ b/mock/ext-api-data/fio-api_v1_history_get_actions.0002.request_json @@ -0,0 +1,3 @@ +{ + "account_name": "fio.treasury" +} \ No newline at end of file diff --git a/mock/ext-api-data/fio-api_v1_history_get_actions.json b/mock/ext-api-data/fio-api_v1_history_get_actions.json new file mode 100644 index 000000000..7ef9eb72d --- /dev/null +++ b/mock/ext-api-data/fio-api_v1_history_get_actions.json @@ -0,0 +1,547 @@ +{ + "actions": [ + { + "global_action_seq": 507847, + "account_action_seq": 0, + "block_num": 358672, + "block_time": "2020-03-27T01:54:16.000", + "action_trace": { + "receipt": { + "receiver": "fio.address", + "response": "{\"status\": \"OK\",\"expiration\":\"2021-03-27T01:54:16\",\"fee_collected\":800000000000}", + "act_digest": "bb4962851e0ddc035f392123fd5aba50a0cc054f77afa9326905a9140d4fce58", + "global_sequence": 507847, + "recv_sequence": 34022, + "auth_sequence": [ + [ + "f5axfpgffiqz", + 122 + ] + ], + "code_sequence": 1, + "abi_sequence": 1 + }, + "receiver": "fio.address", + "act": { + "account": "fio.address", + "name": "regdomain", + "authorization": [ + { + "actor": "f5axfpgffiqz", + "permission": "active" + } + ], + "data": { + "fio_domain": "eosph", + "owner_fio_public_key": "FIO7Q3XfQ2ocGP1zYst6Sfx5qrsiZ865Cu8So2atrub9JN94so7gt", + "max_fee": 800000000000, + "actor": "f5axfpgffiqz", + "tpid": "" + }, + "hex_data": "05656f7370683546494f375133586651326f634750317a5973743653667835717273695a383635437538536f326174727562394a4e3934736f3767740040b743ba000000f0ad5b8bd5d54d5900" + }, + "context_free": false, + "elapsed": 3164, + "console": "", + "trx_id": "6691d467499747b038c22a7eef5dbbea496439977a695949b62211753b70f9ef", + "block_num": 358672, + "block_time": "2020-03-27T01:54:16.000", + "producer_block_id": "000579108da2a1d46aeee860cdcee085554a7b5bd773cf14b5d4ae625541b3af", + "account_ram_deltas": [ + { + "account": "f5axfpgffiqz", + "delta": 559 + }, + { + "account": "fio.address", + "delta": 334 + } + ], + "except": null, + "error_code": null, + "action_ordinal": 1, + "creator_action_ordinal": 0, + "closest_unnotified_ancestor_action_ordinal": 0 + } + }, + { + "global_action_seq": 507848, + "account_action_seq": 1, + "block_num": 358672, + "block_time": "2020-03-27T01:54:16.000", + "action_trace": { + "receipt": { + "receiver": "eosio", + "response": "", + "act_digest": "9b9ca6fbd24dde59d084a1ef4b3291841877f9ab8dee970e53a62df5e50bc80b", + "global_sequence": 507848, + "recv_sequence": 402228, + "auth_sequence": [ + [ + "fio.address", + 72512 + ] + ], + "code_sequence": 2, + "abi_sequence": 2 + }, + "receiver": "eosio", + "act": { + "account": "eosio", + "name": "newaccount", + "authorization": [ + { + "actor": "fio.address", + "permission": "active" + } + ], + "data": { + "creator": "fio.address", + "name": "ezsmbcy2opod", + "owner": { + "threshold": 1, + "keys": [ + { + "key": "FIO7Q3XfQ2ocGP1zYst6Sfx5qrsiZ865Cu8So2atrub9JN94so7gt", + "weight": 1 + } + ], + "accounts": [], + "waits": [] + }, + "active": { + "threshold": 1, + "keys": [ + { + "key": "FIO7Q3XfQ2ocGP1zYst6Sfx5qrsiZ865Cu8So2atrub9JN94so7gt", + "weight": 1 + } + ], + "accounts": [], + "waits": [] + } + }, + "hex_data": "003056372503a85b9068a5c2a323f157010000000100034a7ff8128788fe6294353420e9143e3cc20dda7b6333bd433688218b58abe25601000000010000000100034a7ff8128788fe6294353420e9143e3cc20dda7b6333bd433688218b58abe25601000000" + }, + "context_free": false, + "elapsed": 275, + "console": "", + "trx_id": "6691d467499747b038c22a7eef5dbbea496439977a695949b62211753b70f9ef", + "block_num": 358672, + "block_time": "2020-03-27T01:54:16.000", + "producer_block_id": "000579108da2a1d46aeee860cdcee085554a7b5bd773cf14b5d4ae625541b3af", + "account_ram_deltas": [ + { + "account": "ezsmbcy2opod", + "delta": 2996 + } + ], + "except": null, + "error_code": null, + "action_ordinal": 2, + "creator_action_ordinal": 1, + "closest_unnotified_ancestor_action_ordinal": 1 + } + }, + { + "global_action_seq": 507872, + "account_action_seq": 2, + "block_num": 358689, + "block_time": "2020-03-27T01:54:24.500", + "action_trace": { + "receipt": { + "receiver": "fio.token", + "response": "{\"status\": \"OK\",\"fee_collected\":2000000000}", + "act_digest": "6ef1d997fd449b6fefb8df19401c71425d366a24aab4613ca2059478fef7915f", + "global_sequence": 507872, + "recv_sequence": 656, + "auth_sequence": [ + [ + "f5axfpgffiqz", + 123 + ] + ], + "code_sequence": 1, + "abi_sequence": 1 + }, + "receiver": "fio.token", + "act": { + "account": "fio.token", + "name": "trnsfiopubky", + "authorization": [ + { + "actor": "f5axfpgffiqz", + "permission": "active" + } + ], + "data": { + "payee_public_key": "FIO7Q3XfQ2ocGP1zYst6Sfx5qrsiZ865Cu8So2atrub9JN94so7gt", + "amount": 700000000000, + "max_fee": 2000000000, + "actor": "f5axfpgffiqz", + "tpid": "" + }, + "hex_data": "3546494f375133586651326f634750317a5973743653667835717273695a383635437538536f326174727562394a4e3934736f376774005840fba20000000094357700000000f0ad5b8bd5d54d5900" + }, + "context_free": false, + "elapsed": 2898, + "console": "", + "trx_id": "2e0a7dc3640768e1d644cee871734dd2efa23e65a54c438c1ba03801d7386fb7", + "block_num": 358689, + "block_time": "2020-03-27T01:54:24.500", + "producer_block_id": "00057921b2a5f55fba29f7f08cd49dd095a18f0de2e4e06ba0833ca771ad699b", + "account_ram_deltas": [ + { + "account": "f5axfpgffiqz", + "delta": 240 + } + ], + "except": null, + "error_code": null, + "action_ordinal": 1, + "creator_action_ordinal": 0, + "closest_unnotified_ancestor_action_ordinal": 0 + } + }, + { + "global_action_seq": 507873, + "account_action_seq": 3, + "block_num": 358689, + "block_time": "2020-03-27T01:54:24.500", + "action_trace": { + "receipt": { + "receiver": "f5axfpgffiqz", + "response": "{\"status\": \"OK\",\"fee_collected\":2000000000}", + "act_digest": "6ef1d997fd449b6fefb8df19401c71425d366a24aab4613ca2059478fef7915f", + "global_sequence": 507873, + "recv_sequence": 98, + "auth_sequence": [ + [ + "f5axfpgffiqz", + 124 + ] + ], + "code_sequence": 1, + "abi_sequence": 1 + }, + "receiver": "f5axfpgffiqz", + "act": { + "account": "fio.token", + "name": "trnsfiopubky", + "authorization": [ + { + "actor": "f5axfpgffiqz", + "permission": "active" + } + ], + "data": { + "payee_public_key": "FIO7Q3XfQ2ocGP1zYst6Sfx5qrsiZ865Cu8So2atrub9JN94so7gt", + "amount": 700000000000, + "max_fee": 2000000000, + "actor": "f5axfpgffiqz", + "tpid": "" + }, + "hex_data": "3546494f375133586651326f634750317a5973743653667835717273695a383635437538536f326174727562394a4e3934736f376774005840fba20000000094357700000000f0ad5b8bd5d54d5900" + }, + "context_free": false, + "elapsed": 5, + "console": "", + "trx_id": "2e0a7dc3640768e1d644cee871734dd2efa23e65a54c438c1ba03801d7386fb7", + "block_num": 358689, + "block_time": "2020-03-27T01:54:24.500", + "producer_block_id": "00057921b2a5f55fba29f7f08cd49dd095a18f0de2e4e06ba0833ca771ad699b", + "account_ram_deltas": [], + "except": null, + "error_code": null, + "action_ordinal": 5, + "creator_action_ordinal": 1, + "closest_unnotified_ancestor_action_ordinal": 1 + } + }, + { + "global_action_seq": 507874, + "account_action_seq": 4, + "block_num": 358689, + "block_time": "2020-03-27T01:54:24.500", + "action_trace": { + "receipt": { + "receiver": "ezsmbcy2opod", + "response": "{\"status\": \"OK\",\"fee_collected\":2000000000}", + "act_digest": "6ef1d997fd449b6fefb8df19401c71425d366a24aab4613ca2059478fef7915f", + "global_sequence": 507874, + "recv_sequence": 1, + "auth_sequence": [ + [ + "f5axfpgffiqz", + 125 + ] + ], + "code_sequence": 1, + "abi_sequence": 1 + }, + "receiver": "ezsmbcy2opod", + "act": { + "account": "fio.token", + "name": "trnsfiopubky", + "authorization": [ + { + "actor": "f5axfpgffiqz", + "permission": "active" + } + ], + "data": { + "payee_public_key": "FIO7Q3XfQ2ocGP1zYst6Sfx5qrsiZ865Cu8So2atrub9JN94so7gt", + "amount": 700000000000, + "max_fee": 2000000000, + "actor": "f5axfpgffiqz", + "tpid": "" + }, + "hex_data": "3546494f375133586651326f634750317a5973743653667835717273695a383635437538536f326174727562394a4e3934736f376774005840fba20000000094357700000000f0ad5b8bd5d54d5900" + }, + "context_free": false, + "elapsed": 4, + "console": "", + "trx_id": "2e0a7dc3640768e1d644cee871734dd2efa23e65a54c438c1ba03801d7386fb7", + "block_num": 358689, + "block_time": "2020-03-27T01:54:24.500", + "producer_block_id": "00057921b2a5f55fba29f7f08cd49dd095a18f0de2e4e06ba0833ca771ad699b", + "account_ram_deltas": [], + "except": null, + "error_code": null, + "action_ordinal": 6, + "creator_action_ordinal": 1, + "closest_unnotified_ancestor_action_ordinal": 1 + } + }, + { + "global_action_seq": 508968, + "account_action_seq": 5, + "block_num": 359762, + "block_time": "2020-03-27T02:03:21.000", + "action_trace": { + "receipt": { + "receiver": "fio.address", + "response": "{\"status\": \"OK\",\"expiration\":\"2021-03-27T02:03:21\",\"fee_collected\":40000000000}", + "act_digest": "e054494384148e58122a10c3398d9e01a09a79cd6c22da0203653906afd79b3b", + "global_sequence": 508968, + "recv_sequence": 34025, + "auth_sequence": [ + [ + "ezsmbcy2opod", + 1 + ] + ], + "code_sequence": 1, + "abi_sequence": 1 + }, + "receiver": "fio.address", + "act": { + "account": "fio.address", + "name": "regaddress", + "authorization": [ + { + "actor": "ezsmbcy2opod", + "permission": "active" + } + ], + "data": { + "fio_address": "bp@eosph", + "owner_fio_public_key": "FIO7Q3XfQ2ocGP1zYst6Sfx5qrsiZ865Cu8So2atrub9JN94so7gt", + "max_fee": 40000000000, + "actor": "ezsmbcy2opod", + "tpid": "" + }, + "hex_data": "08627040656f7370683546494f375133586651326f634750317a5973743653667835717273695a383635437538536f326174727562394a4e3934736f37677400902f50090000009068a5c2a323f15700" + }, + "context_free": false, + "elapsed": 4624, + "console": "", + "trx_id": "b7dd60839ccce11cd175fce6816da04bbce9b70825661005d2ea5d3572408c04", + "block_num": 359762, + "block_time": "2020-03-27T02:03:21.000", + "producer_block_id": "00057d5209ad0141445b3ee2eb1ba7265ab4c7093f7bc4c2142e2eac4c8e5d10", + "account_ram_deltas": [ + { + "account": "ezsmbcy2opod", + "delta": 798 + } + ], + "except": null, + "error_code": null, + "action_ordinal": 1, + "creator_action_ordinal": 0, + "closest_unnotified_ancestor_action_ordinal": 0 + } + }, + { + "global_action_seq": 508970, + "account_action_seq": 6, + "block_num": 359762, + "block_time": "2020-03-27T02:03:21.000", + "action_trace": { + "receipt": { + "receiver": "ezsmbcy2opod", + "response": "", + "act_digest": "e6774ab921eabe540049667756efb5567b83b291b8a21c5bec81c8b5dc98c366", + "global_sequence": 508970, + "recv_sequence": 2, + "auth_sequence": [ + [ + "eosio", + 430085 + ] + ], + "code_sequence": 1, + "abi_sequence": 1 + }, + "receiver": "ezsmbcy2opod", + "act": { + "account": "fio.token", + "name": "transfer", + "authorization": [ + { + "actor": "eosio", + "permission": "active" + } + ], + "data": { + "from": "ezsmbcy2opod", + "to": "fio.treasury", + "quantity": "40.000000000 FIO", + "memo": "FIO API fees. Thank you." + }, + "hex_data": "9068a5c2a323f157e0afc646dd0ca85b00902f50090000000946494f000000001846494f2041504920666565732e205468616e6b20796f752e" + }, + "context_free": false, + "elapsed": 4, + "console": "", + "trx_id": "b7dd60839ccce11cd175fce6816da04bbce9b70825661005d2ea5d3572408c04", + "block_num": 359762, + "block_time": "2020-03-27T02:03:21.000", + "producer_block_id": "00057d5209ad0141445b3ee2eb1ba7265ab4c7093f7bc4c2142e2eac4c8e5d10", + "account_ram_deltas": [], + "except": null, + "error_code": null, + "action_ordinal": 6, + "creator_action_ordinal": 2, + "closest_unnotified_ancestor_action_ordinal": 2 + } + }, + { + "global_action_seq": 510503, + "account_action_seq": 7, + "block_num": 361281, + "block_time": "2020-03-27T02:16:00.500", + "action_trace": { + "receipt": { + "receiver": "eosio", + "response": "{\"status\": \"OK\",\"fee_collected\":200000000000}", + "act_digest": "52b1631c84896baaebd4b81a80c2cfab4f9741e0323d2845d1b3df5683ad7c3c", + "global_sequence": 510503, + "recv_sequence": 404854, + "auth_sequence": [ + [ + "ezsmbcy2opod", + 2 + ] + ], + "code_sequence": 2, + "abi_sequence": 2 + }, + "receiver": "eosio", + "act": { + "account": "eosio", + "name": "regproducer", + "authorization": [ + { + "actor": "ezsmbcy2opod", + "permission": "active" + } + ], + "data": { + "fio_address": "bp@eosph", + "fio_pub_key": "FIO5hZB8REVEirigba4N7TKa67MYm4HFwtiKz6GZJ2eRi5Paxwixz", + "url": "https://www.eosph.io", + "location": 10, + "actor": "ezsmbcy2opod", + "max_fee": 400000000000 + }, + "hex_data": "08627040656f7370683546494f35685a423852455645697269676261344e37544b6136374d596d3448467774694b7a36475a4a32655269355061787769787a1468747470733a2f2f7777772e656f7370682e696f0a009068a5c2a323f15700a0db215d000000" + }, + "context_free": false, + "elapsed": 2888, + "console": "", + "trx_id": "5cd8d902a675d608d4c82eca892c7973deaa6aefcc58ed9bcbd382ebdc7271c8", + "block_num": 361281, + "block_time": "2020-03-27T02:16:00.500", + "producer_block_id": "00058341700331f78adea1eec39e7150b743f171c9fd9dfff8ea7310f5e6b515", + "account_ram_deltas": [ + { + "account": "ezsmbcy2opod", + "delta": 635 + } + ], + "except": null, + "error_code": null, + "action_ordinal": 1, + "creator_action_ordinal": 0, + "closest_unnotified_ancestor_action_ordinal": 0 + } + }, + { + "global_action_seq": 510505, + "account_action_seq": 8, + "block_num": 361281, + "block_time": "2020-03-27T02:16:00.500", + "action_trace": { + "receipt": { + "receiver": "ezsmbcy2opod", + "response": "", + "act_digest": "a8dd1a5cfe8db5fb3ca38eed9e348acd73150d88211f93e0d37e332289fe76a3", + "global_sequence": 510505, + "recv_sequence": 3, + "auth_sequence": [ + [ + "eosio", + 431614 + ] + ], + "code_sequence": 1, + "abi_sequence": 1 + }, + "receiver": "ezsmbcy2opod", + "act": { + "account": "fio.token", + "name": "transfer", + "authorization": [ + { + "actor": "eosio", + "permission": "active" + } + ], + "data": { + "from": "ezsmbcy2opod", + "to": "fio.treasury", + "quantity": "200.000000000 FIO", + "memo": "FIO API fees. Thank you." + }, + "hex_data": "9068a5c2a323f157e0afc646dd0ca85b00d0ed902e0000000946494f000000001846494f2041504920666565732e205468616e6b20796f752e" + }, + "context_free": false, + "elapsed": 4, + "console": "", + "trx_id": "5cd8d902a675d608d4c82eca892c7973deaa6aefcc58ed9bcbd382ebdc7271c8", + "block_num": 361281, + "block_time": "2020-03-27T02:16:00.500", + "producer_block_id": "00058341700331f78adea1eec39e7150b743f171c9fd9dfff8ea7310f5e6b515", + "account_ram_deltas": [], + "except": null, + "error_code": null, + "action_ordinal": 6, + "creator_action_ordinal": 2, + "closest_unnotified_ancestor_action_ordinal": 2 + } + } + ], + "last_irreversible_block": 8724206 +} \ No newline at end of file diff --git a/mock/ext-api-data/fio-api_v1_history_get_actions.request_json b/mock/ext-api-data/fio-api_v1_history_get_actions.request_json new file mode 100644 index 000000000..3b372252b --- /dev/null +++ b/mock/ext-api-data/fio-api_v1_history_get_actions.request_json @@ -0,0 +1,3 @@ +{ + "account_name": "ezsmbcy2opod" +} \ No newline at end of file diff --git a/mock/ext-api-data/gochain-api_tokens__address_0x0Fd98FB42C439E5F6484f7E71Caa6661d81d0628.json b/mock/ext-api-data/gochain-api_tokens__address_0x0Fd98FB42C439E5F6484f7E71Caa6661d81d0628.json new file mode 100644 index 000000000..5ab72457f --- /dev/null +++ b/mock/ext-api-data/gochain-api_tokens__address_0x0Fd98FB42C439E5F6484f7E71Caa6661d81d0628.json @@ -0,0 +1 @@ +{"total":1,"docs":[{"address":"0x5f16Fa0B5c9d779a3C8d46859a27973Ff3511188","name":"pukkamex","decimals":18,"symbol":"PUX"}]} \ No newline at end of file diff --git a/mock/ext-api-data/gochain-api_transactions__address_0xEd7F2e81B0264177e0df8f275f97Fd74Fa51A896.json b/mock/ext-api-data/gochain-api_transactions__address_0xEd7F2e81B0264177e0df8f275f97Fd74Fa51A896.json new file mode 100644 index 000000000..6553ba4be --- /dev/null +++ b/mock/ext-api-data/gochain-api_transactions__address_0xEd7F2e81B0264177e0df8f275f97Fd74Fa51A896.json @@ -0,0 +1 @@ +{"docs":[{"operations":[],"contract":null,"_id":"0x2637d7b0e7f66134e983e6af921700718b8a49885a9215ee8033ac384d5d1be7","blockNumber":10070535,"time":1576793173,"nonce":6,"from":"0xEd7F2e81B0264177e0df8f275f97Fd74Fa51A896","to":"0x65a0e277B2d0eEF62b8C30b280B4C49f83a104d3","value":"860000000000000000000000","gas":"90000","gasPrice":"2000000000","gasUsed":"21000","input":"0x","error":"","id":"0x2637d7b0e7f66134e983e6af921700718b8a49885a9215ee8033ac384d5d1be7","timeStamp":"1576793173"},{"operations":[],"contract":null,"_id":"0x472c94385a46072713bb2bf3503fc1610135a70e415046bf61a937789c205f4c","blockNumber":10070520,"time":1576793098,"nonce":5,"from":"0xEd7F2e81B0264177e0df8f275f97Fd74Fa51A896","to":"0x65a0e277B2d0eEF62b8C30b280B4C49f83a104d3","value":"800000000000000000000","gas":"90000","gasPrice":"2000000000","gasUsed":"21000","input":"0x","error":"","id":"0x472c94385a46072713bb2bf3503fc1610135a70e415046bf61a937789c205f4c","timeStamp":"1576793098"},{"operations":[],"contract":null,"_id":"0x2b40299606beff9a6986b7ea20292e218aab27a40e423549124a3640423a9cdc","blockNumber":10070507,"time":1576793033,"nonce":4,"from":"0xEd7F2e81B0264177e0df8f275f97Fd74Fa51A896","to":"0x65a0e277B2d0eEF62b8C30b280B4C49f83a104d3","value":"1000000000000000000","gas":"90000","gasPrice":"2000000000","gasUsed":"21000","input":"0x","error":"","id":"0x2b40299606beff9a6986b7ea20292e218aab27a40e423549124a3640423a9cdc","timeStamp":"1576793033"},{"operations":[],"contract":null,"_id":"0xc1589183bcf01960b07bae9dbb8a43df18a287a663570f8d2dfdfc22fdd2768f","blockNumber":8201186,"nonce":3,"from":"0xEd7F2e81B0264177e0df8f275f97Fd74Fa51A896","to":"0xE12d1FD4B38bd9a162650d35FeC83d5105aD4b41","value":"1119287000000000000000000","gas":"90000","gasPrice":"2000000000","gasUsed":"21000","input":"0x","error":"","time":1567446425,"id":"0xc1589183bcf01960b07bae9dbb8a43df18a287a663570f8d2dfdfc22fdd2768f","timeStamp":"1567446425"},{"operations":[],"contract":null,"_id":"0x582feee80b66486254fc83d7aab9f313e7e6e0625ce5edd2b6a76f2d7b66a91a","blockNumber":5007262,"nonce":2,"from":"0xEd7F2e81B0264177e0df8f275f97Fd74Fa51A896","to":"0x65a0e277B2d0eEF62b8C30b280B4C49f83a104d3","value":"1843321000000000000000000","gas":"90000","gasPrice":"2000000000","gasUsed":"21000","input":"0x","error":"","time":1551472504,"id":"0x582feee80b66486254fc83d7aab9f313e7e6e0625ce5edd2b6a76f2d7b66a91a","timeStamp":"1551472504"}],"total":5} \ No newline at end of file diff --git a/mock/ext-api-data/groestlcoin-api_v2_address_33Ym3fecmWaHD19jymYt6fGd9TqSDQFfQj__details_txs.json b/mock/ext-api-data/groestlcoin-api_v2_address_33Ym3fecmWaHD19jymYt6fGd9TqSDQFfQj__details_txs.json new file mode 100644 index 000000000..043aff2fa --- /dev/null +++ b/mock/ext-api-data/groestlcoin-api_v2_address_33Ym3fecmWaHD19jymYt6fGd9TqSDQFfQj__details_txs.json @@ -0,0 +1,110 @@ +{ + "page": 1, + "totalPages": 1, + "itemsOnPage": 1000, + "address": "33Ym3fecmWaHD19jymYt6fGd9TqSDQFfQj", + "balance": "0", + "totalReceived": "5951153060", + "totalSent": "5951153060", + "unconfirmedBalance": "0", + "unconfirmedTxs": 0, + "txs": 2, + "transactions": [ + { + "txid": "2640aa5de0c9603da1c0d9c16b2fd3fa0a17b1472c3aa02559d3ef5e1defceb5", + "version": 2, + "lockTime": 2959295, + "vin": [ + { + "txid": "d8e0d23dedc2c89e9de317e7a54bdc3d26f514918a9360aa04e271c4d8074c28", + "sequence": 4294967294, + "n": 0, + "addresses": [ + "33Ym3fecmWaHD19jymYt6fGd9TqSDQFfQj" + ], + "isAddress": true, + "value": "5951153060", + "hex": "160014d6c589125f084df1e3286fcd55446b64dc7de130" + } + ], + "vout": [ + { + "value": "1151149700", + "n": 0, + "spent": true, + "hex": "a91436d64490426cc347a50bdd3f8db2ef20d62949f587", + "addresses": [ + "36gy6VVstfso35mS89pBg1PiUcYY3Gesar" + ], + "isAddress": true + }, + { + "value": "4800000000", + "n": 1, + "spent": true, + "hex": "76a914fcad3abf614562d224c6cc8b0e00d2fa9016404388ac", + "addresses": [ + "FtCkFSrwrgiJzjQzGRZvjHzrmHp4HJeGYm" + ], + "isAddress": true + } + ], + "blockHash": "0000000000000a79428395294255704ed877847d93c6d36108dc8184b71c1f0a", + "blockHeight": 2959365, + "confirmations": 126518, + "blockTime": 1581386699, + "value": "5951149700", + "valueIn": "5951153060", + "fees": "3360", + "hex": "02000000000101284c07d8c471e204aa60938a9114f5263ddc4ba5e717e39d9ec8c2ed3dd2e0d80000000017160014d6c589125f084df1e3286fcd55446b64dc7de130feffffff0284269d440000000017a91436d64490426cc347a50bdd3f8db2ef20d62949f58700301a1e010000001976a914fcad3abf614562d224c6cc8b0e00d2fa9016404388ac02473044022034f3f2ab2d021a27ba999aebb40016f921433c39149d6908fe1e96d914c5c96402203d5d12127f64a01429775090abb445b5af2ec90803372c92499a35e12e229adb0121033ca60a0478fee5583e52c3b85c4dacb81faa9c4a10ad8b4f574c1b050f814463bf272d00" + }, + { + "txid": "d8e0d23dedc2c89e9de317e7a54bdc3d26f514918a9360aa04e271c4d8074c28", + "version": 2, + "lockTime": 2959360, + "vin": [ + { + "txid": "2ed852f7881270ec108c86482d609f818ee21ae07033796fb77cb8e52fa86ccd", + "sequence": 4294967294, + "n": 0, + "addresses": [ + "Fg4WGddhNYayAF3mTPDNCFCEqrXydAd6Vu" + ], + "isAddress": true, + "value": "29751157520", + "hex": "47304402201fe0aff8dd5c35be49f824216adb51d0749878dc2d759d0dd6d4ed6612ca09cd02203ad7d2b2eaa52f341f325934cca2c2758ac4c4b7b8bc279e7748d48ab98b484901210246e7e23df8acf0a305b94009d9b60eca7230ce747493201a9574f7ccb03775e9" + } + ], + "vout": [ + { + "value": "5951153060", + "n": 0, + "spent": true, + "hex": "a914146081496e97dbb864af7df601184f8ec3624aa787", + "addresses": [ + "33Ym3fecmWaHD19jymYt6fGd9TqSDQFfQj" + ], + "isAddress": true + }, + { + "value": "23800000000", + "n": 1, + "spent": true, + "hex": "76a914fcad3abf614562d224c6cc8b0e00d2fa9016404388ac", + "addresses": [ + "FtCkFSrwrgiJzjQzGRZvjHzrmHp4HJeGYm" + ], + "isAddress": true + } + ], + "blockHash": "0000000000000a79428395294255704ed877847d93c6d36108dc8184b71c1f0a", + "blockHeight": 2959365, + "confirmations": 126518, + "blockTime": 1581386699, + "value": "29751153060", + "valueIn": "29751157520", + "fees": "4460", + "hex": "0200000001cd6ca82fe5b87cb76f793370e01ae28e819f602d48868c10ec701288f752d82e000000006a47304402201fe0aff8dd5c35be49f824216adb51d0749878dc2d759d0dd6d4ed6612ca09cd02203ad7d2b2eaa52f341f325934cca2c2758ac4c4b7b8bc279e7748d48ab98b484901210246e7e23df8acf0a305b94009d9b60eca7230ce747493201a9574f7ccb03775e9feffffff02a463b7620100000017a914146081496e97dbb864af7df601184f8ec3624aa787002e978a050000001976a914fcad3abf614562d224c6cc8b0e00d2fa9016404388ac00282d00" + } + ] +} diff --git a/mock/ext-api-data/groestlcoin-api_v2_xpub_zpub6rWUMiiVPxjWVHffT8x3AfcbyDu8SZJAiuKUTBmhxT7Bvqk1WitxndDStG1qHN6XzRM7JgsaRaVccRFW3AprWk4Fpaev1N6QSp1aNnP5JPf__details_txs.json b/mock/ext-api-data/groestlcoin-api_v2_xpub_zpub6rWUMiiVPxjWVHffT8x3AfcbyDu8SZJAiuKUTBmhxT7Bvqk1WitxndDStG1qHN6XzRM7JgsaRaVccRFW3AprWk4Fpaev1N6QSp1aNnP5JPf__details_txs.json new file mode 100644 index 000000000..05a25d50c --- /dev/null +++ b/mock/ext-api-data/groestlcoin-api_v2_xpub_zpub6rWUMiiVPxjWVHffT8x3AfcbyDu8SZJAiuKUTBmhxT7Bvqk1WitxndDStG1qHN6XzRM7JgsaRaVccRFW3AprWk4Fpaev1N6QSp1aNnP5JPf__details_txs.json @@ -0,0 +1 @@ +{"page":1,"totalPages":10,"itemsOnPage":10,"address":"zpub6rWUMiiVPxjWVHffT8x3AfcbyDu8SZJAiuKUTBmhxT7Bvqk1WitxndDStG1qHN6XzRM7JgsaRaVccRFW3AprWk4Fpaev1N6QSp1aNnP5JPf","balance":"412844353","totalReceived":"289739972697","totalSent":"289327128344","unconfirmedBalance":"0","unconfirmedTxs":0,"txs":98,"transactions":[{"txid":"686c651223b937b1223560a60631ad79ad17351c88bba67cad8ea0c95fccbb83","version":1,"vin":[{"txid":"1e3362ef26063cae601362721fcde1c0e856b7d81abc9e541ba38a0b15330689","sequence":2147483644,"n":0,"addresses":["grs1qa8pvadg835vy798nr3ktrvlkx07mggu4hqvv04"],"isAddress":true,"value":"100000000"},{"txid":"1e3362ef26063cae601362721fcde1c0e856b7d81abc9e541ba38a0b15330689","vout":1,"sequence":2147483645,"n":1,"addresses":["grs1qa8pvadg835vy798nr3ktrvlkx07mggu4hqvv04"],"isAddress":true,"value":"212864353"},{"txid":"dd7780ee2529f7030153737c8ee2a16ef32817cbd63b6aba8553c4ccbeac368d","sequence":2147483646,"n":2,"addresses":["grs1qa8pvadg835vy798nr3ktrvlkx07mggu4hqvv04"],"isAddress":true,"value":"100000000"}],"vout":[{"value":"10000000","n":0,"hex":"0014e9c2ceb5078d184f14f31c6cb1b3f633fdb42395","addresses":["grs1qa8pvadg835vy798nr3ktrvlkx07mggu4hqvv04"],"isAddress":true},{"value":"402844353","n":1,"hex":"0014e9c2ceb5078d184f14f31c6cb1b3f633fdb42395","addresses":["grs1qa8pvadg835vy798nr3ktrvlkx07mggu4hqvv04"],"isAddress":true}],"blockHash":"00000000000003a48c30ddfaa9c875b902e8372c448413ee65dba418601a5b7e","blockHeight":2998112,"confirmations":98914,"blockTime":1583831414,"value":"412844353","valueIn":"412864353","fees":"20000","hex":"01000000000103890633150b8aa31b549ebc1ad8b756e8c0e1cd1f72621360ae3c0626ef62331e0000000000fcffff7f890633150b8aa31b549ebc1ad8b756e8c0e1cd1f72621360ae3c0626ef62331e0100000000fdffff7f8d36acbeccc45385ba6a3bd6cb1728f36ea1e28e7c73530103f72925ee8077dd0000000000feffff7f028096980000000000160014e9c2ceb5078d184f14f31c6cb1b3f633fdb42395c1ea021800000000160014e9c2ceb5078d184f14f31c6cb1b3f633fdb423950247304402201b4acd75cb1186fba1405bd604a2e24a960d94a39e14316f4e6ef5289808e4c90220569d652a91ecc149d543d7aab0653a646ce60d8e3bed053d421907432bd7c9bd012102ab2d3112dfb83d7e08949ec32128e24a4be5c588640eee5028cdba56aae7b285024730440220426733a0a12dd1c34142d9814e74987fdbb41438189fb0bbed74ab2cd420a9b4022046dc588c6690b1ecba351b8a981ed3db63df9de95df49d5a8333b087b349b6c3012102ab2d3112dfb83d7e08949ec32128e24a4be5c588640eee5028cdba56aae7b285024730440220291f4932101719b70630233d53503854f456a0a944453a6105f4e2b95fde526b0220617d4dd0b4dd12e8917d15f80dadf617ec584fe650a31ca8f07f4d6869256549012102ab2d3112dfb83d7e08949ec32128e24a4be5c588640eee5028cdba56aae7b28500000000"},{"txid":"1e3362ef26063cae601362721fcde1c0e856b7d81abc9e541ba38a0b15330689","version":1,"vin":[{"txid":"dd7780ee2529f7030153737c8ee2a16ef32817cbd63b6aba8553c4ccbeac368d","vout":1,"n":0,"addresses":["grs1qa8pvadg835vy798nr3ktrvlkx07mggu4hqvv04"],"isAddress":true,"value":"312884353"}],"vout":[{"value":"100000000","n":0,"spent":true,"hex":"0014e9c2ceb5078d184f14f31c6cb1b3f633fdb42395","addresses":["grs1qa8pvadg835vy798nr3ktrvlkx07mggu4hqvv04"],"isAddress":true},{"value":"212864353","n":1,"spent":true,"hex":"0014e9c2ceb5078d184f14f31c6cb1b3f633fdb42395","addresses":["grs1qa8pvadg835vy798nr3ktrvlkx07mggu4hqvv04"],"isAddress":true}],"blockHash":"000000000000034560a3a07b6498c9b937da914a4f683d1575197a02c4b69a83","blockHeight":2989928,"confirmations":107098,"blockTime":1583315379,"value":"312864353","valueIn":"312884353","fees":"20000","hex":"010000000001018d36acbeccc45385ba6a3bd6cb1728f36ea1e28e7c73530103f72925ee8077dd0100000000000000000200e1f50500000000160014e9c2ceb5078d184f14f31c6cb1b3f633fdb42395610db00c00000000160014e9c2ceb5078d184f14f31c6cb1b3f633fdb4239502483045022100e0e7e5484f9d06120f0e3a63471d353d90b65ba63b0fbf640c714608414ffa5d02204556b0c2554bc33ebfb338d806fa1589df1e25afe251c5a7869cfad6e6ef0a61012102ab2d3112dfb83d7e08949ec32128e24a4be5c588640eee5028cdba56aae7b28500000000"},{"txid":"dd7780ee2529f7030153737c8ee2a16ef32817cbd63b6aba8553c4ccbeac368d","version":1,"vin":[{"txid":"d9f0569c6eac51a47d2405a09d17c8811a3ef8df212e88d3b6e75f27768b8d83","sequence":2147483645,"n":0,"addresses":["grs1qa8pvadg835vy798nr3ktrvlkx07mggu4hqvv04"],"isAddress":true,"value":"100000000"},{"txid":"797b24cb13964ee062c31d171a84f54431e7eb329b89669a8db36a01fa1ada32","sequence":2147483646,"n":1,"addresses":["grs1qa8pvadg835vy798nr3ktrvlkx07mggu4hqvv04"],"isAddress":true,"value":"312904345"}],"vout":[{"value":"100000000","n":0,"spent":true,"hex":"0014e9c2ceb5078d184f14f31c6cb1b3f633fdb42395","addresses":["grs1qa8pvadg835vy798nr3ktrvlkx07mggu4hqvv04"],"isAddress":true},{"value":"312884353","n":1,"spent":true,"hex":"0014e9c2ceb5078d184f14f31c6cb1b3f633fdb42395","addresses":["grs1qa8pvadg835vy798nr3ktrvlkx07mggu4hqvv04"],"isAddress":true}],"blockHash":"00000000000009f6f6a14d76c13faf60debfd01d068cabf22435b1d24236ecab","blockHeight":2989926,"confirmations":107100,"blockTime":1583314946,"value":"412884353","valueIn":"412904345","fees":"19992","hex":"01000000000102838d8b76275fe7b6d3882e21dff83e1a81c8179da005247da451ac6e9c56f0d90000000000fdffff7f32da1afa016ab38d9a66899b32ebe73144f5841a171dc362e04e9613cb247b790000000000feffff7f0200e1f50500000000160014e9c2ceb5078d184f14f31c6cb1b3f633fdb42395813ca61200000000160014e9c2ceb5078d184f14f31c6cb1b3f633fdb42395024830450221008a65a121c2569ccf2d0c030ac2a30ff4580586b146fe85ce81c7137fd4b2c7a70220613166d4734ebbbc4011a433571088395c6ce3002779021988e58113880029b2012102ab2d3112dfb83d7e08949ec32128e24a4be5c588640eee5028cdba56aae7b28502483045022100f5ca4d53375a62b0945a31ccb6ac736581d088e78a7f9a2fcef823950ac5cc1302204ae591f46de9ac64412a319c91fcd04b42378fd8be7bef21359a61ed3802a2df012102ab2d3112dfb83d7e08949ec32128e24a4be5c588640eee5028cdba56aae7b28500000000"},{"txid":"797b24cb13964ee062c31d171a84f54431e7eb329b89669a8db36a01fa1ada32","version":1,"vin":[{"txid":"25fad1c20e0618ebce0459c69abf6e9c892c07e38a0825568f74ab9cc1ffc629","vout":1,"n":0,"addresses":["grs1qa8pvadg835vy798nr3ktrvlkx07mggu4hqvv04"],"isAddress":true,"value":"10000"},{"txid":"95b6af107a45472754a76939acfc5ce4e324dcd3485630b9aa9fc9b9fcfb7ca5","n":1,"addresses":["grs1qa8pvadg835vy798nr3ktrvlkx07mggu4hqvv04"],"isAddress":true,"value":"10000"},{"txid":"6d7b5636e34cf5c43e545aeb6b2cd0ea7dbe855167d2f531b891d9e73bbbb161","vout":1,"n":2,"addresses":["grs1qa8pvadg835vy798nr3ktrvlkx07mggu4hqvv04"],"isAddress":true,"value":"10000"},{"txid":"c9dc7ce72e9db78c86f9223e28b4b1b822a8f30fb71378e28cc2f49bdb8873de","vout":1,"n":3,"addresses":["grs1qa8pvadg835vy798nr3ktrvlkx07mggu4hqvv04"],"isAddress":true,"value":"10000"},{"txid":"be861703ed533e39310b5e84bf45de3c6d0a009e4afc63d18168bf00f98edde2","vout":1,"n":4,"addresses":["grs1qa8pvadg835vy798nr3ktrvlkx07mggu4hqvv04"],"isAddress":true,"value":"60000"},{"txid":"dc4c38bec0e3ded98269cdf9651ed82936d4282bde51bbcc441a718a0f9b44d2","vout":1,"n":5,"addresses":["grs1qa8pvadg835vy798nr3ktrvlkx07mggu4hqvv04"],"isAddress":true,"value":"60000"},{"txid":"2afd7b893fade931618b5a20a5879970af9ece772f463227e09d555505f778e4","vout":1,"n":6,"addresses":["grs1qa8pvadg835vy798nr3ktrvlkx07mggu4hqvv04"],"isAddress":true,"value":"60000"},{"txid":"fc02e239d2fe65e10e0ac78c8b966140c61c47e66a6e8db67c2a2c26441284d4","vout":1,"n":7,"addresses":["grs1q9lgx0rfcxwra3q76uudtc0z5gsrx74p9eqeezt"],"isAddress":true,"value":"80000"},{"txid":"2afd7b893fade931618b5a20a5879970af9ece772f463227e09d555505f778e4","n":8,"addresses":["grs1qa8pvadg835vy798nr3ktrvlkx07mggu4hqvv04"],"isAddress":true,"value":"100000"},{"txid":"be861703ed533e39310b5e84bf45de3c6d0a009e4afc63d18168bf00f98edde2","n":9,"addresses":["grs1qa8pvadg835vy798nr3ktrvlkx07mggu4hqvv04"],"isAddress":true,"value":"100000"},{"txid":"8d5198d4dcaa1806cd717adc6117f23fe6a2c54aef6e27e93d99620bf4dc851e","vout":1,"n":10,"addresses":["grs1qa8pvadg835vy798nr3ktrvlkx07mggu4hqvv04"],"isAddress":true,"value":"140000"},{"txid":"d3fcee7c551b130583ac4d3122b105cc87026435949372c78d8b61fa9c3ff77a","vout":1,"n":11,"addresses":["grs1qysqxuj7vx04drafu6rx03vp0wgk9rg5pcqsduq"],"isAddress":true,"value":"160000"},{"txid":"d3fcee7c551b130583ac4d3122b105cc87026435949372c78d8b61fa9c3ff77a","n":12,"addresses":["grs1qn6wqssh5d5tc7zhwhj6erp6p28h879480e7tnj"],"isAddress":true,"value":"300000"},{"txid":"1a836aa25b8939c36df133f50104cbc6e00f91f0a6b02fd2951ad1a7260615f8","n":13,"addresses":["grs1q33p5fx3r3zlq7ckqhkh0vr9gx5xz3tltkewrs6"],"isAddress":true,"value":"300000"},{"txid":"a02cb677515fa2431b44139883d3d31ef71a0097489743f4397617698f9e0c72","n":14,"addresses":["grs1qa8pvadg835vy798nr3ktrvlkx07mggu4hqvv04"],"isAddress":true,"value":"300000"},{"txid":"6eec066fcf8a8029faee4f74ecc5264332ac3605e15de79b4a53660bd901203c","vout":1,"n":15,"addresses":["grs1qa8pvadg835vy798nr3ktrvlkx07mggu4hqvv04"],"isAddress":true,"value":"380000"},{"txid":"3e5e9e1de659729be31cd63deafecd29bf2b7766fad0f0ae907b7a5b260401f2","vout":1,"n":16,"addresses":["grs1qaqkc5ll6x0w4dx3g60n7w7gtd26np3lx0wwsey"],"isAddress":true,"value":"380000"},{"txid":"8df8d4f4375264cc5578e46f34c0d0cb1de19c2958220b7b4fd7a34afe6f627e","vout":1,"n":17,"addresses":["grs1qysqxuj7vx04drafu6rx03vp0wgk9rg5pcqsduq"],"isAddress":true,"value":"480000"},{"txid":"46d956d92c85161547038e6d9ecd4205505bc23809bea9979e0d380d78267c32","vout":1,"n":18,"addresses":["grs1qnflfe7dvfp4vysv4m8z0k9chqkteqe2w5ta8vh"],"isAddress":true,"value":"480000"},{"txid":"3e5e9e1de659729be31cd63deafecd29bf2b7766fad0f0ae907b7a5b260401f2","n":19,"addresses":["grs1q0zch5h5uxtfx94x6nh7levd78mq8gj67pa7wta"],"isAddress":true,"value":"600000"},{"txid":"4b994083a3f3ccc73783065c0a23bf9890790f295890edbd2ac8166c52dc77d7","vout":1,"n":20,"addresses":["grs1qa5gxtj9ls89rfjr6ccjydqm7xhq2x5zqvm6dm8"],"isAddress":true,"value":"840000"},{"txid":"b4ea5e7a4006b18410c38302382853e2fcaedb07a58cd53c3cc0ecb0a5f01c2e","vout":1,"n":21,"addresses":["grs1qa5gxtj9ls89rfjr6ccjydqm7xhq2x5zqvm6dm8"],"isAddress":true,"value":"980000"},{"txid":"1b083e1587a090590237b72a68837bb5fce67f50b87ce6933bdfcd24dff0f784","vout":1,"n":22,"addresses":["grs1q5xq4vqyf9jg6mrcjugghkhq0m7ksvl73v6eeq6"],"isAddress":true,"value":"980000"},{"txid":"b4ea5e7a4006b18410c38302382853e2fcaedb07a58cd53c3cc0ecb0a5f01c2e","n":23,"addresses":["grs1qw6spp4sev3c24mhydkllhpt8yt0gvd7tna7pce"],"isAddress":true,"value":"1000000"},{"txid":"b883f18c47a0e7fa25a461b1b8f3ac43d5c4b10be82c3c851931d01047a3a35c","n":24,"addresses":["grs1q66aqr09y4efltet3xu3dl9uxd2cwen9gvmnfdl"],"isAddress":true,"value":"1000000"},{"txid":"8d5198d4dcaa1806cd717adc6117f23fe6a2c54aef6e27e93d99620bf4dc851e","n":25,"addresses":["grs1qa8pvadg835vy798nr3ktrvlkx07mggu4hqvv04"],"isAddress":true,"value":"1000000"},{"txid":"0f9a5819a6cfd389c7870bcdff147e3db787b2682b3c36f51260090458f4c02c","n":26,"addresses":["grs1q3uaxdr5xpk9p3h7dg29gecn6lpy80zn394pkd7"],"isAddress":true,"value":"1000000"},{"txid":"655e88b80ef0c7818014a3711b7cfcf66fd572d886251db55f529756e62fa157","vout":1,"n":27,"addresses":["grs1qulmmx7q6r5gp0w34zz5zv84zmp3al2hmg5ansl"],"isAddress":true,"value":"1960000"},{"txid":"655e88b80ef0c7818014a3711b7cfcf66fd572d886251db55f529756e62fa157","n":28,"addresses":["grs1qgjazwnlc5hnss57u7tg3zzxlvgsxra0chljv40"],"isAddress":true,"value":"2000000"},{"txid":"1b083e1587a090590237b72a68837bb5fce67f50b87ce6933bdfcd24dff0f784","n":29,"addresses":["grs1qs2xyel4tgejyfxylv5xdaxaafnf2qmhsnpar8l"],"isAddress":true,"value":"3000000"},{"txid":"3c662c0051f454df3c998067cbe5028f45a0789a47c331dab6b92bde908de04f","vout":1,"n":30,"addresses":["grs1q7gldkf5p8083nz3dmsktdm3sfdej5n3cwmcaw6"],"isAddress":true,"value":"9860000"},{"txid":"f3078100a2485b62294b257953c89dff6032f4e7b2b81e2e02a304248e5eefec","n":31,"addresses":["grs1qtunv3tapt3ak5str09hfee4zfpwn8lc5ccam3v"],"isAddress":true,"value":"10000000"},{"txid":"3c662c0051f454df3c998067cbe5028f45a0789a47c331dab6b92bde908de04f","n":32,"addresses":["grs1q9hlg5xwfl5tmytung3qrwxfwvd60h897cgzscv"],"isAddress":true,"value":"10000000"},{"txid":"71417cb19534d074f449c12a7fd3c15f6cbe6df063d8035e89859067ddb5e126","n":33,"addresses":["grs1qqc9srdr2l22e3dt99ex738a9apy32swzc5y4r3"],"isAddress":true,"value":"10000000"},{"txid":"9c2b150712803cd419317c417cb8ccf0cc50d22b65c2667f4e677f77fb64b8a9","n":34,"addresses":["grs1qeysq7696ymswzd3nvgq5kngktktkf08ettu2t8"],"isAddress":true,"value":"10000000"},{"txid":"7bda34b60a14f1eb886c1a4ae771754fc7c4e75fae306a72d471c3eedfb1bbc4","n":35,"addresses":["grs1qj4qacxpay5v6p4rpa8juec6fjpjjlg740emrg3"],"isAddress":true,"value":"10000000"},{"txid":"7b3161f9892fb1b7aa08e0a039ebca3c8cd34129f3b7d9d04992d3b73e67e4e6","vout":1,"n":36,"addresses":["grs1qgjzg0rz25atwg4l968xswklhpqj3ngl4kuyl0v"],"isAddress":true,"value":"19980000"},{"txid":"b79cbc6d51b89cdf1756b8c26a2f51a93a5b86c4c35800dbbb7f3f87e7c9940e","n":37,"addresses":["grs1qmmvgl0em0wtvqf9l3fm4fef7ps6k0ckgwd8twz"],"isAddress":true,"value":"20000000"},{"txid":"b79cbc6d51b89cdf1756b8c26a2f51a93a5b86c4c35800dbbb7f3f87e7c9940e","vout":1,"n":38,"addresses":["grs1qsufm8h68fthghkwcu54kshf5jfzunjttek8djl"],"isAddress":true,"value":"29980000"},{"txid":"7b3161f9892fb1b7aa08e0a039ebca3c8cd34129f3b7d9d04992d3b73e67e4e6","n":39,"addresses":["grs1q28w2mmdepq549ylzfx8k6cpauuu6nzp2gw0kv9"],"isAddress":true,"value":"30000000"},{"txid":"4800c0d049ca18e7baac7c3e3b01e1a8109e4e013b3179edc1bb4d8c91dee58e","vout":1,"n":40,"addresses":["grs1qmvsay76u2re6vet9aul6etqzsmnv09rzq63g3d"],"isAddress":true,"value":"35324345"},{"txid":"56a1af8000df7c13a8a5ec0c47c5a9a578392197510cf244a8a1aeeaf399e04b","n":41,"addresses":["grs1qa8pvadg835vy798nr3ktrvlkx07mggu4hqvv04"],"isAddress":true,"value":"50000000"},{"txid":"0d8b50f75abb2ce4d45a96b58d2f785df7839fb0857ae4802f7e7f7af41b8201","n":42,"addresses":["grs1qa8pvadg835vy798nr3ktrvlkx07mggu4hqvv04"],"isAddress":true,"value":"50000000"}],"vout":[{"value":"312904345","n":0,"spent":true,"hex":"0014e9c2ceb5078d184f14f31c6cb1b3f633fdb42395","addresses":["grs1qa8pvadg835vy798nr3ktrvlkx07mggu4hqvv04"],"isAddress":true}],"blockHash":"000000000000000fc88ac750552c327173b6532a50e71bc4c96a6c6b2b431eb0","blockHeight":2964150,"confirmations":132876,"blockTime":1581688771,"value":"312904345","valueIn":"312924345","fees":"20000","hex":"0100000000012b29c6ffc19cab748f5625088ae3072c899c6ebf9ac65904ceeb18060ec2d1fa25010000000000000000a57cfbfcb9c99faab9305648d3dc24e3e45cfcac3969a7542747457a10afb69500000000000000000061b1bb3be7d991b831f5d2675185be7dead02c6beb5a543ec4f54ce336567b6d010000000000000000de7388db9bf4c28ce27813b70ff3a822b8b1b4283e22f9868cb79d2ee77cdcc9010000000000000000e2dd8ef900bf6881d163fc4a9e000a6d3cde45bf845e0b31393e53ed031786be010000000000000000d2449b0f8a711a44ccbb51de2b28d43629d81e65f9cd6982d9dee3c0be384cdc010000000000000000e478f70555559de02732462f77ce9eaf709987a5205a8b6131e9ad3f897bfd2a010000000000000000d4841244262c2a7cb68d6e6ae6471cc64061968b8cc70a0ee165fed239e202fc010000000000000000e478f70555559de02732462f77ce9eaf709987a5205a8b6131e9ad3f897bfd2a000000000000000000e2dd8ef900bf6881d163fc4a9e000a6d3cde45bf845e0b31393e53ed031786be0000000000000000001e85dcf40b62993de9276eef4ac5a2e63ff21761dc7a71cd0618aadcd498518d0100000000000000007af73f9cfa618b8dc772939435640287cc05b122314dac8305131b557ceefcd30100000000000000007af73f9cfa618b8dc772939435640287cc05b122314dac8305131b557ceefcd3000000000000000000f8150626a7d11a95d22fb0a6f0910fe0c6cb0401f533f16dc339895ba26a831a000000000000000000720c9e8f69177639f443974897001af71ed3d3839813441b43a25f5177b62ca00000000000000000003c2001d90b66534a9be75de10536ac324326c5ec744feefa29808acf6f06ec6e010000000000000000f20104265b7a7b90aef0d0fa66772bbf29cdfeea3dd61ce39b7259e61d9e5e3e0100000000000000007e626ffe4aa3d74f7b0b2258299ce11dcbd0c0346fe47855cc645237f4d4f88d010000000000000000327c26780d380d9e97a9be0938c25b500542cd9e6d8e03471516852cd956d946010000000000000000f20104265b7a7b90aef0d0fa66772bbf29cdfeea3dd61ce39b7259e61d9e5e3e000000000000000000d777dc526c16c82abded9058290f799098bf230a5c068337c7ccf3a38340994b0100000000000000002e1cf0a5b0ecc03c3cd58ca507dbaefce25328380283c31084b106407a5eeab401000000000000000084f7f0df24cddf3b93e67cb8507fe6fcb57b83682ab737025990a087153e081b0100000000000000002e1cf0a5b0ecc03c3cd58ca507dbaefce25328380283c31084b106407a5eeab40000000000000000005ca3a34710d03119853c2ce80bb1c4d543acf3b8b161a425fae7a0478cf183b80000000000000000001e85dcf40b62993de9276eef4ac5a2e63ff21761dc7a71cd0618aadcd498518d0000000000000000002cc0f45804096012f5363c2b68b287b73d7e14ffcd0b87c789d3cfa619589a0f00000000000000000057a12fe65697525fb51d2586d872d56ff6fc7c1b71a3148081c7f00eb8885e6501000000000000000057a12fe65697525fb51d2586d872d56ff6fc7c1b71a3148081c7f00eb8885e6500000000000000000084f7f0df24cddf3b93e67cb8507fe6fcb57b83682ab737025990a087153e081b0000000000000000004fe08d90de2bb9b6da31c3479a78a0458f02e5cb6780993cdf54f451002c663c010000000000000000ecef5e8e2404a3022e1eb8b2e7f43260ff9dc85379254b29625b48a2008107f30000000000000000004fe08d90de2bb9b6da31c3479a78a0458f02e5cb6780993cdf54f451002c663c00000000000000000026e1b5dd679085895e03d863f06dbe6c5fc1d37f2ac149f474d03495b17c4171000000000000000000a9b864fb777f674e7f66c2652bd250ccf0ccb87c417c3119d43c801207152b9c000000000000000000c4bbb1dfeec371d4726a30ae5fe7c4c74f7571e74a1a6c88ebf1140ab634da7b000000000000000000e6e4673eb7d39249d0d9b7f32941d38c3ccaeb39a0e008aab7b12f89f961317b0100000000000000000e94c9e7873f7fbbdb0058c3c4865b3aa9512f6ac2b85617df9cb8516dbc9cb70000000000000000000e94c9e7873f7fbbdb0058c3c4865b3aa9512f6ac2b85617df9cb8516dbc9cb7010000000000000000e6e4673eb7d39249d0d9b7f32941d38c3ccaeb39a0e008aab7b12f89f961317b0000000000000000008ee5de918c4dbbc1ed79313b014e9e10a8e1013b3e7cacbae718ca49d0c000480100000000000000004be099f3eaaea1a844f20c5197213978a5a9c5470ceca5a8137cdf0080afa15600000000000000000001821bf47a7f7e2f80e47a85b09f83f75d782f8db5965ad4e42cbb5af7508b0d00000000000000000001998aa61200000000160014e9c2ceb5078d184f14f31c6cb1b3f633fdb4239502483045022100dda68285f5c98ac3f1736ff190a2e931192e38119ea4620ff0c340eee3a225380220118714a3c2fd206a5ef30e6508d2a0c1394abbcd66a00ab11a764e5b2b9456a1012102ab2d3112dfb83d7e08949ec32128e24a4be5c588640eee5028cdba56aae7b2850247304402200aa1d6e9353c2e3375bb8e12821c5974b1698a18d07fccb905fb32cbcf36401c022062c65f61b2413cd6a8e2517ce9f854409b937447be27ebfcf0b20770352acd76012102ab2d3112dfb83d7e08949ec32128e24a4be5c588640eee5028cdba56aae7b2850247304402202335efbc7588bb997a7fe685d345a14d54e5474c97512f51e75272cd7ff542db022003d098bbaf1f29432e030025f326116b74801f162cbe0db2720bd4e15b6a5867012102ab2d3112dfb83d7e08949ec32128e24a4be5c588640eee5028cdba56aae7b28502483045022100e3b26a46738dc8992208c17adda2384424f8c303ee82f5fe2035fa7b4cc224ac02205a713efa63f972a9018b3766d03344a01b5818547917eebb67030bfd11a5b41e012102ab2d3112dfb83d7e08949ec32128e24a4be5c588640eee5028cdba56aae7b2850247304402205ecce3bfe33360ceff821d16ffdb98393ebfa0b70c21d8d7eb9d3586434ea05f0220507b34ef4ddbb61c9d4c25bea254b3bac8b7421434dc25ab051f59cc5fbef014012102ab2d3112dfb83d7e08949ec32128e24a4be5c588640eee5028cdba56aae7b2850247304402207e9ed9125afa12d60bb40202fb640c5ea42093a402bff3eece690eabcb67d992022054f0cdc1632ae450c2fe3ce684bac9c6b35550275f30cd741aa2ab8b7f74b12a012102ab2d3112dfb83d7e08949ec32128e24a4be5c588640eee5028cdba56aae7b2850247304402205013558c3a4645648289d2d583af3c0a16cfbd119473ba797b24da4dfc4fdd36022078469ba29159cfc01eea2e64d531726aee9f7c2d1655f3ec3ee87c9dbf10572a012102ab2d3112dfb83d7e08949ec32128e24a4be5c588640eee5028cdba56aae7b28502483045022100c979d0c578e73a54396921c4873cb6b9621bcdb1724cba891bdfa4b7983dbff70220490b4bb09552de441f34258598337202943209e5c3eb9af719e3e12359e6a8c2012103edbd754a1d9e666428585215dcc08c6c5b53fbfc7ec43c9ed2347816e1859f7402483045022100e291508a1006a8587e6be61b87aebdde15eacb50be63744a844be0b57c59358b022040b03991009ae49e3a7c98dcf84e8be3a414ca7c8409d1faa4a1997cfc0bcb33012102ab2d3112dfb83d7e08949ec32128e24a4be5c588640eee5028cdba56aae7b28502483045022100b250cf13aa399054afa288dd117a7bef97dd09b18f98d1cd248968e1a902d8d402207ccb8d5a4925ddc187e074f196ccd6e7a1ea9609496ac5405a73ea870892f5eb012102ab2d3112dfb83d7e08949ec32128e24a4be5c588640eee5028cdba56aae7b28502473044022075f9cf4f883488c5d5ffcbd6d74f7f8596fd4814ed1fed839954b4bd4b9c05b702204b4bb5aae4bc5da1e2b236de733931691e0fb447a1a1f94737586980981f9f16012102ab2d3112dfb83d7e08949ec32128e24a4be5c588640eee5028cdba56aae7b28502473044022001dcebb22afea18d449bbd3234d62a6fcf7e43e4de33b1a220b0e29940c567b70220568ae3f748d34b3e005406e068ad3e1be3a882d6adb897fa524e0559d1f6ffcc012102d50eb39ae3640520b11a145af5351d094f1d45165f80a88c21fde0acbca8c2b802483045022100862c018754abfbb449daa3b0c110af58180d7584d64f300665965ed9797595fe02202aee69f243ddd79f266b631faa515d8e585f5f0944f625e06378f3d4864ba5ae012102691c3911914784cc628a9248454cee36757f94f073a7d46205c623f1202e4cad02483045022100a15f8d3ce18d804fa06c61d474a4b7e52bfc39892453f7f74520875ccebe4a6a02202b82212215f387618407af1288b2092b63233b131e0d73729cd67ec01c2fe580012102c70aa060c3c3194145309d71208931107a943c426bb2460729e059d957a67ca00247304402203cd32aacdb7a6d9d9e4360ac5545a861ae00d6062d90a49eb3e5f599e695596d0220564ef105ce68d87465d8a84f7af28029b902f88b6a9a86d3c9976fb06d511dfc012102ab2d3112dfb83d7e08949ec32128e24a4be5c588640eee5028cdba56aae7b28502483045022100c0ade5d0763e0ea114d5c3099dff0dc976a602cc11938e97cdbcf9eca36968c40220745c82706ab10fd96be689607b21cab3057631bd4dbd9ad6edfb2a5fc8e72abc012102ab2d3112dfb83d7e08949ec32128e24a4be5c588640eee5028cdba56aae7b28502483045022100d80bbcd4b4ba5345a60c6f6b03499f51316e98cffd81c268f29bfb6bbc95c11802200cd135a3d96d29e9a1718907ab4565d20672f081cc1d10db05dcfd467c4a5e1301210399869f1bb9ca5b578bd9867e9a3ad4307f45f86bf25e086f73e9785167d18c4a0247304402205cca5d4234b7f2501cff3e35931b2823afada7331ec042166e60d887a024603c02206d6c8886d82234a79b06feca0cf26c08c2de6863461575505516cd1d38066d85012102d50eb39ae3640520b11a145af5351d094f1d45165f80a88c21fde0acbca8c2b802483045022100cb5d9e03a736844a75ab55e8211f5838d937d7ea1aa58094fc5d306f9dc14d980220242d1c153724d3350434a97b5cba84cc3531e2e1b2ac775a5ba0c4a22566220001210200bba2d78064e88196be9e44d01e3d633cae02a8a97bbd294ad5b4743466fa6402473044022057fd34054630770dfafcc1107d139795cefbc6becebb18d8f4ccd64cfcf8eb51022057d9235605db264d0f2c482ff9a9933a5295710238cd47cfe53bf09748961c0701210313b7f74f6ccff0e60fec38a6ddcfc85516f6347fe37a84355839cc5b6bd7e5ef02483045022100b78ff12d1f317dea3727bdfe1d5a2a6b2de33cc54ce52d7d42db71a06a6c502902200f9ccd01627e64102090254ba95a0fd93abc4b9a2a72e5673a00958708695178012102067face2b5fd21d6a0c71a2f52592cffc4607b3bda6da141576fadfa8e2fe8ed024730440220388dbad76966e966c4b0a6a9027fb7e28bae393ba5e20e6c352043abef5ff47c022002e0a9de09e3492b3084fbfb2396d9c4ffd12b20b4019512dfe5a5e813582561012102067face2b5fd21d6a0c71a2f52592cffc4607b3bda6da141576fadfa8e2fe8ed02483045022100ca8d7921e5515103abad52d2405f0c5bb59f558a13e5a8db81fe4b10a75da883022021e549a9efe783fbfeabfa1f7572bcc25573cc13046e05cccc85682aa565c1fd0121038b2213fedf1a31fb64893c17bcf95e3a44527ed19b2889afa55afefb85ebf1d302473044022013d1e23a2d2497b9560c2523263c73039a234411826bf50c86100e7e3c8fdd34022072c6fe7ec2d44677994f67339d46d6f6599ca618664c7386590faf16b4cec48a012102811ba8512dd3376f5365d46fd3129496813225c2f7cff20648c1ea1ca0e7467b02483045022100c9d4eba9da02605bfc9ca54033d4d2d18df5060f366faf6582bcbb3575ca60f8022079ff03cb214838d9455b1d23d0eb5d6f980e3d16757fe7973c15ac8405eac5aa01210277a931902ec986935cc7c50acbd9767392c047951f9f492193d23fbd5c1477aa024730440220290d63712eb341898d4d8f28f9a480ed6424f09965c545c7300f964d319176060220729b56e7fae20d56a032362cf020395907693f32d52e356dbd755811f95d0c09012102ab2d3112dfb83d7e08949ec32128e24a4be5c588640eee5028cdba56aae7b28502473044022010dcdbe82f785ccdd5b896aa91226aa8e071d0cd5b30dab8dfae9294296b394c02200ec34b1e4f8c992e70ab951caa8965193a8fa1602054ce6af682bd9b77d49ba7012102ec51df51936fc88305953727467960ef6f20c7b1e94484f60e0042e6e083974102463043022068f4223f9427cf521901f02715dd13ad228780073f7f0e2859fc4a148bcd5172021f0bcf979a56b14990d2db33928e67e7fad6073934ad8d7b710a456b9a5802ef01210275a6842bf4f000cc2b65034379a2cd240d241d9889027830e14d5d04b89fc7a90248304502210094baa0d9f3d91906deb394ec1c0f1e90ce4abb900eb1aebc4147e6a93daa577c02203793da9cc37682e7e3e17a3fcb8db864c55117cbda1cf9e8f7666ddcc724fe200121021c88fdbed94569b9673316a7ecf1b294e852d4778fdc0a540756cb11ce7d0e7102473044022005acf933345d5d2f80d95cc51a7bc852566127b6345b910aec679c3f89a7854802206b83101cc2d58c5a6e44c4bd99c750100b82ed0b2d7eb83640f215fa8bc7ea48012102d342287ffcd5b1d6e5ad75f526f253a914729c4cbc1db7f9837c55345479ebbd02483045022100a92afd6ff17e1bf4f034e6708e5b3a9fecfb921ddcac143f972c7f6c9ea90983022056373802c75b39898a04a70dd19d15b41f9a63fb6b199d0adf22ba6aa6d05cf6012103ef14c253b8c2d8e70f52e12066a87891dc36f388a7969711995871d0296c198f02483045022100ee66c3c4511f8e792c2291b59b686d1461b6d70e9ba82452db882c5cab4c4aa302201134ca0be18ab192fbf560b81037ce3db6c14b355eb54297c258a343fd1670620121036879b519b860ce9a0163705cb455ad9ca0f8916aaee9199c15dfaa195fd1e5ff02473044022070c2dba854e7a4805231131b99a5019edf7a9257c190481f85da2cb64c5ad23a02202ac776845c473e4d531bc72dbef7d1bb56b7e91c47782d875b402d42ac48a745012103b19992fe4f69e4178ce4235c1f97f7744cc7f134e9c31fb4b13cc05e4a717cc0024730440220546dc2404fc2f7d293876daa89bc57a0e5a8ac70c6477e1657a9689f694d844d02202798957ce5e07042e70fe07c9e961ab37f6c609d4eea44829c90d3f4641bf4b9012103e64a3083a453563dc008f59057fd3d8ecba0b8cca3ee063c0e9969a0aa5c673502473044022003879cbd7269be371c29cf3a8700c61a4c4e5aa9a3e201707787a731b2953d4702200f2365c53ce69a9887bd253d727cd3f1c4ee03fd2aa2abe3773f7b71645c1519012103c824f725960ebfaffbead29603ff839946d56ab49f8752b98340a94e558f3c0a02483045022100ca17414822a367194f09110591bb1db4c665a2d9dc47ced5f6274725c4c1e37e02201edcb9f84e293343a1386a928a135275bf7e08b30863a8d68d000b71c6b65681012103ffeadeb731370d6499f9a76d05351934a2e7ed1617d14dd84802c53177caeb3b02483045022100af87f2203f91194d6a49214062289c3d740671c87f0bf868cf0339b62d3da4810220137f6f743a9fde2353174b63dcab37544ffa3a2204002497cd3803d11d38341a012102440e20dc21e094ae046df896c4f56fed4fe0ca2e28e1497bb8e0f4d40049644c0247304402202aa214769893ae100d4e3f209d2ae4cfceb303fa033531d91764b23eb3d53a7602205888afaa73a7a9c7f42ab7f3ebd1feb5ab06d9679ed52e858441632a9c8cb8570121039d5aaa3e073c087f2fe02543dc8bea715999374b6ca4d33e0594169b4d162b080247304402206e2444c90bb2bab858b59613c6078373b1aec997a624d09e86a4a0545108bfba02204fbb292824da95fa0f456d936016d30ebc622f5cf6286faa9f5193247c4b70300121031e2eecd58bb0db3f57bfe5ff67b6178da2a9d823c8796be737bd0b6fa92ba5ad024730440220400a612984efc092a31efc5b50b8d80353b7412a32298fd4e053fb488ad1e07102206ffb46bce7b25745b3713f85105668409a51c6081c037804256825a2888ff7580121023d966cc3d039eab86c6e336c6fc1e9a52cf580c9960b7547a47989b0b8a5dd83024730440220157a51269fdf2ffa2a309440f11f796367c8459353bf52d4e2fd2628313007790220252732976412d249252de8b5a835218598ecfdb7c8fc5591465855163dc359d9012102168643c5e8d097fd3bf12053d2c5f04ad5eede983ff6dd1eb4ef4b81122eb396024730440220211f11b60f6ad795f09fef7d83bbe731c0b57628c879e1ba657a782a8538844b02200cf54877fdd5c5c4b69fd7ed8c2277d81af7f302ab89ea7573f0f1fce080159c012102ab2d3112dfb83d7e08949ec32128e24a4be5c588640eee5028cdba56aae7b285024830450221008c1bea7747fc0600327df340bedffb8824497f74b0c2c556c33511f6c186bf0402200f6c2d70daa9f1a9c7d15a7697d5de838eae1a2b4537a6a4c8376e0e2e19dcdc012102ab2d3112dfb83d7e08949ec32128e24a4be5c588640eee5028cdba56aae7b28500000000"},{"txid":"d9f0569c6eac51a47d2405a09d17c8811a3ef8df212e88d3b6e75f27768b8d83","version":1,"vin":[{"txid":"0aac62c7f63dea9398e7f5459432b2228c2896d4e68a11a02e66b91f5336e403","vout":1,"n":0,"addresses":["grs1qzj8ha64pvccsu0yvel8uqvgdndcg8zx0rm30dt"],"isAddress":true,"value":"388937964"}],"vout":[{"value":"100000000","n":0,"spent":true,"hex":"0014e9c2ceb5078d184f14f31c6cb1b3f633fdb42395","addresses":["grs1qa8pvadg835vy798nr3ktrvlkx07mggu4hqvv04"],"isAddress":true},{"value":"288917964","n":1,"hex":"0014d19952adf465581f3262bded696cd869cf9619d6","addresses":["grs1q6xv49t05v4vp7vnzhhkkjmxcd88evxwkjeukhc"],"isAddress":true}],"blockHash":"000000000000000fc88ac750552c327173b6532a50e71bc4c96a6c6b2b431eb0","blockHeight":2964150,"confirmations":132876,"blockTime":1581688771,"value":"388917964","valueIn":"388937964","fees":"20000","hex":"0100000000010103e436531fb9662ea0118ae6d496288c22b2329445f5e79893ea3df6c762ac0a0100000000000000000200e1f50500000000160014e9c2ceb5078d184f14f31c6cb1b3f633fdb42395cc89381100000000160014d19952adf465581f3262bded696cd869cf9619d602483045022100b94d6b8dacffa6bd2eb7d34ecdd3f330b4b9df8b8ea8e5c6fcc1d9f9777fb377022049cc1534a177f296b03f0fcc6821501433add29990dfe795ca28f41e2e22008d0121037d4305c4c893c806fe789e46eb9e16926ac7c43fc99c8c3602ae04185dad512b00000000"},{"txid":"4800c0d049ca18e7baac7c3e3b01e1a8109e4e013b3179edc1bb4d8c91dee58e","version":1,"vin":[{"txid":"568acc4f54ce8eb03e09ccc16dbeee2b882f6ed620d565708133f71e0e163b60","vout":1,"n":0,"addresses":["grs1qa8pvadg835vy798nr3ktrvlkx07mggu4hqvv04"],"isAddress":true,"value":"145474926"},{"txid":"027f784db0849c599b411e8690f257bc3feb23272ffe709c7d486626c4872955","vout":1,"n":1,"addresses":["grs1qa8pvadg835vy798nr3ktrvlkx07mggu4hqvv04"],"isAddress":true,"value":"439889419"},{"txid":"56a1af8000df7c13a8a5ec0c47c5a9a578392197510cf244a8a1aeeaf399e04b","vout":1,"n":2,"addresses":["grs1qa8pvadg835vy798nr3ktrvlkx07mggu4hqvv04"],"isAddress":true,"value":"449980000"}],"vout":[{"value":"1000000000","n":0,"spent":true,"hex":"76a914bc3b34231b16f2af9d41c100ab833510c1d81b0988ac","addresses":["FnKzQWuu8zcL3u6hEuNZDsjBpgfDMhMhE1"],"isAddress":true},{"value":"35324345","n":1,"spent":true,"hex":"0014db21d27b5c50f3a66565ef3facac0286e6c79462","addresses":["grs1qmvsay76u2re6vet9aul6etqzsmnv09rzq63g3d"],"isAddress":true}],"blockHash":"0000000000000b2d30be42fd05d3f2a6807e6e53d203efb51496aa0fa8a80445","blockHeight":2964145,"confirmations":132881,"blockTime":1581688548,"value":"1035324345","valueIn":"1035344345","fees":"20000","hex":"01000000000103603b160e1ef733817065d520d66e2f882beebe6dc1cc093eb08ece544fcc8a56010000000000000000552987c42666487d9c70fe2f2723eb3fbc57f290861e419b599c84b04d787f020100000000000000004be099f3eaaea1a844f20c5197213978a5a9c5470ceca5a8137cdf0080afa1560100000000000000000200ca9a3b000000001976a914bc3b34231b16f2af9d41c100ab833510c1d81b0988acb9011b0200000000160014db21d27b5c50f3a66565ef3facac0286e6c7946202473044022062dadbf1c2b87701d4914ad3890bbd57004abd418b981d38c2403a49501ebdc402207ddf47f3be5ba2c6c7d82c79470c734acbb93941cbf1248008b7c9f242858689012102ab2d3112dfb83d7e08949ec32128e24a4be5c588640eee5028cdba56aae7b28502483045022100d43d73fc0d4fffeb4bcf71cea47e67f83f081ca5807cc3a0389e30611f7a450b0220371bdc9978fa570e2a27b6d2e88787d6a2b6ed2214af012499eb24a63f3da4c9012102ab2d3112dfb83d7e08949ec32128e24a4be5c588640eee5028cdba56aae7b2850247304402200df81ade9e3ed8343c4ef75a3ec32455436fb9e0a511ff1e63447753f320db9a022064155850471cf0a5d50d684dd82144094ef11dbba0988bc34809237a8d6eb9f7012102ab2d3112dfb83d7e08949ec32128e24a4be5c588640eee5028cdba56aae7b28500000000"},{"txid":"d71c47c7958f9867c0949bb3f8b66947b4fc117451e370dfa37ef5f94e95cc16","version":1,"vin":[{"txid":"27f1d526c40a097672571f9ce9eeb2b43c5f08ba5196cf452f023bd4ddde0c55","vout":1,"n":0,"addresses":["grs1qa8pvadg835vy798nr3ktrvlkx07mggu4hqvv04"],"isAddress":true,"value":"4439929419"}],"vout":[{"value":"2000000000","n":0,"spent":true,"hex":"76a914bc3b34231b16f2af9d41c100ab833510c1d81b0988ac","addresses":["FnKzQWuu8zcL3u6hEuNZDsjBpgfDMhMhE1"],"isAddress":true},{"value":"2439909419","n":1,"spent":true,"hex":"0014e9c2ceb5078d184f14f31c6cb1b3f633fdb42395","addresses":["grs1qa8pvadg835vy798nr3ktrvlkx07mggu4hqvv04"],"isAddress":true}],"blockHash":"000000000000069196de5fb7d848deb7e9a9ee8586a889e262e8e5444d0883ac","blockHeight":2960855,"confirmations":136171,"blockTime":1581480399,"value":"4439909419","valueIn":"4439929419","fees":"20000","hex":"01000000000101550cdeddd43b022f45cf9651ba085f3cb4b2eee99c1f577276090ac426d5f1270100000000000000000200943577000000001976a914bc3b34231b16f2af9d41c100ab833510c1d81b0988ac2b106e9100000000160014e9c2ceb5078d184f14f31c6cb1b3f633fdb423950247304402206c50a3677f4fad4d721b869117581b4e1cf9534182efba30c17c7b1a6a9af52b022059d3a78a653d0479983287d679ce09f29aeef97cfe7e4b3a4f80cb4f9e2a4614012102ab2d3112dfb83d7e08949ec32128e24a4be5c588640eee5028cdba56aae7b28500000000"},{"txid":"027f784db0849c599b411e8690f257bc3feb23272ffe709c7d486626c4872955","version":1,"vin":[{"txid":"d71c47c7958f9867c0949bb3f8b66947b4fc117451e370dfa37ef5f94e95cc16","vout":1,"n":0,"addresses":["grs1qa8pvadg835vy798nr3ktrvlkx07mggu4hqvv04"],"isAddress":true,"value":"2439909419"}],"vout":[{"value":"2000000000","n":0,"spent":true,"hex":"76a914bc3b34231b16f2af9d41c100ab833510c1d81b0988ac","addresses":["FnKzQWuu8zcL3u6hEuNZDsjBpgfDMhMhE1"],"isAddress":true},{"value":"439889419","n":1,"spent":true,"hex":"0014e9c2ceb5078d184f14f31c6cb1b3f633fdb42395","addresses":["grs1qa8pvadg835vy798nr3ktrvlkx07mggu4hqvv04"],"isAddress":true}],"blockHash":"000000000000069196de5fb7d848deb7e9a9ee8586a889e262e8e5444d0883ac","blockHeight":2960855,"confirmations":136171,"blockTime":1581480399,"value":"2439889419","valueIn":"2439909419","fees":"20000","hex":"0100000000010116cc954ef9f57ea3df70e3517411fcb44769b6f8b39b94c067988f95c7471cd70100000000000000000200943577000000001976a914bc3b34231b16f2af9d41c100ab833510c1d81b0988ac0b2e381a00000000160014e9c2ceb5078d184f14f31c6cb1b3f633fdb42395024830450221009dd13372c1929d9d50d89297dd1ffb0887031186b68d353e6b5a1de60e4d1f29022033fa7956567456ebf1f32b4a2fb80e138b9052718d3250d54a95b79d196edafc012102ab2d3112dfb83d7e08949ec32128e24a4be5c588640eee5028cdba56aae7b28500000000"},{"txid":"568acc4f54ce8eb03e09ccc16dbeee2b882f6ed620d565708133f71e0e163b60","version":1,"vin":[{"txid":"cfc8d72bc809328f6008b20e2aaa8409ad81c2f313ceb02b04c66af7ea76205b","vout":1,"n":0,"addresses":["grs1qa8pvadg835vy798nr3ktrvlkx07mggu4hqvv04"],"isAddress":true,"value":"1145494926"}],"vout":[{"value":"1000000000","n":0,"spent":true,"hex":"76a914bc3b34231b16f2af9d41c100ab833510c1d81b0988ac","addresses":["FnKzQWuu8zcL3u6hEuNZDsjBpgfDMhMhE1"],"isAddress":true},{"value":"145474926","n":1,"spent":true,"hex":"0014e9c2ceb5078d184f14f31c6cb1b3f633fdb42395","addresses":["grs1qa8pvadg835vy798nr3ktrvlkx07mggu4hqvv04"],"isAddress":true}],"blockHash":"000000000000069196de5fb7d848deb7e9a9ee8586a889e262e8e5444d0883ac","blockHeight":2960855,"confirmations":136171,"blockTime":1581480399,"value":"1145474926","valueIn":"1145494926","fees":"20000","hex":"010000000001015b2076eaf76ac6042bb0ce13f3c281ad0984aa2a0eb208608f3209c82bd7c8cf0100000000000000000200ca9a3b000000001976a914bc3b34231b16f2af9d41c100ab833510c1d81b0988ac6ec5ab0800000000160014e9c2ceb5078d184f14f31c6cb1b3f633fdb42395024730440220213d174a1ab818d62200684247f26a66714134079efa421125203ae5687138bf02206f0639a2f441edbfd69384cefa4c9fa196a4a401880a5cfc48cf6ba3589e8a86012102ab2d3112dfb83d7e08949ec32128e24a4be5c588640eee5028cdba56aae7b28500000000"},{"txid":"2afd7b893fade931618b5a20a5879970af9ece772f463227e09d555505f778e4","version":1,"vin":[{"txid":"1a836aa25b8939c36df133f50104cbc6e00f91f0a6b02fd2951ad1a7260615f8","vout":1,"n":0,"addresses":["grs1qny6hgcxsw2lcm8g5prsuamytkehhv0m7gtktws"],"isAddress":true,"value":"180000"}],"vout":[{"value":"100000","n":0,"spent":true,"hex":"0014e9c2ceb5078d184f14f31c6cb1b3f633fdb42395","addresses":["grs1qa8pvadg835vy798nr3ktrvlkx07mggu4hqvv04"],"isAddress":true},{"value":"60000","n":1,"spent":true,"hex":"0014e9c2ceb5078d184f14f31c6cb1b3f633fdb42395","addresses":["grs1qa8pvadg835vy798nr3ktrvlkx07mggu4hqvv04"],"isAddress":true}],"blockHash":"00000000000006e959edec52f260e1c6c58930c96282b94ded283f9dda1973c5","blockHeight":2953512,"confirmations":143514,"blockTime":1581017188,"value":"160000","valueIn":"180000","fees":"20000","hex":"01000000000101f8150626a7d11a95d22fb0a6f0910fe0c6cb0401f533f16dc339895ba26a831a01000000000000000002a086010000000000160014e9c2ceb5078d184f14f31c6cb1b3f633fdb4239560ea000000000000160014e9c2ceb5078d184f14f31c6cb1b3f633fdb4239502483045022100fb5c6e06ec96646aba0ee19bedf98952ed5ae7145711258a3fd451dbfbdbbc5d022053660e9551f8deacd47fbaf5d688cad27f8400fc30bb28365f529c5939d749150121022ac3ed710b6ef6559923fa37dc128cfa6956fe307e55ed6620b8e600c1f3e7a200000000"}],"usedTokens":79,"tokens":[{"type":"XPUBAddress","name":"grs1qa8pvadg835vy798nr3ktrvlkx07mggu4hqvv04","path":"m/84'/17'/0'/0/0","transfers":53,"decimals":8,"balance":"412844353","totalReceived":"34760610350","totalSent":"34347765997"}]} diff --git a/mock/ext-api-data/harmony-api.json b/mock/ext-api-data/harmony-api.json new file mode 100644 index 000000000..edc740137 --- /dev/null +++ b/mock/ext-api-data/harmony-api.json @@ -0,0 +1,84 @@ +{ + "jsonrpc": "2.0", + "id": 1, + "result": { + "transactions": [ + { + "blockHash": "0xe6e65f0f9f1e694d93012f1f2b4713cdd253cc6a15e729ff6df23a78d7694013", + "blockNumber": "0x1b2cd7", + "from": "one1syjs6cnfwd9fgrhng03dyzs07suwtywwreczmk", + "timestamp": "0x5df7cb24", + "gas": "0x33450", + "gasPrice": "0x3b9aca00", + "hash": "0x391af85c5e25ee96cbbc417121b6bacc0ed466c0423467354192c075444e7603", + "input": "0x", + "nonce": "0x1f", + "to": "one1e4mr7tp0a76wnhv9xd0wzentdjnjnsh3fwzgfv", + "transactionIndex": "0x0", + "value": "0x1bc0ae68df60e000", + "shardID": 0, + "toShardID": 0, + "v": "0x25", + "r": "0xb65b59fd1c9733977b0689e07a1869713ae2b2f8eabecee0a426c3f7fe62ac6b", + "s": "0x52b5be00be05173d89ffbf82a47b03f50268e6fe1ccd36a3fa7123a5255d2be2" + }, + { + "blockHash": "0x1b45da220f94f41bd42dc0eb89a5e83ce77b37cc78dbc9032bd10a5bbab13674", + "blockNumber": "0x1b2cdb", + "from": "one1e4mr7tp0a76wnhv9xd0wzentdjnjnsh3fwzgfv", + "timestamp": "0x5df7cb45", + "gas": "0x33450", + "gasPrice": "0x3b9aca00", + "hash": "0x6bfd003239bf137855342f6266c456ae1b342e886bd1965a47edd4c74dd1a687", + "input": "0x", + "nonce": "0x0", + "to": "one1syjs6cnfwd9fgrhng03dyzs07suwtywwreczmk", + "transactionIndex": "0x0", + "value": "0x1bbfef6a6ff9c000", + "shardID": 0, + "toShardID": 0, + "v": "0x26", + "r": "0x44c2a7b8c38612a3ce8b51967947c0c9756dda8d82d0f12137451ce33bbef390", + "s": "0x34234c6c26fe36bda246db845692fd248cb4060cda0d1c6056298b39486ed4f2" + }, + { + "blockHash": "0x58cc90d1b9302d0121b426f5fd35014acbc009defe36c5bbff6ac920d6005526", + "blockNumber": "0x1b2cf2", + "from": "one1syjs6cnfwd9fgrhng03dyzs07suwtywwreczmk", + "timestamp": "0x5df7cc02", + "gas": "0x33450", + "gasPrice": "0x3b9aca00", + "hash": "0xf54f6f86df1624f38fcedf56eb248854a13a733e0b0f92d4b31b9cc7196d90b0", + "input": "0x", + "nonce": "0x20", + "to": "one1e4mr7tp0a76wnhv9xd0wzentdjnjnsh3fwzgfv", + "transactionIndex": "0x0", + "value": "0x1bc0ae68df60e000", + "shardID": 0, + "toShardID": 0, + "v": "0x25", + "r": "0x46d14df06948f055e519ac244bcaaa3c3446ed20671d41db01546ddaad32503b", + "s": "0x50d13aeb94f2e8c760723afa4d892f3ca17690451a57465ea7e39c5d347efe8" + }, + { + "blockHash": "0xa84376f0f4d082b76355ccc6ec491660c0062d9ef3f39985ca00986e8dcbacc1", + "blockNumber": "0x1b2d1b", + "from": "one1e4mr7tp0a76wnhv9xd0wzentdjnjnsh3fwzgfv", + "timestamp": "0x5df7cd50", + "gas": "0x33450", + "gasPrice": "0x3b9aca00", + "hash": "0x73355f625d0f7ef31512657c0f669e710c8c91a67180cd28bc919cfca0a2af82", + "input": "0x", + "nonce": "0x1", + "to": "one1syjs6cnfwd9fgrhng03dyzs07suwtywwreczmk", + "transactionIndex": "0x0", + "value": "0x1bc09b4f6dd69000", + "shardID": 0, + "toShardID": 0, + "v": "0x26", + "r": "0xf31271b93e446bce8cc83eb997183146b4da2378a5f2cb1fc4ae64fbd65a93f5", + "s": "0x77e8e5693a87394204f96693a15f2157459b0329a2ddab97da0bf1cfb6fbce8c" + } + ] + } +} diff --git a/mock/ext-api-data/harmony-api.request_json b/mock/ext-api-data/harmony-api.request_json new file mode 100644 index 000000000..8349619a5 --- /dev/null +++ b/mock/ext-api-data/harmony-api.request_json @@ -0,0 +1,11 @@ +{ + "jsonrpc": "2.0", + "method": "hmy_getTransactionsHistory", + "params": [ + { + "address": "one1e4mr7tp0a76wnhv9xd0wzentdjnjnsh3fwzgfv", + "fullTx": true + } + ], + "id": 1 +} \ No newline at end of file diff --git a/mock/ext-api-data/icon-api_address_txList__address_hxee691e7bccc4eb11fee922896e9f51490e62b12e_count_25.json b/mock/ext-api-data/icon-api_address_txList__address_hxee691e7bccc4eb11fee922896e9f51490e62b12e_count_25.json new file mode 100644 index 000000000..05e09038d --- /dev/null +++ b/mock/ext-api-data/icon-api_address_txList__address_hxee691e7bccc4eb11fee922896e9f51490e62b12e_count_25.json @@ -0,0 +1,53 @@ +{ + "data": [ + { + "txHash": "0x3b1a382884091e683350d6285d908406c149a030a7d52eb347f4571c1c904382", + "height": 7044559, + "createDate": "2019-08-13T06:53:56.000+0000", + "fromAddr": "hxee691e7bccc4eb11fee922896e9f51490e62b12e", + "toAddr": "hx06d5b88bb7089033a2d8a2b61b8a305ecff8774f", + "txType": "0", + "dataType": "icx", + "amount": "0.498", + "fee": "0.001", + "state": 1, + "errorMsg": null, + "targetContractAddr": null, + "id": null + }, + { + "txHash": "0x990b7f289aa465369e638b4f719c99f0d050f9756c19081ba86b2bae5b8e2f0d", + "height": 361987, + "createDate": "2019-04-17T01:16:02.000+0000", + "fromAddr": "hxee691e7bccc4eb11fee922896e9f51490e62b12e", + "toAddr": "hxee691e7bccc4eb11fee922896e9f51490e62b12e", + "txType": "0", + "dataType": "icx", + "amount": "0.00347", + "fee": "0.001", + "state": 1, + "errorMsg": null, + "targetContractAddr": null, + "id": null + }, + { + "txHash": "0x3a455daca1f5e4588adbc6ac5cdfd84126d0617d3ebcf5610eb44b15dfc71402", + "height": 112100, + "createDate": "2018-11-23T21:52:15.000+0000", + "fromAddr": "hx3709f4e615f072158247ca4973218e1d40e0ea35", + "toAddr": "hxee691e7bccc4eb11fee922896e9f51490e62b12e", + "txType": "0", + "dataType": "icx", + "amount": "0.5", + "fee": "0.001", + "state": 1, + "errorMsg": null, + "targetContractAddr": null, + "id": null + } + ], + "listSize": 3, + "totalSize": 3, + "result": "200", + "description": "success" +} \ No newline at end of file diff --git a/mock/ext-api-data/iotex-api_accounts_io1mwekae7qqwlr23220k5n9z3fmjxz72tuchra3m.json b/mock/ext-api-data/iotex-api_accounts_io1mwekae7qqwlr23220k5n9z3fmjxz72tuchra3m.json new file mode 100644 index 000000000..11b108553 --- /dev/null +++ b/mock/ext-api-data/iotex-api_accounts_io1mwekae7qqwlr23220k5n9z3fmjxz72tuchra3m.json @@ -0,0 +1,9 @@ +{ + "accountMeta": { + "address": "io1mwekae7qqwlr23220k5n9z3fmjxz72tuchra3m", + "balance": "3472246872153132576758722", + "nonce": "628", + "pendingNonce": "629", + "numActions": "730" + } +} \ No newline at end of file diff --git a/mock/ext-api-data/iotex-api_accounts_io1vg808avg2ydye8djl2axmkc9j0xhzu6vdaw6g5.json b/mock/ext-api-data/iotex-api_accounts_io1vg808avg2ydye8djl2axmkc9j0xhzu6vdaw6g5.json new file mode 100644 index 000000000..d4957669a --- /dev/null +++ b/mock/ext-api-data/iotex-api_accounts_io1vg808avg2ydye8djl2axmkc9j0xhzu6vdaw6g5.json @@ -0,0 +1,9 @@ +{ + "accountMeta": { + "address": "io1vg808avg2ydye8djl2axmkc9j0xhzu6vdaw6g5", + "balance": "76393702651088989820", + "nonce": "4", + "pendingNonce": "5", + "numActions": "94" + } +} \ No newline at end of file diff --git a/mock/ext-api-data/iotex-api_actions_addr_io1vg808avg2ydye8djl2axmkc9j0xhzu6vdaw6g5__count_25_start_32.json b/mock/ext-api-data/iotex-api_actions_addr_io1vg808avg2ydye8djl2axmkc9j0xhzu6vdaw6g5__count_25_start_32.json new file mode 100644 index 000000000..3164324d0 --- /dev/null +++ b/mock/ext-api-data/iotex-api_actions_addr_io1vg808avg2ydye8djl2axmkc9j0xhzu6vdaw6g5__count_25_start_32.json @@ -0,0 +1,555 @@ +{ + "total": "25", + "actionInfo": [ + { + "action": { + "core": { + "version": 1, + "nonce": "28462", + "gasLimit": "10000", + "gasPrice": "1000000000000", + "transfer": { + "amount": "1139739152873976225", + "recipient": "io1vg808avg2ydye8djl2axmkc9j0xhzu6vdaw6g5" + } + }, + "senderPubKey": "BOWWJrWizG7CKbZUhT0ljmq6HlTAWzqBeo2mW+rt3HfWvODg1UBWz7U4nzJEo02HybleBQbHOoyehaspU0t7jlQ=", + "signature": "XPR9K36edqdorIp0/cGS8eWhY6i4+NAj0NCFG0VG88UeBpDwNSvljhZn5/MfmaBWRuqhKn/MUtEqUqNPl/OcBQA=" + }, + "actHash": "fb24096a9b1de30d419c3615470e6af0d76767dd5857b30d09be913c349114bb", + "blkHash": "8096fd14b838a82acfc32ac0aa278f75f7c39c748feafd4bfd7f55fbf4563573", + "blkHeight": "3771852", + "sender": "io1ey8s7p7kzu9lh68we7mstmyllaxc6tgwuj2whh", + "gasFee": "10000000000000000", + "timestamp": "2020-03-12T22:58:30Z" + }, + { + "action": { + "core": { + "version": 1, + "nonce": "29979", + "gasLimit": "10000", + "gasPrice": "1000000000000", + "transfer": { + "amount": "1111805680886352291", + "recipient": "io1vg808avg2ydye8djl2axmkc9j0xhzu6vdaw6g5" + } + }, + "senderPubKey": "BOWWJrWizG7CKbZUhT0ljmq6HlTAWzqBeo2mW+rt3HfWvODg1UBWz7U4nzJEo02HybleBQbHOoyehaspU0t7jlQ=", + "signature": "8e5VPalYrJEOcW0G0Hg+xNRKieUb14A7fikf+kmG3pUVfrGXCrfHb3dQlim5+3INi+mVIupWCz9lair8dn+AcwA=" + }, + "actHash": "fda766a321e525d1e444585ba9646f939660e8ecdd1b02e09830efad4f29b0fa", + "blkHash": "8c4d6bd99536567dfea8270a4cc44f969c3ab0cd0193489c2379f4f765b32e71", + "blkHeight": "3789752", + "sender": "io1ey8s7p7kzu9lh68we7mstmyllaxc6tgwuj2whh", + "gasFee": "10000000000000000", + "timestamp": "2020-03-13T23:50:15Z" + }, + { + "action": { + "core": { + "version": 1, + "nonce": "30824", + "gasLimit": "10000", + "gasPrice": "1000000000000", + "transfer": { + "amount": "1131271796026741329", + "recipient": "io1vg808avg2ydye8djl2axmkc9j0xhzu6vdaw6g5" + } + }, + "senderPubKey": "BOWWJrWizG7CKbZUhT0ljmq6HlTAWzqBeo2mW+rt3HfWvODg1UBWz7U4nzJEo02HybleBQbHOoyehaspU0t7jlQ=", + "signature": "amZfy8FnWCixh1DCZTJY956dLpw6dFj5zqS3pUexVtA2excq1eJ/hMVTmfUqa0et+2CRR4/56trgiy1Wsg2sIQE=" + }, + "actHash": "40fe7c8fa7f1a21e9c1b2808440b7b32e2da6eda591bba251cf5ffb9072c9fc4", + "blkHash": "edea990dff3e2937d0e2a1e8039b10211a4be71672d6f264fd798b2eb8ffb545", + "blkHeight": "3807009", + "sender": "io1ey8s7p7kzu9lh68we7mstmyllaxc6tgwuj2whh", + "gasFee": "10000000000000000", + "timestamp": "2020-03-14T23:48:50Z" + }, + { + "action": { + "core": { + "version": 1, + "nonce": "32045", + "gasLimit": "10000", + "gasPrice": "1000000000000", + "transfer": { + "amount": "1204451131406840247", + "recipient": "io1vg808avg2ydye8djl2axmkc9j0xhzu6vdaw6g5" + } + }, + "senderPubKey": "BOWWJrWizG7CKbZUhT0ljmq6HlTAWzqBeo2mW+rt3HfWvODg1UBWz7U4nzJEo02HybleBQbHOoyehaspU0t7jlQ=", + "signature": "Y+Dd+Day889zF+6OYLAa+2VXF9WsvvOh/UYZ/4MKsB46RXJjpBHXaq3vq+UH8gLj52h9O90iKegxY/9q/rB97AA=" + }, + "actHash": "d7adb924e0045eafc83849c5d3f5f0611e91ea220c4db5e78e5d4e9947e3f264", + "blkHash": "dfeea435007456c242acc73370ffb79d86a832ecc10b6edc739ad6abd3cc72d5", + "blkHeight": "3846116", + "sender": "io1ey8s7p7kzu9lh68we7mstmyllaxc6tgwuj2whh", + "gasFee": "10000000000000000", + "timestamp": "2020-03-17T06:08:40Z" + }, + { + "action": { + "core": { + "version": 1, + "nonce": "32651", + "gasLimit": "10000", + "gasPrice": "1000000000000", + "transfer": { + "amount": "1119197072222693878", + "recipient": "io1vg808avg2ydye8djl2axmkc9j0xhzu6vdaw6g5" + } + }, + "senderPubKey": "BOWWJrWizG7CKbZUhT0ljmq6HlTAWzqBeo2mW+rt3HfWvODg1UBWz7U4nzJEo02HybleBQbHOoyehaspU0t7jlQ=", + "signature": "bc/6E7HvxFWAQkkYsh/fajg4w2eCxg5KxvjFQy/u43p6Fw+N7eIF3XGfYIjMH6O5hvC3QWtLjO0+QmdbpaKI1QE=" + }, + "actHash": "8f40e5e4c9fb4e8e29505a8d0db6428f3d372109c1a96c807d120ae9fe84ff9e", + "blkHash": "d7351f1ebef30a156c7a015f8e22861d792919b31aa21b0fca2094fa6f9df3c9", + "blkHeight": "3847025", + "sender": "io1ey8s7p7kzu9lh68we7mstmyllaxc6tgwuj2whh", + "gasFee": "10000000000000000", + "timestamp": "2020-03-17T07:24:25Z" + }, + { + "action": { + "core": { + "version": 1, + "nonce": "33170", + "gasLimit": "10000", + "gasPrice": "1000000000000", + "transfer": { + "amount": "616085709830862489", + "recipient": "io1vg808avg2ydye8djl2axmkc9j0xhzu6vdaw6g5" + } + }, + "senderPubKey": "BOWWJrWizG7CKbZUhT0ljmq6HlTAWzqBeo2mW+rt3HfWvODg1UBWz7U4nzJEo02HybleBQbHOoyehaspU0t7jlQ=", + "signature": "ghjLaSWIXzYXcnLm3R5xDX2TXbOMytdnoDoCJR2YYtRGq/U47v9zNIekPEOiuAr50958KqB9Jnxx+5eiitrdkgE=" + }, + "actHash": "b95d7eee5c4be3c3adc1b77dec67703217abc12859058ece4cbc6d0fac67e279", + "blkHash": "b9206c4013cbb5b4b5ca1c4252172762d888cad9d89e2a129c1f3a0851b94069", + "blkHeight": "3857939", + "sender": "io1ey8s7p7kzu9lh68we7mstmyllaxc6tgwuj2whh", + "gasFee": "10000000000000000", + "timestamp": "2020-03-17T22:34:05Z" + }, + { + "action": { + "core": { + "version": 1, + "nonce": "34930", + "gasLimit": "10000", + "gasPrice": "1000000000000", + "transfer": { + "amount": "1137180233280393945", + "recipient": "io1vg808avg2ydye8djl2axmkc9j0xhzu6vdaw6g5" + } + }, + "senderPubKey": "BOWWJrWizG7CKbZUhT0ljmq6HlTAWzqBeo2mW+rt3HfWvODg1UBWz7U4nzJEo02HybleBQbHOoyehaspU0t7jlQ=", + "signature": "jAeGulwT5pdSDbvAorEGaWwPMt8TQ7JqphRp8b83lfBeq2AzzC2BjnNnAt1KdOtTCi7tdP0FmwJcd2IDWvK86gA=" + }, + "actHash": "2ed4f066b1ac98e77e28d76c3a7b589d32fdd7170dff93c936ff06964a7e8364", + "blkHash": "51152bc5405b015eb7d546731800edde5cd1b9d6196fe220a1daee0fdeefb816", + "blkHeight": "3876469", + "sender": "io1ey8s7p7kzu9lh68we7mstmyllaxc6tgwuj2whh", + "gasFee": "10000000000000000", + "timestamp": "2020-03-19T00:18:35Z" + }, + { + "action": { + "core": { + "version": 1, + "nonce": "35808", + "gasLimit": "10000", + "gasPrice": "1000000000000", + "transfer": { + "amount": "1129516449938091591", + "recipient": "io1vg808avg2ydye8djl2axmkc9j0xhzu6vdaw6g5" + } + }, + "senderPubKey": "BOWWJrWizG7CKbZUhT0ljmq6HlTAWzqBeo2mW+rt3HfWvODg1UBWz7U4nzJEo02HybleBQbHOoyehaspU0t7jlQ=", + "signature": "S1JgjE+sUau9F3pCSqBQFEdld6JgyhHnpTS7MT7VfY8vChkzR64MOp0piTeG5LypwU085omb68cqWiZ4w7rZqwE=" + }, + "actHash": "924c7d38a8b7ea1790190a6c3251b8822a7d879f3dc7858b7d5146cbfa28d94b", + "blkHash": "a7875facf7db064acf5b2f40cc00c99f53a0abe1b46bead7d419fdaf952e09d1", + "blkHeight": "3893406", + "sender": "io1ey8s7p7kzu9lh68we7mstmyllaxc6tgwuj2whh", + "gasFee": "10000000000000000", + "timestamp": "2020-03-19T23:50:35Z" + }, + { + "action": { + "core": { + "version": 1, + "nonce": "36585", + "gasLimit": "10000", + "gasPrice": "1000000000000", + "transfer": { + "amount": "1181978062448451578", + "recipient": "io1vg808avg2ydye8djl2axmkc9j0xhzu6vdaw6g5" + } + }, + "senderPubKey": "BOWWJrWizG7CKbZUhT0ljmq6HlTAWzqBeo2mW+rt3HfWvODg1UBWz7U4nzJEo02HybleBQbHOoyehaspU0t7jlQ=", + "signature": "V1ukS9nGBatNPtFmhqwYZ58zJfZlr2My41OWMOEY2TsdTiFM2vn6U6dUOzP2Q87XK+POImXo1WuFPQKEVBESiwA=" + }, + "actHash": "d9dd50577c9ec22fad396994b6f568129304777b297cd38360a85c9100f89f04", + "blkHash": "94a0ee3e2d1acdc1da30a8a60ab13e926424dfabb5774cbe93ba13fd950ae9b1", + "blkHeight": "3910443", + "sender": "io1ey8s7p7kzu9lh68we7mstmyllaxc6tgwuj2whh", + "gasFee": "10000000000000000", + "timestamp": "2020-03-20T23:31:40Z" + }, + { + "action": { + "core": { + "version": 1, + "nonce": "37104", + "gasLimit": "10000", + "gasPrice": "1000000000000", + "transfer": { + "amount": "1137074169236917509", + "recipient": "io1vg808avg2ydye8djl2axmkc9j0xhzu6vdaw6g5" + } + }, + "senderPubKey": "BOWWJrWizG7CKbZUhT0ljmq6HlTAWzqBeo2mW+rt3HfWvODg1UBWz7U4nzJEo02HybleBQbHOoyehaspU0t7jlQ=", + "signature": "JveynAk719BtUVoD0qkrhU6yHnWLrxccJ8fJLjQCV1sI0x+mXGBtUo+VnsETNcaGgS3ZVXZ+/yljH207zZAUHAE=" + }, + "actHash": "c6d0c7635f572a6347f8af2e222ae390a1004c8781f0e86604d5f1b72d0fb08e", + "blkHash": "ec168e8daf8f8f2c069a574dfc14b5b35445e357a4cb2cd290f11c050c052d14", + "blkHeight": "3927027", + "sender": "io1ey8s7p7kzu9lh68we7mstmyllaxc6tgwuj2whh", + "gasFee": "10000000000000000", + "timestamp": "2020-03-21T22:34:45Z" + }, + { + "action": { + "core": { + "version": 1, + "nonce": "37961", + "gasLimit": "10000", + "gasPrice": "1000000000000", + "transfer": { + "amount": "1184316808242241414", + "recipient": "io1vg808avg2ydye8djl2axmkc9j0xhzu6vdaw6g5" + } + }, + "senderPubKey": "BOWWJrWizG7CKbZUhT0ljmq6HlTAWzqBeo2mW+rt3HfWvODg1UBWz7U4nzJEo02HybleBQbHOoyehaspU0t7jlQ=", + "signature": "vszB/AhgC+dDP/9O9W/sa/lRciYA5QEEwBvCH/1K22MNpfxSnBc/RFBQCUkwNZbWGReTwa8u1c0ZHJtM9mvRjAA=" + }, + "actHash": "b8da1695e9b29536e41020c38b9169aaf41044f537f237a77d9eea2112db1537", + "blkHash": "73af0b36b966992833e314d5e4956beb5252572b24093a54eea789d109aa1560", + "blkHeight": "3944042", + "sender": "io1ey8s7p7kzu9lh68we7mstmyllaxc6tgwuj2whh", + "gasFee": "10000000000000000", + "timestamp": "2020-03-22T22:12:45Z" + }, + { + "action": { + "core": { + "version": 1, + "nonce": "39144", + "gasLimit": "10000", + "gasPrice": "1000000000000", + "transfer": { + "amount": "1185206155867839721", + "recipient": "io1vg808avg2ydye8djl2axmkc9j0xhzu6vdaw6g5" + } + }, + "senderPubKey": "BOWWJrWizG7CKbZUhT0ljmq6HlTAWzqBeo2mW+rt3HfWvODg1UBWz7U4nzJEo02HybleBQbHOoyehaspU0t7jlQ=", + "signature": "wiaaZGhWP7shWeJ+jAZ0LJQ02Iqu3HpwD5l2ZUD/XgE5h9nzSJ01jeBmg0/eJfl1CSwBgjzbHuitSFQr8qkOAAA=" + }, + "actHash": "b551f9345b9ec7ab60a9cfdeba7f425c039d29b29ca85cdcccc76a258416943d", + "blkHash": "c038f79c56de675a6e73166f66c28e97077d32a3a20602558ebbe8b0bdf56c46", + "blkHeight": "3961739", + "sender": "io1ey8s7p7kzu9lh68we7mstmyllaxc6tgwuj2whh", + "gasFee": "10000000000000000", + "timestamp": "2020-03-23T22:47:55Z" + }, + { + "action": { + "core": { + "version": 1, + "nonce": "40067", + "gasLimit": "10000", + "gasPrice": "1000000000000", + "transfer": { + "amount": "1120195881668261370", + "recipient": "io1vg808avg2ydye8djl2axmkc9j0xhzu6vdaw6g5" + } + }, + "senderPubKey": "BOWWJrWizG7CKbZUhT0ljmq6HlTAWzqBeo2mW+rt3HfWvODg1UBWz7U4nzJEo02HybleBQbHOoyehaspU0t7jlQ=", + "signature": "eXBaTtXM94uKCfWFP4UMBMs7lQJx9cChvekJvF1GprtYwpuFUAYnOOw3zL8CNkIcYeu1vvFP7bKqcVWjvpq1AQA=" + }, + "actHash": "91ee5311e8b925d6b4f9990661b6346fff7621bb232f1bd57cf0865c6ec13f6a", + "blkHash": "508e96f8c8ad396492e8faee556ebda56934ca88d632b16fe70de1798dbfc992", + "blkHeight": "3978946", + "sender": "io1ey8s7p7kzu9lh68we7mstmyllaxc6tgwuj2whh", + "gasFee": "10000000000000000", + "timestamp": "2020-03-24T22:44:50Z" + }, + { + "action": { + "core": { + "version": 1, + "nonce": "40896", + "gasLimit": "10000", + "gasPrice": "1000000000000", + "transfer": { + "amount": "1149507256400194232", + "recipient": "io1vg808avg2ydye8djl2axmkc9j0xhzu6vdaw6g5" + } + }, + "senderPubKey": "BOWWJrWizG7CKbZUhT0ljmq6HlTAWzqBeo2mW+rt3HfWvODg1UBWz7U4nzJEo02HybleBQbHOoyehaspU0t7jlQ=", + "signature": "SeUHtmepKY7XqgNFgRsddSSDhl9hq1jEWprsD5RAfCJcCG4jDyhFfD1fSshq+3aXa4WsSzQL5VvEu9NNLX3JoAA=" + }, + "actHash": "16e4073278e504e531f7e27aa37debe0ace0319e7f8c7a1f1ae58fcb1f9c232e", + "blkHash": "18248815cfca2256d8dd3a71f2ee621a6ce53a509743f9aa0915d9f57068d4dd", + "blkHeight": "3995866", + "sender": "io1ey8s7p7kzu9lh68we7mstmyllaxc6tgwuj2whh", + "gasFee": "10000000000000000", + "timestamp": "2020-03-25T22:14:55Z" + }, + { + "action": { + "core": { + "version": 1, + "nonce": "42361", + "gasLimit": "10000", + "gasPrice": "1000000000000", + "transfer": { + "amount": "1178751709816943912", + "recipient": "io1vg808avg2ydye8djl2axmkc9j0xhzu6vdaw6g5" + } + }, + "senderPubKey": "BOWWJrWizG7CKbZUhT0ljmq6HlTAWzqBeo2mW+rt3HfWvODg1UBWz7U4nzJEo02HybleBQbHOoyehaspU0t7jlQ=", + "signature": "ItkmQLsdpbIh8l61Sv0dsIknSYEaNUH9MMGi3z1RPYBcskdqtUl+uA4exeGqmBPcB14KRpHxS0vn/ylv3rZElwE=" + }, + "actHash": "b926eb0785f51009d56994f420384239b906063709e6f28135fe87f8f6fa8eed", + "blkHash": "a687e5949c3fe7dadaed819108c4d6f88272a2bef43f6577407950d64b97bf95", + "blkHeight": "4014008", + "sender": "io1ey8s7p7kzu9lh68we7mstmyllaxc6tgwuj2whh", + "gasFee": "10000000000000000", + "timestamp": "2020-03-26T23:27:30Z" + }, + { + "action": { + "core": { + "version": 1, + "nonce": "43185", + "gasLimit": "10000", + "gasPrice": "1000000000000", + "transfer": { + "amount": "1163519091815786084", + "recipient": "io1vg808avg2ydye8djl2axmkc9j0xhzu6vdaw6g5" + } + }, + "senderPubKey": "BOWWJrWizG7CKbZUhT0ljmq6HlTAWzqBeo2mW+rt3HfWvODg1UBWz7U4nzJEo02HybleBQbHOoyehaspU0t7jlQ=", + "signature": "o8AKMh3tfGTVejJZEHgl1ru1NBGX58l3enO+Hgpfv4s//kMJJDXWmZPKyFkNPAi0pRUoDCcfhfgu3CQ5E+FqgwA=" + }, + "actHash": "b300484bf548132f8764faa7226cf834a9771b0bd3903815690c2fb4f57e6d70", + "blkHash": "be5f08a2d21fce143ebc54df600318c82ba0f0444395c47d9dc8148fc37bf17e", + "blkHeight": "4030942", + "sender": "io1ey8s7p7kzu9lh68we7mstmyllaxc6tgwuj2whh", + "gasFee": "10000000000000000", + "timestamp": "2020-03-27T22:58:40Z" + }, + { + "action": { + "core": { + "version": 1, + "nonce": "44643", + "gasLimit": "10000", + "gasPrice": "1000000000000", + "transfer": { + "amount": "1187241207292272207", + "recipient": "io1vg808avg2ydye8djl2axmkc9j0xhzu6vdaw6g5" + } + }, + "senderPubKey": "BOWWJrWizG7CKbZUhT0ljmq6HlTAWzqBeo2mW+rt3HfWvODg1UBWz7U4nzJEo02HybleBQbHOoyehaspU0t7jlQ=", + "signature": "a/ZabeQVo+q8OH62WT05wK6NrQ1foJ8MdIphfKZ16EEFHKw1/ORchlKnC45WQMdEptoQpgjBmlwNAshtWQ1YyQA=" + }, + "actHash": "43d787886c81368185300c3dbe6d230622f3a4fec0cf5c890264fcd8b8ccd451", + "blkHash": "b2fefb3f4999cc49ed939cc874910eb5e99444119bc05e7455d793f128b45bb6", + "blkHeight": "4048898", + "sender": "io1ey8s7p7kzu9lh68we7mstmyllaxc6tgwuj2whh", + "gasFee": "10000000000000000", + "timestamp": "2020-03-28T23:55:15Z" + }, + { + "action": { + "core": { + "version": 1, + "nonce": "45616", + "gasLimit": "10000", + "gasPrice": "1000000000000", + "transfer": { + "amount": "1179608785863654375", + "recipient": "io1vg808avg2ydye8djl2axmkc9j0xhzu6vdaw6g5" + } + }, + "senderPubKey": "BOWWJrWizG7CKbZUhT0ljmq6HlTAWzqBeo2mW+rt3HfWvODg1UBWz7U4nzJEo02HybleBQbHOoyehaspU0t7jlQ=", + "signature": "SnPDh1PGnRJRjxPK+VvSjI3X9l4VnSrWW1cT2Q6QyndrrJH5nFbH/lrYLO1billkU44BdB1J4cq4h+8JWUIbjwA=" + }, + "actHash": "f3827899d82f49b41e32eadcd2f5c1c77bd10bbe9426b4aee4108c6b8c6ff44f", + "blkHash": "52591d93ecd21afb578b8288dfbabc95065c58bcbde7f5b5e239c4a3a30e5bff", + "blkHeight": "4066230", + "sender": "io1ey8s7p7kzu9lh68we7mstmyllaxc6tgwuj2whh", + "gasFee": "10000000000000000", + "timestamp": "2020-03-30T00:00:55Z" + }, + { + "action": { + "core": { + "version": 1, + "nonce": "46208", + "gasLimit": "10000", + "gasPrice": "1000000000000", + "transfer": { + "amount": "1216969233453951224", + "recipient": "io1vg808avg2ydye8djl2axmkc9j0xhzu6vdaw6g5" + } + }, + "senderPubKey": "BOWWJrWizG7CKbZUhT0ljmq6HlTAWzqBeo2mW+rt3HfWvODg1UBWz7U4nzJEo02HybleBQbHOoyehaspU0t7jlQ=", + "signature": "cJ4tF0PdchnWFt/1VyRehYCU6//rs0TOvLrWQ/hjZ5FBXk1cslEworPBkDf+Y/Daaa/Kt67x+s19h/sWCOZ9AwE=" + }, + "actHash": "70a3e5d047feb19a6cf6fe5c462b99183e7c302f142496c067d9c8c7f551165d", + "blkHash": "7b20c3973ea91581301617d9e4fb2e2d29bb2907a6c1921f340bec7daf2fd1ed", + "blkHeight": "4082972", + "sender": "io1ey8s7p7kzu9lh68we7mstmyllaxc6tgwuj2whh", + "gasFee": "10000000000000000", + "timestamp": "2020-03-30T23:36:55Z" + }, + { + "action": { + "core": { + "version": 1, + "nonce": "46956", + "gasLimit": "10000", + "gasPrice": "1000000000000", + "transfer": { + "amount": "1137658532468953742", + "recipient": "io1vg808avg2ydye8djl2axmkc9j0xhzu6vdaw6g5" + } + }, + "senderPubKey": "BOWWJrWizG7CKbZUhT0ljmq6HlTAWzqBeo2mW+rt3HfWvODg1UBWz7U4nzJEo02HybleBQbHOoyehaspU0t7jlQ=", + "signature": "04Iz5C2ZEbz5W4XqOVkfd1Iu2L5cCwnNmA6kTgW5Dydj3eE+fUstEhXezFnYm84BKceS4S0IjY/fN2PNBLMCAAA=" + }, + "actHash": "7eb7defd7ca912cce37e164df0e29af7c0bd4a607546404278a48fe670df07f0", + "blkHash": "6d50e2ac079dfa1d30222a823573e6f7c67d159b7f9c67782b9e8db0b06ad74d", + "blkHeight": "4100040", + "sender": "io1ey8s7p7kzu9lh68we7mstmyllaxc6tgwuj2whh", + "gasFee": "10000000000000000", + "timestamp": "2020-03-31T23:33:05Z" + }, + { + "action": { + "core": { + "version": 1, + "nonce": "48530", + "gasLimit": "10000", + "gasPrice": "1000000000000", + "transfer": { + "amount": "1109317313247383997", + "recipient": "io1vg808avg2ydye8djl2axmkc9j0xhzu6vdaw6g5" + } + }, + "senderPubKey": "BOWWJrWizG7CKbZUhT0ljmq6HlTAWzqBeo2mW+rt3HfWvODg1UBWz7U4nzJEo02HybleBQbHOoyehaspU0t7jlQ=", + "signature": "L5vuCdcu7oVBL+bImrmhg6mAV9eB2b8P1Ro/9bUpjppb20cpOgSzex+u7zd9/bQ0y5xfo8Vusd9hGTLf+WyE2wE=" + }, + "actHash": "33adb824f4764c28d0fbc647070c673e56778a4336cb5231b4bafe66a6ca03f3", + "blkHash": "70dee6fa86281e7baa86fb1a122ac248bc9e60a796e05a007b03c8e403cdbd42", + "blkHeight": "4118003", + "sender": "io1ey8s7p7kzu9lh68we7mstmyllaxc6tgwuj2whh", + "gasFee": "10000000000000000", + "timestamp": "2020-04-02T01:17:20Z" + }, + { + "action": { + "core": { + "version": 1, + "nonce": "49203", + "gasLimit": "10000", + "gasPrice": "1000000000000", + "transfer": { + "amount": "1183775597584344784", + "recipient": "io1vg808avg2ydye8djl2axmkc9j0xhzu6vdaw6g5" + } + }, + "senderPubKey": "BOWWJrWizG7CKbZUhT0ljmq6HlTAWzqBeo2mW+rt3HfWvODg1UBWz7U4nzJEo02HybleBQbHOoyehaspU0t7jlQ=", + "signature": "DKT1Z0a5wSbVyCtosj2iLYVAX8bKT+VXnG7KdRaz/M5wgiH0qHB0rPwWBT0Ex6mWfV7TZv4Nk8N+wIXmF8QH1QA=" + }, + "actHash": "46f70a7b86717e4106bed9d87e40e9b34299e8058b4d840ac803ab0d91923025", + "blkHash": "0cb941b6bc328a18eb90c74450b4e5bbf2f3de09b892810118e00caaea48dcbc", + "blkHeight": "4134883", + "sender": "io1ey8s7p7kzu9lh68we7mstmyllaxc6tgwuj2whh", + "gasFee": "10000000000000000", + "timestamp": "2020-04-03T01:25:20Z" + }, + { + "action": { + "core": { + "version": 1, + "nonce": "50571", + "gasLimit": "10000", + "gasPrice": "1000000000000", + "transfer": { + "amount": "1174691181833403746", + "recipient": "io1vg808avg2ydye8djl2axmkc9j0xhzu6vdaw6g5" + } + }, + "senderPubKey": "BOWWJrWizG7CKbZUhT0ljmq6HlTAWzqBeo2mW+rt3HfWvODg1UBWz7U4nzJEo02HybleBQbHOoyehaspU0t7jlQ=", + "signature": "gwOpLdA8bdQ/GiVvW6r9xFCnxbXXcljoIvxfczkTnAIdEEDxWBVTRzU6/PhBsvK2zrciK9Xe6rietJTaKvL2mwA=" + }, + "actHash": "92c16dba51da8ed20f32dbbc2eb9761e02e1fc0b2bd0dc83eeb1060e2ac9b5e9", + "blkHash": "bacf45b2a93a17ff7c11017a218cebbde062167326acc6c7d9cce04838b1835b", + "blkHeight": "4152703", + "sender": "io1ey8s7p7kzu9lh68we7mstmyllaxc6tgwuj2whh", + "gasFee": "10000000000000000", + "timestamp": "2020-04-04T02:17:00Z" + }, + { + "action": { + "core": { + "version": 1, + "nonce": "51520", + "gasLimit": "10000", + "gasPrice": "1000000000000", + "transfer": { + "amount": "1199779673372762660", + "recipient": "io1vg808avg2ydye8djl2axmkc9j0xhzu6vdaw6g5" + } + }, + "senderPubKey": "BOWWJrWizG7CKbZUhT0ljmq6HlTAWzqBeo2mW+rt3HfWvODg1UBWz7U4nzJEo02HybleBQbHOoyehaspU0t7jlQ=", + "signature": "7aGfci1M3b0CfW/WM+amhDG/1CujoHM7Fo5iogUsbhFgs8CKqvLlKBxhnTe8RlTx9vvB7E7GIpZr+nnu7TWCwAA=" + }, + "actHash": "84db1a50fa3245355f2eeba6df65429ae821bb109aa6369ef623e4ddf72a6187", + "blkHash": "449bb470cb5790598c1b62a428d3eb3e3e76498bc2ca313b3753b83f67de39e4", + "blkHeight": "4169897", + "sender": "io1ey8s7p7kzu9lh68we7mstmyllaxc6tgwuj2whh", + "gasFee": "10000000000000000", + "timestamp": "2020-04-05T02:09:55Z" + }, + { + "action": { + "core": { + "version": 1, + "nonce": "51884", + "gasLimit": "10000", + "gasPrice": "1000000000000", + "transfer": { + "amount": "1207553760674973468", + "recipient": "io1vg808avg2ydye8djl2axmkc9j0xhzu6vdaw6g5" + } + }, + "senderPubKey": "BOWWJrWizG7CKbZUhT0ljmq6HlTAWzqBeo2mW+rt3HfWvODg1UBWz7U4nzJEo02HybleBQbHOoyehaspU0t7jlQ=", + "signature": "qVaSqVfZ8jjkhnLJn486b40mzqFSaWZkW861lctzRhhTzZLBTCOaRwaOwzLpjxhluE+EI5BcF9e18pWhwLEb4QA=" + }, + "actHash": "dc0155fbb1936737b39e0c61a29be88dcaad88b765c69a6af34284d83a310c19", + "blkHash": "50e0787868975543d42fb6ac221ab1546b5d0745b8c2fb75d8f60e1ea479b6a1", + "blkHeight": "4186453", + "sender": "io1ey8s7p7kzu9lh68we7mstmyllaxc6tgwuj2whh", + "gasFee": "10000000000000000", + "timestamp": "2020-04-06T01:09:40Z" + } + ] +} \ No newline at end of file diff --git a/mock/ext-api-data/iotex-api_staking_delegations_io1mwekae7qqwlr23220k5n9z3fmjxz72tuchra3m.json b/mock/ext-api-data/iotex-api_staking_delegations_io1mwekae7qqwlr23220k5n9z3fmjxz72tuchra3m.json new file mode 100644 index 000000000..25c2074cd --- /dev/null +++ b/mock/ext-api-data/iotex-api_staking_delegations_io1mwekae7qqwlr23220k5n9z3fmjxz72tuchra3m.json @@ -0,0 +1,23 @@ +[ + { + "delegator": { + "id": "iotxplorerio", + "status": true, + "info": { + "name": "iotxplorer", + "description": "", + "image": "https://imgc.iotex.io/dokc3pa1x/image/upload/v1551121446/delegates/iotxplorer/Group_2.png", + "website": "https://twitter.com/iotxplorer" + }, + "details": { + "reward": { + "annual": 0 + }, + "locktime": 259200, + "minimum_amount": "100000000000000000000" + } + }, + "value": "100000000000000000000", + "status": "active" + } +] \ No newline at end of file diff --git a/mock/ext-api-data/iotex-api_staking_validators__status_bonded.json b/mock/ext-api-data/iotex-api_staking_validators__status_bonded.json new file mode 100644 index 000000000..718af9ac3 --- /dev/null +++ b/mock/ext-api-data/iotex-api_staking_validators__status_bonded.json @@ -0,0 +1,794 @@ +[ + { + "id": "droute", + "status": true, + "details": { + "reward": { + "annual": 0 + }, + "locktime": 259200, + "minimum_amount": "100000000000000000000" + } + }, + { + "id": "longz", + "status": true, + "details": { + "reward": { + "annual": 0 + }, + "locktime": 259200, + "minimum_amount": "100000000000000000000" + } + }, + { + "id": "coredev", + "status": true, + "details": { + "reward": { + "annual": 0 + }, + "locktime": 259200, + "minimum_amount": "100000000000000000000" + } + }, + { + "id": "keys", + "status": true, + "details": { + "reward": { + "annual": 0 + }, + "locktime": 259200, + "minimum_amount": "100000000000000000000" + } + }, + { + "id": "pubxpayments", + "status": true, + "details": { + "reward": { + "annual": 0 + }, + "locktime": 259200, + "minimum_amount": "100000000000000000000" + } + }, + { + "id": "royalland", + "status": true, + "details": { + "reward": { + "annual": 0 + }, + "locktime": 259200, + "minimum_amount": "100000000000000000000" + } + }, + { + "id": "gamefantasy#", + "status": true, + "details": { + "reward": { + "annual": 0 + }, + "locktime": 259200, + "minimum_amount": "100000000000000000000" + } + }, + { + "id": "iosg", + "status": true, + "details": { + "reward": { + "annual": 0 + }, + "locktime": 259200, + "minimum_amount": "100000000000000000000" + } + }, + { + "id": "laomao", + "status": true, + "details": { + "reward": { + "annual": 0 + }, + "locktime": 259200, + "minimum_amount": "100000000000000000000" + } + }, + { + "id": "huobiwallet", + "status": true, + "details": { + "reward": { + "annual": 0 + }, + "locktime": 259200, + "minimum_amount": "100000000000000000000" + } + }, + { + "id": "cpc", + "status": true, + "details": { + "reward": { + "annual": 0 + }, + "locktime": 259200, + "minimum_amount": "100000000000000000000" + } + }, + { + "id": "hashbuy", + "status": true, + "details": { + "reward": { + "annual": 0 + }, + "locktime": 259200, + "minimum_amount": "100000000000000000000" + } + }, + { + "id": "enlightiv", + "status": true, + "details": { + "reward": { + "annual": 0 + }, + "locktime": 259200, + "minimum_amount": "100000000000000000000" + } + }, + { + "id": "metanyx", + "status": true, + "details": { + "reward": { + "annual": 0 + }, + "locktime": 259200, + "minimum_amount": "100000000000000000000" + } + }, + { + "id": "consensusnet", + "status": true, + "details": { + "reward": { + "annual": 0 + }, + "locktime": 259200, + "minimum_amount": "100000000000000000000" + } + }, + { + "id": "airfoil", + "status": true, + "details": { + "reward": { + "annual": 0 + }, + "locktime": 259200, + "minimum_amount": "100000000000000000000" + } + }, + { + "id": "iotexteam", + "status": true, + "details": { + "reward": { + "annual": 0 + }, + "locktime": 259200, + "minimum_amount": "100000000000000000000" + } + }, + { + "id": "capitmu", + "status": true, + "details": { + "reward": { + "annual": 0 + }, + "locktime": 259200, + "minimum_amount": "100000000000000000000" + } + }, + { + "id": "hashquark", + "status": true, + "details": { + "reward": { + "annual": 0 + }, + "locktime": 259200, + "minimum_amount": "100000000000000000000" + } + }, + { + "id": "ducapital", + "status": true, + "details": { + "reward": { + "annual": 0 + }, + "locktime": 259200, + "minimum_amount": "100000000000000000000" + } + }, + { + "id": "iotxplorerio", + "status": true, + "details": { + "reward": { + "annual": 0 + }, + "locktime": 259200, + "minimum_amount": "100000000000000000000" + } + }, + { + "id": "pnp", + "status": true, + "details": { + "reward": { + "annual": 0 + }, + "locktime": 259200, + "minimum_amount": "100000000000000000000" + } + }, + { + "id": "iotexcore", + "status": true, + "details": { + "reward": { + "annual": 0 + }, + "locktime": 259200, + "minimum_amount": "100000000000000000000" + } + }, + { + "id": "hofancrypto", + "status": true, + "details": { + "reward": { + "annual": 0 + }, + "locktime": 259200, + "minimum_amount": "100000000000000000000" + } + }, + { + "id": "draperdragon", + "status": true, + "details": { + "reward": { + "annual": 0 + }, + "locktime": 259200, + "minimum_amount": "100000000000000000000" + } + }, + { + "id": "coingecko", + "status": true, + "details": { + "reward": { + "annual": 0 + }, + "locktime": 259200, + "minimum_amount": "100000000000000000000" + } + }, + { + "id": "satoshi", + "status": true, + "details": { + "reward": { + "annual": 0 + }, + "locktime": 259200, + "minimum_amount": "100000000000000000000" + } + }, + { + "id": "iotexlab", + "status": true, + "details": { + "reward": { + "annual": 0 + }, + "locktime": 259200, + "minimum_amount": "100000000000000000000" + } + }, + { + "id": "mrtrump", + "status": true, + "details": { + "reward": { + "annual": 0 + }, + "locktime": 259200, + "minimum_amount": "100000000000000000000" + } + }, + { + "id": "elitex", + "status": true, + "details": { + "reward": { + "annual": 0 + }, + "locktime": 259200, + "minimum_amount": "100000000000000000000" + } + }, + { + "id": "yvalidator", + "status": true, + "details": { + "reward": { + "annual": 0 + }, + "locktime": 259200, + "minimum_amount": "100000000000000000000" + } + }, + { + "id": "ratels", + "status": true, + "details": { + "reward": { + "annual": 0 + }, + "locktime": 259200, + "minimum_amount": "100000000000000000000" + } + }, + { + "id": "rockx", + "status": true, + "details": { + "reward": { + "annual": 0 + }, + "locktime": 259200, + "minimum_amount": "100000000000000000000" + } + }, + { + "id": "hotbit", + "status": true, + "details": { + "reward": { + "annual": 0 + }, + "locktime": 259200, + "minimum_amount": "100000000000000000000" + } + }, + { + "id": "infstones", + "status": true, + "details": { + "reward": { + "annual": 0 + }, + "locktime": 259200, + "minimum_amount": "100000000000000000000" + } + }, + { + "id": "blockfolio", + "status": true, + "details": { + "reward": { + "annual": 0 + }, + "locktime": 259200, + "minimum_amount": "100000000000000000000" + } + }, + { + "id": "blockboost", + "status": true, + "details": { + "reward": { + "annual": 0 + }, + "locktime": 259200, + "minimum_amount": "100000000000000000000" + } + }, + { + "id": "thebottoken#", + "status": true, + "details": { + "reward": { + "annual": 0 + }, + "locktime": 259200, + "minimum_amount": "100000000000000000000" + } + }, + { + "id": "zhcapital", + "status": true, + "details": { + "reward": { + "annual": 0 + }, + "locktime": 259200, + "minimum_amount": "100000000000000000000" + } + }, + { + "id": "cobo", + "status": true, + "details": { + "reward": { + "annual": 0 + }, + "locktime": 259200, + "minimum_amount": "100000000000000000000" + } + }, + { + "id": "tgb", + "status": true, + "details": { + "reward": { + "annual": 0 + }, + "locktime": 259200, + "minimum_amount": "100000000000000000000" + } + }, + { + "id": "iotask", + "status": true, + "details": { + "reward": { + "annual": 0 + }, + "locktime": 259200, + "minimum_amount": "100000000000000000000" + } + }, + { + "id": "cryptolionsx", + "status": true, + "details": { + "reward": { + "annual": 0 + }, + "locktime": 259200, + "minimum_amount": "100000000000000000000" + } + }, + { + "id": "iotexgeeks", + "status": true, + "details": { + "reward": { + "annual": 0 + }, + "locktime": 259200, + "minimum_amount": "100000000000000000000" + } + }, + { + "id": "bittaker", + "status": true, + "details": { + "reward": { + "annual": 0 + }, + "locktime": 259200, + "minimum_amount": "100000000000000000000" + } + }, + { + "id": "snzholding", + "status": true, + "details": { + "reward": { + "annual": 0 + }, + "locktime": 259200, + "minimum_amount": "100000000000000000000" + } + }, + { + "id": "raketat8", + "status": true, + "details": { + "reward": { + "annual": 0 + }, + "locktime": 259200, + "minimum_amount": "100000000000000000000" + } + }, + { + "id": "wannodes", + "status": true, + "details": { + "reward": { + "annual": 0 + }, + "locktime": 259200, + "minimum_amount": "100000000000000000000" + } + }, + { + "id": "citex2018", + "status": true, + "details": { + "reward": { + "annual": 0 + }, + "locktime": 259200, + "minimum_amount": "100000000000000000000" + } + }, + { + "id": "wetez", + "status": true, + "details": { + "reward": { + "annual": 0 + }, + "locktime": 259200, + "minimum_amount": "100000000000000000000" + } + }, + { + "id": "eon", + "status": true, + "details": { + "reward": { + "annual": 0 + }, + "locktime": 259200, + "minimum_amount": "100000000000000000000" + } + }, + { + "id": "whales", + "status": true, + "details": { + "reward": { + "annual": 0 + }, + "locktime": 259200, + "minimum_amount": "100000000000000000000" + } + }, + { + "id": "iotexunion", + "status": true, + "details": { + "reward": { + "annual": 0 + }, + "locktime": 259200, + "minimum_amount": "100000000000000000000" + } + }, + { + "id": "preangel", + "status": true, + "details": { + "reward": { + "annual": 0 + }, + "locktime": 259200, + "minimum_amount": "100000000000000000000" + } + }, + { + "id": "eatliverun", + "status": true, + "details": { + "reward": { + "annual": 0 + }, + "locktime": 259200, + "minimum_amount": "100000000000000000000" + } + }, + { + "id": "iotexicu", + "status": true, + "details": { + "reward": { + "annual": 0 + }, + "locktime": 259200, + "minimum_amount": "100000000000000000000" + } + }, + { + "id": "matrix", + "status": true, + "details": { + "reward": { + "annual": 0 + }, + "locktime": 259200, + "minimum_amount": "100000000000000000000" + } + }, + { + "id": "everstake", + "status": true, + "details": { + "reward": { + "annual": 0 + }, + "locktime": 259200, + "minimum_amount": "100000000000000000000" + } + }, + { + "id": "nodeasy", + "status": true, + "details": { + "reward": { + "annual": 0 + }, + "locktime": 259200, + "minimum_amount": "100000000000000000000" + } + }, + { + "id": "slowmist", + "status": true, + "details": { + "reward": { + "annual": 0 + }, + "locktime": 259200, + "minimum_amount": "100000000000000000000" + } + }, + { + "id": "alphacoin", + "status": true, + "details": { + "reward": { + "annual": 0 + }, + "locktime": 259200, + "minimum_amount": "100000000000000000000" + } + }, + { + "id": "blackpool", + "status": true, + "details": { + "reward": { + "annual": 0 + }, + "locktime": 259200, + "minimum_amount": "100000000000000000000" + } + }, + { + "id": "link", + "status": true, + "details": { + "reward": { + "annual": 0 + }, + "locktime": 259200, + "minimum_amount": "100000000000000000000" + } + }, + { + "id": "lanhu", + "status": true, + "details": { + "reward": { + "annual": 0 + }, + "locktime": 259200, + "minimum_amount": "100000000000000000000" + } + }, + { + "id": "iotexmainnet", + "status": true, + "details": { + "reward": { + "annual": 0 + }, + "locktime": 259200, + "minimum_amount": "100000000000000000000" + } + }, + { + "id": "meter", + "status": true, + "details": { + "reward": { + "annual": 0 + }, + "locktime": 259200, + "minimum_amount": "100000000000000000000" + } + }, + { + "id": "elink", + "status": true, + "details": { + "reward": { + "annual": 0 + }, + "locktime": 259200, + "minimum_amount": "100000000000000000000" + } + }, + { + "id": "bitwires", + "status": true, + "details": { + "reward": { + "annual": 0 + }, + "locktime": 259200, + "minimum_amount": "100000000000000000000" + } + }, + { + "id": "piexgo", + "status": true, + "details": { + "reward": { + "annual": 0 + }, + "locktime": 259200, + "minimum_amount": "100000000000000000000" + } + }, + { + "id": "iotexhub", + "status": true, + "details": { + "reward": { + "annual": 0 + }, + "locktime": 259200, + "minimum_amount": "100000000000000000000" + } + }, + { + "id": "superiotex", + "status": true, + "details": { + "reward": { + "annual": 0 + }, + "locktime": 259200, + "minimum_amount": "100000000000000000000" + } + }, + { + "id": "iotexbgogo", + "status": true, + "details": { + "reward": { + "annual": 0 + }, + "locktime": 259200, + "minimum_amount": "100000000000000000000" + } + } +] \ No newline at end of file diff --git a/mock/ext-api-data/kava-api_auth_accounts_kava1l8va9zyl50cpzv447c694k3jndelc9ygtfll2m.json b/mock/ext-api-data/kava-api_auth_accounts_kava1l8va9zyl50cpzv447c694k3jndelc9ygtfll2m.json new file mode 100644 index 000000000..a08ebead9 --- /dev/null +++ b/mock/ext-api-data/kava-api_auth_accounts_kava1l8va9zyl50cpzv447c694k3jndelc9ygtfll2m.json @@ -0,0 +1 @@ +{"height":"2283151","result":{"type":"cosmos-sdk/Account","value":{"address":"kava1l8va9zyl50cpzv447c694k3jndelc9ygtfll2m","coins":[],"public_key":{"type":"tendermint/PubKeySecp256k1","value":"AvgGasyPvRpG68UQ6IGPVKN+HrJix24tgwcYXIcIfsna"},"account_number":"284","sequence":"1"}}} \ No newline at end of file diff --git a/mock/ext-api-data/kava-api_minting_inflation.json b/mock/ext-api-data/kava-api_minting_inflation.json new file mode 100644 index 000000000..e3fdddcc3 --- /dev/null +++ b/mock/ext-api-data/kava-api_minting_inflation.json @@ -0,0 +1,4 @@ +{ + "height": "2251949", + "result": "0.058055354540680354" +} \ No newline at end of file diff --git a/mock/ext-api-data/kava-api_staking_delegators_kava1l8va9zyl50cpzv447c694k3jndelc9ygtfll2m_delegations.json b/mock/ext-api-data/kava-api_staking_delegators_kava1l8va9zyl50cpzv447c694k3jndelc9ygtfll2m_delegations.json new file mode 100644 index 000000000..c78a91c88 --- /dev/null +++ b/mock/ext-api-data/kava-api_staking_delegators_kava1l8va9zyl50cpzv447c694k3jndelc9ygtfll2m_delegations.json @@ -0,0 +1,4 @@ +{ + "height": "2251949", + "result": [] +} \ No newline at end of file diff --git a/mock/ext-api-data/kava-api_staking_pool.json b/mock/ext-api-data/kava-api_staking_pool.json new file mode 100644 index 000000000..acef3bc08 --- /dev/null +++ b/mock/ext-api-data/kava-api_staking_pool.json @@ -0,0 +1,7 @@ +{ + "height": "2251949", + "result": { + "not_bonded_tokens": "1411599189144", + "bonded_tokens": "80779823240237" + } +} \ No newline at end of file diff --git a/mock/ext-api-data/kava-api_staking_validators__status_bonded.json b/mock/ext-api-data/kava-api_staking_validators__status_bonded.json new file mode 100644 index 000000000..a28a80c59 --- /dev/null +++ b/mock/ext-api-data/kava-api_staking_validators__status_bonded.json @@ -0,0 +1,2371 @@ +{ + "height": "2251949", + "result": [ + { + "operator_address": "kavavaloper1qyc2cfl0nw8r95dsdw534x99wq0xcj9rmxpl7z", + "consensus_pubkey": "kavavalconspub1zcjduepqyj4j29k7hn58g7n6ert7mm4m7d0kllrx6h5rzzgpvjdt69r80zsq3az2xq", + "jailed": false, + "status": 2, + "tokens": "23004398541", + "delegator_shares": "23009000000.002955930745759376", + "description": { + "moniker": "Stake Capital", + "identity": "", + "website": "", + "security_contact": "", + "details": "\"Trustless Digital Asset Management\", Twitter: @StakeCapital, operated by @bneiluj @leopoldjoy" + }, + "unbonding_height": "1971549", + "unbonding_time": "2020-05-11T17:02:08.405902954Z", + "commission": { + "commission_rates": { + "rate": "0.500000000000000000", + "max_rate": "0.500000000000000000", + "max_change_rate": "0.500000000000000000" + }, + "update_time": "2020-02-05T09:55:51.495267155Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "kavavaloper1qfy0e2w62g6j4jg5djcqd4py3zsaeqexjplj2d", + "consensus_pubkey": "kavavalconspub1zcjduepqftv90yrm4g4w4mq47rdx9f384yxegfx7qfpkft89x2nlzafv36pq47wgls", + "jailed": false, + "status": 2, + "tokens": "20069063571", + "delegator_shares": "20069063571.000000000000000000", + "description": { + "moniker": "DragonStake", + "identity": "EA61A46F31742B22", + "website": "https://dragonstake.io", + "security_contact": "dragonstake@protonmail.com", + "details": "Forking the Banks" + }, + "unbonding_height": "0", + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "1.000000000000000000", + "max_rate": "1.000000000000000000", + "max_change_rate": "1.000000000000000000" + }, + "update_time": "2019-11-20T18:38:18.607985797Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "kavavaloper1q3y9qga5hf360dmzta67vp54qz25tmv4hhkk4t", + "consensus_pubkey": "kavavalconspub1zcjduepquu3m094f3j9jnklursgngn667tt3rz0ahpt4f7406qzqclc42mnqxlrn7e", + "jailed": false, + "status": 2, + "tokens": "20004700000", + "delegator_shares": "20004700000.000000000000000000", + "description": { + "moniker": "funky", + "identity": "1EBAA06E87B6DD60", + "website": "https://kava-funkyvalidator.nl", + "security_contact": "", + "details": "Validating with love in Holland for the world :)" + }, + "unbonding_height": "0", + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.110000000000000000", + "max_rate": "0.200000000000000000", + "max_change_rate": "0.010000000000000000" + }, + "update_time": "2019-11-21T00:42:13.651988876Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "kavavaloper1qk0pta4ga5t8p5vv7me8dz32lvcrv2rp098cas", + "consensus_pubkey": "kavavalconspub1zcjduepq3tj0qkd8jw0w4epa3cmdr0mc2rp8qkkyllrged575vacx09alzdszuahy0", + "jailed": false, + "status": 2, + "tokens": "5515168654", + "delegator_shares": "5515168654.000000000000000000", + "description": { + "moniker": "silver", + "identity": "", + "website": "", + "security_contact": "", + "details": "" + }, + "unbonding_height": "0", + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.100000000000000000", + "max_rate": "0.500000000000000000", + "max_change_rate": "0.010000000000000000" + }, + "update_time": "2020-04-06T12:51:42.070726745Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "kavavaloper1ptyzewnns2kn37ewtmv6ppsvhdnmeapvl7z9xh", + "consensus_pubkey": "kavavalconspub1zcjduepqfkq6kfq6v3avvrc6qvh0tr6h97qhqxcxw6yhmsgwrclpm3qdqwwq4zl4kc", + "jailed": false, + "status": 2, + "tokens": "124252239542", + "delegator_shares": "124252239542.000000000000000000", + "description": { + "moniker": "WeStaking", + "identity": "DA9C5AD3E308E426", + "website": "https://westaking.io", + "security_contact": "", + "details": "" + }, + "unbonding_height": "0", + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.000000000000000000", + "max_rate": "1.000000000000000000", + "max_change_rate": "0.100000000000000000" + }, + "update_time": "2020-05-13T01:35:13.408787775Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "kavavaloper1pn5k9c5pxmg5f0rycpl9rrx6k6mk85scxf06zx", + "consensus_pubkey": "kavavalconspub1zcjduepq5gqsp02excuz03zequ5xkygsj8t0su4g46p00q9p0se5kkhr2fmsusw7w7", + "jailed": false, + "status": 2, + "tokens": "22999900000", + "delegator_shares": "22999900000.000000000000000000", + "description": { + "moniker": "Stir", + "identity": "", + "website": "", + "security_contact": "", + "details": "" + }, + "unbonding_height": "0", + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.100000000000000000", + "max_rate": "0.200000000000000000", + "max_change_rate": "0.010000000000000000" + }, + "update_time": "2019-11-15T14:45:39.203670522Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "kavavaloper1phd8jz25lumudc7ac7rhmupvcqcv7lg3c8dprc", + "consensus_pubkey": "kavavalconspub1zcjduepquugppwhq0s4t5q8vh6n3j0t4t3susfasdfapa0zp8a8c36tpgj6qpqvs3s", + "jailed": false, + "status": 2, + "tokens": "2116667666660", + "delegator_shares": "2116667666660.000000000000000000", + "description": { + "moniker": "the_valiator", + "identity": "", + "website": "", + "security_contact": "", + "details": "" + }, + "unbonding_height": "0", + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "1.000000000000000000", + "max_rate": "1.000000000000000000", + "max_change_rate": "0.010000000000000000" + }, + "update_time": "2019-12-13T08:47:32.032003423Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "kavavaloper1pceqe8we7drpfqrutchwy3f99800hhzuw6cc84", + "consensus_pubkey": "kavavalconspub1zcjduepqypw0nlaweu77hnlmy37gy82d0cn57g07yy9qrkm36tx5zhp6rjzqzfqta0", + "jailed": false, + "status": 2, + "tokens": "23459640449", + "delegator_shares": "23459640449.000000000000000000", + "description": { + "moniker": "Galaxy", + "identity": "", + "website": "", + "security_contact": "", + "details": "" + }, + "unbonding_height": "0", + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.500000000000000000", + "max_rate": "0.500000000000000000", + "max_change_rate": "0.100000000000000000" + }, + "update_time": "2019-11-25T09:53:43.24669958Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "kavavaloper1rgcgqmnkeffks7enrv6hk5u4wg3nzfkmqlzjqd", + "consensus_pubkey": "kavavalconspub1zcjduepqv3f0m888swgzamf2mh3vh2gaehredz9uktv9rjcyfdjzvzvsthks4e5f4t", + "jailed": false, + "status": 2, + "tokens": "21000000000", + "delegator_shares": "21000000000.000000000000000000", + "description": { + "moniker": "syncnode", + "identity": "F422F328C14AFBFA", + "website": "wallet.syncnode.ro", + "security_contact": "", + "details": "https://www.linkedin.com/in/gbunea/" + }, + "unbonding_height": "0", + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.190000000000000000", + "max_rate": "0.200000000000000000", + "max_change_rate": "0.010000000000000000" + }, + "update_time": "2020-03-26T09:09:30.282258822Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "kavavaloper1yrm63pqvld8uyzkavz55p2cktpm2gm8jd8xxlu", + "consensus_pubkey": "kavavalconspub1zcjduepq6nje57k4x0n0uua5dl26ufpgj9jw2n945hkrv066fv54924vnmeq60d92r", + "jailed": false, + "status": 2, + "tokens": "100010000000", + "delegator_shares": "100010000000.000000000000000000", + "description": { + "moniker": "Nodeasy.com", + "identity": "F7BABF2C95B02A9F", + "website": "https://www.nodeasy.com", + "security_contact": "", + "details": "Nodeasy.com,助你进入Staking时代!" + }, + "unbonding_height": "0", + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.100000000000000000", + "max_rate": "1.000000000000000000", + "max_change_rate": "1.000000000000000000" + }, + "update_time": "2019-12-04T03:53:57.870109232Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "kavavaloper1yjj2wfers947l6n5pynpgsqlz7svc5n8ssl6ye", + "consensus_pubkey": "kavavalconspub1zcjduepqftnrqaely46s7tzfkczuqfecuk3664wks5www53x6cj7rtl90zhqq6pacf", + "jailed": false, + "status": 2, + "tokens": "20410000001", + "delegator_shares": "20410000001.000000000000000000", + "description": { + "moniker": "StakingHub", + "identity": "25D7A4013B5C2A8F", + "website": "http://www.stakinghub.net/", + "security_contact": "", + "details": "" + }, + "unbonding_height": "0", + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.200000000000000000", + "max_rate": "0.200000000000000000", + "max_change_rate": "0.010000000000000000" + }, + "update_time": "2020-01-14T23:30:14.565194467Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "kavavaloper1yna6lete8nwwwctsalzdg04ldqaz73gtn33ydq", + "consensus_pubkey": "kavavalconspub1zcjduepqzwu26st99545k4qp79vuuslynk5qaxne9z4ucjfzs5g6646klwrqg5dxfa", + "jailed": false, + "status": 2, + "tokens": "23163160000", + "delegator_shares": "23163160000.000000000000000000", + "description": { + "moniker": "ChainodeTech", + "identity": "E34BF744FF5BA8A9", + "website": "https://chainode.tech/", + "security_contact": "", + "details": "" + }, + "unbonding_height": "0", + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.100000000000000000", + "max_rate": "0.200000000000000000", + "max_change_rate": "0.010000000000000000" + }, + "update_time": "2019-11-15T14:35:31.864391537Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "kavavaloper196anr2ycsalg806dz29afklnecuaupvkh5qz6c", + "consensus_pubkey": "kavavalconspub1zcjduepqh525w7mx9apyra8jqeclcs90e6u9p22jrqaw8ymuf7mug2m5cg6sw7v7yu", + "jailed": false, + "status": 2, + "tokens": "50894061712", + "delegator_shares": "50894061712.000000000000000000", + "description": { + "moniker": "Phorest 🌲", + "identity": "A5281CA10EBCDCB5", + "website": "http://phorest.xyz/kava", + "security_contact": "", + "details": "Secure and stable PoS validator" + }, + "unbonding_height": "0", + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.000000000000000000", + "max_rate": "0.200000000000000000", + "max_change_rate": "0.050000000000000000" + }, + "update_time": "2020-01-20T14:02:20.813362703Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "kavavaloper1xzud24na9tucauc7lf6pjk84kqsgq3eq747ta7", + "consensus_pubkey": "kavavalconspub1zcjduepqncgh9yjqhyk4ezjkmfsugetqv3t3t59ddtu5qnaee5k4aam9x6wsj27w8a", + "jailed": false, + "status": 2, + "tokens": "23158079821", + "delegator_shares": "23160395806.729217551585427189", + "description": { + "moniker": "goose", + "identity": "EE700892E1359CE4", + "website": "", + "security_contact": "honk", + "details": "honk. honk." + }, + "unbonding_height": "1217698", + "unbonding_time": "2020-03-12T10:11:32.17419165Z", + "commission": { + "commission_rates": { + "rate": "0.250000000000000000", + "max_rate": "0.250000000000000000", + "max_change_rate": "0.100000000000000000" + }, + "update_time": "2019-12-19T22:27:40.022974742Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "kavavaloper1x9hq3rjc48t5upcsr3c209ycgekfasne3l5nkc", + "consensus_pubkey": "kavavalconspub1zcjduepqvrf8r43ymaj39x73luu4qsp9sn4sw4t2lh77799mau2739xtrlnsqxyqju", + "jailed": false, + "status": 2, + "tokens": "32933474240", + "delegator_shares": "32933474240.000000000000000000", + "description": { + "moniker": "Masternode24.de", + "identity": "7EBA7730A85C865C", + "website": "https://masternode24.de/", + "security_contact": "", + "details": "Investieren Sie mit uns zusammen in die besten Blockchain Projekte" + }, + "unbonding_height": "0", + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.000000000000000000", + "max_rate": "0.200000000000000000", + "max_change_rate": "0.100000000000000000" + }, + "update_time": "2020-04-13T19:49:42.142115841Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "kavavaloper1xftqdxvq0xkv2mu8c5y0jrsc578tak4m9u0s44", + "consensus_pubkey": "kavavalconspub1zcjduepqngw3s4hpzj8xscq6dfg4m8a6qeh5xwau0sjrknmlvg2lqdlgp0zszj7ewc", + "jailed": false, + "status": 2, + "tokens": "37775800000", + "delegator_shares": "37775800000.000000000000000000", + "description": { + "moniker": "Ping.pub", + "identity": "6EA723DA332200B2", + "website": "", + "security_contact": "", + "details": "We are one of the most secure and stable validator, welcome to delegate to us. 我们是最安全,最稳定,性价比最高的验证人节点,欢迎委托给我们!" + }, + "unbonding_height": "0", + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.020000000000000000", + "max_rate": "0.500000000000000000", + "max_change_rate": "0.100000000000000000" + }, + "update_time": "2019-11-21T09:12:17.124698721Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "kavavaloper1xka27j0jvmq97yunj5wp8fv242lycmax8ejlaf", + "consensus_pubkey": "kavavalconspub1zcjduepqx4zjl7vsh8pg4l3ndceu88h3027q0vvmpf7anv5c4xxq0htng5kqf24q07", + "jailed": false, + "status": 2, + "tokens": "2827139316200", + "delegator_shares": "2827139316200.000000000000000000", + "description": { + "moniker": "page2", + "identity": "", + "website": "https://coinmarketcap.com/2/", + "security_contact": "", + "details": "Lorem Ipsum" + }, + "unbonding_height": "0", + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.050000000000000000", + "max_rate": "0.200000000000000000", + "max_change_rate": "0.050000000000000000" + }, + "update_time": "2019-11-05T14:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "kavavaloper1xhxzmj8fvkqn76knay9x2chfra826369dhdu2c", + "consensus_pubkey": "kavavalconspub1zcjduepqwsmxfu5vdulvnrwej06v4jj5hvdxxqqk82flvznhxkh5whrdnxms2z2kjx", + "jailed": false, + "status": 2, + "tokens": "929346000000", + "delegator_shares": "929346000000.000000000000000000", + "description": { + "moniker": "Figment Networks", + "identity": "", + "website": "", + "security_contact": "", + "details": "" + }, + "unbonding_height": "0", + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.100000000000000000", + "max_rate": "0.250000000000000000", + "max_change_rate": "0.050000000000000000" + }, + "update_time": "2019-11-05T14:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "kavavaloper18zksjhrefqew0zahmts894p8asscufxvdfq702", + "consensus_pubkey": "kavavalconspub1zcjduepq7qm0l9hy8m8a4my03x7rfvcy3vru0y0kv29n2fwcpmrvjda8n23skzza6m", + "jailed": false, + "status": 2, + "tokens": "14040219", + "delegator_shares": "14040219.000000000000000000", + "description": { + "moniker": "Consulnode", + "identity": "", + "website": "", + "security_contact": "", + "details": "" + }, + "unbonding_height": "0", + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.100000000000000000", + "max_rate": "0.200000000000000000", + "max_change_rate": "0.010000000000000000" + }, + "update_time": "2020-03-04T19:27:58.259245834Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "kavavaloper18s9m5d5cjf0humjv7mkq8pm47kchwm0r0369cx", + "consensus_pubkey": "kavavalconspub1zcjduepqphfe0vnahkpurcc6jn3kesfch6c0afnph8qv9ryx29gpec7rtf3q968vu3", + "jailed": false, + "status": 2, + "tokens": "20010000000", + "delegator_shares": "20010000000.000000000000000000", + "description": { + "moniker": "Stake5 Labs", + "identity": "C7595F18CC5D4FA6", + "website": "https://www.stake5labs.com", + "security_contact": "", + "details": "Professional PoS node contributor" + }, + "unbonding_height": "0", + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.100000000000000000", + "max_rate": "0.200000000000000000", + "max_change_rate": "0.010000000000000000" + }, + "update_time": "2019-11-15T14:01:13.609429004Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "kavavaloper18cf35l7req0k6ulqapeyv830mrrucn9xj87plr", + "consensus_pubkey": "kavavalconspub1zcjduepq7rr7drhvr6d67nydvwxtcqv3k0uv6krfn9ktm23l77eqrra9af9s828zrk", + "jailed": false, + "status": 2, + "tokens": "1171728959900", + "delegator_shares": "1171846144514.451445144514451445", + "description": { + "moniker": "mxcpospool", + "identity": "", + "website": "https://www.mxc.co", + "security_contact": "", + "details": "" + }, + "unbonding_height": "1433843", + "unbonding_time": "2020-03-29T19:11:06.277346205Z", + "commission": { + "commission_rates": { + "rate": "0.100000000000000000", + "max_rate": "0.200000000000000000", + "max_change_rate": "0.010000000000000000" + }, + "update_time": "2019-12-13T10:05:51.300009009Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "kavavaloper1g20mhvcpjxp6gzlwhtfcphjehwcl2njqydgu7q", + "consensus_pubkey": "kavavalconspub1zcjduepqcg7v7vpgw7tj2f4z6yle5vpwutm3n5zjmlx2dpypphxd0cdvyaeqyeyteg", + "jailed": false, + "status": 2, + "tokens": "23184200000", + "delegator_shares": "23184200000.000000000000000000", + "description": { + "moniker": "pi-londoner", + "identity": "", + "website": "", + "security_contact": "", + "details": "" + }, + "unbonding_height": "0", + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.200000000000000000", + "max_rate": "0.200000000000000000", + "max_change_rate": "0.010000000000000000" + }, + "update_time": "2020-02-10T23:44:11.226734593Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "kavavaloper1gtd040dmljyaty9tkhq0mlqz7saer48v4d608x", + "consensus_pubkey": "kavavalconspub1zcjduepqqy2kzt636d5ak6l6gxsxexgtadcm8d59qh3wumgtswpa8hau7apsk4ecma", + "jailed": false, + "status": 2, + "tokens": "35931185577", + "delegator_shares": "35931185577.000000000000000000", + "description": { + "moniker": "kava.bi23", + "identity": "EB3470949B3E89E2", + "website": "https://kava.bi23.com", + "security_contact": "", + "details": "Bi23 focuses on the Crypto-Assets, providing customers with Staking and DeFi services." + }, + "unbonding_height": "0", + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.000000000000000000", + "max_rate": "1.000000000000000000", + "max_change_rate": "0.100000000000000000" + }, + "update_time": "2019-12-04T23:42:01.494010426Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "kavavaloper1g4qpetrj59a29e4wxpe74x93q4df2czjh8r9ak", + "consensus_pubkey": "kavavalconspub1zcjduepqe3evdke2eyzv7ngkwj0w4qarpqad47s6eqsqavesmzhz664ewmzsre8fkj", + "jailed": false, + "status": 2, + "tokens": "466602000000", + "delegator_shares": "466602000000.000000000000000000", + "description": { + "moniker": "IOSG", + "identity": "", + "website": "", + "security_contact": "", + "details": "" + }, + "unbonding_height": "0", + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.100000000000000000", + "max_rate": "0.200000000000000000", + "max_change_rate": "0.010000000000000000" + }, + "update_time": "2019-11-05T14:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "kavavaloper1ffcujj05v6220ccxa6qdnpz3j48ng024ykh2df", + "consensus_pubkey": "kavavalconspub1zcjduepqxzqld0trat9nu9j53rzxwvpnpjekxf02eeg8mw3xewjky2qgy69sgh0tcw", + "jailed": false, + "status": 2, + "tokens": "2303407078450", + "delegator_shares": "2303407078450.000000000000000000", + "description": { + "moniker": "🐠stake.fish", + "identity": "90B597A673FC950E", + "website": "http://stake.fish", + "security_contact": "", + "details": "stake.fish is a reliable validator for PoS blockchains. Stake with us. We know staking." + }, + "unbonding_height": "0", + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.100000000000000000", + "max_rate": "1.000000000000000000", + "max_change_rate": "1.000000000000000000" + }, + "update_time": "2019-12-03T18:59:42.821933888Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "kavavaloper1fmas0qlsucg4qwf8mqyrylcg3uluz2ffg8952q", + "consensus_pubkey": "kavavalconspub1zcjduepqkv4fkh6u8l068xusy5dhz2jpz969nzszntuavsc0uu6sxxr9wafqewxkac", + "jailed": false, + "status": 2, + "tokens": "22631605772", + "delegator_shares": "22631605772.000000000000000000", + "description": { + "moniker": "mintonium", + "identity": "0FF7C542EF9422AB", + "website": "", + "security_contact": "", + "details": "" + }, + "unbonding_height": "0", + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.100000000000000000", + "max_rate": "0.500000000000000000", + "max_change_rate": "0.050000000000000000" + }, + "update_time": "2019-11-15T14:00:18.218278987Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "kavavaloper12qn7y04wzr5s3h4dmdtre4q9f4nvc03a9a9qsz", + "consensus_pubkey": "kavavalconspub1zcjduepqsnl9ahysm5hypmpfuwyqkha280aa9ushdlvvqza4u7rfmf0pvdxqlla0wj", + "jailed": false, + "status": 2, + "tokens": "22994500500", + "delegator_shares": "22999100000.000000000000000000", + "description": { + "moniker": "dexhybrid", + "identity": "", + "website": "", + "security_contact": "", + "details": "" + }, + "unbonding_height": "2111209", + "unbonding_time": "2020-05-23T00:58:22.825067041Z", + "commission": { + "commission_rates": { + "rate": "0.100000000000000000", + "max_rate": "0.250000000000000000", + "max_change_rate": "0.020000000000000000" + }, + "update_time": "2019-11-16T14:33:31.092253347Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "kavavaloper12r77hhj6ylvvl4etjm0fmpzh07jum8u7qqd695", + "consensus_pubkey": "kavavalconspub1zcjduepq3ndp4jxqsvxlp5crspvu6tcra7zg7cnnxzm3hx6sxhcd409ytzyskcadfv", + "jailed": false, + "status": 2, + "tokens": "10000000", + "delegator_shares": "10000000.000000000000000000", + "description": { + "moniker": "stefansky", + "identity": "878AB3284CD8CBED", + "website": "http://stefancondurachi.com", + "security_contact": "", + "details": "Software Architect" + }, + "unbonding_height": "0", + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.100000000000000000", + "max_rate": "0.200000000000000000", + "max_change_rate": "0.010000000000000000" + }, + "update_time": "2020-02-03T05:32:50.725944775Z" + }, + "min_self_delegation": "1000000" + }, + { + "operator_address": "kavavaloper129kkennsm7na34lu6sn4kwxp7ewes58y4fx6y9", + "consensus_pubkey": "kavavalconspub1zcjduepqz354kpmk0970fpvhw6va6ufhasrnh4sgzh82cfd5egm9ggl5gy6qlgwqjt", + "jailed": false, + "status": 2, + "tokens": "23011000000", + "delegator_shares": "23011000000.000000000000000000", + "description": { + "moniker": "stake.zone", + "identity": "0A888728046018EC", + "website": "http://stake.zone", + "security_contact": "", + "details": "" + }, + "unbonding_height": "0", + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.100000000000000000", + "max_rate": "0.250000000000000000", + "max_change_rate": "0.040000000000000000" + }, + "update_time": "2019-11-15T14:01:07.22222101Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "kavavaloper12g40q2parn5z9ewh5xpltmayv6y0q3zs6ddmdg", + "consensus_pubkey": "kavavalconspub1zcjduepq0plta99ns8ec5h5sj8x4ufzkdpsz6xu7ckp62hkagfxey242qzgstm0ldw", + "jailed": false, + "status": 2, + "tokens": "5089172619037", + "delegator_shares": "5089172619037.000000000000000000", + "description": { + "moniker": "P2P.ORG - P2P Validator", + "identity": "E12F4695036D8072", + "website": "https://p2p.org", + "security_contact": "vladimir.m@p2p.org", + "details": "" + }, + "unbonding_height": "0", + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.100000000000000000", + "max_rate": "0.200000000000000000", + "max_change_rate": "0.010000000000000000" + }, + "update_time": "2019-11-05T14:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "kavavaloper1t5l8ht0wxpd4lpe4cweftrpg5kyn3qp437yvnr", + "consensus_pubkey": "kavavalconspub1zcjduepqe58zj7f5zjqu023l3sd96qwurtzy7ayv2549z6mca8zmalvtlxfs80qsja", + "jailed": false, + "status": 2, + "tokens": "20650150000", + "delegator_shares": "20650150000.000000000000000000", + "description": { + "moniker": "DelegaNetworks", + "identity": "1BED7C08416A619F", + "website": "https://delega.io", + "security_contact": "", + "details": "" + }, + "unbonding_height": "0", + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "1.000000000000000000", + "max_rate": "1.000000000000000000", + "max_change_rate": "1.000000000000000000" + }, + "update_time": "2019-11-24T20:37:25.840600387Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "kavavaloper1vyx7wt8s8dwcspdt7dy49sq4l3jwyhxyndakmm", + "consensus_pubkey": "kavavalconspub1zcjduepq2v03gwaywadc7ar423rxmy7k7ev3y3tkvsetq7w30j0whymjkacsxjg9lt", + "jailed": false, + "status": 2, + "tokens": "1513306965388", + "delegator_shares": "1513306965388.000000000000000000", + "description": { + "moniker": "InfStones", + "identity": "39A41C2FDE0AD040", + "website": "https://infstones.io", + "security_contact": "", + "details": "Fueling Blockchain Beyond Infinity" + }, + "unbonding_height": "0", + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.010000000000000000", + "max_rate": "1.000000000000000000", + "max_change_rate": "0.100000000000000000" + }, + "update_time": "2019-11-05T14:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "kavavaloper1vfawvtzvmcjkpqzhezvhk9q5tv5t7x8smz95uu", + "consensus_pubkey": "kavavalconspub1zcjduepq2yhf7ntk9dkkqpg07ead9nzjmldf2ar6tx6uz8jeaqjedrj9keqsq0hn02", + "jailed": false, + "status": 2, + "tokens": "23189000000", + "delegator_shares": "23189000000.000000000000000000", + "description": { + "moniker": "Newroad Network", + "identity": "91FAC10CA3718A17", + "website": "https://newroad.network/kava/", + "security_contact": "", + "details": "We provide a professional delegation service for multiple Proof of Stake networks. We use a secure and redundant setup. Visit our website for more information." + }, + "unbonding_height": "0", + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.080000000000000000", + "max_rate": "0.500000000000000000", + "max_change_rate": "0.100000000000000000" + }, + "update_time": "2020-04-28T16:16:55.826119569Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "kavavaloper1vw35vclatlrcmzuaxf2fleyuk38xa7xf4vdaq2", + "consensus_pubkey": "kavavalconspub1zcjduepqnrpursauds6wjnqht0979kjr0pvk5jp4c0cv46feazqv4qappqsqn5rd22", + "jailed": false, + "status": 2, + "tokens": "125050100000", + "delegator_shares": "125050100000.000000000000000000", + "description": { + "moniker": "hashquark", + "identity": "", + "website": "", + "security_contact": "", + "details": "" + }, + "unbonding_height": "0", + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.100000000000000000", + "max_rate": "1.000000000000000000", + "max_change_rate": "1.000000000000000000" + }, + "update_time": "2019-11-05T14:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "kavavaloper1vw4t8ge2ephu0wuhcmclcw04ag2vzj9rpdme2x", + "consensus_pubkey": "kavavalconspub1zcjduepq0fjxw9wq8swcrk26j2vk8qm90d0vn94c2c7cs0ru5rgy2zlyv5eq8q5kvc", + "jailed": false, + "status": 2, + "tokens": "20153000000", + "delegator_shares": "20153000000.000000000000000000", + "description": { + "moniker": "UbikCapital", + "identity": "8265DEAF50B61DF7", + "website": "https://ubik.capital", + "security_contact": "", + "details": "" + }, + "unbonding_height": "0", + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.500000000000000000", + "max_rate": "0.500000000000000000", + "max_change_rate": "0.050000000000000000" + }, + "update_time": "2019-12-25T21:46:08.338409716Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "kavavaloper1vuylvflgy75d8zr07ta8x0gcqynvkvw70et853", + "consensus_pubkey": "kavavalconspub1zcjduepqvk6tye9w7399g7xys6j5ycw5rly8wz92mp0pevgmrv30qc4nva5sc2u25u", + "jailed": false, + "status": 2, + "tokens": "1999980100000", + "delegator_shares": "1999980100000.000000000000000000", + "description": { + "moniker": "Lemniscap", + "identity": "", + "website": "", + "security_contact": "", + "details": "" + }, + "unbonding_height": "0", + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.100000000000000000", + "max_rate": "0.250000000000000000", + "max_change_rate": "0.050000000000000000" + }, + "update_time": "2019-11-05T14:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "kavavaloper1dwae0ny4uuvacucakm9v8r8mxhw82zack4cn7y", + "consensus_pubkey": "kavavalconspub1zcjduepq3rfkl40umrfy0wq9u9m5mc5zv30x4lmj08vup2u5d90t4fu3qe7qvq5scl", + "jailed": false, + "status": 2, + "tokens": "3317977023616", + "delegator_shares": "3317977023616.000000000000000000", + "description": { + "moniker": "OKExPool", + "identity": "", + "website": "www.okex.com/pool", + "security_contact": "", + "details": "" + }, + "unbonding_height": "0", + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.100000000000000000", + "max_rate": "0.200000000000000000", + "max_change_rate": "0.010000000000000000" + }, + "update_time": "2019-12-20T02:25:09.919481267Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "kavavaloper1dj63l3z0smqa8au5yek37nmj0xd60zs9dwmdh0", + "consensus_pubkey": "kavavalconspub1zcjduepqq0hj2jx5x7p65t56c7s750e85yp0u6xvydk6eh5m45xq755rjqlsthzygr", + "jailed": false, + "status": 2, + "tokens": "20100000782", + "delegator_shares": "20100000782.000000000000000000", + "description": { + "moniker": "Yn", + "identity": "", + "website": "", + "security_contact": "", + "details": "" + }, + "unbonding_height": "0", + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.100000000000000000", + "max_rate": "0.200000000000000000", + "max_change_rate": "0.010000000000000000" + }, + "update_time": "2019-11-15T14:04:52.626128649Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "kavavaloper1dntlhrw3jrej6ssdp64yfmkkz08ykyx4n7hphh", + "consensus_pubkey": "kavavalconspub1zcjduepqxd9wm06lw0p6nrysw2ecmusgrmsq6438ht4wh7gx64a0m6vnu4qs7jhyjk", + "jailed": false, + "status": 2, + "tokens": "4001052087322", + "delegator_shares": "4001052087322.000000000000000000", + "description": { + "moniker": "Staked", + "identity": "E7BFA6515FB02B3B", + "website": "", + "security_contact": "", + "details": "" + }, + "unbonding_height": "0", + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.100000000000000000", + "max_rate": "0.200000000000000000", + "max_change_rate": "0.010000000000000000" + }, + "update_time": "2019-12-03T16:23:23.639110694Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "kavavaloper1dede4flaq24j2g9u8f83vkqrqxe6cwzrxt5zsu", + "consensus_pubkey": "kavavalconspub1zcjduepqstxrft39yrg5hgalcnjqurms5tj2yqpw9y85axv9gsxyld62cneqg6k7nk", + "jailed": false, + "status": 2, + "tokens": "109213032359", + "delegator_shares": "109213032359.000000000000000000", + "description": { + "moniker": "Stakin by POS Bakerz", + "identity": "3AFAE7268F4DFD10", + "website": "http://stakin.com/", + "security_contact": "", + "details": "Your Trusted Crypto Rewards" + }, + "unbonding_height": "0", + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.000000000000000000", + "max_rate": "1.000000000000000000", + "max_change_rate": "0.010000000000000000" + }, + "update_time": "2020-05-07T20:51:51.964006239Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "kavavaloper1davtd9w5yadvlg5x7aw0kpkyhckk5m5ecrmnyl", + "consensus_pubkey": "kavavalconspub1zcjduepq9x39e7g3m2hv8v6nxcx2lmy6fzaeqmvdz4uqtpm8qaxtr6527yrsh3fkgl", + "jailed": false, + "status": 2, + "tokens": "23000000000", + "delegator_shares": "23000000000.000000000000000000", + "description": { + "moniker": "Cyberili", + "identity": "3554F49719B1BF6F", + "website": "", + "security_contact": "", + "details": "" + }, + "unbonding_height": "0", + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.100000000000000000", + "max_rate": "0.200000000000000000", + "max_change_rate": "0.010000000000000000" + }, + "update_time": "2019-11-15T14:55:31.701406451Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "kavavaloper1wtcn3ylrsp4qp4urlhkf78kkt8f2ch7p0f0p98", + "consensus_pubkey": "kavavalconspub1zcjduepqjffmrcy39vaecs9rjaju3hzq97nggr2l0zg96k2u3c54mfx20hks43wvdy", + "jailed": false, + "status": 2, + "tokens": "23145977490", + "delegator_shares": "23145977490.000000000000000000", + "description": { + "moniker": "007", + "identity": "", + "website": "", + "security_contact": "", + "details": "" + }, + "unbonding_height": "0", + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.300000000000000000", + "max_rate": "0.500000000000000000", + "max_change_rate": "0.100000000000000000" + }, + "update_time": "2020-04-07T07:36:37.293429517Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "kavavaloper1wu8m65vqazssv2rh8rthv532hzggfr3h9azwz9", + "consensus_pubkey": "kavavalconspub1zcjduepqqg29usle4d3hgt4eadn3epppa2h6dsga9mj6sxvyj5prchufgr5qmrneka", + "jailed": false, + "status": 2, + "tokens": "5005157202698", + "delegator_shares": "5005157202698.000000000000000000", + "description": { + "moniker": "Binance Staking", + "identity": "", + "website": "https://binance.com", + "security_contact": "", + "details": "Exchange the world!" + }, + "unbonding_height": "0", + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "1.000000000000000000", + "max_rate": "1.000000000000000000", + "max_change_rate": "0.100000000000000000" + }, + "update_time": "2019-11-05T14:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "kavavaloper1wacmlkst8s39fq83tqhlcuuacts2z6lvwfq8hv", + "consensus_pubkey": "kavavalconspub1zcjduepq8rt2a49hdz0tfp2gty7upe27k7gwkavf3kh60np940atacmwdxjs05uft3", + "jailed": false, + "status": 2, + "tokens": "4835289500", + "delegator_shares": "4835289500.000000000000000000", + "description": { + "moniker": "tokenweb.io", + "identity": "", + "website": "https://tokenweb.io", + "security_contact": "", + "details": "put your tokens to work" + }, + "unbonding_height": "0", + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.100000000000000000", + "max_rate": "0.200000000000000000", + "max_change_rate": "0.010000000000000000" + }, + "update_time": "2020-04-22T13:34:07.741893579Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "kavavaloper1006e7kwuhthdtxe0d90pc209cy803ehem0dg0q", + "consensus_pubkey": "kavavalconspub1zcjduepq78wv8373p09g0kx9z02rm0vvfwy999d74wr2mnzplwmfphy7lxkshkgm54", + "jailed": false, + "status": 2, + "tokens": "251000000", + "delegator_shares": "251000000.000000000000000000", + "description": { + "moniker": "vcmain", + "identity": "", + "website": "", + "security_contact": "", + "details": "" + }, + "unbonding_height": "0", + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.030000000000000000", + "max_rate": "0.200000000000000000", + "max_change_rate": "0.010000000000000000" + }, + "update_time": "2020-04-20T19:53:59.310652973Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "kavavaloper10m3hjapny44txmgr47rf277364htgqpr646cty", + "consensus_pubkey": "kavavalconspub1zcjduepqy8galhn5awgvk5etjtuugkja6k2s8z0jsslharpprczjtec73gpskvt0pz", + "jailed": false, + "status": 2, + "tokens": "1010061607032", + "delegator_shares": "1010061607032.000000000000000000", + "description": { + "moniker": "HotBitPool", + "identity": "", + "website": "https://www.hotbit.io", + "security_contact": "", + "details": "Cryptocurrency Exchange" + }, + "unbonding_height": "0", + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.100000000000000000", + "max_rate": "0.200000000000000000", + "max_change_rate": "0.010000000000000000" + }, + "update_time": "2020-04-07T04:00:47.76026917Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "kavavaloper1spkjjtwks5zt0dqexj8rv8ljwmwxe8ufkraukq", + "consensus_pubkey": "kavavalconspub1zcjduepq9gppak7hsjrwvyxz2y9hy830gzsx2r4nax43vh2lprj0wj3rvghsyu6xev", + "jailed": false, + "status": 2, + "tokens": "22950000000", + "delegator_shares": "22950000000.000000000000000000", + "description": { + "moniker": "Jupiter.IAM", + "identity": "", + "website": "", + "security_contact": "", + "details": "" + }, + "unbonding_height": "0", + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.100000000000000000", + "max_rate": "0.200000000000000000", + "max_change_rate": "0.010000000000000000" + }, + "update_time": "2019-11-17T11:35:54.989770823Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "kavavaloper1srhded4xw0krcwlvddtcyycuh70fp5ry9yvp86", + "consensus_pubkey": "kavavalconspub1zcjduepq64ugztwcunjrpema5pqwherkfznms8ykc4jx7syc6tm5ztv58keqxlc6fv", + "jailed": false, + "status": 2, + "tokens": "1965109266679", + "delegator_shares": "1965109266679.000000000000000000", + "description": { + "moniker": "TRGCapital", + "identity": "", + "website": "", + "security_contact": "", + "details": "" + }, + "unbonding_height": "0", + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.100000000000000000", + "max_rate": "1.000000000000000000", + "max_change_rate": "0.100000000000000000" + }, + "update_time": "2019-12-12T17:38:19.894601876Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "kavavaloper1s8akp0nq7z7vuf5g9agdswcwq7vm9uwudk0han", + "consensus_pubkey": "kavavalconspub1zcjduepqpgz29c6efzyj96y0kkjrxns67nsm5t3rae0ra2nmrx4fm5j33nkqn066rz", + "jailed": false, + "status": 2, + "tokens": "22950000000", + "delegator_shares": "22950000000.000000000000000000", + "description": { + "moniker": "IvoryTower", + "identity": "", + "website": "", + "security_contact": "", + "details": "" + }, + "unbonding_height": "0", + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.100000000000000000", + "max_rate": "0.200000000000000000", + "max_change_rate": "0.010000000000000000" + }, + "update_time": "2019-11-17T02:12:20.831453541Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "kavavaloper13fxkk4730cqglgdv7w0mdelyx07myyq76uf9f3", + "consensus_pubkey": "kavavalconspub1zcjduepquwqhhvst3t6pg7rzutmvr3dma46ux6nggfxrju4f6u2dza9n3l7s54jgu7", + "jailed": false, + "status": 2, + "tokens": "23213610000", + "delegator_shares": "23215931593.159315931593159315", + "description": { + "moniker": "Finantra.com", + "identity": "", + "website": "http://finantra.com", + "security_contact": "", + "details": "" + }, + "unbonding_height": "1122467", + "unbonding_time": "2020-03-04T18:59:03.214161979Z", + "commission": { + "commission_rates": { + "rate": "0.500000000000000000", + "max_rate": "0.500000000000000000", + "max_change_rate": "0.100000000000000000" + }, + "update_time": "2020-03-14T19:38:24.407313925Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "kavavaloper13vstf6ecmfe4p0gaufumk569sdawhtrf8gu56h", + "consensus_pubkey": "kavavalconspub1zcjduepq2ye3234dt2jes9g49mf5sdy7f7xfshekg5xyjm7vq7m07s9uq82qger9yk", + "jailed": false, + "status": 2, + "tokens": "23081092090", + "delegator_shares": "23081092090.000000000000000000", + "description": { + "moniker": "QuantaFrontier.com", + "identity": "", + "website": "https://QuantaFrontier.com", + "security_contact": "", + "details": "" + }, + "unbonding_height": "0", + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.120000000000000000", + "max_rate": "0.200000000000000000", + "max_change_rate": "0.100000000000000000" + }, + "update_time": "2020-03-10T19:08:38.751434231Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "kavavaloper13dfu6et0m8zm4hachudvn62w0c2zvcmrqn8cs3", + "consensus_pubkey": "kavavalconspub1zcjduepqcctrta82mcm79j0e6ttgguekmljvud0y4rlggrm9uw9t49qemujsd69h59", + "jailed": false, + "status": 2, + "tokens": "23144338847", + "delegator_shares": "23144338847.000000000000000000", + "description": { + "moniker": "Sunshine", + "identity": "24DB71E8B5076192", + "website": "", + "security_contact": "", + "details": "" + }, + "unbonding_height": "0", + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.300000000000000000", + "max_rate": "0.500000000000000000", + "max_change_rate": "0.100000000000000000" + }, + "update_time": "2020-04-05T16:35:57.63239062Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "kavavaloper1jyuv7z9at27elvmnmzh2v39dc06r9kjcy59xkr", + "consensus_pubkey": "kavavalconspub1zcjduepqcznteuyudn9zmfzyu6cksgh9qv3e9sc9fkyu32djy9d29ertyjrqfwcnvj", + "jailed": false, + "status": 2, + "tokens": "2588950000000", + "delegator_shares": "2588950000000.000000000000000000", + "description": { + "moniker": "DAF", + "identity": "", + "website": "", + "security_contact": "", + "details": "" + }, + "unbonding_height": "0", + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.050000000000000000", + "max_rate": "0.200000000000000000", + "max_change_rate": "0.010000000000000000" + }, + "update_time": "2019-11-05T14:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "kavavaloper1j26c4k2jj9tv95whdhva3e8v2fcm4s3dsgstd2", + "consensus_pubkey": "kavavalconspub1zcjduepq3ra0zhkgeyqzksspztcx475dtlra5lckdpzwht29mk9fuepnkjqsw2rly7", + "jailed": false, + "status": 2, + "tokens": "3148249101016", + "delegator_shares": "3148249101016.000000000000000000", + "description": { + "moniker": "DokiaCapital", + "identity": "", + "website": "https://staking.dokia.cloud", + "security_contact": "", + "details": "" + }, + "unbonding_height": "0", + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.120000000000000000", + "max_rate": "0.120000000000000000", + "max_change_rate": "0.010000000000000000" + }, + "update_time": "2019-11-05T14:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "kavavaloper1jhraz4ftxl2pd37knmeua7wjxghmlskwf7x8pf", + "consensus_pubkey": "kavavalconspub1zcjduepq6rxswfd9puq5t7jlp52cetv5s7cqm4l4n5tx4gqsclg9ngswe45qwhz2dm", + "jailed": false, + "status": 2, + "tokens": "23443000000", + "delegator_shares": "23443000000.000000000000000000", + "description": { + "moniker": "mariposa2", + "identity": "", + "website": "", + "security_contact": "", + "details": "" + }, + "unbonding_height": "0", + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "1.000000000000000000", + "max_rate": "1.000000000000000000", + "max_change_rate": "1.000000000000000000" + }, + "update_time": "2019-12-26T13:44:37.328086675Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "kavavaloper1jlzx4js09d9zzyuhuz8sfdweklrapzacuhsxq5", + "consensus_pubkey": "kavavalconspub1zcjduepqg94y638yaj7es28zdktmar4jn9wu0v2l4h8mr40gerr2rek8q3rq9d3gh6", + "jailed": false, + "status": 2, + "tokens": "3153557198531", + "delegator_shares": "3153557198531.000000000000000000", + "description": { + "moniker": "shiprekt", + "identity": "", + "website": "", + "security_contact": "", + "details": "" + }, + "unbonding_height": "0", + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.000000000000000000", + "max_rate": "1.000000000000000000", + "max_change_rate": "0.100000000000000000" + }, + "update_time": "2019-11-05T14:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "kavavaloper1jl42l225565y3hm9dm4my33hjgdzleucqryhlx", + "consensus_pubkey": "kavavalconspub1zcjduepqtlmej0vprfmun69nsnmuv56j3dctzw90tmk0f805lqxcqn9sr77s4nzkx0", + "jailed": false, + "status": 2, + "tokens": "69171541930", + "delegator_shares": "69171541930.000000000000000000", + "description": { + "moniker": "0% commission: melea Validator", + "identity": "4BE49EABAA41B8BF", + "website": "https://meleatrust.com/kava/", + "security_contact": "meleacrypto@gmail.com", + "details": "Free Validator service at 0% Commission secure and trusted, awarded in Game Of Steaks" + }, + "unbonding_height": "0", + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.000000000000000000", + "max_rate": "0.250000000000000000", + "max_change_rate": "0.050000000000000000" + }, + "update_time": "2019-12-27T14:23:19.174760869Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "kavavaloper1nxgg4grsc0fwh893mks62d3x3r6uazgpj3m3cr", + "consensus_pubkey": "kavavalconspub1zcjduepqkk7jeymtt9rk3jlhxtxu95akmxfusj44mqq2wuq8c2hckulpga0q4yrauv", + "jailed": false, + "status": 2, + "tokens": "23085863116", + "delegator_shares": "23085863116.000000000000000000", + "description": { + "moniker": "Easy 2 Stake", + "identity": "2C877AC873132C91", + "website": "www.easy2stake.com", + "security_contact": "", + "details": "Easy.Stake.Trust. As easy and as simple as you would click next. Complete transparency and trust with a secure and stable validator." + }, + "unbonding_height": "0", + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.100000000000000000", + "max_rate": "0.200000000000000000", + "max_change_rate": "0.010000000000000000" + }, + "update_time": "2019-11-15T14:00:10.631092707Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "kavavaloper1ndkn5rdl9n929am6q2zt9ndfhhggcxkhetna90", + "consensus_pubkey": "kavavalconspub1zcjduepq6ptpugu70hqgms3g3neyjx4fnse42tthm294g6vp5njpmgtw4wcs5l07lf", + "jailed": false, + "status": 2, + "tokens": "94355033398", + "delegator_shares": "94355033398.000000000000000000", + "description": { + "moniker": "stakewolf", + "identity": "F012ABCA5EA51F6B", + "website": "", + "security_contact": "", + "details": "Stake is Money, Stakewolf is Stake" + }, + "unbonding_height": "0", + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.000000000000000000", + "max_rate": "1.000000000000000000", + "max_change_rate": "1.000000000000000000" + }, + "update_time": "2020-04-14T01:18:50.785865364Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "kavavaloper1njvaku4qg9pxmx9jgjks36xrxfd6fyqs3tgs4d", + "consensus_pubkey": "kavavalconspub1zcjduepqsxtm3s99l58x9e3sqfxx4z88v6t4pyhku6fnu60drwmq8zm4jwjqx257u9", + "jailed": false, + "status": 2, + "tokens": "1090886500000", + "delegator_shares": "1090886500000.000000000000000000", + "description": { + "moniker": "BitMax Staking", + "identity": "", + "website": "https://bitmax.io/", + "security_contact": "", + "details": "Trading Platform Industry Leader driven by Product Innovation" + }, + "unbonding_height": "0", + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.100000000000000000", + "max_rate": "0.200000000000000000", + "max_change_rate": "0.010000000000000000" + }, + "update_time": "2020-01-15T09:09:05.545733701Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "kavavaloper1nnwwu4km0alut2q8vhg7zjt45wyehddpwlfrmj", + "consensus_pubkey": "kavavalconspub1zcjduepqey9flxqkdw5ewlskac3wltu4yl93asdamt66prm393zc8g93dcuszezutf", + "jailed": false, + "status": 2, + "tokens": "5744799001", + "delegator_shares": "5745373480.003702086936008957", + "description": { + "moniker": "Wetez", + "identity": "26FA2B24F46A98EF", + "website": "https://www.wetez.io", + "security_contact": "", + "details": "Wetez is the most professional team in the POS ( Proof of Stake) field.Wetez是POS领域最专业的团队,为POS带来的权益做更多赋能。" + }, + "unbonding_height": "448243", + "unbonding_time": "2020-01-11T04:03:40.112446434Z", + "commission": { + "commission_rates": { + "rate": "0.010000000000000000", + "max_rate": "0.200000000000000000", + "max_change_rate": "0.050000000000000000" + }, + "update_time": "2019-11-17T01:33:27.008856884Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "kavavaloper15kwwzz908wl0qv4w66a5ee70kytpmfc9khvah6", + "consensus_pubkey": "kavavalconspub1zcjduepq8ylkkt83ktmljrmmk7evkj600j3p9xjnm4kf44z33hyr3cum448sqw2a6j", + "jailed": false, + "status": 2, + "tokens": "6118996081", + "delegator_shares": "6118996081.000000000000000000", + "description": { + "moniker": "Staking4All", + "identity": "", + "website": "https://www.staking4all.org", + "security_contact": "", + "details": "Validator for Proof of Stake blockchains. Delegate to us for a easy staking experience" + }, + "unbonding_height": "0", + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.100000000000000000", + "max_rate": "0.300000000000000000", + "max_change_rate": "0.010000000000000000" + }, + "update_time": "2020-03-25T15:53:47.321864774Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "kavavaloper15urq2dtp9qce4fyc85m6upwm9xul3049dcs7da", + "consensus_pubkey": "kavavalconspub1zcjduepqsglrgfudcqw4la7e54lfdu2va9z5gd4r8z6wrwe8m5rtz3d2vtsq55njyr", + "jailed": false, + "status": 2, + "tokens": "2224337117663", + "delegator_shares": "2224559573585.687076200777774018", + "description": { + "moniker": "Chorus One", + "identity": "00B79D689B7DC1CE", + "website": "https://chorus.one", + "security_contact": "security@chorus.one", + "details": "Secure Kava and shape its future by delegating to Chorus One, a highly secure and stable validator. By delegating, you agree to the terms of service." + }, + "unbonding_height": "2033098", + "unbonding_time": "2020-05-16T16:56:53.71682445Z", + "commission": { + "commission_rates": { + "rate": "0.075000000000000000", + "max_rate": "0.300000000000000000", + "max_change_rate": "0.100000000000000000" + }, + "update_time": "2019-11-05T14:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "kavavaloper14fkp35j5nkvtztmxmsxh88jks6p3w8u7p76zs9", + "consensus_pubkey": "kavavalconspub1zcjduepqlgrd20pqzw4dmkdkg3nd65mra077pjne8l0d43wsvw93y9dw450smyh79n", + "jailed": false, + "status": 2, + "tokens": "23744500000", + "delegator_shares": "23744500000.000000000000000000", + "description": { + "moniker": "Bit Cat🐱", + "identity": "FAB46CEEAEAB9FA1", + "website": "https://www.bitcat365.com", + "security_contact": "", + "details": "Secure and stable KAVA validator service from China team" + }, + "unbonding_height": "0", + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.100000000000000000", + "max_rate": "0.200000000000000000", + "max_change_rate": "0.010000000000000000" + }, + "update_time": "2019-11-15T14:01:37.718892109Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "kavavaloper140g8fnnl46mlvfhygj3zvjqlku6x0fwu6lgey7", + "consensus_pubkey": "kavavalconspub1zcjduepqvtvkhh22hgfvp865tj4uwltv0hu7fs3vwmxwrl0n2mdpfuzj0p0qes2k9e", + "jailed": false, + "status": 2, + "tokens": "3536248896890", + "delegator_shares": "3536248896890.000000000000000000", + "description": { + "moniker": "Cosmostation", + "identity": "AE4C403A6E7AA1AC", + "website": "https://www.cosmostation.io", + "security_contact": "", + "details": "Delegate your Kava and start earning your staking rewards." + }, + "unbonding_height": "0", + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.150000000000000000", + "max_rate": "0.300000000000000000", + "max_change_rate": "0.100000000000000000" + }, + "update_time": "2019-11-18T01:27:53.436530462Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "kavavaloper14kn0kk33szpwus9nh8n87fjel8djx0y02c7me3", + "consensus_pubkey": "kavavalconspub1zcjduepqk8fq7ssjps5r40j32lmhxrdzfg72k8dknc3xndljjtlghc9u9nrshrlf3r", + "jailed": false, + "status": 2, + "tokens": "2888251903903", + "delegator_shares": "2888251903903.000000000000000000", + "description": { + "moniker": "Forbole", + "identity": "2861F5EE06627224", + "website": "https://www.forbole.com", + "security_contact": "info@forbole.com", + "details": "Professional PoS validator based in Hong Kong" + }, + "unbonding_height": "0", + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.095000000000000000", + "max_rate": "0.300000000000000000", + "max_change_rate": "0.010000000000000000" + }, + "update_time": "2019-11-05T14:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "kavavaloper1kgddca7qj96z0qcxr2c45z73cfl0c75p27tsg6", + "consensus_pubkey": "kavavalconspub1zcjduepqzah30dnsz855gnufkqlqnq50ksyc4jetprhz4ugg2rmuzhh3gvwsfxan38", + "jailed": false, + "status": 2, + "tokens": "2106193827976", + "delegator_shares": "2106193827976.000000000000000000", + "description": { + "moniker": "ChainLayer", + "identity": "AD3CDBC91802F94A", + "website": "https://www.chainlayer.io", + "security_contact": "", + "details": "Secure and reliable validator. TG: https://t.me/chainlayer" + }, + "unbonding_height": "0", + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.100000000000000000", + "max_rate": "0.100000000000000000", + "max_change_rate": "0.010000000000000000" + }, + "update_time": "2019-11-05T14:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "kavavaloper1kwj4l5putuymgxw9kx8emh3e5dpaca0hnf3zdy", + "consensus_pubkey": "kavavalconspub1zcjduepqmqwfzwnmjdnkmt9k75k3q7rez3lr08m9fqev06rh6m2sdke8kmusjhywm9", + "jailed": false, + "status": 2, + "tokens": "23230000000", + "delegator_shares": "23230000000.000000000000000000", + "description": { + "moniker": "InChainWorks", + "identity": "BE448F9ECAB40ABE", + "website": "https://inchain.works", + "security_contact": "", + "details": "" + }, + "unbonding_height": "0", + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.200000000000000000", + "max_rate": "0.200000000000000000", + "max_change_rate": "0.010000000000000000" + }, + "update_time": "2019-12-06T10:37:03.352901001Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "kavavaloper1k4kxxfkhhwvyzxxxgksefkzpxahp9wfc572esl", + "consensus_pubkey": "kavavalconspub1zcjduepqt0k39t3zmz460are7rf9n97u20qhfmukp8ujeqhe0jg2q7ye99cqprr8nr", + "jailed": false, + "status": 2, + "tokens": "23388000000", + "delegator_shares": "23388000000.000000000000000000", + "description": { + "moniker": "Mr.K", + "identity": "74D3AF53635231D9", + "website": "", + "security_contact": "", + "details": "Validator on Tendermint base project" + }, + "unbonding_height": "0", + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.500000000000000000", + "max_rate": "0.500000000000000000", + "max_change_rate": "0.100000000000000000" + }, + "update_time": "2019-11-29T03:49:52.013497324Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "kavavaloper1kc6vzheht92jwf0gtzhjk6jjht67rxhal9z04v", + "consensus_pubkey": "kavavalconspub1zcjduepqt8065r783whzn3w47uuhm0t8rw2ke0zda6awa4j5lemlhw029mtqs79pcs", + "jailed": false, + "status": 2, + "tokens": "20028000000", + "delegator_shares": "20028000000.000000000000000000", + "description": { + "moniker": "moonli.me", + "identity": "662AEC27BD90D036", + "website": "https://moonli.me", + "security_contact": "", + "details": "How to Delegete: https://go.moonli.me/kava" + }, + "unbonding_height": "972523", + "unbonding_time": "2020-02-21T16:44:26.247476886Z", + "commission": { + "commission_rates": { + "rate": "0.120000000000000000", + "max_rate": "0.300000000000000000", + "max_change_rate": "0.010000000000000000" + }, + "update_time": "2019-11-15T14:03:28.153247409Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "kavavaloper1k760ypy9tzhp6l2rmg06sq4n74z0d3rejwwaa0", + "consensus_pubkey": "kavavalconspub1zcjduepqqnxh5k4mhggtdx2u9j9xgq0etpkxpevg333sm954efqema6mn5yqqyf0gw", + "jailed": false, + "status": 2, + "tokens": "25830577485", + "delegator_shares": "25830577485.000000000000000000", + "description": { + "moniker": "novy", + "identity": "5422BE13389B2B4D", + "website": "https://novy.pw", + "security_contact": "", + "details": "Let's validate this network!" + }, + "unbonding_height": "0", + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.100000000000000000", + "max_rate": "0.200000000000000000", + "max_change_rate": "0.010000000000000000" + }, + "update_time": "2019-12-29T20:44:00.222304348Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "kavavaloper1h9ulmhqv5e2373khk6s9n0wtrfc5qavre09fxl", + "consensus_pubkey": "kavavalconspub1zcjduepqjqsd0jkhftta7fuc9e45f3yat25ja9xknzrdqye6zk9kyx40wkaq50hcdv", + "jailed": false, + "status": 2, + "tokens": "23225502889", + "delegator_shares": "23225502889.000000000000000000", + "description": { + "moniker": "alexDcrypto", + "identity": "", + "website": "", + "security_contact": "", + "details": "" + }, + "unbonding_height": "0", + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.190000000000000000", + "max_rate": "0.200000000000000000", + "max_change_rate": "0.010000000000000000" + }, + "update_time": "2020-01-02T22:54:47.953329027Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "kavavaloper1hezl6xwva28xt0hk204dllalagenmfsnuu50j6", + "consensus_pubkey": "kavavalconspub1zcjduepqwf05tj86hm83n55lha6zgeyf9jyyz053cwq957nhhv933v9z9sgqdcmt5s", + "jailed": false, + "status": 2, + "tokens": "169401000000", + "delegator_shares": "169401000000.000000000000000000", + "description": { + "moniker": "01node.com", + "identity": "22823CD59617B8E3", + "website": "https://01node.com", + "security_contact": "", + "details": "01node Staking Services" + }, + "unbonding_height": "0", + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.100000000000000000", + "max_rate": "0.150000000000000000", + "max_change_rate": "0.010000000000000000" + }, + "update_time": "2019-11-15T14:00:18.218278987Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "kavavaloper1c9ye54e3pzwm3e0zpdlel6pnavrj9qqvh0atdq", + "consensus_pubkey": "kavavalconspub1zcjduepqc8585309s34yq92calayzy4xc4hu8rrx4pkrymewdy5qyjkx5tjqjgp7tq", + "jailed": false, + "status": 2, + "tokens": "4121140835669", + "delegator_shares": "4121140835669.000000000000000000", + "description": { + "moniker": "StakeWith.Us", + "identity": "609F83752053AD57", + "website": "https://stakewith.us", + "security_contact": "node@stakewith.us", + "details": "Secured Staking Made Easy. Put Your Crypto to Work - Hassle Free. Disclaimer: Delegators should understand that delegation comes with slashing risk. By delegating to StakeWithUs Pte Ltd, you acknowledge that StakeWithUs Pte Ltd is not liable for any losses on your investment." + }, + "unbonding_height": "0", + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.100000000000000000", + "max_rate": "0.250000000000000000", + "max_change_rate": "0.050000000000000000" + }, + "update_time": "2019-11-05T14:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "kavavaloper1cj9cdx9mg95lhvpquym08ncgzpjvhmnwdvm5kc", + "consensus_pubkey": "kavavalconspub1zcjduepq3w00ypwl5652c8unvwhn4urpkpcpztkusgqsdztdsq8fhycw224qwlcd33", + "jailed": false, + "status": 2, + "tokens": "933362497", + "delegator_shares": "933362497.000000000000000000", + "description": { + "moniker": "Sifu Ventures", + "identity": "", + "website": "http://sifu.ventures", + "security_contact": "", + "details": "dPos Tokens Investment Fund" + }, + "unbonding_height": "0", + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.050000000000000000", + "max_rate": "0.200000000000000000", + "max_change_rate": "0.010000000000000000" + }, + "update_time": "2020-03-24T08:49:40.805033852Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "kavavaloper1ceun2qqw65qce5la33j8zv8ltyyaqqfctl35n4", + "consensus_pubkey": "kavavalconspub1zcjduepqsqtuf26ph4szcxutxscz5eq0g9tnqvedhdf203cha77m8xlnuy0sy3nky9", + "jailed": false, + "status": 2, + "tokens": "2451388401349", + "delegator_shares": "2451388401349.000000000000000000", + "description": { + "moniker": "sikka", + "identity": "", + "website": "https://sikka.tech", + "security_contact": "", + "details": "" + }, + "unbonding_height": "0", + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.010000000000000000", + "max_rate": "1.000000000000000000", + "max_change_rate": "1.000000000000000000" + }, + "update_time": "2019-11-05T14:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "kavavaloper168g9nn9vnamhsnjkm7uqqee9f3v07flgwwddf9", + "consensus_pubkey": "kavavalconspub1zcjduepq29lrp34q3dveyt8r2mnc3kd82y5a5dsq39laj6yhkwans0ay2u9smmru3r", + "jailed": false, + "status": 2, + "tokens": "23202449322", + "delegator_shares": "23202449322.000000000000000000", + "description": { + "moniker": "sebytza05", + "identity": "", + "website": "", + "security_contact": "", + "details": "" + }, + "unbonding_height": "0", + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.140000000000000000", + "max_rate": "0.200000000000000000", + "max_change_rate": "0.010000000000000000" + }, + "update_time": "2019-11-15T14:00:18.218278987Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "kavavaloper1645czvg787l0jr6mawhs9dm3mljnggj003yed9", + "consensus_pubkey": "kavavalconspub1zcjduepqws4aku5x2z0806kpyd750yzdpwrergpj82akyj0zz4ft6t38c4esdztwm8", + "jailed": false, + "status": 2, + "tokens": "23136261400", + "delegator_shares": "23143203500.319736666961944921", + "description": { + "moniker": "Mike Pocket", + "identity": "C57B29418AE33CC0", + "website": "", + "security_contact": "", + "details": "GO KAVA GO" + }, + "unbonding_height": "2123509", + "unbonding_time": "2020-05-24T00:52:50.9426213Z", + "commission": { + "commission_rates": { + "rate": "0.200000000000000000", + "max_rate": "0.200000000000000000", + "max_change_rate": "0.010000000000000000" + }, + "update_time": "2020-03-08T11:13:06.439174757Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "kavavaloper16lnfpgn6llvn4fstg5nfrljj6aaxyee9z59jqd", + "consensus_pubkey": "kavavalconspub1zcjduepquwh8pq39pwddp3etxk82d3u57kdfnvftgxamx4kcqduk8q02c3xqsyfaaa", + "jailed": false, + "status": 2, + "tokens": "2833230807310", + "delegator_shares": "2833230807310.000000000000000000", + "description": { + "moniker": "pylonvalidator", + "identity": "0979483D4F669CFF", + "website": "https://pylonvalidator.com", + "security_contact": "security@pylonvalidator.com", + "details": "'It doesn't matter whether the cat is black or white, as long as it catches mice.' --Deng Xiaoping" + }, + "unbonding_height": "0", + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.100000000000000000", + "max_rate": "1.000000000000000000", + "max_change_rate": "1.000000000000000000" + }, + "update_time": "2019-11-05T14:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "kavavaloper1m9y0c7j7wxyu3nqtmeevyfzzpga8jhdyqw42wx", + "consensus_pubkey": "kavavalconspub1zcjduepqqpq85gztxdvheh48pugwp624mm6ey6u3464pj80c6s2epa8m9uwq4xr44m", + "jailed": false, + "status": 2, + "tokens": "1255000000000", + "delegator_shares": "1255000000000.000000000000000000", + "description": { + "moniker": "B-Harvest", + "identity": "8957C5091FBF4192", + "website": "https://bharvest.io", + "security_contact": "contact@bharvest.io", + "details": "" + }, + "unbonding_height": "0", + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.100000000000000000", + "max_rate": "0.300000000000000000", + "max_change_rate": "0.010000000000000000" + }, + "update_time": "2019-11-20T04:34:50.0221158Z" + }, + "min_self_delegation": "1000" + }, + { + "operator_address": "kavavaloper1mu78xhlr705mzgwqykcafp4xy3kgatvwzrww8z", + "consensus_pubkey": "kavavalconspub1zcjduepqhux83t9q55l0em60vq5a0p22zpf6kcqk3qs7cyzcc5huhycp6qnsutwsz3", + "jailed": false, + "status": 2, + "tokens": "21000000000", + "delegator_shares": "21000000000.000000000000000000", + "description": { + "moniker": "joesatri", + "identity": "649DD29EE41766EB", + "website": "", + "security_contact": "", + "details": "Game of Stakes Never Been Jailed Crew | Kava Founder Badge" + }, + "unbonding_height": "0", + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.110000000000000000", + "max_rate": "0.200000000000000000", + "max_change_rate": "0.010000000000000000" + }, + "update_time": "2019-11-15T15:01:47.310662882Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "kavavaloper1uvz0vus7ktxt47cermscwe3k9gs7h9ag05sh6g", + "consensus_pubkey": "kavavalconspub1zcjduepq06xpflh9qkvgax8avl4wen49z48svsv4vplxk2jp2p4qx2htckzsfe2mwq", + "jailed": false, + "status": 2, + "tokens": "32995000000", + "delegator_shares": "32995000000.000000000000000000", + "description": { + "moniker": "Genesis Lab", + "identity": "C1A123F2723041F0", + "website": "https://genesislab.net", + "security_contact": "", + "details": "Genesis Lab is a blockchain-focused development company and validation nodes operator in PoS networks" + }, + "unbonding_height": "0", + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.070000000000000000", + "max_rate": "0.200000000000000000", + "max_change_rate": "0.010000000000000000" + }, + "update_time": "2019-11-15T14:15:12.174174763Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "kavavaloper1udg4pal8c9gffv4l7zhvza027z0y345gd6esa6", + "consensus_pubkey": "kavavalconspub1zcjduepqpdjehvuwljjjp5se8t9xselu0hlneh2np3vrxwd0f4v6csdahclqktmkdp", + "jailed": false, + "status": 2, + "tokens": "1739652025086", + "delegator_shares": "1739652025086.000000000000000000", + "description": { + "moniker": "ATEAM", + "identity": "0CB9A4E7643FF992", + "website": "", + "security_contact": "", + "details": "Kava_Founding member | Cosmos_GOS: Never Jailed \u0026 Top-Tier | Terra_Validator Drill: Top 3 | IOV_Validator candidates score for mainnet: Top 5 | Lino_Founding Validator Prize Winners: Top 7 | IRISnet_Nyancat: Perfect score" + }, + "unbonding_height": "0", + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.050000000000000000", + "max_rate": "0.300000000000000000", + "max_change_rate": "0.100000000000000000" + }, + "update_time": "2019-11-19T01:30:06.727558554Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "kavavaloper1u0kfndes0pf8dstaunsgumv7scsnmy09p3ln9r", + "consensus_pubkey": "kavavalconspub1zcjduepqxzxd363ej2v0kljvfvy5ff4dka90gnkkfemej9p6rkqv3zac9qhsy8p567", + "jailed": false, + "status": 2, + "tokens": "4370445500000", + "delegator_shares": "4370445500000.000000000000000000", + "description": { + "moniker": "SNZPool", + "identity": "FF2019D4CF1F3185", + "website": "https://snzholding.com", + "security_contact": "", + "details": "SNZ Pool is a professional \u0026 reliable POS validator for a dozen of projects like Cosmos, IRISnet, EOS, ONT, Loom, etc." + }, + "unbonding_height": "0", + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.100000000000000000", + "max_rate": "0.200000000000000000", + "max_change_rate": "0.100000000000000000" + }, + "update_time": "2019-11-15T14:18:22.510513847Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "kavavaloper1u3jf6c2f85kmjldxsncnhsdp44nac7v5j7vzpc", + "consensus_pubkey": "kavavalconspub1zcjduepqvd3xz6346n447pvl3s3s73ee3zwwn54f4ejwjfue3ppvpjgdfxwqu95mqu", + "jailed": false, + "status": 2, + "tokens": "3304153570689", + "delegator_shares": "3304153570689.000000000000000000", + "description": { + "moniker": "HuobiPool", + "identity": "23536C5BDE3EB949", + "website": "https://www.huobipool.com/", + "security_contact": "", + "details": "Huobi Pool is a sub-brand of Huobi Group, which is an important part of the global ecological strategy of Huobi.Huobi Pool has become one of the largest POS communities in the Asia- Pacific region, the leading POW pool and nodes of a number of public chains." + }, + "unbonding_height": "0", + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.100000000000000000", + "max_rate": "0.200000000000000000", + "max_change_rate": "0.010000000000000000" + }, + "update_time": "2019-12-12T15:50:40.940881395Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "kavavaloper1u3hqe2m7vm59l30tyaqd3zurz864dlsg7nq83f", + "consensus_pubkey": "kavavalconspub1zcjduepqrtnnezp4g67f7hh8fs7gtx23pmdfjwu37uqguq4hsrglqkfmyensl4xvdt", + "jailed": false, + "status": 2, + "tokens": "3308604907366", + "delegator_shares": "3308935800933.172872447705074902", + "description": { + "moniker": "Delchain", + "identity": "", + "website": "", + "security_contact": "", + "details": "" + }, + "unbonding_height": "388052", + "unbonding_time": "2020-01-06T09:05:10.544078799Z", + "commission": { + "commission_rates": { + "rate": "0.050000000000000000", + "max_rate": "0.200000000000000000", + "max_change_rate": "0.010000000000000000" + }, + "update_time": "2019-11-05T14:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "kavavaloper1u7vsaanwt4e5mdzmxuqurmccxjka3h0ns2n3f5", + "consensus_pubkey": "kavavalconspub1zcjduepq7uy7ln7afmgrfutfpzhyy0llcndntx9q55nl5puqxcq5dqdzrnqswahrha", + "jailed": false, + "status": 2, + "tokens": "1000009950010", + "delegator_shares": "1000009950010.000000000000000000", + "description": { + "moniker": "BiKi Pool", + "identity": "", + "website": "https://www.biki.com", + "security_contact": "", + "details": "Popular Token's Choice" + }, + "unbonding_height": "0", + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.100000000000000000", + "max_rate": "0.200000000000000000", + "max_change_rate": "0.010000000000000000" + }, + "update_time": "2020-03-04T12:26:32.258743177Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "kavavaloper1aj9r9ll8m72xr5pmxr9fmum88k864tqg39nkfu", + "consensus_pubkey": "kavavalconspub1zcjduepq9nq9gdnvtl5as9sgl92exde7hju797hl20c9htje2chgwnlkwluq8hmtu0", + "jailed": false, + "status": 2, + "tokens": "21000000000", + "delegator_shares": "21000000000.000000000000000000", + "description": { + "moniker": "kytzu", + "identity": "909A480D5643CCC5", + "website": "https://www.linkedin.com/in/calinchitu", + "security_contact": "", + "details": "Blockchain consultant and developer" + }, + "unbonding_height": "0", + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.190000000000000000", + "max_rate": "0.200000000000000000", + "max_change_rate": "0.010000000000000000" + }, + "update_time": "2019-11-15T16:04:53.477387115Z" + }, + "min_self_delegation": "1000000" + }, + { + "operator_address": "kavavaloper1ajwfalplxnhkwhsycfax36yyyxpxz3450s800x", + "consensus_pubkey": "kavavalconspub1zcjduepq33ekkklqez4tdd37mrvptrkawejnj0p5caa0a6c7efqs8n7eg37qa2vega", + "jailed": false, + "status": 2, + "tokens": "61532020969", + "delegator_shares": "61532020969.000000000000000000", + "description": { + "moniker": "Ryabina.io - Staking provider in awesome networks", + "identity": "6B1C8FDD84CF4ACD", + "website": "https://ryabina.io", + "security_contact": "", + "details": "" + }, + "unbonding_height": "0", + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.010000000000000000", + "max_rate": "0.200000000000000000", + "max_change_rate": "0.010000000000000000" + }, + "update_time": "2020-02-24T18:08:47.865265697Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "kavavaloper17wcggpjx007uc09s8y4hwrj8f228mlwez945ey", + "consensus_pubkey": "kavavalconspub1zcjduepq5jtcd7kxpft40l65gm5p2ecg8rcxp59nml424u88lxkpxu6yl9cq6hxvzd", + "jailed": false, + "status": 2, + "tokens": "23092086042", + "delegator_shares": "23092086042.000000000000000000", + "description": { + "moniker": "Inotel", + "identity": "975D494265B1AC25", + "website": "", + "security_contact": "", + "details": "" + }, + "unbonding_height": "0", + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.100000000000000000", + "max_rate": "0.200000000000000000", + "max_change_rate": "0.010000000000000000" + }, + "update_time": "2019-11-15T14:04:03.245058425Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "kavavaloper17498ffqdj49zca4jm7mdf3eevq7uhcsgjvm0uk", + "consensus_pubkey": "kavavalconspub1zcjduepq0mk39ccslman3ame4s3dn5exml8upqearp089sa5tae6pchdyrcsmvwmhn", + "jailed": false, + "status": 2, + "tokens": "23794000000", + "delegator_shares": "23794000000.000000000000000000", + "description": { + "moniker": "kaval", + "identity": "5281C9C7BE5C2646", + "website": "", + "security_contact": "", + "details": "" + }, + "unbonding_height": "0", + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.550000000000000000", + "max_rate": "1.000000000000000000", + "max_change_rate": "0.010000000000000000" + }, + "update_time": "2020-03-07T10:24:27.851934685Z" + }, + "min_self_delegation": "1" + } + ] +} \ No newline at end of file diff --git a/mock/ext-api-data/kava-api_txs__limit_25_message.sender_kava1l8va9zyl50cpzv447c694k3jndelc9ygtfll2m_page_1.json b/mock/ext-api-data/kava-api_txs__limit_25_message.sender_kava1l8va9zyl50cpzv447c694k3jndelc9ygtfll2m_page_1.json new file mode 100644 index 000000000..f65e7f75c --- /dev/null +++ b/mock/ext-api-data/kava-api_txs__limit_25_message.sender_kava1l8va9zyl50cpzv447c694k3jndelc9ygtfll2m_page_1.json @@ -0,0 +1,127 @@ +{ + "total_count": "1", + "count": "1", + "page_number": "1", + "page_total": "1", + "limit": "25", + "txs": [ + { + "height": "1101012", + "txhash": "30EFE9E830D317F84629F9DC35177577DF6713D78D354C2C469DE633900303BC", + "raw_log": "[{\"msg_index\":0,\"success\":true,\"log\":\"\",\"events\":[{\"type\":\"message\",\"attributes\":[{\"key\":\"action\",\"value\":\"send\"},{\"key\":\"sender\",\"value\":\"kava1l8va9zyl50cpzv447c694k3jndelc9ygtfll2m\"},{\"key\":\"module\",\"value\":\"bank\"}]},{\"type\":\"transfer\",\"attributes\":[{\"key\":\"recipient\",\"value\":\"kava1ys70jvnajkv88529ys6urjcyle3k2j9r24g6a7\"},{\"key\":\"amount\",\"value\":\"9998000ukava\"}]}]}]", + "logs": [ + { + "msg_index": 0, + "success": true, + "log": "", + "events": [ + { + "type": "message", + "attributes": [ + { + "key": "action", + "value": "send" + }, + { + "key": "sender", + "value": "kava1l8va9zyl50cpzv447c694k3jndelc9ygtfll2m" + }, + { + "key": "module", + "value": "bank" + } + ] + }, + { + "type": "transfer", + "attributes": [ + { + "key": "recipient", + "value": "kava1ys70jvnajkv88529ys6urjcyle3k2j9r24g6a7" + }, + { + "key": "amount", + "value": "9998000ukava" + } + ] + } + ] + } + ], + "gas_wanted": "200000", + "gas_used": "68317", + "tx": { + "type": "cosmos-sdk/StdTx", + "value": { + "msg": [ + { + "type": "cosmos-sdk/MsgSend", + "value": { + "from_address": "kava1l8va9zyl50cpzv447c694k3jndelc9ygtfll2m", + "to_address": "kava1ys70jvnajkv88529ys6urjcyle3k2j9r24g6a7", + "amount": [ + { + "denom": "ukava", + "amount": "9998000" + } + ] + } + } + ], + "fee": { + "amount": [ + { + "denom": "ukava", + "amount": "1000" + } + ], + "gas": "200000" + }, + "signatures": [ + { + "pub_key": { + "type": "tendermint/PubKeySecp256k1", + "value": "AvgGasyPvRpG68UQ6IGPVKN+HrJix24tgwcYXIcIfsna" + }, + "signature": "iST3iM8TtkR5VHTFFhJE1zi+Nh6Invrg4hKgLEY2HCQ+R6Qj9L3jET4yRtAg6+QxitJab27+etoPjJbK20V/Cw==" + } + ], + "memo": "100009547" + } + }, + "timestamp": "2020-02-11T01:33:46Z", + "events": [ + { + "type": "message", + "attributes": [ + { + "key": "action", + "value": "send" + }, + { + "key": "sender", + "value": "kava1l8va9zyl50cpzv447c694k3jndelc9ygtfll2m" + }, + { + "key": "module", + "value": "bank" + } + ] + }, + { + "type": "transfer", + "attributes": [ + { + "key": "recipient", + "value": "kava1ys70jvnajkv88529ys6urjcyle3k2j9r24g6a7" + }, + { + "key": "amount", + "value": "9998000ukava" + } + ] + } + ] + } + ] +} \ No newline at end of file diff --git a/mock/ext-api-data/kava-api_txs__limit_25_page_1_transfer.recipient_kava1l8va9zyl50cpzv447c694k3jndelc9ygtfll2m.json b/mock/ext-api-data/kava-api_txs__limit_25_page_1_transfer.recipient_kava1l8va9zyl50cpzv447c694k3jndelc9ygtfll2m.json new file mode 100644 index 000000000..c20a2b4c6 --- /dev/null +++ b/mock/ext-api-data/kava-api_txs__limit_25_page_1_transfer.recipient_kava1l8va9zyl50cpzv447c694k3jndelc9ygtfll2m.json @@ -0,0 +1,127 @@ +{ + "total_count": "1", + "count": "1", + "page_number": "1", + "page_total": "1", + "limit": "25", + "txs": [ + { + "height": "793039", + "txhash": "84FFA6CC8428B7A5E82003A7BCA6D1FAB2DF296AD18BE73EE61CBCBF67623880", + "raw_log": "[{\"msg_index\":0,\"success\":true,\"log\":\"\",\"events\":[{\"type\":\"message\",\"attributes\":[{\"key\":\"action\",\"value\":\"send\"},{\"key\":\"sender\",\"value\":\"kava1g2rqynrdw22ca7y8a4cj3sncylspsg7r04fcr7\"},{\"key\":\"module\",\"value\":\"bank\"}]},{\"type\":\"transfer\",\"attributes\":[{\"key\":\"recipient\",\"value\":\"kava1l8va9zyl50cpzv447c694k3jndelc9ygtfll2m\"},{\"key\":\"amount\",\"value\":\"9999000ukava\"}]}]}]", + "logs": [ + { + "msg_index": 0, + "success": true, + "log": "", + "events": [ + { + "type": "message", + "attributes": [ + { + "key": "action", + "value": "send" + }, + { + "key": "sender", + "value": "kava1g2rqynrdw22ca7y8a4cj3sncylspsg7r04fcr7" + }, + { + "key": "module", + "value": "bank" + } + ] + }, + { + "type": "transfer", + "attributes": [ + { + "key": "recipient", + "value": "kava1l8va9zyl50cpzv447c694k3jndelc9ygtfll2m" + }, + { + "key": "amount", + "value": "9999000ukava" + } + ] + } + ] + } + ], + "gas_wanted": "200000", + "gas_used": "70019", + "tx": { + "type": "cosmos-sdk/StdTx", + "value": { + "msg": [ + { + "type": "cosmos-sdk/MsgSend", + "value": { + "from_address": "kava1g2rqynrdw22ca7y8a4cj3sncylspsg7r04fcr7", + "to_address": "kava1l8va9zyl50cpzv447c694k3jndelc9ygtfll2m", + "amount": [ + { + "denom": "ukava", + "amount": "9999000" + } + ] + } + } + ], + "fee": { + "amount": [ + { + "denom": "ukava", + "amount": "1000" + } + ], + "gas": "200000" + }, + "signatures": [ + { + "pub_key": { + "type": "tendermint/PubKeySecp256k1", + "value": "As3eDIXFkLdMkBep+aV+6q9ccVRkA94snsXq2iL5bCTt" + }, + "signature": "QFx3iARLhLeuCCHRUbFAZTePzq+vGAYd4lB/F4JuCGYw1TrfIbAzJhmUHbXHcB/GC+f7Myv5xNrnlCPfCR53uA==" + } + ], + "memo": "" + } + }, + "timestamp": "2020-01-17T11:17:36Z", + "events": [ + { + "type": "message", + "attributes": [ + { + "key": "action", + "value": "send" + }, + { + "key": "sender", + "value": "kava1g2rqynrdw22ca7y8a4cj3sncylspsg7r04fcr7" + }, + { + "key": "module", + "value": "bank" + } + ] + }, + { + "type": "transfer", + "attributes": [ + { + "key": "recipient", + "value": "kava1l8va9zyl50cpzv447c694k3jndelc9ygtfll2m" + }, + { + "key": "amount", + "value": "9999000ukava" + } + ] + } + ] + } + ] +} \ No newline at end of file diff --git a/mock/ext-api-data/kin-api_accounts_GBHKUZ7C2SZ5N3X2S7O6TT6LNUWSEA2BXMSR5GTTSR6VZARSVAXIQNGH_payments__limit_25_order_desc.json b/mock/ext-api-data/kin-api_accounts_GBHKUZ7C2SZ5N3X2S7O6TT6LNUWSEA2BXMSR5GTTSR6VZARSVAXIQNGH_payments__limit_25_order_desc.json new file mode 100644 index 000000000..5ae11e3a6 --- /dev/null +++ b/mock/ext-api-data/kin-api_accounts_GBHKUZ7C2SZ5N3X2S7O6TT6LNUWSEA2BXMSR5GTTSR6VZARSVAXIQNGH_payments__limit_25_order_desc.json @@ -0,0 +1,750 @@ +{ + "_links": { + "self": { + "href": "https://horizon-block-explorer.kininfrastructure.com/accounts/GBHKUZ7C2SZ5N3X2S7O6TT6LNUWSEA2BXMSR5GTTSR6VZARSVAXIQNGH/payments?cursor=\u0026limit=25\u0026order=desc" + }, + "next": { + "href": "https://horizon-block-explorer.kininfrastructure.com/accounts/GBHKUZ7C2SZ5N3X2S7O6TT6LNUWSEA2BXMSR5GTTSR6VZARSVAXIQNGH/payments?cursor=35733968989097985\u0026limit=25\u0026order=desc" + }, + "prev": { + "href": "https://horizon-block-explorer.kininfrastructure.com/accounts/GBHKUZ7C2SZ5N3X2S7O6TT6LNUWSEA2BXMSR5GTTSR6VZARSVAXIQNGH/payments?cursor=35876948450299905\u0026limit=25\u0026order=asc" + } + }, + "_embedded": { + "records": [ + { + "_links": { + "self": { + "href": "https://horizon-block-explorer.kininfrastructure.com/operations/35876948450299905" + }, + "transaction": { + "href": "https://horizon-block-explorer.kininfrastructure.com/transactions/1f84fef40d35a0ac46cd286063d517507d3ef553ce3c5284156b96267d21cf61" + }, + "effects": { + "href": "https://horizon-block-explorer.kininfrastructure.com/operations/35876948450299905/effects" + }, + "succeeds": { + "href": "https://horizon-block-explorer.kininfrastructure.com/effects?order=desc\u0026cursor=35876948450299905" + }, + "precedes": { + "href": "https://horizon-block-explorer.kininfrastructure.com/effects?order=asc\u0026cursor=35876948450299905" + } + }, + "id": "35876948450299905", + "paging_token": "35876948450299905", + "source_account": "GBHKUZ7C2SZ5N3X2S7O6TT6LNUWSEA2BXMSR5GTTSR6VZARSVAXIQNGH", + "type": "create_account", + "type_i": 0, + "created_at": "2020-05-13T08:14:53Z", + "transaction_hash": "1f84fef40d35a0ac46cd286063d517507d3ef553ce3c5284156b96267d21cf61", + "starting_balance": "382691.56353", + "funder": "GBHKUZ7C2SZ5N3X2S7O6TT6LNUWSEA2BXMSR5GTTSR6VZARSVAXIQNGH", + "account": "GA6UCXDAYFVSFTAKMDUM5H7FGVLYF6CSDFHZ5X4QRLKG64EDLW6PEWSN" + }, + { + "_links": { + "self": { + "href": "https://horizon-block-explorer.kininfrastructure.com/operations/35871399352672257" + }, + "transaction": { + "href": "https://horizon-block-explorer.kininfrastructure.com/transactions/4188de4157264c5dfbb11d78ddb9fe4fbdb30f2b893c44bcf2d1e07f4b41ce61" + }, + "effects": { + "href": "https://horizon-block-explorer.kininfrastructure.com/operations/35871399352672257/effects" + }, + "succeeds": { + "href": "https://horizon-block-explorer.kininfrastructure.com/effects?order=desc\u0026cursor=35871399352672257" + }, + "precedes": { + "href": "https://horizon-block-explorer.kininfrastructure.com/effects?order=asc\u0026cursor=35871399352672257" + } + }, + "id": "35871399352672257", + "paging_token": "35871399352672257", + "source_account": "GBHKUZ7C2SZ5N3X2S7O6TT6LNUWSEA2BXMSR5GTTSR6VZARSVAXIQNGH", + "type": "payment", + "type_i": 1, + "created_at": "2020-05-13T06:27:12Z", + "transaction_hash": "4188de4157264c5dfbb11d78ddb9fe4fbdb30f2b893c44bcf2d1e07f4b41ce61", + "asset_type": "native", + "from": "GBHKUZ7C2SZ5N3X2S7O6TT6LNUWSEA2BXMSR5GTTSR6VZARSVAXIQNGH", + "to": "GD7J5ZYRUN6GCY7XUP7MA2XPPKVFADYAJPTFMFK6SY5PBS6BX4SZNYUA", + "amount": "2106990.68969" + }, + { + "_links": { + "self": { + "href": "https://horizon-block-explorer.kininfrastructure.com/operations/35871085820084225" + }, + "transaction": { + "href": "https://horizon-block-explorer.kininfrastructure.com/transactions/e2816c4de264e4e561a3509ff32794942a529896f7043527bdab6604de9d8f39" + }, + "effects": { + "href": "https://horizon-block-explorer.kininfrastructure.com/operations/35871085820084225/effects" + }, + "succeeds": { + "href": "https://horizon-block-explorer.kininfrastructure.com/effects?order=desc\u0026cursor=35871085820084225" + }, + "precedes": { + "href": "https://horizon-block-explorer.kininfrastructure.com/effects?order=asc\u0026cursor=35871085820084225" + } + }, + "id": "35871085820084225", + "paging_token": "35871085820084225", + "source_account": "GBHKUZ7C2SZ5N3X2S7O6TT6LNUWSEA2BXMSR5GTTSR6VZARSVAXIQNGH", + "type": "create_account", + "type_i": 0, + "created_at": "2020-05-13T06:21:06Z", + "transaction_hash": "e2816c4de264e4e561a3509ff32794942a529896f7043527bdab6604de9d8f39", + "starting_balance": "1.00000", + "funder": "GBHKUZ7C2SZ5N3X2S7O6TT6LNUWSEA2BXMSR5GTTSR6VZARSVAXIQNGH", + "account": "GD7J5ZYRUN6GCY7XUP7MA2XPPKVFADYAJPTFMFK6SY5PBS6BX4SZNYUA" + }, + { + "_links": { + "self": { + "href": "https://horizon-block-explorer.kininfrastructure.com/operations/35860975466917889" + }, + "transaction": { + "href": "https://horizon-block-explorer.kininfrastructure.com/transactions/91fc518ab3b2d3e869c91dc4871af450b967f1b8591c2b78df4ebeaeff67f936" + }, + "effects": { + "href": "https://horizon-block-explorer.kininfrastructure.com/operations/35860975466917889/effects" + }, + "succeeds": { + "href": "https://horizon-block-explorer.kininfrastructure.com/effects?order=desc\u0026cursor=35860975466917889" + }, + "precedes": { + "href": "https://horizon-block-explorer.kininfrastructure.com/effects?order=asc\u0026cursor=35860975466917889" + } + }, + "id": "35860975466917889", + "paging_token": "35860975466917889", + "source_account": "GBHKUZ7C2SZ5N3X2S7O6TT6LNUWSEA2BXMSR5GTTSR6VZARSVAXIQNGH", + "type": "create_account", + "type_i": 0, + "created_at": "2020-05-13T03:04:50Z", + "transaction_hash": "91fc518ab3b2d3e869c91dc4871af450b967f1b8591c2b78df4ebeaeff67f936", + "starting_balance": "1449999.10000", + "funder": "GBHKUZ7C2SZ5N3X2S7O6TT6LNUWSEA2BXMSR5GTTSR6VZARSVAXIQNGH", + "account": "GCGD3QF5IRUWVKGY23XDANIOKYZTGUKSRTXUYQZ5H5PADAHZFXLZRGDI" + }, + { + "_links": { + "self": { + "href": "https://horizon-block-explorer.kininfrastructure.com/operations/35846127765123073" + }, + "transaction": { + "href": "https://horizon-block-explorer.kininfrastructure.com/transactions/fb9573473914636f9dfcc95667e33e9f00793da16fa302344ae21bedb05be48a" + }, + "effects": { + "href": "https://horizon-block-explorer.kininfrastructure.com/operations/35846127765123073/effects" + }, + "succeeds": { + "href": "https://horizon-block-explorer.kininfrastructure.com/effects?order=desc\u0026cursor=35846127765123073" + }, + "precedes": { + "href": "https://horizon-block-explorer.kininfrastructure.com/effects?order=asc\u0026cursor=35846127765123073" + } + }, + "id": "35846127765123073", + "paging_token": "35846127765123073", + "source_account": "GBHKUZ7C2SZ5N3X2S7O6TT6LNUWSEA2BXMSR5GTTSR6VZARSVAXIQNGH", + "type": "create_account", + "type_i": 0, + "created_at": "2020-05-12T22:16:42Z", + "transaction_hash": "fb9573473914636f9dfcc95667e33e9f00793da16fa302344ae21bedb05be48a", + "starting_balance": "7213285.00000", + "funder": "GBHKUZ7C2SZ5N3X2S7O6TT6LNUWSEA2BXMSR5GTTSR6VZARSVAXIQNGH", + "account": "GBMAIJKLMHSKAVMTI7AMHWBXM522LJOC2AMB3XZA2ZMGXTSL5GNGVLSX" + }, + { + "_links": { + "self": { + "href": "https://horizon-block-explorer.kininfrastructure.com/operations/35842472747794433" + }, + "transaction": { + "href": "https://horizon-block-explorer.kininfrastructure.com/transactions/0ab3c335134ed91d79bbbbad043cca6f5edbf31fee1785db000618859a742961" + }, + "effects": { + "href": "https://horizon-block-explorer.kininfrastructure.com/operations/35842472747794433/effects" + }, + "succeeds": { + "href": "https://horizon-block-explorer.kininfrastructure.com/effects?order=desc\u0026cursor=35842472747794433" + }, + "precedes": { + "href": "https://horizon-block-explorer.kininfrastructure.com/effects?order=asc\u0026cursor=35842472747794433" + } + }, + "id": "35842472747794433", + "paging_token": "35842472747794433", + "source_account": "GBHKUZ7C2SZ5N3X2S7O6TT6LNUWSEA2BXMSR5GTTSR6VZARSVAXIQNGH", + "type": "payment", + "type_i": 1, + "created_at": "2020-05-12T21:05:47Z", + "transaction_hash": "0ab3c335134ed91d79bbbbad043cca6f5edbf31fee1785db000618859a742961", + "asset_type": "native", + "from": "GBHKUZ7C2SZ5N3X2S7O6TT6LNUWSEA2BXMSR5GTTSR6VZARSVAXIQNGH", + "to": "GCI2AFKGQ3JHSNHUYDRIYOOORC4V6IOICO62E73F6NA6IQFTGH7W6YJO", + "amount": "50.00000" + }, + { + "_links": { + "self": { + "href": "https://horizon-block-explorer.kininfrastructure.com/operations/35833809798836225" + }, + "transaction": { + "href": "https://horizon-block-explorer.kininfrastructure.com/transactions/1524d2b591e8033e33ecd4dd7a729312125908ea1181d12a4da872c233b873d8" + }, + "effects": { + "href": "https://horizon-block-explorer.kininfrastructure.com/operations/35833809798836225/effects" + }, + "succeeds": { + "href": "https://horizon-block-explorer.kininfrastructure.com/effects?order=desc\u0026cursor=35833809798836225" + }, + "precedes": { + "href": "https://horizon-block-explorer.kininfrastructure.com/effects?order=asc\u0026cursor=35833809798836225" + } + }, + "id": "35833809798836225", + "paging_token": "35833809798836225", + "source_account": "GBHKUZ7C2SZ5N3X2S7O6TT6LNUWSEA2BXMSR5GTTSR6VZARSVAXIQNGH", + "type": "payment", + "type_i": 1, + "created_at": "2020-05-12T18:17:42Z", + "transaction_hash": "1524d2b591e8033e33ecd4dd7a729312125908ea1181d12a4da872c233b873d8", + "asset_type": "native", + "from": "GBHKUZ7C2SZ5N3X2S7O6TT6LNUWSEA2BXMSR5GTTSR6VZARSVAXIQNGH", + "to": "GDEYJYEGU3XNZM5Q3JI3AEDXSVIQMSPPJURVHHIFV6BJL65ZAGCYOU3A", + "amount": "3521990.00000" + }, + { + "_links": { + "self": { + "href": "https://horizon-block-explorer.kininfrastructure.com/operations/35832933625516033" + }, + "transaction": { + "href": "https://horizon-block-explorer.kininfrastructure.com/transactions/67586614cd531da0c7c7bae22ca0598d138c46435c0bc20ef03464cd0d31a59b" + }, + "effects": { + "href": "https://horizon-block-explorer.kininfrastructure.com/operations/35832933625516033/effects" + }, + "succeeds": { + "href": "https://horizon-block-explorer.kininfrastructure.com/effects?order=desc\u0026cursor=35832933625516033" + }, + "precedes": { + "href": "https://horizon-block-explorer.kininfrastructure.com/effects?order=asc\u0026cursor=35832933625516033" + } + }, + "id": "35832933625516033", + "paging_token": "35832933625516033", + "source_account": "GBHKUZ7C2SZ5N3X2S7O6TT6LNUWSEA2BXMSR5GTTSR6VZARSVAXIQNGH", + "type": "create_account", + "type_i": 0, + "created_at": "2020-05-12T18:00:42Z", + "transaction_hash": "67586614cd531da0c7c7bae22ca0598d138c46435c0bc20ef03464cd0d31a59b", + "starting_balance": "10.00000", + "funder": "GBHKUZ7C2SZ5N3X2S7O6TT6LNUWSEA2BXMSR5GTTSR6VZARSVAXIQNGH", + "account": "GDEYJYEGU3XNZM5Q3JI3AEDXSVIQMSPPJURVHHIFV6BJL65ZAGCYOU3A" + }, + { + "_links": { + "self": { + "href": "https://horizon-block-explorer.kininfrastructure.com/operations/35831928603242497" + }, + "transaction": { + "href": "https://horizon-block-explorer.kininfrastructure.com/transactions/384388d24a51d9fa71c314d175ecc4afb4a39734c7e628fda0c91ce112ecaf49" + }, + "effects": { + "href": "https://horizon-block-explorer.kininfrastructure.com/operations/35831928603242497/effects" + }, + "succeeds": { + "href": "https://horizon-block-explorer.kininfrastructure.com/effects?order=desc\u0026cursor=35831928603242497" + }, + "precedes": { + "href": "https://horizon-block-explorer.kininfrastructure.com/effects?order=asc\u0026cursor=35831928603242497" + } + }, + "id": "35831928603242497", + "paging_token": "35831928603242497", + "source_account": "GBHKUZ7C2SZ5N3X2S7O6TT6LNUWSEA2BXMSR5GTTSR6VZARSVAXIQNGH", + "type": "create_account", + "type_i": 0, + "created_at": "2020-05-12T17:41:12Z", + "transaction_hash": "384388d24a51d9fa71c314d175ecc4afb4a39734c7e628fda0c91ce112ecaf49", + "starting_balance": "509751.60000", + "funder": "GBHKUZ7C2SZ5N3X2S7O6TT6LNUWSEA2BXMSR5GTTSR6VZARSVAXIQNGH", + "account": "GATZKATB7GEQNRKKIGCQKSKBRK4OSL3VRZROTQPVSGOYMDR6CSINONNJ" + }, + { + "_links": { + "self": { + "href": "https://horizon-block-explorer.kininfrastructure.com/operations/35831769689432065" + }, + "transaction": { + "href": "https://horizon-block-explorer.kininfrastructure.com/transactions/b9931b144c93b416ca304dceeb04dc32587c569080b11ed7e25599e44c82f448" + }, + "effects": { + "href": "https://horizon-block-explorer.kininfrastructure.com/operations/35831769689432065/effects" + }, + "succeeds": { + "href": "https://horizon-block-explorer.kininfrastructure.com/effects?order=desc\u0026cursor=35831769689432065" + }, + "precedes": { + "href": "https://horizon-block-explorer.kininfrastructure.com/effects?order=asc\u0026cursor=35831769689432065" + } + }, + "id": "35831769689432065", + "paging_token": "35831769689432065", + "source_account": "GBHKUZ7C2SZ5N3X2S7O6TT6LNUWSEA2BXMSR5GTTSR6VZARSVAXIQNGH", + "type": "payment", + "type_i": 1, + "created_at": "2020-05-12T17:38:07Z", + "transaction_hash": "b9931b144c93b416ca304dceeb04dc32587c569080b11ed7e25599e44c82f448", + "asset_type": "native", + "from": "GBHKUZ7C2SZ5N3X2S7O6TT6LNUWSEA2BXMSR5GTTSR6VZARSVAXIQNGH", + "to": "GBQDSG233R5YPPKIYJRKFTAQHXU6EZIFEOBX3SD25DICYM7UZGK5KWXL", + "amount": "2862401.34917" + }, + { + "_links": { + "self": { + "href": "https://horizon-block-explorer.kininfrastructure.com/operations/35819082356064257" + }, + "transaction": { + "href": "https://horizon-block-explorer.kininfrastructure.com/transactions/76de247dc7b7e3fa5398a44ee110851d8c20a2a2bfe1101b7331194a623edb2f" + }, + "effects": { + "href": "https://horizon-block-explorer.kininfrastructure.com/operations/35819082356064257/effects" + }, + "succeeds": { + "href": "https://horizon-block-explorer.kininfrastructure.com/effects?order=desc\u0026cursor=35819082356064257" + }, + "precedes": { + "href": "https://horizon-block-explorer.kininfrastructure.com/effects?order=asc\u0026cursor=35819082356064257" + } + }, + "id": "35819082356064257", + "paging_token": "35819082356064257", + "source_account": "GBHKUZ7C2SZ5N3X2S7O6TT6LNUWSEA2BXMSR5GTTSR6VZARSVAXIQNGH", + "type": "payment", + "type_i": 1, + "created_at": "2020-05-12T13:31:42Z", + "transaction_hash": "76de247dc7b7e3fa5398a44ee110851d8c20a2a2bfe1101b7331194a623edb2f", + "asset_type": "native", + "from": "GBHKUZ7C2SZ5N3X2S7O6TT6LNUWSEA2BXMSR5GTTSR6VZARSVAXIQNGH", + "to": "GCMWV4BHZKMBTXR2DU6TRROYE6CAIMZNYZZI6PPNNBFAXCXVIR2OT62G", + "amount": "1202214.16773" + }, + { + "_links": { + "self": { + "href": "https://horizon-block-explorer.kininfrastructure.com/operations/35815710806609921" + }, + "transaction": { + "href": "https://horizon-block-explorer.kininfrastructure.com/transactions/e4e69fa1c534f1b64cab38690be253985d33f3cb486393f08186c178c9146d5f" + }, + "effects": { + "href": "https://horizon-block-explorer.kininfrastructure.com/operations/35815710806609921/effects" + }, + "succeeds": { + "href": "https://horizon-block-explorer.kininfrastructure.com/effects?order=desc\u0026cursor=35815710806609921" + }, + "precedes": { + "href": "https://horizon-block-explorer.kininfrastructure.com/effects?order=asc\u0026cursor=35815710806609921" + } + }, + "id": "35815710806609921", + "paging_token": "35815710806609921", + "source_account": "GBHKUZ7C2SZ5N3X2S7O6TT6LNUWSEA2BXMSR5GTTSR6VZARSVAXIQNGH", + "type": "create_account", + "type_i": 0, + "created_at": "2020-05-12T12:26:15Z", + "transaction_hash": "e4e69fa1c534f1b64cab38690be253985d33f3cb486393f08186c178c9146d5f", + "starting_balance": "200920.38792", + "funder": "GBHKUZ7C2SZ5N3X2S7O6TT6LNUWSEA2BXMSR5GTTSR6VZARSVAXIQNGH", + "account": "GAX72BTGWQLIVSB7443VNKGY7H6D4K5B7AOKFF5UMHHMRCVK2XSAQO3G" + }, + { + "_links": { + "self": { + "href": "https://horizon-block-explorer.kininfrastructure.com/operations/35807460174491649" + }, + "transaction": { + "href": "https://horizon-block-explorer.kininfrastructure.com/transactions/bdbd4075e6197a97e4732e534f93c7a75a56a6f12770d2ad9a06e2bcd669b871" + }, + "effects": { + "href": "https://horizon-block-explorer.kininfrastructure.com/operations/35807460174491649/effects" + }, + "succeeds": { + "href": "https://horizon-block-explorer.kininfrastructure.com/effects?order=desc\u0026cursor=35807460174491649" + }, + "precedes": { + "href": "https://horizon-block-explorer.kininfrastructure.com/effects?order=asc\u0026cursor=35807460174491649" + } + }, + "id": "35807460174491649", + "paging_token": "35807460174491649", + "source_account": "GBHKUZ7C2SZ5N3X2S7O6TT6LNUWSEA2BXMSR5GTTSR6VZARSVAXIQNGH", + "type": "create_account", + "type_i": 0, + "created_at": "2020-05-12T09:46:08Z", + "transaction_hash": "bdbd4075e6197a97e4732e534f93c7a75a56a6f12770d2ad9a06e2bcd669b871", + "starting_balance": "210000.00000", + "funder": "GBHKUZ7C2SZ5N3X2S7O6TT6LNUWSEA2BXMSR5GTTSR6VZARSVAXIQNGH", + "account": "GCWYBCAZLPQTDLKZOMWGCIKYMKFK6AYKGS46Z6IHWQ4R67FMDRSGREMQ" + }, + { + "_links": { + "self": { + "href": "https://horizon-block-explorer.kininfrastructure.com/operations/35786724072296449" + }, + "transaction": { + "href": "https://horizon-block-explorer.kininfrastructure.com/transactions/9387b2f623dfc60491616dd0b3e51ea12773ef7a6154d71660eb0467d5924a26" + }, + "effects": { + "href": "https://horizon-block-explorer.kininfrastructure.com/operations/35786724072296449/effects" + }, + "succeeds": { + "href": "https://horizon-block-explorer.kininfrastructure.com/effects?order=desc\u0026cursor=35786724072296449" + }, + "precedes": { + "href": "https://horizon-block-explorer.kininfrastructure.com/effects?order=asc\u0026cursor=35786724072296449" + } + }, + "id": "35786724072296449", + "paging_token": "35786724072296449", + "source_account": "GBHKUZ7C2SZ5N3X2S7O6TT6LNUWSEA2BXMSR5GTTSR6VZARSVAXIQNGH", + "type": "create_account", + "type_i": 0, + "created_at": "2020-05-12T03:03:39Z", + "transaction_hash": "9387b2f623dfc60491616dd0b3e51ea12773ef7a6154d71660eb0467d5924a26", + "starting_balance": "1001057.00000", + "funder": "GBHKUZ7C2SZ5N3X2S7O6TT6LNUWSEA2BXMSR5GTTSR6VZARSVAXIQNGH", + "account": "GBNLJH6VGCTX4GO6L5WIHIHEZ65LS56PWBLKYJ5TRDBEJACRYM7U3B4R" + }, + { + "_links": { + "self": { + "href": "https://horizon-block-explorer.kininfrastructure.com/operations/35775509912895489" + }, + "transaction": { + "href": "https://horizon-block-explorer.kininfrastructure.com/transactions/ed193af0d6e0f2f0cb20545f02d23e2bb74143267959e77750f75b208a82888b" + }, + "effects": { + "href": "https://horizon-block-explorer.kininfrastructure.com/operations/35775509912895489/effects" + }, + "succeeds": { + "href": "https://horizon-block-explorer.kininfrastructure.com/effects?order=desc\u0026cursor=35775509912895489" + }, + "precedes": { + "href": "https://horizon-block-explorer.kininfrastructure.com/effects?order=asc\u0026cursor=35775509912895489" + } + }, + "id": "35775509912895489", + "paging_token": "35775509912895489", + "source_account": "GBHKUZ7C2SZ5N3X2S7O6TT6LNUWSEA2BXMSR5GTTSR6VZARSVAXIQNGH", + "type": "create_account", + "type_i": 0, + "created_at": "2020-05-11T23:25:54Z", + "transaction_hash": "ed193af0d6e0f2f0cb20545f02d23e2bb74143267959e77750f75b208a82888b", + "starting_balance": "8415499.17415", + "funder": "GBHKUZ7C2SZ5N3X2S7O6TT6LNUWSEA2BXMSR5GTTSR6VZARSVAXIQNGH", + "account": "GAGFPW2F7US2NHS4ZFATHTGCPAHIIWISKURZ6TMV7KJ5E7T7QFHRAFW3" + }, + { + "_links": { + "self": { + "href": "https://horizon-block-explorer.kininfrastructure.com/operations/35768148338966529" + }, + "transaction": { + "href": "https://horizon-block-explorer.kininfrastructure.com/transactions/cd315376a6f777c6c995f5798906fba1d6194bdc86c008af502ef4c77363e17e" + }, + "effects": { + "href": "https://horizon-block-explorer.kininfrastructure.com/operations/35768148338966529/effects" + }, + "succeeds": { + "href": "https://horizon-block-explorer.kininfrastructure.com/effects?order=desc\u0026cursor=35768148338966529" + }, + "precedes": { + "href": "https://horizon-block-explorer.kininfrastructure.com/effects?order=asc\u0026cursor=35768148338966529" + } + }, + "id": "35768148338966529", + "paging_token": "35768148338966529", + "source_account": "GBHKUZ7C2SZ5N3X2S7O6TT6LNUWSEA2BXMSR5GTTSR6VZARSVAXIQNGH", + "type": "payment", + "type_i": 1, + "created_at": "2020-05-11T21:02:59Z", + "transaction_hash": "cd315376a6f777c6c995f5798906fba1d6194bdc86c008af502ef4c77363e17e", + "asset_type": "native", + "from": "GBHKUZ7C2SZ5N3X2S7O6TT6LNUWSEA2BXMSR5GTTSR6VZARSVAXIQNGH", + "to": "GBWTT6VXCGSMOZN2AWX2JWLHTQLPEIZCB34DZOEUEXYU7FMGQEWVVAA3", + "amount": "204286496.00000" + }, + { + "_links": { + "self": { + "href": "https://horizon-block-explorer.kininfrastructure.com/operations/35766670869966849" + }, + "transaction": { + "href": "https://horizon-block-explorer.kininfrastructure.com/transactions/7c8da7a5d2d5f2ef757fe2419fc7dbefd273fc7fb28d7c65f725e08cff3837e1" + }, + "effects": { + "href": "https://horizon-block-explorer.kininfrastructure.com/operations/35766670869966849/effects" + }, + "succeeds": { + "href": "https://horizon-block-explorer.kininfrastructure.com/effects?order=desc\u0026cursor=35766670869966849" + }, + "precedes": { + "href": "https://horizon-block-explorer.kininfrastructure.com/effects?order=asc\u0026cursor=35766670869966849" + } + }, + "id": "35766670869966849", + "paging_token": "35766670869966849", + "source_account": "GBHKUZ7C2SZ5N3X2S7O6TT6LNUWSEA2BXMSR5GTTSR6VZARSVAXIQNGH", + "type": "create_account", + "type_i": 0, + "created_at": "2020-05-11T20:34:19Z", + "transaction_hash": "7c8da7a5d2d5f2ef757fe2419fc7dbefd273fc7fb28d7c65f725e08cff3837e1", + "starting_balance": "2000.00000", + "funder": "GBHKUZ7C2SZ5N3X2S7O6TT6LNUWSEA2BXMSR5GTTSR6VZARSVAXIQNGH", + "account": "GBWTT6VXCGSMOZN2AWX2JWLHTQLPEIZCB34DZOEUEXYU7FMGQEWVVAA3" + }, + { + "_links": { + "self": { + "href": "https://horizon-block-explorer.kininfrastructure.com/operations/35754696501268481" + }, + "transaction": { + "href": "https://horizon-block-explorer.kininfrastructure.com/transactions/177871adfaadc911a4357653d2c60ff62cbfb6677ae381b94ddceea80d3c116d" + }, + "effects": { + "href": "https://horizon-block-explorer.kininfrastructure.com/operations/35754696501268481/effects" + }, + "succeeds": { + "href": "https://horizon-block-explorer.kininfrastructure.com/effects?order=desc\u0026cursor=35754696501268481" + }, + "precedes": { + "href": "https://horizon-block-explorer.kininfrastructure.com/effects?order=asc\u0026cursor=35754696501268481" + } + }, + "id": "35754696501268481", + "paging_token": "35754696501268481", + "source_account": "GBHKUZ7C2SZ5N3X2S7O6TT6LNUWSEA2BXMSR5GTTSR6VZARSVAXIQNGH", + "type": "create_account", + "type_i": 0, + "created_at": "2020-05-11T16:41:58Z", + "transaction_hash": "177871adfaadc911a4357653d2c60ff62cbfb6677ae381b94ddceea80d3c116d", + "starting_balance": "926347.00000", + "funder": "GBHKUZ7C2SZ5N3X2S7O6TT6LNUWSEA2BXMSR5GTTSR6VZARSVAXIQNGH", + "account": "GDHIZK6G5BLLYDNFRDCXI7Z2EV7XIFFLOGO2FNB226YUTBMXWKDODUMK" + }, + { + "_links": { + "self": { + "href": "https://horizon-block-explorer.kininfrastructure.com/operations/35751930542325761" + }, + "transaction": { + "href": "https://horizon-block-explorer.kininfrastructure.com/transactions/4d70f0d571839fcd2b1acd548464612b9e9f5e7844618cdf383d22ed24e7f282" + }, + "effects": { + "href": "https://horizon-block-explorer.kininfrastructure.com/operations/35751930542325761/effects" + }, + "succeeds": { + "href": "https://horizon-block-explorer.kininfrastructure.com/effects?order=desc\u0026cursor=35751930542325761" + }, + "precedes": { + "href": "https://horizon-block-explorer.kininfrastructure.com/effects?order=asc\u0026cursor=35751930542325761" + } + }, + "id": "35751930542325761", + "paging_token": "35751930542325761", + "source_account": "GBHKUZ7C2SZ5N3X2S7O6TT6LNUWSEA2BXMSR5GTTSR6VZARSVAXIQNGH", + "type": "create_account", + "type_i": 0, + "created_at": "2020-05-11T15:48:18Z", + "transaction_hash": "4d70f0d571839fcd2b1acd548464612b9e9f5e7844618cdf383d22ed24e7f282", + "starting_balance": "2651456.00000", + "funder": "GBHKUZ7C2SZ5N3X2S7O6TT6LNUWSEA2BXMSR5GTTSR6VZARSVAXIQNGH", + "account": "GB563OBW7JS4VMJNP7PMQWBZQBQSW4XKHTTMSZUMOEL5NW6APUYOHKOR" + }, + { + "_links": { + "self": { + "href": "https://horizon-block-explorer.kininfrastructure.com/operations/35751535405195265" + }, + "transaction": { + "href": "https://horizon-block-explorer.kininfrastructure.com/transactions/94c15cb26fd088ad1ccd0bd3b0530a2cdee6107c9005dcf58abe18a9a367e703" + }, + "effects": { + "href": "https://horizon-block-explorer.kininfrastructure.com/operations/35751535405195265/effects" + }, + "succeeds": { + "href": "https://horizon-block-explorer.kininfrastructure.com/effects?order=desc\u0026cursor=35751535405195265" + }, + "precedes": { + "href": "https://horizon-block-explorer.kininfrastructure.com/effects?order=asc\u0026cursor=35751535405195265" + } + }, + "id": "35751535405195265", + "paging_token": "35751535405195265", + "source_account": "GBHKUZ7C2SZ5N3X2S7O6TT6LNUWSEA2BXMSR5GTTSR6VZARSVAXIQNGH", + "type": "create_account", + "type_i": 0, + "created_at": "2020-05-11T15:40:38Z", + "transaction_hash": "94c15cb26fd088ad1ccd0bd3b0530a2cdee6107c9005dcf58abe18a9a367e703", + "starting_balance": "2380384.05211", + "funder": "GBHKUZ7C2SZ5N3X2S7O6TT6LNUWSEA2BXMSR5GTTSR6VZARSVAXIQNGH", + "account": "GAJZQ6QUXL2I4E43OZWCSRSTART5WLDONBCIVATLGEIJLSSMSLUX73TE" + }, + { + "_links": { + "self": { + "href": "https://horizon-block-explorer.kininfrastructure.com/operations/35750023576711169" + }, + "transaction": { + "href": "https://horizon-block-explorer.kininfrastructure.com/transactions/1969f26276e5d3c3fc844da1065b1f067af2b6fb43c6b373b084193f75825fd5" + }, + "effects": { + "href": "https://horizon-block-explorer.kininfrastructure.com/operations/35750023576711169/effects" + }, + "succeeds": { + "href": "https://horizon-block-explorer.kininfrastructure.com/effects?order=desc\u0026cursor=35750023576711169" + }, + "precedes": { + "href": "https://horizon-block-explorer.kininfrastructure.com/effects?order=asc\u0026cursor=35750023576711169" + } + }, + "id": "35750023576711169", + "paging_token": "35750023576711169", + "source_account": "GBHKUZ7C2SZ5N3X2S7O6TT6LNUWSEA2BXMSR5GTTSR6VZARSVAXIQNGH", + "type": "payment", + "type_i": 1, + "created_at": "2020-05-11T15:11:18Z", + "transaction_hash": "1969f26276e5d3c3fc844da1065b1f067af2b6fb43c6b373b084193f75825fd5", + "asset_type": "native", + "from": "GBHKUZ7C2SZ5N3X2S7O6TT6LNUWSEA2BXMSR5GTTSR6VZARSVAXIQNGH", + "to": "GDSSFOUI6NDAE44XBO2EMEXUQTLKERLB3TO5NQGZOCBSG5NVND6IWUAR", + "amount": "4799900.00000" + }, + { + "_links": { + "self": { + "href": "https://horizon-block-explorer.kininfrastructure.com/operations/35749684274331649" + }, + "transaction": { + "href": "https://horizon-block-explorer.kininfrastructure.com/transactions/4f7950f3458823252b3a725857dc403169dd59bc52e4bef3e9bf89008f88eb9a" + }, + "effects": { + "href": "https://horizon-block-explorer.kininfrastructure.com/operations/35749684274331649/effects" + }, + "succeeds": { + "href": "https://horizon-block-explorer.kininfrastructure.com/effects?order=desc\u0026cursor=35749684274331649" + }, + "precedes": { + "href": "https://horizon-block-explorer.kininfrastructure.com/effects?order=asc\u0026cursor=35749684274331649" + } + }, + "id": "35749684274331649", + "paging_token": "35749684274331649", + "source_account": "GBHKUZ7C2SZ5N3X2S7O6TT6LNUWSEA2BXMSR5GTTSR6VZARSVAXIQNGH", + "type": "create_account", + "type_i": 0, + "created_at": "2020-05-11T15:04:43Z", + "transaction_hash": "4f7950f3458823252b3a725857dc403169dd59bc52e4bef3e9bf89008f88eb9a", + "starting_balance": "100.00000", + "funder": "GBHKUZ7C2SZ5N3X2S7O6TT6LNUWSEA2BXMSR5GTTSR6VZARSVAXIQNGH", + "account": "GDSSFOUI6NDAE44XBO2EMEXUQTLKERLB3TO5NQGZOCBSG5NVND6IWUAR" + }, + { + "_links": { + "self": { + "href": "https://horizon-block-explorer.kininfrastructure.com/operations/35748400079122433" + }, + "transaction": { + "href": "https://horizon-block-explorer.kininfrastructure.com/transactions/8c53bf0ed861d956f91cf6eda4a7581280773ac7e778e53b8aca189cca6f6815" + }, + "effects": { + "href": "https://horizon-block-explorer.kininfrastructure.com/operations/35748400079122433/effects" + }, + "succeeds": { + "href": "https://horizon-block-explorer.kininfrastructure.com/effects?order=desc\u0026cursor=35748400079122433" + }, + "precedes": { + "href": "https://horizon-block-explorer.kininfrastructure.com/effects?order=asc\u0026cursor=35748400079122433" + } + }, + "id": "35748400079122433", + "paging_token": "35748400079122433", + "source_account": "GBHKUZ7C2SZ5N3X2S7O6TT6LNUWSEA2BXMSR5GTTSR6VZARSVAXIQNGH", + "type": "payment", + "type_i": 1, + "created_at": "2020-05-11T14:39:46Z", + "transaction_hash": "8c53bf0ed861d956f91cf6eda4a7581280773ac7e778e53b8aca189cca6f6815", + "asset_type": "native", + "from": "GBHKUZ7C2SZ5N3X2S7O6TT6LNUWSEA2BXMSR5GTTSR6VZARSVAXIQNGH", + "to": "GBNVREV4JCITKKOILHR3FGSKLBT3PKCSWUIKTSF5ETEUIOZA3X2EZBAF", + "amount": "215499.00000" + }, + { + "_links": { + "self": { + "href": "https://horizon-block-explorer.kininfrastructure.com/operations/35748146676203521" + }, + "transaction": { + "href": "https://horizon-block-explorer.kininfrastructure.com/transactions/8f41a95986ed015982ab41cbffa85aca5efc80e913fa2d57b20059b3a9ecfd48" + }, + "effects": { + "href": "https://horizon-block-explorer.kininfrastructure.com/operations/35748146676203521/effects" + }, + "succeeds": { + "href": "https://horizon-block-explorer.kininfrastructure.com/effects?order=desc\u0026cursor=35748146676203521" + }, + "precedes": { + "href": "https://horizon-block-explorer.kininfrastructure.com/effects?order=asc\u0026cursor=35748146676203521" + } + }, + "id": "35748146676203521", + "paging_token": "35748146676203521", + "source_account": "GBHKUZ7C2SZ5N3X2S7O6TT6LNUWSEA2BXMSR5GTTSR6VZARSVAXIQNGH", + "type": "create_account", + "type_i": 0, + "created_at": "2020-05-11T14:34:50Z", + "transaction_hash": "8f41a95986ed015982ab41cbffa85aca5efc80e913fa2d57b20059b3a9ecfd48", + "starting_balance": "1.00000", + "funder": "GBHKUZ7C2SZ5N3X2S7O6TT6LNUWSEA2BXMSR5GTTSR6VZARSVAXIQNGH", + "account": "GBNVREV4JCITKKOILHR3FGSKLBT3PKCSWUIKTSF5ETEUIOZA3X2EZBAF" + }, + { + "_links": { + "self": { + "href": "https://horizon-block-explorer.kininfrastructure.com/operations/35733968989097985" + }, + "transaction": { + "href": "https://horizon-block-explorer.kininfrastructure.com/transactions/15324f705df23f021b8dd443032965444880b0a64aa36a2b0766feede99e6ba3" + }, + "effects": { + "href": "https://horizon-block-explorer.kininfrastructure.com/operations/35733968989097985/effects" + }, + "succeeds": { + "href": "https://horizon-block-explorer.kininfrastructure.com/effects?order=desc\u0026cursor=35733968989097985" + }, + "precedes": { + "href": "https://horizon-block-explorer.kininfrastructure.com/effects?order=asc\u0026cursor=35733968989097985" + } + }, + "id": "35733968989097985", + "paging_token": "35733968989097985", + "source_account": "GBHKUZ7C2SZ5N3X2S7O6TT6LNUWSEA2BXMSR5GTTSR6VZARSVAXIQNGH", + "type": "create_account", + "type_i": 0, + "created_at": "2020-05-11T09:59:40Z", + "transaction_hash": "15324f705df23f021b8dd443032965444880b0a64aa36a2b0766feede99e6ba3", + "starting_balance": "3215955.01000", + "funder": "GBHKUZ7C2SZ5N3X2S7O6TT6LNUWSEA2BXMSR5GTTSR6VZARSVAXIQNGH", + "account": "GAHV6GEJC77UTTR2NFWEQWRPQPFVPJZH6MPH7IUSGQOGUQPALYDGW4JN" + } + ] + } +} \ No newline at end of file diff --git a/mock/ext-api-data/kin-api_transactions_b2131beb8e0c57dfd3309914fce08ac4e094c51dc918087171150dd5b996076a__.json b/mock/ext-api-data/kin-api_transactions_b2131beb8e0c57dfd3309914fce08ac4e094c51dc918087171150dd5b996076a__.json new file mode 100644 index 000000000..3a9b870d4 --- /dev/null +++ b/mock/ext-api-data/kin-api_transactions_b2131beb8e0c57dfd3309914fce08ac4e094c51dc918087171150dd5b996076a__.json @@ -0,0 +1,45 @@ +{ + "memo": "Namilak8", + "_links": { + "self": { + "href": "https://horizon-block-explorer.kininfrastructure.com/transactions/b2131beb8e0c57dfd3309914fce08ac4e094c51dc918087171150dd5b996076a" + }, + "account": { + "href": "https://horizon-block-explorer.kininfrastructure.com/accounts/GBHKUZ7C2SZ5N3X2S7O6TT6LNUWSEA2BXMSR5GTTSR6VZARSVAXIQNGH" + }, + "ledger": { + "href": "https://horizon-block-explorer.kininfrastructure.com/ledgers/7485062" + }, + "operations": { + "href": "https://horizon-block-explorer.kininfrastructure.com/transactions/b2131beb8e0c57dfd3309914fce08ac4e094c51dc918087171150dd5b996076a/operations{?cursor,limit,order}", + "templated": true + }, + "effects": { + "href": "https://horizon-block-explorer.kininfrastructure.com/transactions/b2131beb8e0c57dfd3309914fce08ac4e094c51dc918087171150dd5b996076a/effects{?cursor,limit,order}", + "templated": true + }, + "precedes": { + "href": "https://horizon-block-explorer.kininfrastructure.com/transactions?order=asc\u0026cursor=32148096498577408" + }, + "succeeds": { + "href": "https://horizon-block-explorer.kininfrastructure.com/transactions?order=desc\u0026cursor=32148096498577408" + } + }, + "id": "b2131beb8e0c57dfd3309914fce08ac4e094c51dc918087171150dd5b996076a", + "paging_token": "32148096498577408", + "hash": "b2131beb8e0c57dfd3309914fce08ac4e094c51dc918087171150dd5b996076a", + "ledger": 7485062, + "created_at": "2020-03-24T01:43:00Z", + "source_account": "GBHKUZ7C2SZ5N3X2S7O6TT6LNUWSEA2BXMSR5GTTSR6VZARSVAXIQNGH", + "source_account_sequence": "3873257342118155", + "fee_paid": 100, + "operation_count": 1, + "envelope_xdr": "AAAAAE6qZ+LUs9bu+pfd6c/LbS0iA0G7JR6ac5R9XIIyqC6IAAAAZAANwrUAACkLAAAAAAAAAAEAAAAITmFtaWxhazgAAAABAAAAAQAAAABOqmfi1LPW7vqX3enPy20tIgNBuyUemnOUfVyCMqguiAAAAAEAAAAAbDIyvkAp46X97VW4/zmT18NY7BAFyxQxDNv5ve/FylMAAAAAAAAAA4aZXmAAAAAAAAAAATKoLogAAABAiivAdbjfQvWTMheamksBZp9yBc9oRN2E2OpPhTCeT/bICu6eSr3FJy+WqYlieBlXtdVbBaoCWOlR07Mi4QqjDQ==", + "result_xdr": "AAAAAAAAAGQAAAAAAAAAAQAAAAAAAAABAAAAAAAAAAA=", + "result_meta_xdr": "AAAAAAAAAAEAAAAEAAAAAwByNoYAAAAAAAAAAE6qZ+LUs9bu+pfd6c/LbS0iA0G7JR6ac5R9XIIyqC6IAABHRPE+rKwADcK1AAApCwAAAAAAAAAAAAAAAAAAAAABAAAAAAAAAAAAAAAAAAAAAAAAAQByNoYAAAAAAAAAAE6qZ+LUs9bu+pfd6c/LbS0iA0G7JR6ac5R9XIIyqC6IAABHQWqlTkwADcK1AAApCwAAAAAAAAAAAAAAAAAAAAABAAAAAAAAAAAAAAAAAAAAAAAAAwBwLBkAAAAAAAAAAGwyMr5AKeOl/e1VuP85k9fDWOwQBcsUMQzb+b3vxcpTAAAAAzCVZ9QAcAeUAAAAAwAAAAAAAAAAAAAAAAAAAAABAAAAAAAAAAAAAAAAAAAAAAAAAQByNoYAAAAAAAAAAGwyMr5AKeOl/e1VuP85k9fDWOwQBcsUMQzb+b3vxcpTAAAABrcuxjQAcAeUAAAAAwAAAAAAAAAAAAAAAAAAAAABAAAAAAAAAAAAAAAAAAAA", + "fee_meta_xdr": "AAAAAgAAAAMAcindAAAAAAAAAABOqmfi1LPW7vqX3enPy20tIgNBuyUemnOUfVyCMqguiAAAR0TxPq0QAA3CtQAAKQoAAAAAAAAAAAAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAEAcjaGAAAAAAAAAABOqmfi1LPW7vqX3enPy20tIgNBuyUemnOUfVyCMqguiAAAR0TxPqysAA3CtQAAKQsAAAAAAAAAAAAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAA==", + "memo_type": "text", + "signatures": [ + "iivAdbjfQvWTMheamksBZp9yBc9oRN2E2OpPhTCeT/bICu6eSr3FJy+WqYlieBlXtdVbBaoCWOlR07Mi4QqjDQ==" + ] +} \ No newline at end of file diff --git a/mock/ext-api-data/kin-api_transactions_eb070218bfde8c48af6071432bc9f19b7690b9dc50535cc135f67ea046e70bed.json b/mock/ext-api-data/kin-api_transactions_eb070218bfde8c48af6071432bc9f19b7690b9dc50535cc135f67ea046e70bed.json new file mode 100644 index 000000000..7b568db8a --- /dev/null +++ b/mock/ext-api-data/kin-api_transactions_eb070218bfde8c48af6071432bc9f19b7690b9dc50535cc135f67ea046e70bed.json @@ -0,0 +1,45 @@ +{ + "memo": "", + "_links": { + "self": { + "href": "https://horizon-block-explorer.kininfrastructure.com/transactions/eb070218bfde8c48af6071432bc9f19b7690b9dc50535cc135f67ea046e70bed" + }, + "account": { + "href": "https://horizon-block-explorer.kininfrastructure.com/accounts/GBHKUZ7C2SZ5N3X2S7O6TT6LNUWSEA2BXMSR5GTTSR6VZARSVAXIQNGH" + }, + "ledger": { + "href": "https://horizon-block-explorer.kininfrastructure.com/ledgers/7481821" + }, + "operations": { + "href": "https://horizon-block-explorer.kininfrastructure.com/transactions/eb070218bfde8c48af6071432bc9f19b7690b9dc50535cc135f67ea046e70bed/operations{?cursor,limit,order}", + "templated": true + }, + "effects": { + "href": "https://horizon-block-explorer.kininfrastructure.com/transactions/eb070218bfde8c48af6071432bc9f19b7690b9dc50535cc135f67ea046e70bed/effects{?cursor,limit,order}", + "templated": true + }, + "precedes": { + "href": "https://horizon-block-explorer.kininfrastructure.com/transactions?order=asc\u0026cursor=32134176509775872" + }, + "succeeds": { + "href": "https://horizon-block-explorer.kininfrastructure.com/transactions?order=desc\u0026cursor=32134176509775872" + } + }, + "id": "eb070218bfde8c48af6071432bc9f19b7690b9dc50535cc135f67ea046e70bed", + "paging_token": "32134176509775872", + "hash": "eb070218bfde8c48af6071432bc9f19b7690b9dc50535cc135f67ea046e70bed", + "ledger": 7481821, + "created_at": "2020-03-23T21:12:01Z", + "source_account": "GBHKUZ7C2SZ5N3X2S7O6TT6LNUWSEA2BXMSR5GTTSR6VZARSVAXIQNGH", + "source_account_sequence": "3873257342118154", + "fee_paid": 100, + "operation_count": 1, + "envelope_xdr": "AAAAAE6qZ+LUs9bu+pfd6c/LbS0iA0G7JR6ac5R9XIIyqC6IAAAAZAANwrUAACkKAAAAAAAAAAEAAAAAAAAAAQAAAAEAAAAATqpn4tSz1u76l93pz8ttLSIDQbslHppzlH1cgjKoLogAAAABAAAAADqMsEcsu8a3aP7yB8M2R8im3p4D+wRWZFJY8tvI0bNRAAAAAAAAAF1caQX1AAAAAAAAAAEyqC6IAAAAQFsrhOcyOXVWLIFf8aSJh37W1bx4ZP3qKXPejdB2M0z+FG09ggG0uDiV7FAsmRvzPUGoEgI3reEw+eAFByO6dAs=", + "result_xdr": "AAAAAAAAAGQAAAAAAAAAAQAAAAAAAAABAAAAAAAAAAA=", + "result_meta_xdr": "AAAAAAAAAAEAAAAEAAAAAwByKaQAAAAAAAAAADqMsEcsu8a3aP7yB8M2R8im3p4D+wRWZFJY8tvI0bNRAAAAdGpUDqAAcik+AAAAAAAAAAAAAAAAAAAAAAAAAAABAAAAAAAAAAAAAAAAAAAAAAAAAQByKd0AAAAAAAAAADqMsEcsu8a3aP7yB8M2R8im3p4D+wRWZFJY8tvI0bNRAAAA0ca9FJUAcik+AAAAAAAAAAAAAAAAAAAAAAAAAAABAAAAAAAAAAAAAAAAAAAAAAAAAwByKd0AAAAAAAAAAE6qZ+LUs9bu+pfd6c/LbS0iA0G7JR6ac5R9XIIyqC6IAABHok2nswUADcK1AAApCgAAAAAAAAAAAAAAAAAAAAABAAAAAAAAAAAAAAAAAAAAAAAAAQByKd0AAAAAAAAAAE6qZ+LUs9bu+pfd6c/LbS0iA0G7JR6ac5R9XIIyqC6IAABHRPE+rRAADcK1AAApCgAAAAAAAAAAAAAAAAAAAAABAAAAAAAAAAAAAAAAAAAA", + "fee_meta_xdr": "AAAAAgAAAAMAcimkAAAAAAAAAABOqmfi1LPW7vqX3enPy20tIgNBuyUemnOUfVyCMqguiAAAR6JNp7NpAA3CtQAAKQkAAAAAAAAAAAAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAEAcindAAAAAAAAAABOqmfi1LPW7vqX3enPy20tIgNBuyUemnOUfVyCMqguiAAAR6JNp7MFAA3CtQAAKQoAAAAAAAAAAAAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAA==", + "memo_type": "text", + "signatures": [ + "WyuE5zI5dVYsgV/xpImHftbVvHhk/eopc96N0HYzTP4UbT2CAbS4OJXsUCyZG/M9QagSAjet4TD54AUHI7p0Cw==" + ] +} \ No newline at end of file diff --git a/mock/ext-api-data/kusama-api_scan_transfers.json b/mock/ext-api-data/kusama-api_scan_transfers.json new file mode 100644 index 000000000..f59c65f36 --- /dev/null +++ b/mock/ext-api-data/kusama-api_scan_transfers.json @@ -0,0 +1 @@ +{"code":0,"message":"Success","ttl":1,"data":{"count":16,"transfers":[{"from":"EonK7NScfhd7ZRfgnLhm4cKRFJWK1z59zPximUZRg8VjHQj","to":"HZaz6cUo8wJ9zjwoDtA3ZzYkrCLfDYU8b3uPmYttKFFvvRK","module":"balances","amount":"15","hash":"0x5a5f9a4c2e09f5111244d77b424151b4e21be8e29b4b4e382a7b35a896512757","block_timestamp":1587746376,"block_num":2023403,"extrinsic_index":"2023403-3","success":true,"fee":"10000000000"},{"from":"HZaz6cUo8wJ9zjwoDtA3ZzYkrCLfDYU8b3uPmYttKFFvvRK","to":"HZaz6cUo8wJ9zjwoDtA3ZzYkrCLfDYU8b3uPmYttKFFvvRK","module":"balances","amount":"140","hash":"0xbcb7e99387c65024ef9ed1fc35ac703c1d4917694bb4c969c7d698142cc7c63d","block_timestamp":1586095086,"block_num":1756978,"extrinsic_index":"1756978-3","success":true,"fee":"10000000000"},{"from":"EonK7NScfhd7ZRfgnLhm4cKRFJWK1z59zPximUZRg8VjHQj","to":"HZaz6cUo8wJ9zjwoDtA3ZzYkrCLfDYU8b3uPmYttKFFvvRK","module":"balances","amount":"30","hash":"0x9908579abffb409aef95394128f9097f0a21cfdf16675588423e31ab0d3c58e2","block_timestamp":1583243826,"block_num":1291387,"extrinsic_index":"1291387-3","success":true,"fee":"10000000000"},{"from":"EEWyMLHgwtemr48spFNnS3U2XjaYswqAYAbadx2jr9ppp4X","to":"HZaz6cUo8wJ9zjwoDtA3ZzYkrCLfDYU8b3uPmYttKFFvvRK","module":"balances","amount":"7.333459","hash":"0xab5dbf2d38f249785c260c3fca9e19a17df298c5294a99eaec2baab29970eb85","block_timestamp":1581154290,"block_num":961987,"extrinsic_index":"961987-2","success":true,"fee":"10000000000"},{"from":"EEWyMLHgwtemr48spFNnS3U2XjaYswqAYAbadx2jr9ppp4X","to":"HZaz6cUo8wJ9zjwoDtA3ZzYkrCLfDYU8b3uPmYttKFFvvRK","module":"balances","amount":"233.193373","hash":"0x08aad18956058ee385387da2f7d613ed17ac5c98ad23683cfea855b0fd529a63","block_timestamp":1579722240,"block_num":738814,"extrinsic_index":"738814-3","success":true,"fee":"10000000000"},{"from":"HZaz6cUo8wJ9zjwoDtA3ZzYkrCLfDYU8b3uPmYttKFFvvRK","to":"EonK7NScfhd7ZRfgnLhm4cKRFJWK1z59zPximUZRg8VjHQj","module":"balances","amount":"10","hash":"0xe05a4493cd013e182ebf82169e818a251b2ed52e064452293e81428f825a70a2","block_timestamp":1579511916,"block_num":704522,"extrinsic_index":"704522-3","success":true,"fee":"10000000000"},{"from":"HZaz6cUo8wJ9zjwoDtA3ZzYkrCLfDYU8b3uPmYttKFFvvRK","to":"EonK7NScfhd7ZRfgnLhm4cKRFJWK1z59zPximUZRg8VjHQj","module":"balances","amount":"30","hash":"0x18e175b836a6ec97a7dddfe5ee142844681987480a29ae5d5166d36213a90c91","block_timestamp":1579442088,"block_num":693483,"extrinsic_index":"693483-3","success":true,"fee":"10000000000"},{"from":"HZaz6cUo8wJ9zjwoDtA3ZzYkrCLfDYU8b3uPmYttKFFvvRK","to":"EonK7NScfhd7ZRfgnLhm4cKRFJWK1z59zPximUZRg8VjHQj","module":"balances","amount":"5","hash":"0x95526174daf76fcff648f2c4bf88f347a84c9f8a88aa82e757d51d8f1cdbbd98","block_timestamp":1579441998,"block_num":693468,"extrinsic_index":"693468-3","success":true,"fee":"10000000000"},{"from":"EEWyMLHgwtemr48spFNnS3U2XjaYswqAYAbadx2jr9ppp4X","to":"HZaz6cUo8wJ9zjwoDtA3ZzYkrCLfDYU8b3uPmYttKFFvvRK","module":"balances","amount":"245.749804","hash":"0x290800b497f7b41a820df030d7a5311180b1584e4fa4e091e3a07d03db036427","block_timestamp":1579264992,"block_num":664802,"extrinsic_index":"664802-3","success":true,"fee":"10000000000"},{"from":"EEWyMLHgwtemr48spFNnS3U2XjaYswqAYAbadx2jr9ppp4X","to":"HZaz6cUo8wJ9zjwoDtA3ZzYkrCLfDYU8b3uPmYttKFFvvRK","module":"balances","amount":"985.894918","hash":"0x2c317ed47a9b9f8fed938f8541b5bca3dcd6702827e41ed38921cdce21017069","block_timestamp":1576716144,"block_num":285215,"extrinsic_index":"285215-3","success":true,"fee":"0"},{"from":"EEWyMLHgwtemr48spFNnS3U2XjaYswqAYAbadx2jr9ppp4X","to":"HZaz6cUo8wJ9zjwoDtA3ZzYkrCLfDYU8b3uPmYttKFFvvRK","module":"balances","amount":"327.967504","hash":"0xc6fdca126d15dd145ecdd704009881d8fa301f634766f909fb8d68e654c0d14a","block_timestamp":1576662756,"block_num":276469,"extrinsic_index":"276469-3","success":true,"fee":"0"},{"from":"EEWyMLHgwtemr48spFNnS3U2XjaYswqAYAbadx2jr9ppp4X","to":"HZaz6cUo8wJ9zjwoDtA3ZzYkrCLfDYU8b3uPmYttKFFvvRK","module":"balances","amount":"161.771866","hash":"0x4acc84472e2da51e9b35aa086296f8a256f75ff081a9e77468f10a74254f489b","block_timestamp":1576600764,"block_num":266305,"extrinsic_index":"266305-3","success":true,"fee":"0"},{"from":"EEWyMLHgwtemr48spFNnS3U2XjaYswqAYAbadx2jr9ppp4X","to":"HZaz6cUo8wJ9zjwoDtA3ZzYkrCLfDYU8b3uPmYttKFFvvRK","module":"balances","amount":"302.185312","hash":"0xa1ba1d239bb2511dcefba82e40d03fdf8be0c41a3b0353c414ad128d80205129","block_timestamp":1576507356,"block_num":251047,"extrinsic_index":"251047-3","success":true,"fee":"0"},{"from":"EEWyMLHgwtemr48spFNnS3U2XjaYswqAYAbadx2jr9ppp4X","to":"HZaz6cUo8wJ9zjwoDtA3ZzYkrCLfDYU8b3uPmYttKFFvvRK","module":"balances","amount":"533.4697945","hash":"0x755d63741e0068abdc6151eea305be952b7b7685c998964f170a3030f0581247","block_timestamp":1576163976,"block_num":194836,"extrinsic_index":"194836-3","success":true,"fee":"0"},{"from":"EEWyMLHgwtemr48spFNnS3U2XjaYswqAYAbadx2jr9ppp4X","to":"HZaz6cUo8wJ9zjwoDtA3ZzYkrCLfDYU8b3uPmYttKFFvvRK","module":"balances","amount":"533.4697945","hash":"0x5e976ac0316c5f0037fa89f40480e0d41b4d494c0dde786d6c80d2bbeb2b32bc","block_timestamp":1576162248,"block_num":194553,"extrinsic_index":"194553-3","success":true,"fee":"0"},{"from":"EEWyMLHgwtemr48spFNnS3U2XjaYswqAYAbadx2jr9ppp4X","to":"HZaz6cUo8wJ9zjwoDtA3ZzYkrCLfDYU8b3uPmYttKFFvvRK","module":"balances","amount":"2.8","hash":"0x9d42d83a6e340ac08a35ef691bbc71da9249e37d33d310bda08661cc8e2171a1","block_timestamp":1576161810,"block_num":194481,"extrinsic_index":"194481-2","success":true,"fee":"0"}]}} \ No newline at end of file diff --git a/mock/ext-api-data/kusama-api_scan_transfers.request_json b/mock/ext-api-data/kusama-api_scan_transfers.request_json new file mode 100644 index 000000000..fc31d1c0c --- /dev/null +++ b/mock/ext-api-data/kusama-api_scan_transfers.request_json @@ -0,0 +1,4 @@ +{ + "address": "HZaz6cUo8wJ9zjwoDtA3ZzYkrCLfDYU8b3uPmYttKFFvvRK", + "row": 25 +} \ No newline at end of file diff --git a/mock/ext-api-data/litecoin-api_v2_address_ltc1qpm594ntjq6ayqjngf6t9td2dxtey9d7985eept__details_txs.json b/mock/ext-api-data/litecoin-api_v2_address_ltc1qpm594ntjq6ayqjngf6t9td2dxtey9d7985eept__details_txs.json new file mode 100644 index 000000000..26bd7b790 --- /dev/null +++ b/mock/ext-api-data/litecoin-api_v2_address_ltc1qpm594ntjq6ayqjngf6t9td2dxtey9d7985eept__details_txs.json @@ -0,0 +1,1081 @@ +{ + "page": 1, + "totalPages": 1, + "itemsOnPage": 1000, + "address": "ltc1qpm594ntjq6ayqjngf6t9td2dxtey9d7985eept", + "balance": "1688078", + "totalReceived": "25679292", + "totalSent": "23991214", + "unconfirmedBalance": "0", + "unconfirmedTxs": 0, + "txs": 19, + "transactions": [ + { + "txid": "bfce02fdd69ec01c08486b75fa5e4a93d82a0e6f346c8eade6437affb0f817b1", + "version": 1, + "vin": [ + { + "txid": "674092ed2b166f0f21ba6287b1df23abb9612e140e77bd52f2885312c69bf867", + "vout": 1, + "n": 0, + "addresses": [ + "ltc1qpm594ntjq6ayqjngf6t9td2dxtey9d7985eept" + ], + "isAddress": true, + "value": "788530" + } + ], + "vout": [ + { + "value": "100000", + "n": 0, + "hex": "0014ccf05f3bc453f7f66fb48b124bd79690bc309e22", + "addresses": [ + "ltc1qenc97w7y20mlvma53vfyh4ukjz7rp83zf892wx" + ], + "isAddress": true + }, + { + "value": "688078", + "n": 1, + "hex": "00140ee85acd7206ba404a684e9655b54d32f242b7c5", + "addresses": [ + "ltc1qpm594ntjq6ayqjngf6t9td2dxtey9d7985eept" + ], + "isAddress": true + } + ], + "blockHash": "ae8df4fb9cbbd07375eef217dd25e8b918a1b2746907c23cf4f2e15cd18fccdd", + "blockHeight": 1804076, + "confirmations": 36291, + "blockTime": 1583910871, + "value": "788078", + "valueIn": "788530", + "fees": "452", + "hex": "0100000000010167f89bc6125388f252bd770e142e61b9ab23dfb18762ba210f6f162bed92406701000000000000000002a086010000000000160014ccf05f3bc453f7f66fb48b124bd79690bc309e22ce7f0a00000000001600140ee85acd7206ba404a684e9655b54d32f242b7c502483045022100a40df50e2b419a35001f40d508e911f36d01497ebe5225dc93c81f53a30452fb022034c086517326be293019c2cbf215d6b9a53aa0ab4a0c2b890a9f1b05e8052aac012102872f9e841a8150ab716574ff897d915f575ed9abe9b4c9426617f6a1d8b3bbd100000000" + }, + { + "txid": "674092ed2b166f0f21ba6287b1df23abb9612e140e77bd52f2885312c69bf867", + "version": 1, + "vin": [ + { + "txid": "f8ddc3eca55aa4bffd27b030fc3b35ceb8d503b31a03dafd32df56eec552fe99", + "vout": 1, + "sequence": 4294967290, + "n": 0, + "addresses": [ + "ltc1qpm594ntjq6ayqjngf6t9td2dxtey9d7985eept" + ], + "isAddress": true, + "value": "1788982" + } + ], + "vout": [ + { + "value": "1000000", + "n": 0, + "hex": "00140ee85acd7206ba404a684e9655b54d32f242b7c5", + "addresses": [ + "ltc1qpm594ntjq6ayqjngf6t9td2dxtey9d7985eept" + ], + "isAddress": true + }, + { + "value": "788530", + "n": 1, + "spent": true, + "hex": "00140ee85acd7206ba404a684e9655b54d32f242b7c5", + "addresses": [ + "ltc1qpm594ntjq6ayqjngf6t9td2dxtey9d7985eept" + ], + "isAddress": true + } + ], + "blockHash": "dd92763dcb8477d8f012e5ec0598ebf3c135a15780d7491754fff40d3d24dd9b", + "blockHeight": 1803562, + "confirmations": 36805, + "blockTime": 1583831802, + "value": "1788530", + "valueIn": "1788982", + "fees": "452", + "hex": "0100000000010199fe52c5ee56df32fdda031ab303d5b8ce353bfc30b027fdbfa45aa5ecc3ddf80100000000faffffff0240420f00000000001600140ee85acd7206ba404a684e9655b54d32f242b7c532080c00000000001600140ee85acd7206ba404a684e9655b54d32f242b7c502483045022100bbde918ff538468c440424323bbe8ba78eef14d9dde357c8e6496905d540098c02205700d984884edff918f827289898c16ec9ad30344a637ea85dc55f7f836143bd012102872f9e841a8150ab716574ff897d915f575ed9abe9b4c9426617f6a1d8b3bbd100000000" + }, + { + "txid": "f8ddc3eca55aa4bffd27b030fc3b35ceb8d503b31a03dafd32df56eec552fe99", + "version": 1, + "vin": [ + { + "txid": "0bc6314b50a192853d09b2ca3ebadea75288bfb66e9b254c8f55ebaa720a7d2f", + "vout": 1, + "n": 0, + "addresses": [ + "ltc1qd0huz2atjj0uyjlcp48ml9tltkzdta7sg8fn89" + ], + "isAddress": true, + "value": "1889434" + } + ], + "vout": [ + { + "value": "100000", + "n": 0, + "spent": true, + "hex": "0014e8d0e2bade0aefda201fad8ff5859d743b252a5b", + "addresses": [ + "ltc1qargw9wk7ptha5gql4k8ltpvawsaj22jmr8cejf" + ], + "isAddress": true + }, + { + "value": "1788982", + "n": 1, + "spent": true, + "hex": "00140ee85acd7206ba404a684e9655b54d32f242b7c5", + "addresses": [ + "ltc1qpm594ntjq6ayqjngf6t9td2dxtey9d7985eept" + ], + "isAddress": true + } + ], + "blockHash": "c9503e0fe18dd16a8a1e836d08d6966e443fbe79eeb0561f2fb18e5993a0cfec", + "blockHeight": 1800498, + "confirmations": 39869, + "blockTime": 1583384860, + "value": "1888982", + "valueIn": "1889434", + "fees": "452", + "hex": "010000000001012f7d0a72aaeb558f4c259b6eb6bf8852a7deba3ecab2093d8592a1504b31c60b01000000000000000002a086010000000000160014e8d0e2bade0aefda201fad8ff5859d743b252a5b364c1b00000000001600140ee85acd7206ba404a684e9655b54d32f242b7c502483045022100f6adacde68792f7862ec58b066ed4b521444929d90c163b5eb7b0a3d3e16c133022018f649e6a9cece3dc58fdb09f8cffb5cf9ba64f7a453ae6d82043b3fc65fe8ba01210273a11ff2e056c52a0a10c3b93590f60802ab8a74bf9828ea76ae87885fddfc8d00000000" + }, + { + "txid": "fdbf28c741e55f846a0a378e0cf2a7263540f8d24123b658f2beb0bd1b1788f0", + "version": 1, + "vin": [ + { + "txid": "07eb5638d1a2833a7eaea596b0dc8bacd8a51be6f18f8bb8cabd514255acebff", + "vout": 1, + "sequence": 4294967294, + "n": 0, + "addresses": [ + "ltc1qpm594ntjq6ayqjngf6t9td2dxtey9d7985eept" + ], + "isAddress": true, + "value": "96312" + }, + { + "txid": "152c3d81f7272c91bd3d880d7b570619ef4141482cbcd62b5556fb00efc2bd94", + "sequence": 4294967293, + "n": 1, + "addresses": [ + "ltc1q5usqkt2x9tnqljy0tss9jqmlvcmakdp4l4rdt5" + ], + "isAddress": true, + "value": "400000" + }, + { + "txid": "152c3d81f7272c91bd3d880d7b570619ef4141482cbcd62b5556fb00efc2bd94", + "vout": 1, + "sequence": 4294967292, + "n": 2, + "addresses": [ + "ltc1q69juwlyyyks4ws8rdklldjvdxk3vk6gy9qkn99" + ], + "isAddress": true, + "value": "1650696" + } + ], + "vout": [ + { + "value": "1989886", + "n": 0, + "spent": true, + "hex": "001450e07ca8c4f2c7ec53351710013a03251ab5d1d8", + "addresses": [ + "ltc1q2rs8e2xy7tr7c5e4zugqzwsry5dtt5wcdk4zv9" + ], + "isAddress": true + } + ], + "blockHash": "5977afe7c387c7390498309e29ad71e8daef8c59df5b910cb05a3ae661db0919", + "blockHeight": 1783073, + "confirmations": 57294, + "blockTime": 1580799867, + "value": "1989886", + "valueIn": "2147008", + "fees": "157122", + "hex": "01000000000103ffebac554251bdcab88b8ff1e61ba5d8ac8bdcb096a5ae7e3a83a2d13856eb070100000000feffffff94bdc2ef00fb56552bd6bc2c484141ef1906577b0d883dbd912c27f7813d2c150000000000fdffffff94bdc2ef00fb56552bd6bc2c484141ef1906577b0d883dbd912c27f7813d2c150100000000fcffffff01fe5c1e000000000016001450e07ca8c4f2c7ec53351710013a03251ab5d1d802473044022015d518ae11502d4c832cde4627372c60fb89293d14f3dd39006445dce3bfe47f02207b97301e3f8b9016a515882072dafba705a4ec5e29f5ae222dbdfd5a6d83c90a012102872f9e841a8150ab716574ff897d915f575ed9abe9b4c9426617f6a1d8b3bbd1024730440220478a6c3144e882f736b7b674d43768636f8d74eec28138d9ea36d05f64634aa402203827a08bb554c930e58178536257eb247a790866a7984fdffe549da7376244f201210262da88bf17e0b0575a3c9efecf7387e6d96fa9039547ac6707219defd321986102473044022053999ec5a5b454c60136144096f55a0de2402addd4a250396884bd00f3763dfe022054812eca7798ed4a4418b166c6a4e3e880cbd93ce41c620b611c35ad1c80735e012103c497991dbbf809288e18c5ab4744d59ab6b0b0bf875d2095267ea373e9837d3400000000" + }, + { + "txid": "152c3d81f7272c91bd3d880d7b570619ef4141482cbcd62b5556fb00efc2bd94", + "version": 1, + "vin": [ + { + "txid": "9cad90704b2c24e2300c496398ba66ba216bc1df01851ba8c14fc0da8814a8ec", + "vout": 1, + "n": 0, + "addresses": [ + "ltc1qpm594ntjq6ayqjngf6t9td2dxtey9d7985eept" + ], + "isAddress": true, + "value": "2051148" + } + ], + "vout": [ + { + "value": "400000", + "n": 0, + "spent": true, + "hex": "0014a7200b2d462ae60fc88f5c2059037f6637db3435", + "addresses": [ + "ltc1q5usqkt2x9tnqljy0tss9jqmlvcmakdp4l4rdt5" + ], + "isAddress": true + }, + { + "value": "1650696", + "n": 1, + "spent": true, + "hex": "0014d165c77c8425a15740e36dbff6c98d35a2cb6904", + "addresses": [ + "ltc1q69juwlyyyks4ws8rdklldjvdxk3vk6gy9qkn99" + ], + "isAddress": true + } + ], + "blockHash": "686ab90a08327f65c4cb5aa4227f3c0c0eb3120e922f6f6a8ba37fd20d6d2a72", + "blockHeight": 1782650, + "confirmations": 57717, + "blockTime": 1580744939, + "value": "2050696", + "valueIn": "2051148", + "fees": "452", + "hex": "01000000000101eca81488dac04fc1a81b8501dfc16b21ba66ba9863490c30e2242c4b7090ad9c01000000000000000002801a060000000000160014a7200b2d462ae60fc88f5c2059037f6637db34350830190000000000160014d165c77c8425a15740e36dbff6c98d35a2cb690402483045022100e633d87b26da1f508018fdf1c54f9b8bb0813aeb326c17a2622e29dec94f48ce0220123208bd0d13e1c2f16c4d3a450b783ea89211fcb054db2211ed6403335a48f3012102872f9e841a8150ab716574ff897d915f575ed9abe9b4c9426617f6a1d8b3bbd100000000" + }, + { + "txid": "9cad90704b2c24e2300c496398ba66ba216bc1df01851ba8c14fc0da8814a8ec", + "version": 1, + "vin": [ + { + "txid": "b784d0389a2450e43ea043567329d0f4e00277ac430bbcedf335d9d85451e088", + "vout": 1, + "n": 0, + "addresses": [ + "ltc1q720spapzfq8j79gal5mg2efcrtv92hvktc8u76" + ], + "isAddress": true, + "value": "3051600" + } + ], + "vout": [ + { + "value": "1000000", + "n": 0, + "hex": "0014463fec54ea2c7210057b2d6d1972a8aaaf39a543", + "addresses": [ + "ltc1qgcl7c48293epqptm94k3ju4g42hnnf2r5d4ewq" + ], + "isAddress": true + }, + { + "value": "2051148", + "n": 1, + "spent": true, + "hex": "00140ee85acd7206ba404a684e9655b54d32f242b7c5", + "addresses": [ + "ltc1qpm594ntjq6ayqjngf6t9td2dxtey9d7985eept" + ], + "isAddress": true + } + ], + "blockHash": "8eccbbf11afd2c3a54f2a5eae52734b37b67df50cbdea00224ad39896e0bf4f7", + "blockHeight": 1781067, + "confirmations": 59300, + "blockTime": 1580515445, + "value": "3051148", + "valueIn": "3051600", + "fees": "452", + "hex": "0100000000010188e05154d8d935f3edbc0b43ac7702e0f4d029735643a03ee450249a38d084b70100000000000000000240420f0000000000160014463fec54ea2c7210057b2d6d1972a8aaaf39a5434c4c1f00000000001600140ee85acd7206ba404a684e9655b54d32f242b7c5024830450221009f248a6c27f931afca2480a0d9867f77a7ed9d15a1c81aa3f1398c86cd14b02502205b96bc4b1c4dc2b16835acc656203f837c37d389ec65decfe25691e667cc3dfe012103a845425673d8c68211ab69f7de46c81ed2c42e5afbadfe3a6eab971ce5da56fa00000000" + }, + { + "txid": "b784d0389a2450e43ea043567329d0f4e00277ac430bbcedf335d9d85451e088", + "version": 1, + "vin": [ + { + "txid": "b1208bcfb49b5fbc3366bf07b0000b884d59ecdbebc25b1a55f91330317603db", + "vout": 1, + "n": 0, + "addresses": [ + "ltc1qpm594ntjq6ayqjngf6t9td2dxtey9d7985eept" + ], + "isAddress": true, + "value": "3152052" + } + ], + "vout": [ + { + "value": "100000", + "n": 0, + "spent": true, + "hex": "0014b329897dc74dc8d7fa2a68a366593bf266dcda5c", + "addresses": [ + "ltc1qkv5cjlw8fhyd0732dz3kvkfm7fndekjurha9ua" + ], + "isAddress": true + }, + { + "value": "3051600", + "n": 1, + "spent": true, + "hex": "0014f29f00f422480f2f151dfd368565381ad8555d96", + "addresses": [ + "ltc1q720spapzfq8j79gal5mg2efcrtv92hvktc8u76" + ], + "isAddress": true + } + ], + "blockHash": "28f684c412c4394e2da6255567957a493d35a7c7675d8d21a21fab4f3210d772", + "blockHeight": 1778975, + "confirmations": 61392, + "blockTime": 1580198750, + "value": "3151600", + "valueIn": "3152052", + "fees": "452", + "hex": "01000000000101db0376313013f9551a5bc2ebdbec594d880b00b007bf6633bc5f9bb4cf8b20b101000000000000000002a086010000000000160014b329897dc74dc8d7fa2a68a366593bf266dcda5c50902e0000000000160014f29f00f422480f2f151dfd368565381ad8555d9602483045022100e1af3d8173ca2c4c4ac5c2b1e5b20f7cc736563d67154ab8616cfc4f62c3d1b00220296e9595ad8276765d3f83119cb393c3adc4c2a9fb0ad1cb382d3dc13ad59707012102872f9e841a8150ab716574ff897d915f575ed9abe9b4c9426617f6a1d8b3bbd100000000" + }, + { + "txid": "b1208bcfb49b5fbc3366bf07b0000b884d59ecdbebc25b1a55f91330317603db", + "version": 1, + "vin": [ + { + "txid": "a54db30dd54adc3e90a1c5e72b6a5b94992591cbc325adfc28cee55ab5f9dbc0", + "vout": 1, + "n": 0, + "addresses": [ + "ltc1qpm594ntjq6ayqjngf6t9td2dxtey9d7985eept" + ], + "isAddress": true, + "value": "3252504" + } + ], + "vout": [ + { + "value": "100000", + "n": 0, + "spent": true, + "hex": "0014b329897dc74dc8d7fa2a68a366593bf266dcda5c", + "addresses": [ + "ltc1qkv5cjlw8fhyd0732dz3kvkfm7fndekjurha9ua" + ], + "isAddress": true + }, + { + "value": "3152052", + "n": 1, + "spent": true, + "hex": "00140ee85acd7206ba404a684e9655b54d32f242b7c5", + "addresses": [ + "ltc1qpm594ntjq6ayqjngf6t9td2dxtey9d7985eept" + ], + "isAddress": true + } + ], + "blockHash": "28f684c412c4394e2da6255567957a493d35a7c7675d8d21a21fab4f3210d772", + "blockHeight": 1778975, + "confirmations": 61392, + "blockTime": 1580198750, + "value": "3252052", + "valueIn": "3252504", + "fees": "452", + "hex": "01000000000101c0dbf9b55ae5ce28fcad25c3cb912599945b6a2be7c5a1903edc4ad50db34da501000000000000000002a086010000000000160014b329897dc74dc8d7fa2a68a366593bf266dcda5cb4183000000000001600140ee85acd7206ba404a684e9655b54d32f242b7c502473044022007410f524d5597d7ffde5ceff733bcbc05d842194c1ed650ba3ac0bcde4f561902201dde5782c6c47fac0d05fde0df0b7862649b6c3d391d61881733e4e0bb8bc0d8012102872f9e841a8150ab716574ff897d915f575ed9abe9b4c9426617f6a1d8b3bbd100000000" + }, + { + "txid": "07eb5638d1a2833a7eaea596b0dc8bacd8a51be6f18f8bb8cabd514255acebff", + "version": 1, + "vin": [ + { + "txid": "1d646fc08ce623e25db1ffb2a24edc9047290ed381a17055a3f80af73cb7b5f6", + "vout": 1, + "n": 0, + "addresses": [ + "ltc1qpm594ntjq6ayqjngf6t9td2dxtey9d7985eept" + ], + "isAddress": true, + "value": "196764" + } + ], + "vout": [ + { + "value": "100000", + "n": 0, + "spent": true, + "hex": "0014b329897dc74dc8d7fa2a68a366593bf266dcda5c", + "addresses": [ + "ltc1qkv5cjlw8fhyd0732dz3kvkfm7fndekjurha9ua" + ], + "isAddress": true + }, + { + "value": "96312", + "n": 1, + "spent": true, + "hex": "00140ee85acd7206ba404a684e9655b54d32f242b7c5", + "addresses": [ + "ltc1qpm594ntjq6ayqjngf6t9td2dxtey9d7985eept" + ], + "isAddress": true + } + ], + "blockHash": "345e8d0e0db46e61a6cac57d6510c8a10aa96d19acc67b77a6f3da46852c534b", + "blockHeight": 1776086, + "confirmations": 64281, + "blockTime": 1579768496, + "value": "196312", + "valueIn": "196764", + "fees": "452", + "hex": "01000000000101f6b5b73cf70af8a35570a181d30e294790dc4ea2b2ffb15de223e68cc06f641d01000000000000000002a086010000000000160014b329897dc74dc8d7fa2a68a366593bf266dcda5c38780100000000001600140ee85acd7206ba404a684e9655b54d32f242b7c50247304402206245362876d0c13acd72bda09855d4bf9eee7ee0d1c7f623773b9bfe76a93c4d02201be35a5b8bb99c182afeed0bdf35b5b4e235945e8a8e50e8d35ab8176d81567e012102872f9e841a8150ab716574ff897d915f575ed9abe9b4c9426617f6a1d8b3bbd100000000" + }, + { + "txid": "1d646fc08ce623e25db1ffb2a24edc9047290ed381a17055a3f80af73cb7b5f6", + "version": 1, + "vin": [ + { + "txid": "b690c2b2d279f79d3f61fc9bdb7a21278b1614844c2131a0decc960e0a7f2168", + "n": 0, + "addresses": [ + "ltc1qwna0xhkrevtqmhzvhxk4m04l63wm7dpesz24qw" + ], + "isAddress": true, + "value": "299024" + } + ], + "vout": [ + { + "value": "100000", + "n": 0, + "spent": true, + "hex": "0014b329897dc74dc8d7fa2a68a366593bf266dcda5c", + "addresses": [ + "ltc1qkv5cjlw8fhyd0732dz3kvkfm7fndekjurha9ua" + ], + "isAddress": true + }, + { + "value": "196764", + "n": 1, + "spent": true, + "hex": "00140ee85acd7206ba404a684e9655b54d32f242b7c5", + "addresses": [ + "ltc1qpm594ntjq6ayqjngf6t9td2dxtey9d7985eept" + ], + "isAddress": true + } + ], + "blockHash": "68bf0fa93887199ced90a5eebf67af0fd93384b329fd1c93b23012ce0876ffcc", + "blockHeight": 1776080, + "confirmations": 64287, + "blockTime": 1579768089, + "value": "296764", + "valueIn": "299024", + "fees": "2260", + "hex": "0100000000010168217f0a0e96ccdea031214c8414168b27217adb9bfc613f9df779d2b2c290b600000000000000000002a086010000000000160014b329897dc74dc8d7fa2a68a366593bf266dcda5c9c000300000000001600140ee85acd7206ba404a684e9655b54d32f242b7c502483045022100ab047a8d9acfc6dd818d8bee9aadfe2c53fb9991bc7bad81340df1dbce56325502202ab65afb51ec1f1104d95d773770cb4a6b51dc6cc81262a335d7ce51787df89c01210348dec0e7e62b72ba01b63fe25eb12ec8fc1a1e723383eacdc14acda7aef89bc000000000" + }, + { + "txid": "a54db30dd54adc3e90a1c5e72b6a5b94992591cbc325adfc28cee55ab5f9dbc0", + "version": 1, + "vin": [ + { + "txid": "002c4890e61f8469c440fb1d3f393a2decedce809f864215b325623ff22c378d", + "n": 0, + "addresses": [ + "ltc1qsht40umvdekkehcvhw36f4hr0yrgxkykmeccka" + ], + "isAddress": true, + "value": "4252956" + } + ], + "vout": [ + { + "value": "1000000", + "n": 0, + "hex": "0014463fec54ea2c7210057b2d6d1972a8aaaf39a543", + "addresses": [ + "ltc1qgcl7c48293epqptm94k3ju4g42hnnf2r5d4ewq" + ], + "isAddress": true + }, + { + "value": "3252504", + "n": 1, + "spent": true, + "hex": "00140ee85acd7206ba404a684e9655b54d32f242b7c5", + "addresses": [ + "ltc1qpm594ntjq6ayqjngf6t9td2dxtey9d7985eept" + ], + "isAddress": true + } + ], + "blockHash": "b176f179d76b21969f6f004900f1e507fa75a8514c7808b585e01f85f39adb75", + "blockHeight": 1775782, + "confirmations": 64585, + "blockTime": 1579720477, + "value": "4252504", + "valueIn": "4252956", + "fees": "452", + "hex": "010000000001018d372cf23f6225b31542869f80ceedec2d3a393f1dfb40c469841fe690482c000000000000000000000240420f0000000000160014463fec54ea2c7210057b2d6d1972a8aaaf39a54318a13100000000001600140ee85acd7206ba404a684e9655b54d32f242b7c50247304402207e77674f7980ac6579ebbdbc9bcb879da5dde0d7a640fda87187886a12f287d0022013f85719f8f187e315a9eda950b052549bbd839a921546b5b5001c138cda460e0121030b262bf5e861190da899d6165f272c51515ffc3371f1a4c2fb1454c9e0f0b17a00000000" + }, + { + "txid": "002c4890e61f8469c440fb1d3f393a2decedce809f864215b325623ff22c378d", + "version": 1, + "vin": [ + { + "txid": "a0a06e038a056a901f8661b95912427c758a67846a18c9e5c131bcf28840e25b", + "n": 0, + "addresses": [ + "ltc1q80jcymjkypzrmg7t7s77rjtxdlwu95hj24ejl9" + ], + "isAddress": true, + "value": "100000" + }, + { + "txid": "187e023a2ff48ff513b80f54e1ab11e436a41ee8c7e0da63e3c32a2b33a5d641", + "vout": 1, + "n": 1, + "addresses": [ + "ltc1qpm594ntjq6ayqjngf6t9td2dxtey9d7985eept" + ], + "isAddress": true, + "value": "4153636" + } + ], + "vout": [ + { + "value": "4252956", + "n": 0, + "spent": true, + "hex": "001485d757f36c6e6d6cdf0cbba3a4d6e37906835896", + "addresses": [ + "ltc1qsht40umvdekkehcvhw36f4hr0yrgxkykmeccka" + ], + "isAddress": true + } + ], + "blockHash": "b4c819420647722388529da151021a65f3eba29edec797687ba20276268a153e", + "blockHeight": 1774980, + "confirmations": 65387, + "blockTime": 1579585144, + "value": "4252956", + "valueIn": "4253636", + "fees": "680", + "hex": "010000000001025be24088f2bc31c1e5c9186a84678a757c421259b961861f906a058a036ea0a000000000000000000041d6a5332b2ac3e363dae0c7e81ea436e411abe1540fb813f58ff42f3a027e18010000000000000000011ce540000000000016001485d757f36c6e6d6cdf0cbba3a4d6e3790683589602483045022100bf9187a8b6e892ed9e6baf688a0b3099298876d5761575e25689a37a91d858430220232c9dd0f3d6ef5c5eff8e4d79ae8fcb3e6449f2de3f508950005a41a6e50aba01210349f5f593538e07d0353a19126148051ac2c3524f2a609d99ddef3f6cf120db9202473044022016f4fffa57e335405d114aaa3c10b14c75bdb496e72cab156efc0701c0fb6fb902200c20e9e61c5033f86a40f340923b22b3986314a017ffb5aba6c257c411ce812a012102872f9e841a8150ab716574ff897d915f575ed9abe9b4c9426617f6a1d8b3bbd100000000" + }, + { + "txid": "187e023a2ff48ff513b80f54e1ab11e436a41ee8c7e0da63e3c32a2b33a5d641", + "version": 1, + "vin": [ + { + "txid": "8ec0737898fc47b617e3cbae0bca4051e41dd819bca42d017ff3a2920b3c4509", + "vout": 1, + "n": 0, + "addresses": [ + "ltc1q5fe05r6kcdvtxeegp806p72kyky67394hpmsum" + ], + "isAddress": true, + "value": "4254088" + } + ], + "vout": [ + { + "value": "100000", + "n": 0, + "spent": true, + "hex": "0014b329897dc74dc8d7fa2a68a366593bf266dcda5c", + "addresses": [ + "ltc1qkv5cjlw8fhyd0732dz3kvkfm7fndekjurha9ua" + ], + "isAddress": true + }, + { + "value": "4153636", + "n": 1, + "spent": true, + "hex": "00140ee85acd7206ba404a684e9655b54d32f242b7c5", + "addresses": [ + "ltc1qpm594ntjq6ayqjngf6t9td2dxtey9d7985eept" + ], + "isAddress": true + } + ], + "blockHash": "98ab28fe0b5983eb1d0f8b416229f45a68428dedeb86ab3955513036f62c6487", + "blockHeight": 1774979, + "confirmations": 65388, + "blockTime": 1579584910, + "value": "4253636", + "valueIn": "4254088", + "fees": "452", + "hex": "0100000000010109453c0b92a2f37f012da4bc19d81de45140ca0baecbe317b647fc987873c08e01000000000000000002a086010000000000160014b329897dc74dc8d7fa2a68a366593bf266dcda5c24613f00000000001600140ee85acd7206ba404a684e9655b54d32f242b7c5024830450221009a577593c93bf576c25a91efe8fbb6b73a969eb383fab4fbbead2fc3c4689cfd022022036d3dfadbd81c35a2512225da857a6d6d3c4953de21421be9bb2d7f590dfb012102405d626b98304b8f35bf90004894f40f0d54aedef11b46612fed2e82a08640fe00000000" + }, + { + "txid": "a0a06e038a056a901f8661b95912427c758a67846a18c9e5c131bcf28840e25b", + "version": 1, + "vin": [ + { + "txid": "c58315f8f640bc758fb550860e6e7c0564f97933d2950f6436146265ac215c9e", + "n": 0, + "addresses": [ + "ltc1qpm594ntjq6ayqjngf6t9td2dxtey9d7985eept" + ], + "isAddress": true, + "value": "4555444" + } + ], + "vout": [ + { + "value": "100000", + "n": 0, + "spent": true, + "hex": "00143be5826e5620443da3cbf43de1c9666fddc2d2f2", + "addresses": [ + "ltc1q80jcymjkypzrmg7t7s77rjtxdlwu95hj24ejl9" + ], + "isAddress": true + }, + { + "value": "4454992", + "n": 1, + "spent": true, + "hex": "00142f6288391f29e894b4841a679bf3bffa1a2605dd", + "addresses": [ + "ltc1q9a3gswgl985ffdyyrfnehuallgdzvpwa9xyu0s" + ], + "isAddress": true + } + ], + "blockHash": "3128d4b4e5faeaa788048f39ae2c11d759b32057f81898b7873314e6bd0af6ea", + "blockHeight": 1773960, + "confirmations": 66407, + "blockTime": 1579432769, + "value": "4554992", + "valueIn": "4555444", + "fees": "452", + "hex": "010000000001019e5c21ac65621436640f95d23379f964057c6e0e8650b58f75bc40f6f81583c500000000000000000002a0860100000000001600143be5826e5620443da3cbf43de1c9666fddc2d2f250fa4300000000001600142f6288391f29e894b4841a679bf3bffa1a2605dd02483045022100d045b6218596f68e62da33b7ef1e24ffce728b0bdf9645169256fd9b2ea90e8f02207f2170ae269c8f7f5e1c6e4f728056ae8f642f0c41dac76d2bc1ae3b91416ba8012102872f9e841a8150ab716574ff897d915f575ed9abe9b4c9426617f6a1d8b3bbd100000000" + }, + { + "txid": "c58315f8f640bc758fb550860e6e7c0564f97933d2950f6436146265ac215c9e", + "version": 1, + "vin": [ + { + "txid": "afcaae3d72a005b3534fd2cceb756584e789a364422c1818cee1cc1a50f65b7b", + "n": 0, + "addresses": [ + "ltc1q2j0k8v7aczdajd42g96h7gy4jef63feh77494u" + ], + "isAddress": true, + "value": "1000" + }, + { + "txid": "afcaae3d72a005b3534fd2cceb756584e789a364422c1818cee1cc1a50f65b7b", + "vout": 1, + "n": 1, + "addresses": [ + "ltc1qctr5lrsrpek4uxhdkyvska86swvdvgdj5m6272" + ], + "isAddress": true, + "value": "4555124" + } + ], + "vout": [ + { + "value": "4555444", + "n": 0, + "spent": true, + "hex": "00140ee85acd7206ba404a684e9655b54d32f242b7c5", + "addresses": [ + "ltc1qpm594ntjq6ayqjngf6t9td2dxtey9d7985eept" + ], + "isAddress": true + } + ], + "blockHash": "85b2d5e43d9707cf230a01445c5a25c273da9fa54926e40a11e27b4c51507be5", + "blockHeight": 1773954, + "confirmations": 66413, + "blockTime": 1579432217, + "value": "4555444", + "valueIn": "4556124", + "fees": "680", + "hex": "010000000001027b5bf6501acce1ce18182c4264a389e7846575ebccd24f53b305a0723daecaaf0000000000000000007b5bf6501acce1ce18182c4264a389e7846575ebccd24f53b305a0723daecaaf01000000000000000001b4824500000000001600140ee85acd7206ba404a684e9655b54d32f242b7c50247304402206b44554da9ee7b0a5cd15fae67799cee60f9d1237cc85e939597b15c91caa5370220768d26750a4fd7c566282ebd162db24058bc0938d2d2aa8205e2b418c90733d90121023c3c2a4f46b4d9dd305d8e030efd76bee0f22f5794cdb69c761aaa7139d3885b02483045022100a38bd5236acaa978073ce5f6d67cf499b8dbb771cf4bc0b6e4dbfeecb637a1d0022042e076375eb8f4d872e2fa55089a5de2dd5de67ae91d0e621e4998fa4a2eda13012103de91c9cd7f1e0c7b37c997fc6ba9353504d9f283cda1e58cffee627bc1528bf300000000" + }, + { + "txid": "a86bec27c5c517f140d69e092c746296dcf2430602edd81bf680890a29b1108b", + "version": 1, + "vin": [ + { + "txid": "8658c06633a538405f4569cf6238641e80fa6fab176797a43c5b26c4fbac9ae8", + "n": 0, + "addresses": [ + "ltc1qmpsjljyexwn0dk4myglykyu56x9qkqnkgmpdrl" + ], + "isAddress": true, + "value": "10000" + }, + { + "txid": "511692fb776631e54f554a419115b975e60ac499f0e084851a1c01408fdf30a1", + "n": 1, + "addresses": [ + "ltc1qt7frzf37ndtta78fvmc3a4gphsvths9g4fqufk" + ], + "isAddress": true, + "value": "10000" + }, + { + "txid": "2f637249f0124fe6153b6489ed4c1f7dd0cd3a2a9889063de193064b720127ef", + "vout": 1, + "n": 2, + "addresses": [ + "ltc1qjzrcnxst987jepzuvmpgesu59zmnv44mjqs48t" + ], + "isAddress": true, + "value": "28644" + }, + { + "txid": "fbcf72d702ee78a83adf9c5699a45c367eaeb17e151ce4e320da423d8b7430cb", + "vout": 1, + "n": 3, + "addresses": [ + "ltc1q4g6egkjhwr64zptf2pngkn2u3v8wfa8n4fj8wr" + ], + "isAddress": true, + "value": "43866" + }, + { + "txid": "36734bc826395b278f5dc01f01f98276357660e81ffa27cd531d5db5b52fe621", + "vout": 1, + "n": 4, + "addresses": [ + "ltc1qxtx6ak7s2t3sjxvpvqccl4velnhmwlv0pqegce" + ], + "isAddress": true, + "value": "45886" + }, + { + "txid": "fbcf72d702ee78a83adf9c5699a45c367eaeb17e151ce4e320da423d8b7430cb", + "n": 5, + "addresses": [ + "ltc1qjvqng3u009ek9926eume6vmyu9quc0uy0utcpq" + ], + "isAddress": true, + "value": "55682" + }, + { + "txid": "36734bc826395b278f5dc01f01f98276357660e81ffa27cd531d5db5b52fe621", + "n": 6, + "addresses": [ + "ltc1qpm594ntjq6ayqjngf6t9td2dxtey9d7985eept" + ], + "isAddress": true, + "value": "55686" + }, + { + "txid": "00395a5ae5dd4a241827e5111df360a00a4823067da5b65b3c8e18a73449e50b", + "vout": 1, + "n": 7, + "addresses": [ + "ltc1qcjnfzmy6n34lqwvmv9j7nsj5dx042kswxjz2v7" + ], + "isAddress": true, + "value": "60246" + }, + { + "txid": "611c047d6e717414481f7c585b35c08c819f9fcd76f33de53976dcd64b33d6c5", + "vout": 1, + "n": 8, + "addresses": [ + "ltc1q7tz7p6g5gpgvnxg0t7glahl5ufg6fnq2q0uq4q" + ], + "isAddress": true, + "value": "82209" + }, + { + "txid": "ed2998bdab40da72b51c3e9c41e5363cfa344a0a066b4c5fbb9cc6d5848c6470", + "n": 9, + "addresses": [ + "ltc1qvetv0ghlrzf520d9hh508vwu273whxxlu8ln4v" + ], + "isAddress": true, + "value": "98244" + }, + { + "txid": "f9d23fa8e27ac9becc0a7087155478f1669b75b86f66e981c7ab44edecf41f82", + "vout": 1, + "n": 10, + "addresses": [ + "ltc1q9gsu5fdspttjq9wwnezjr43kd0luhqn329d0n9" + ], + "isAddress": true, + "value": "99548" + }, + { + "txid": "daca8142ff4e5bc58d6b61c91f7587cf57311e0aeef912b98e603b350a0116d1", + "n": 11, + "addresses": [ + "ltc1q8q9l9sjkdg840zgmf0egfaw5ndv4wxtwfck8d3" + ], + "isAddress": true, + "value": "100000" + }, + { + "txid": "00395a5ae5dd4a241827e5111df360a00a4823067da5b65b3c8e18a73449e50b", + "n": 12, + "addresses": [ + "ltc1qt84md3dmkwks35lawgwha95vmvvk8vhmfl98de" + ], + "isAddress": true, + "value": "100000" + }, + { + "txid": "f9d23fa8e27ac9becc0a7087155478f1669b75b86f66e981c7ab44edecf41f82", + "n": 13, + "addresses": [ + "ltc1qsjkccjvfzk9uewq9k9ckk3ar5ka4gp46vzwlt3" + ], + "isAddress": true, + "value": "100000" + }, + { + "txid": "644a3be94f70d3976796163fdef4c60ad1dc0e7ed8f1cee5d111e45fe2fa9189", + "vout": 1, + "n": 14, + "addresses": [ + "ltc1q3yq785557a33dhjzp59jrkkaujn0afsrguetcp" + ], + "isAddress": true, + "value": "188048" + }, + { + "txid": "4fe68a083656b6fae2d7fa623264698ce48f34ec37357c9177556b20b7dbe77c", + "n": 15, + "addresses": [ + "ltc1qpr6qvgwr4uv0tka9p5zx7gyhf88gam99xkhsn4" + ], + "isAddress": true, + "value": "288550" + }, + { + "txid": "9013075bc9ff19f7f23f8010585983bca5d602c6ed80e48ffe659de97246344c", + "n": 16, + "addresses": [ + "ltc1qjz0ent2u5xgsah9ar6zfm0e280g84yaw3060ze" + ], + "isAddress": true, + "value": "300000" + }, + { + "txid": "9e257fe060539ab61dd6285ffb6663035e4c74bc2a4269bea49688249a4a9672", + "vout": 1, + "n": 17, + "addresses": [ + "ltc1q4qsmvmhnvg5kf84syx3fxdyptfr0h7w7uf2et2" + ], + "isAddress": true, + "value": "543134" + }, + { + "txid": "ce9c46df8ef5fba0a385f71e89c2eab29f1b25cda0d257c4e3abb2da5259b83b", + "vout": 1, + "n": 18, + "addresses": [ + "ltc1q2vez3w9f7c0q4yreehjkmva8pv60uy77z69vm5" + ], + "isAddress": true, + "value": "667304" + }, + { + "txid": "574894f61396adb14b974031efda701829f0a91106bdd4745f7acd6a59b79563", + "n": 19, + "addresses": [ + "ltc1q3dq4vhjezkst2gtztw7a25z9jsmnzktc7jgcth" + ], + "isAddress": true, + "value": "690743" + }, + { + "txid": "b8fd90d4be97d54c8d737180ce405cf2293f54cc5000a34f11c13f889d2352d0", + "n": 20, + "addresses": [ + "ltc1q3hhcu482usaq66rzesdpdzne0wq54p3r7rknr2" + ], + "isAddress": true, + "value": "1000000" + }, + { + "txid": "d4f13258ac3595da242a83856dd3324522507a7f2a06b4c3c4829a570aa1990e", + "n": 21, + "addresses": [ + "ltc1qp96jhevfs75rlp34nxaanyxwn9mtgx5g0j896g" + ], + "isAddress": true, + "value": "1000000" + } + ], + "vout": [ + { + "value": "5561190", + "n": 0, + "spent": true, + "hex": "001474f62cc6a965d238623efd3868c2385eeb97aaba", + "addresses": [ + "ltc1qwnmze34fvhfrsc37l5ux3s3ctm4e0246w7lfy9" + ], + "isAddress": true + } + ], + "blockHash": "117bee1c7f2980b29cbcaf541f5b53a4f42f4ea34a4154e93744c713442a1c51", + "blockHeight": 1701667, + "confirmations": 138700, + "blockTime": 1568367063, + "value": "5561190", + "valueIn": "5567790", + "fees": "6600", + "hex": "01000000000116e89aacfbc4265b3ca4976717ab6ffa801e643862cf69455f4038a53366c05886000000000000000000a130df8f40011c1a8584e0f099c40ae675b91591414a554fe5316677fb921651000000000000000000ef2701724b0693e13d0689982a3acdd07d1f4ced89643b15e64f12f04972632f010000000000000000cb30748b3d42da20e3e41c157eb1ae7e365ca499569cdf3aa878ee02d772cffb01000000000000000021e62fb5b55d1d53cd27fa1fe86076357682f9011fc05d8f275b3926c84b7336010000000000000000cb30748b3d42da20e3e41c157eb1ae7e365ca499569cdf3aa878ee02d772cffb00000000000000000021e62fb5b55d1d53cd27fa1fe86076357682f9011fc05d8f275b3926c84b73360000000000000000000be54934a7188e3c5bb6a57d0623480aa060f31d11e52718244adde55a5a3900010000000000000000c5d6334bd6dc7639e53df376cd9f9f818cc0355b587c1f481474716e7d041c6101000000000000000070648c84d5c69cbb5f4c6b060a4a34fa3c36e5419c3e1cb572da40abbd9829ed000000000000000000821ff4eced44abc781e9666fb8759b66f178541587700accbec97ae2a83fd2f9010000000000000000d116010a353b608eb912f9ee0a1e3157cf87751fc9616b8dc55b4eff4281cada0000000000000000000be54934a7188e3c5bb6a57d0623480aa060f31d11e52718244adde55a5a3900000000000000000000821ff4eced44abc781e9666fb8759b66f178541587700accbec97ae2a83fd2f90000000000000000008991fae25fe411d1e5cef1d87e0edcd10ac6f4de3f16966797d3704fe93b4a640100000000000000007ce7dbb7206b5577917c3537ec348fe48c69643262fad7e2fab65636088ae64f0000000000000000004c344672e99d65fe8fe480edc602d6a5bc83595810803ff2f719ffc95b07139000000000000000000072964a9a248896a4be69422abc744c5e036366fb5f28d61db69a5360e07f259e0100000000000000003bb85952dab2abe3c457d2a0cd251b9fb2eac2891ef785a3a0fbf58edf469cce0100000000000000006395b7596acd7a5f74d4bd0611a9f0291870daef3140974bb1ad9613f6944857000000000000000000d052239d883fc1114fa30050cc543f29f25c40ce8071738d4cd597bed490fdb80000000000000000000e99a10a579a82c4c3b4062a7f7a50224532d36d85832a24da9535ac5832f1d40000000000000000000166db54000000000016001474f62cc6a965d238623efd3868c2385eeb97aaba0247304402203bf6ab7ea29cb1ca9e80555f07e5fea03941236db0e7eda0629126c22ec56eaf0220552aa5f962a8876ac74a5242b622668027f8f7417ae88032356d3b15c642668f012102b65d85bcfb9aadc1fe3b40fb79e8b52f096da4e588d2f9174a773d894e98c6fe02483045022100eb01bf49b1330223f00d03db4490a3d1fc09f5e25d8fa9e10805d782568483c902204e05f06f1184b63a2acc76ee6c0e16989329780aa3c1f9c981671c0b1400634e0121024657d84015314cec7322f9fba0137062cc5befd1c453f06a45ef9b254f95e4710247304402206f981a9fbb7805823a05156d0eb4d360f97151f8f56cf9c12d2ca5a4e32e758b022012ff0eee5a39b6f27188b639afc2dec45b40e3d87ae4f381b28af1b49bcdfd7e012103824fe9af295ce51dcf812e27162d346f2a278ac024610c184780d28989b896460247304402206e1818d244b9cddb31c20a2dfa55df18b66ed2b88c1dedf4fa842042c8b0760e022006c379842cb494a03c1cdb47a6a9e476854539e32954323fe7d550b81cdb0b970121021d27a125a6539b9c4f0a9c7be2b4ecb768603fb82559f971053d688184d84d5c02483045022100a5257c7fa40dc8e7f041ce6834b1ca2fd9db6a5e24d8e9bf4bc62dfe5175fd1202202a11909b2627c381bc56504c6bea08ed2a87fde1bd89b46b784f1787a8c65898012102fa952e151f9b7ce62774b428f0c65703955d3e9e82f6b8b06151b11ac5e6b9db02473044022018448ce769628b90c39047a8d98d622039882f3c68bf400a408cef14277244c1022065ca98159288b3967e47d6b76f04cb79aa86ad850ebfc8d6576837e7efa9eece01210255fc01e2aeb3f3d3d25dff9c8cbf5f722bb93c152d4646d01ef34ef7f041806102483045022100d42037c4feb57200e4ed4723f0f0f9150f2f3882491e9b086caedb8452ffde530220167d68970905568e3dab926a96cbfe94b01dd886902ef9895c3f332be890eb8f012102872f9e841a8150ab716574ff897d915f575ed9abe9b4c9426617f6a1d8b3bbd102473044022067cbaa14c80f6ce2af43dcea8e50f162d64bd9d73d788dee5ec8aa0b3669dc7402206cc30081ef3a7a25d3386c8338a16c8ccbc84756885c5077a264245f5fefc83a012103f4ae1b4010e52d142ef2c07e2e1b14d716f8d29ea507127fe7ca59a4398c65460247304402205d7e19f44e23c03656a8c9c54c29a57248886a8217f1f9d5b341ca8382caf67902204c155a398b900d4fe9b8f06549dc0e81a0bd36bbd43e7943841c66280b0217220121021137293acd25f8494a6c5d585f113d96aa91cae982818a0aed862108f3552e470247304402206633b5bcf7357bde337cad546e844beb6145199a2762b842b623e519ea49a469022041dc087919d48c3f36be4cf8d065a9645ef61d179f7ddc5ec171991f5f99a43b0121030a7bd368800f5fcb0cd3691aae72cc10ae18d19418b1e9f340cedf447ae3c5020247304402207e524f9adc38f317002682c10a0fcf59f025b2e49da7f5dab447fc738c5a23f402202bb18a495da49203de0e36cf2416d0f10a3a39355abaaac643c2e756126ae46601210208c5e94833465331e6f6a4dba0bc93b9e486a1012e11a38fe5fc76c5b16ec21f0247304402205f7f65fc707468e9a21fb4be7ce4ed5d757c1a1eeef6147f8827c8ef8bd638af02204e33f0a5a84d641c2e921abcc3d64d27314ea4a5bfea9aee36e76ce67c3757dc0121033af85cca3c0a341068b0900a098d5a1c1ecda1dac67db6b457b65937fde93cfe0247304402201bba3c382c5c3298231b79fce8eb3c31473a95b8602ce89d03f317edea03d83102206de06bdfc5a0adbf0fd3700c5b3ce1e764be19d92d8269b8b340835218e81658012103f6c4ec9154083c6f4a82fabaf3253d87b61e64ad1023e5ffe3003e3ee92ba2cb0247304402202fbf0503733fdc01e7fb87902e0d144583aabc6bbb03dda71c251a8abc5f21eb022052dd70bb3caf32f7f9a9efb2a5008124b1494aa1e215828fd2c5039e3d28a8e10121028745fd18d99f19ea79f45dede4ff4297396d39464086a9e58f3100c6efcb8179024730440220662f7285e89d56c31429a39f5a68414529824c7e827d99ef2420e24a180604fa022078d9f263b636f4414dc190ee0a7b4a54f103abdefcc228874014c09fd9d72eae012102440f980c9746170db2a5aac6eed16f68bb0f83d2e4e7cfe953a025ac6e414e910247304402201ad5d8cb11d9ca2896509d99eef6496694920e6dd4c1804a8cd846da194d209a02201a4d6e635c6b23100272b4207ed77eeb45f8aa8dcd90801386432d6746f0acdf012103ad66203dc92d5b81773f332bc2c8bdfd3b27d90d359a21a8141407512f011f4502483045022100c1a82aa837704b975ed12785e9a33a4ec6f0d1a9131e17b6f28aaef8eb187a98022069e197cecff059133816c9e228c74242211a20a59aed646d3c12dcbcb48350cf012102c955da9410883590a79358485867ba6e3f53ea8d456873fc8d6f0b3b3fa6bc3402483045022100e4c0e7b2861c41e67b100e6c3c7a42a45ec7df9f276afcb60098b409e4677c7802207feb60ce5261b1d59818de0394e9492268b83d263da600fc9147f415fa6b652101210252127d906aa59a02d2fb617d7ff0789ce1e08b4bfea250575da50183963f56cd02473044022013b37a47a7b712569ad2db5016b81bc8ed308a1ef1e84a81326891b5fcbddb5402203574f470584185218dab0e8d9a634cd5c1f359ced78f36f4146ada86799dae360121037f0980f1dd44fe36db1cea51042ba40e88325e3792da02b2b5a6b246ca5862ab0248304502210080a2378ba9ad0738028994e1d6aa4c57405e0c7867bdb0cca578cc815ac1cd9e022020bd9a779cba23f9e6f2922ba70741b9403913d6ddc49df5c0a2544eb9a14f2c012103d37a0609c9ddbb8105e89c125f3531316322c2d9410b52512cf93a0076bdad180247304402200305f95ed6e310e12765c278f223cfef463954df9119bf2bdff357c558e856b5022019903dc65a8f3d267e56e009b85e63e86de05baebdb804f4538b753695491fec01210202f6bb1a32dd40d63f0e40a986b40bc316d69ccbf613b0e9e3f8f81e4afda63302483045022100f1e59775253a28a7f9483889d03a24216a2cd26f7a2ef4f27aa8a87b0acae11202204cb1d53dc9af89e6e4f03df16f74ef4db12ab451e616e0b2c0d745d310f93c0c0121023f82a1cb6dc690a0663518cd8f37de0b0ffc2d6701965f36e1fc6593a362266900000000" + }, + { + "txid": "36734bc826395b278f5dc01f01f98276357660e81ffa27cd531d5db5b52fe621", + "version": 1, + "vin": [ + { + "txid": "daca8142ff4e5bc58d6b61c91f7587cf57311e0aeef912b98e603b350a0116d1", + "vout": 1, + "sequence": 4294967289, + "n": 0, + "addresses": [ + "ltc1q54pcpg2fcnd4c4gwqc6uw30mjgnt086yxtfjpt" + ], + "isAddress": true, + "value": "102024" + } + ], + "vout": [ + { + "value": "55686", + "n": 0, + "spent": true, + "hex": "00140ee85acd7206ba404a684e9655b54d32f242b7c5", + "addresses": [ + "ltc1qpm594ntjq6ayqjngf6t9td2dxtey9d7985eept" + ], + "isAddress": true + }, + { + "value": "45886", + "n": 1, + "spent": true, + "hex": "001432cdaedbd052e309198160318fd599fcefb77d8f", + "addresses": [ + "ltc1qxtx6ak7s2t3sjxvpvqccl4velnhmwlv0pqegce" + ], + "isAddress": true + } + ], + "blockHash": "f6312bc43fb69c100c3faf23c9977760e1fa3932fe6f03762c62c1e38758ec19", + "blockHeight": 1699469, + "confirmations": 140898, + "blockTime": 1568043854, + "value": "101572", + "valueIn": "102024", + "fees": "452", + "hex": "01000000000101d116010a353b608eb912f9ee0a1e3157cf87751fc9616b8dc55b4eff4281cada0100000000f9ffffff0286d90000000000001600140ee85acd7206ba404a684e9655b54d32f242b7c53eb300000000000016001432cdaedbd052e309198160318fd599fcefb77d8f02473044022076533ef6060c6f92c25aa5c2f1e1cfeb9e215226518913a6cc6e2622fadf6827022078319b8fd96785034797693c0c5a8aae1504287bba2d39ad7c3d1e78d6b1aa9c01210341bc7668f0c3f15a6e227788f2654d3c9178ef0d9e7ec90312c2dcb6ff43295c00000000" + }, + { + "txid": "bf7e50d2556f5557756c52a7ccdd5349850a0552de043c96bf38dee05b9fcdcc", + "version": 1, + "vin": [ + { + "txid": "054685957c82eec4a729919809ca880e093d27d50d5fc364b6bc4000a66c62d8", + "sequence": 4294967295, + "n": 0, + "addresses": [ + "ltc1qpm594ntjq6ayqjngf6t9td2dxtey9d7985eept" + ], + "isAddress": true, + "value": "3900156" + } + ], + "vout": [ + { + "value": "100000", + "n": 0, + "spent": true, + "hex": "00142b12c909673ca18b4f0e6a5eb7381e03aa94064a", + "addresses": [ + "ltc1q9vfvjzt88jsckncwdf0twwq7qw4fgpj2uf2jht" + ], + "isAddress": true + }, + { + "value": "3799704", + "n": 1, + "spent": true, + "hex": "0014260483f197a26a803ee8a57ef587bafeb74c8dbd", + "addresses": [ + "ltc1qyczg8uvh5f4gq0hg54l0tpa6l6m5erda6tw5jh" + ], + "isAddress": true + } + ], + "blockHash": "b54f669d59620ffb17a13e841bd4addcff223b8bd9a73ff10ff3e0b9b5a9dfaa", + "blockHeight": 1539785, + "confirmations": 300582, + "blockTime": 1544245351, + "value": "3899704", + "valueIn": "3900156", + "fees": "452", + "hex": "01000000000101d8626ca60040bcb664c35f0dd5273d090e88ca09989129a7c4ee827c958546050000000000ffffffff02a0860100000000001600142b12c909673ca18b4f0e6a5eb7381e03aa94064a98fa390000000000160014260483f197a26a803ee8a57ef587bafeb74c8dbd02483045022100b1fc6e52f4f462eb96ec396de56e6ea1b9bb67ceb5e447711907d1d08e78dd9702200b278ac4700ff295261d05b461984aa3ea04de118605866de12883adb52312e6012102872f9e841a8150ab716574ff897d915f575ed9abe9b4c9426617f6a1d8b3bbd100000000" + }, + { + "txid": "054685957c82eec4a729919809ca880e093d27d50d5fc364b6bc4000a66c62d8", + "version": 1, + "vin": [ + { + "txid": "cf7ed8eb0b830868632072293de303d6d90ee240e80c104414b3ffeed4332e83", + "vout": 14, + "sequence": 4294967295, + "n": 0, + "addresses": [ + "MWceeqZHxJBj4UJCebKfnb1ie5akap9xsf" + ], + "isAddress": true, + "value": "5000000", + "hex": "160014c21653fb1b3d73b9b2aff9459a459e770adcc0d2" + } + ], + "vout": [ + { + "value": "3900156", + "n": 0, + "spent": true, + "hex": "00140ee85acd7206ba404a684e9655b54d32f242b7c5", + "addresses": [ + "ltc1qpm594ntjq6ayqjngf6t9td2dxtey9d7985eept" + ], + "isAddress": true + }, + { + "value": "1099342", + "n": 1, + "spent": true, + "hex": "0014f26491d75185515cfb1d64a88eba8f3b48789137", + "addresses": [ + "ltc1q7fjfr463s4g4e7cavj5gaw508dy83yfhx7vgpw" + ], + "isAddress": true + } + ], + "blockHash": "9d5f9faba06cda333e32fb2fdc82daefeb65991417f2cebea25dabe51cd68ce6", + "blockHeight": 1539738, + "confirmations": 300629, + "blockTime": 1544237458, + "value": "4999498", + "valueIn": "5000000", + "fees": "502", + "hex": "01000000000101832e33d4eeffb31444100ce840e20ed9d603e33d297220636808830bebd87ecf0e00000017160014c21653fb1b3d73b9b2aff9459a459e770adcc0d2ffffffff02fc823b00000000001600140ee85acd7206ba404a684e9655b54d32f242b7c54ec6100000000000160014f26491d75185515cfb1d64a88eba8f3b487891370247304402202c339116fc96796f40d8ead3ad7be4c26861b7b0a493ea4c4945b0fc4465c2ec02203055725efedbe971405671a6c148991e16b2e212c37ac02cc764881028b725690121029bbbd9e73d00bd5cb95e29077f17746cac5caa8abb7e23939a00ac18f1d8b99d00000000" + } + ] +} diff --git a/mock/ext-api-data/litecoin-api_v2_xpub_zpub6rpF5Uxuz4KKWePLorSz2QrHMmk1iiZvGUGgtSHpor8yiGekyRuWf5ZNmf6GUKB4v3ibQDuZp5v8RnjEGq58kR3WPtGPn8Lrg677MQ8YeKu__details_txs.json b/mock/ext-api-data/litecoin-api_v2_xpub_zpub6rpF5Uxuz4KKWePLorSz2QrHMmk1iiZvGUGgtSHpor8yiGekyRuWf5ZNmf6GUKB4v3ibQDuZp5v8RnjEGq58kR3WPtGPn8Lrg677MQ8YeKu__details_txs.json new file mode 100644 index 000000000..17698facd --- /dev/null +++ b/mock/ext-api-data/litecoin-api_v2_xpub_zpub6rpF5Uxuz4KKWePLorSz2QrHMmk1iiZvGUGgtSHpor8yiGekyRuWf5ZNmf6GUKB4v3ibQDuZp5v8RnjEGq58kR3WPtGPn8Lrg677MQ8YeKu__details_txs.json @@ -0,0 +1 @@ +{"page":1,"totalPages":13,"itemsOnPage":10,"address":"zpub6rpF5Uxuz4KKWePLorSz2QrHMmk1iiZvGUGgtSHpor8yiGekyRuWf5ZNmf6GUKB4v3ibQDuZp5v8RnjEGq58kR3WPtGPn8Lrg677MQ8YeKu","balance":"1818078","totalReceived":"379622767","totalSent":"377804689","unconfirmedBalance":"0","unconfirmedTxs":0,"txs":130,"transactions":[{"txid":"bfce02fdd69ec01c08486b75fa5e4a93d82a0e6f346c8eade6437affb0f817b1","version":1,"vin":[{"txid":"674092ed2b166f0f21ba6287b1df23abb9612e140e77bd52f2885312c69bf867","vout":1,"n":0,"addresses":["ltc1qpm594ntjq6ayqjngf6t9td2dxtey9d7985eept"],"isAddress":true,"value":"788530"}],"vout":[{"value":"100000","n":0,"hex":"0014ccf05f3bc453f7f66fb48b124bd79690bc309e22","addresses":["ltc1qenc97w7y20mlvma53vfyh4ukjz7rp83zf892wx"],"isAddress":true},{"value":"688078","n":1,"hex":"00140ee85acd7206ba404a684e9655b54d32f242b7c5","addresses":["ltc1qpm594ntjq6ayqjngf6t9td2dxtey9d7985eept"],"isAddress":true}],"blockHash":"ae8df4fb9cbbd07375eef217dd25e8b918a1b2746907c23cf4f2e15cd18fccdd","blockHeight":1804076,"confirmations":40929,"blockTime":1583910871,"value":"788078","valueIn":"788530","fees":"452","hex":"0100000000010167f89bc6125388f252bd770e142e61b9ab23dfb18762ba210f6f162bed92406701000000000000000002a086010000000000160014ccf05f3bc453f7f66fb48b124bd79690bc309e22ce7f0a00000000001600140ee85acd7206ba404a684e9655b54d32f242b7c502483045022100a40df50e2b419a35001f40d508e911f36d01497ebe5225dc93c81f53a30452fb022034c086517326be293019c2cbf215d6b9a53aa0ab4a0c2b890a9f1b05e8052aac012102872f9e841a8150ab716574ff897d915f575ed9abe9b4c9426617f6a1d8b3bbd100000000"},{"txid":"674092ed2b166f0f21ba6287b1df23abb9612e140e77bd52f2885312c69bf867","version":1,"vin":[{"txid":"f8ddc3eca55aa4bffd27b030fc3b35ceb8d503b31a03dafd32df56eec552fe99","vout":1,"sequence":4294967290,"n":0,"addresses":["ltc1qpm594ntjq6ayqjngf6t9td2dxtey9d7985eept"],"isAddress":true,"value":"1788982"}],"vout":[{"value":"1000000","n":0,"hex":"00140ee85acd7206ba404a684e9655b54d32f242b7c5","addresses":["ltc1qpm594ntjq6ayqjngf6t9td2dxtey9d7985eept"],"isAddress":true},{"value":"788530","n":1,"spent":true,"hex":"00140ee85acd7206ba404a684e9655b54d32f242b7c5","addresses":["ltc1qpm594ntjq6ayqjngf6t9td2dxtey9d7985eept"],"isAddress":true}],"blockHash":"dd92763dcb8477d8f012e5ec0598ebf3c135a15780d7491754fff40d3d24dd9b","blockHeight":1803562,"confirmations":41443,"blockTime":1583831802,"value":"1788530","valueIn":"1788982","fees":"452","hex":"0100000000010199fe52c5ee56df32fdda031ab303d5b8ce353bfc30b027fdbfa45aa5ecc3ddf80100000000faffffff0240420f00000000001600140ee85acd7206ba404a684e9655b54d32f242b7c532080c00000000001600140ee85acd7206ba404a684e9655b54d32f242b7c502483045022100bbde918ff538468c440424323bbe8ba78eef14d9dde357c8e6496905d540098c02205700d984884edff918f827289898c16ec9ad30344a637ea85dc55f7f836143bd012102872f9e841a8150ab716574ff897d915f575ed9abe9b4c9426617f6a1d8b3bbd100000000"},{"txid":"f8ddc3eca55aa4bffd27b030fc3b35ceb8d503b31a03dafd32df56eec552fe99","version":1,"vin":[{"txid":"0bc6314b50a192853d09b2ca3ebadea75288bfb66e9b254c8f55ebaa720a7d2f","vout":1,"n":0,"addresses":["ltc1qd0huz2atjj0uyjlcp48ml9tltkzdta7sg8fn89"],"isAddress":true,"value":"1889434"}],"vout":[{"value":"100000","n":0,"spent":true,"hex":"0014e8d0e2bade0aefda201fad8ff5859d743b252a5b","addresses":["ltc1qargw9wk7ptha5gql4k8ltpvawsaj22jmr8cejf"],"isAddress":true},{"value":"1788982","n":1,"spent":true,"hex":"00140ee85acd7206ba404a684e9655b54d32f242b7c5","addresses":["ltc1qpm594ntjq6ayqjngf6t9td2dxtey9d7985eept"],"isAddress":true}],"blockHash":"c9503e0fe18dd16a8a1e836d08d6966e443fbe79eeb0561f2fb18e5993a0cfec","blockHeight":1800498,"confirmations":44507,"blockTime":1583384860,"value":"1888982","valueIn":"1889434","fees":"452","hex":"010000000001012f7d0a72aaeb558f4c259b6eb6bf8852a7deba3ecab2093d8592a1504b31c60b01000000000000000002a086010000000000160014e8d0e2bade0aefda201fad8ff5859d743b252a5b364c1b00000000001600140ee85acd7206ba404a684e9655b54d32f242b7c502483045022100f6adacde68792f7862ec58b066ed4b521444929d90c163b5eb7b0a3d3e16c133022018f649e6a9cece3dc58fdb09f8cffb5cf9ba64f7a453ae6d82043b3fc65fe8ba01210273a11ff2e056c52a0a10c3b93590f60802ab8a74bf9828ea76ae87885fddfc8d00000000"},{"txid":"0bc6314b50a192853d09b2ca3ebadea75288bfb66e9b254c8f55ebaa720a7d2f","version":1,"vin":[{"txid":"fdbf28c741e55f846a0a378e0cf2a7263540f8d24123b658f2beb0bd1b1788f0","sequence":4294967291,"n":0,"addresses":["ltc1q2rs8e2xy7tr7c5e4zugqzwsry5dtt5wcdk4zv9"],"isAddress":true,"value":"1989886"}],"vout":[{"value":"100000","n":0,"hex":"0014307b46c6979c94598ce49d1145bc4d8eeb2704fb","addresses":["ltc1qxpa5d35hnj29nr8yn5g5t0zd3m4jwp8mwchc9c"],"isAddress":true},{"value":"1889434","n":1,"spent":true,"hex":"00146befc12bab949fc24bf80d4fbf957f5d84d5f7d0","addresses":["ltc1qd0huz2atjj0uyjlcp48ml9tltkzdta7sg8fn89"],"isAddress":true}],"blockHash":"d6aedacf9e98591e6fad1116d13d202a9067e0ace5e6c6ade28dba8ae06abe77","blockHeight":1797397,"confirmations":47608,"blockTime":1582916585,"value":"1989434","valueIn":"1989886","fees":"452","hex":"01000000000101f088171bbdb0bef258b62341d2f8403526a7f20c8e370a6a845fe541c728bffd0000000000fbffffff02a086010000000000160014307b46c6979c94598ce49d1145bc4d8eeb2704fb9ad41c00000000001600146befc12bab949fc24bf80d4fbf957f5d84d5f7d002483045022100bd323bdeb84893c4e8779a411f40d12a4ee29daf19f294e106c972f12c7a8df602207364621931435107e0b4abadc3182eb9cce20dbb932965b5a8c29196d40fb5d30121022a9c9134668be7db7109d82a55afdcc7d323eeccd8ab48704c9d16305349c08f00000000"},{"txid":"fdbf28c741e55f846a0a378e0cf2a7263540f8d24123b658f2beb0bd1b1788f0","version":1,"vin":[{"txid":"07eb5638d1a2833a7eaea596b0dc8bacd8a51be6f18f8bb8cabd514255acebff","vout":1,"sequence":4294967294,"n":0,"addresses":["ltc1qpm594ntjq6ayqjngf6t9td2dxtey9d7985eept"],"isAddress":true,"value":"96312"},{"txid":"152c3d81f7272c91bd3d880d7b570619ef4141482cbcd62b5556fb00efc2bd94","sequence":4294967293,"n":1,"addresses":["ltc1q5usqkt2x9tnqljy0tss9jqmlvcmakdp4l4rdt5"],"isAddress":true,"value":"400000"},{"txid":"152c3d81f7272c91bd3d880d7b570619ef4141482cbcd62b5556fb00efc2bd94","vout":1,"sequence":4294967292,"n":2,"addresses":["ltc1q69juwlyyyks4ws8rdklldjvdxk3vk6gy9qkn99"],"isAddress":true,"value":"1650696"}],"vout":[{"value":"1989886","n":0,"spent":true,"hex":"001450e07ca8c4f2c7ec53351710013a03251ab5d1d8","addresses":["ltc1q2rs8e2xy7tr7c5e4zugqzwsry5dtt5wcdk4zv9"],"isAddress":true}],"blockHash":"5977afe7c387c7390498309e29ad71e8daef8c59df5b910cb05a3ae661db0919","blockHeight":1783073,"confirmations":61932,"blockTime":1580799867,"value":"1989886","valueIn":"2147008","fees":"157122","hex":"01000000000103ffebac554251bdcab88b8ff1e61ba5d8ac8bdcb096a5ae7e3a83a2d13856eb070100000000feffffff94bdc2ef00fb56552bd6bc2c484141ef1906577b0d883dbd912c27f7813d2c150000000000fdffffff94bdc2ef00fb56552bd6bc2c484141ef1906577b0d883dbd912c27f7813d2c150100000000fcffffff01fe5c1e000000000016001450e07ca8c4f2c7ec53351710013a03251ab5d1d802473044022015d518ae11502d4c832cde4627372c60fb89293d14f3dd39006445dce3bfe47f02207b97301e3f8b9016a515882072dafba705a4ec5e29f5ae222dbdfd5a6d83c90a012102872f9e841a8150ab716574ff897d915f575ed9abe9b4c9426617f6a1d8b3bbd1024730440220478a6c3144e882f736b7b674d43768636f8d74eec28138d9ea36d05f64634aa402203827a08bb554c930e58178536257eb247a790866a7984fdffe549da7376244f201210262da88bf17e0b0575a3c9efecf7387e6d96fa9039547ac6707219defd321986102473044022053999ec5a5b454c60136144096f55a0de2402addd4a250396884bd00f3763dfe022054812eca7798ed4a4418b166c6a4e3e880cbd93ce41c620b611c35ad1c80735e012103c497991dbbf809288e18c5ab4744d59ab6b0b0bf875d2095267ea373e9837d3400000000"},{"txid":"152c3d81f7272c91bd3d880d7b570619ef4141482cbcd62b5556fb00efc2bd94","version":1,"vin":[{"txid":"9cad90704b2c24e2300c496398ba66ba216bc1df01851ba8c14fc0da8814a8ec","vout":1,"n":0,"addresses":["ltc1qpm594ntjq6ayqjngf6t9td2dxtey9d7985eept"],"isAddress":true,"value":"2051148"}],"vout":[{"value":"400000","n":0,"spent":true,"hex":"0014a7200b2d462ae60fc88f5c2059037f6637db3435","addresses":["ltc1q5usqkt2x9tnqljy0tss9jqmlvcmakdp4l4rdt5"],"isAddress":true},{"value":"1650696","n":1,"spent":true,"hex":"0014d165c77c8425a15740e36dbff6c98d35a2cb6904","addresses":["ltc1q69juwlyyyks4ws8rdklldjvdxk3vk6gy9qkn99"],"isAddress":true}],"blockHash":"686ab90a08327f65c4cb5aa4227f3c0c0eb3120e922f6f6a8ba37fd20d6d2a72","blockHeight":1782650,"confirmations":62355,"blockTime":1580744939,"value":"2050696","valueIn":"2051148","fees":"452","hex":"01000000000101eca81488dac04fc1a81b8501dfc16b21ba66ba9863490c30e2242c4b7090ad9c01000000000000000002801a060000000000160014a7200b2d462ae60fc88f5c2059037f6637db34350830190000000000160014d165c77c8425a15740e36dbff6c98d35a2cb690402483045022100e633d87b26da1f508018fdf1c54f9b8bb0813aeb326c17a2622e29dec94f48ce0220123208bd0d13e1c2f16c4d3a450b783ea89211fcb054db2211ed6403335a48f3012102872f9e841a8150ab716574ff897d915f575ed9abe9b4c9426617f6a1d8b3bbd100000000"},{"txid":"d1dddff6518f20a251738d2e8e60a32a24a51f7714f115073724f1c926235c35","version":1,"vin":[{"txid":"ec3dabd2b86f78238fd8c1f113170815d8d8c71828e2b902b24123081cc18400","n":0,"addresses":["ltc1qargw9wk7ptha5gql4k8ltpvawsaj22jmr8cejf"],"isAddress":true,"value":"1000000"}],"vout":[{"value":"10000","n":0,"hex":"001450e07ca8c4f2c7ec53351710013a03251ab5d1d8","addresses":["ltc1q2rs8e2xy7tr7c5e4zugqzwsry5dtt5wcdk4zv9"],"isAddress":true},{"value":"989548","n":1,"spent":true,"hex":"0014a80b968f4309bff939d19a1c07155673087e45f4","addresses":["ltc1q4q9edr6rpxlljww3ngwqw92kwvy8u305z0uc0z"],"isAddress":true}],"blockHash":"3fa995b85d0a5a16ba7ea2201f18fff1093698abf589b509a6d03679fbca174a","blockHeight":1782621,"confirmations":62384,"blockTime":1580740200,"value":"999548","valueIn":"1000000","fees":"452","hex":"010000000001010084c11c082341b202b9e22818c7d8d815081713f1c1d88f23786fb8d2ab3dec00000000000000000002102700000000000016001450e07ca8c4f2c7ec53351710013a03251ab5d1d86c190f0000000000160014a80b968f4309bff939d19a1c07155673087e45f40247304402201551a2b9e94a2a257eed8056fe057f0c09a5199f2f1848793ef45e76a56e45ed022052205cbf0408b962a7b02343fade9ea383923c091ba8def4727f15ddcba8c73b012103ad9ca0f2fff21e45b0ebc715ed2b2d49d64e2c1ae0cd04b6caf5730471e273ca00000000"},{"txid":"c2730eca5ff4e5136371647623a0b55c020ef9003218aefebbe9347bff90c999","version":1,"vin":[{"txid":"d1dddff6518f20a251738d2e8e60a32a24a51f7714f115073724f1c926235c35","vout":1,"n":0,"addresses":["ltc1q4q9edr6rpxlljww3ngwqw92kwvy8u305z0uc0z"],"isAddress":true,"value":"989548"}],"vout":[{"value":"10000","n":0,"hex":"001450e07ca8c4f2c7ec53351710013a03251ab5d1d8","addresses":["ltc1q2rs8e2xy7tr7c5e4zugqzwsry5dtt5wcdk4zv9"],"isAddress":true},{"value":"979096","n":1,"spent":true,"hex":"0014a80b968f4309bff939d19a1c07155673087e45f4","addresses":["ltc1q4q9edr6rpxlljww3ngwqw92kwvy8u305z0uc0z"],"isAddress":true}],"blockHash":"3fa995b85d0a5a16ba7ea2201f18fff1093698abf589b509a6d03679fbca174a","blockHeight":1782621,"confirmations":62384,"blockTime":1580740200,"value":"989096","valueIn":"989548","fees":"452","hex":"01000000000101355c2326c9f124370715f114771fa5242aa3608e2e8d7351a2208f51f6dfddd101000000000000000002102700000000000016001450e07ca8c4f2c7ec53351710013a03251ab5d1d898f00e0000000000160014a80b968f4309bff939d19a1c07155673087e45f402473044022024c8ef5422a06aeb0caafa28cca510e2515896eb63b2e507ac8e466d3687983d022036529a6cff163a2c14610b1f407e8e7a0516921e454eaf0354b95888789d19d001210360847b9e16828bcad89705de8b752ea2a58ce95983ff0c30a64d48f52dfa57df00000000"},{"txid":"9cad90704b2c24e2300c496398ba66ba216bc1df01851ba8c14fc0da8814a8ec","version":1,"vin":[{"txid":"b784d0389a2450e43ea043567329d0f4e00277ac430bbcedf335d9d85451e088","vout":1,"n":0,"addresses":["ltc1q720spapzfq8j79gal5mg2efcrtv92hvktc8u76"],"isAddress":true,"value":"3051600"}],"vout":[{"value":"1000000","n":0,"hex":"0014463fec54ea2c7210057b2d6d1972a8aaaf39a543","addresses":["ltc1qgcl7c48293epqptm94k3ju4g42hnnf2r5d4ewq"],"isAddress":true},{"value":"2051148","n":1,"spent":true,"hex":"00140ee85acd7206ba404a684e9655b54d32f242b7c5","addresses":["ltc1qpm594ntjq6ayqjngf6t9td2dxtey9d7985eept"],"isAddress":true}],"blockHash":"8eccbbf11afd2c3a54f2a5eae52734b37b67df50cbdea00224ad39896e0bf4f7","blockHeight":1781067,"confirmations":63938,"blockTime":1580515445,"value":"3051148","valueIn":"3051600","fees":"452","hex":"0100000000010188e05154d8d935f3edbc0b43ac7702e0f4d029735643a03ee450249a38d084b70100000000000000000240420f0000000000160014463fec54ea2c7210057b2d6d1972a8aaaf39a5434c4c1f00000000001600140ee85acd7206ba404a684e9655b54d32f242b7c5024830450221009f248a6c27f931afca2480a0d9867f77a7ed9d15a1c81aa3f1398c86cd14b02502205b96bc4b1c4dc2b16835acc656203f837c37d389ec65decfe25691e667cc3dfe012103a845425673d8c68211ab69f7de46c81ed2c42e5afbadfe3a6eab971ce5da56fa00000000"},{"txid":"b1208bcfb49b5fbc3366bf07b0000b884d59ecdbebc25b1a55f91330317603db","version":1,"vin":[{"txid":"a54db30dd54adc3e90a1c5e72b6a5b94992591cbc325adfc28cee55ab5f9dbc0","vout":1,"n":0,"addresses":["ltc1qpm594ntjq6ayqjngf6t9td2dxtey9d7985eept"],"isAddress":true,"value":"3252504"}],"vout":[{"value":"100000","n":0,"spent":true,"hex":"0014b329897dc74dc8d7fa2a68a366593bf266dcda5c","addresses":["ltc1qkv5cjlw8fhyd0732dz3kvkfm7fndekjurha9ua"],"isAddress":true},{"value":"3152052","n":1,"spent":true,"hex":"00140ee85acd7206ba404a684e9655b54d32f242b7c5","addresses":["ltc1qpm594ntjq6ayqjngf6t9td2dxtey9d7985eept"],"isAddress":true}],"blockHash":"28f684c412c4394e2da6255567957a493d35a7c7675d8d21a21fab4f3210d772","blockHeight":1778975,"confirmations":66030,"blockTime":1580198750,"value":"3252052","valueIn":"3252504","fees":"452","hex":"01000000000101c0dbf9b55ae5ce28fcad25c3cb912599945b6a2be7c5a1903edc4ad50db34da501000000000000000002a086010000000000160014b329897dc74dc8d7fa2a68a366593bf266dcda5cb4183000000000001600140ee85acd7206ba404a684e9655b54d32f242b7c502473044022007410f524d5597d7ffde5ceff733bcbc05d842194c1ed650ba3ac0bcde4f561902201dde5782c6c47fac0d05fde0df0b7862649b6c3d391d61881733e4e0bb8bc0d8012102872f9e841a8150ab716574ff897d915f575ed9abe9b4c9426617f6a1d8b3bbd100000000"}],"usedTokens":123,"tokens":[{"type":"XPUBAddress","name":"ltc1qpm594ntjq6ayqjngf6t9td2dxtey9d7985eept","path":"m/84'/2'/0'/0/0","transfers":19,"decimals":8,"balance":"1688078","totalReceived":"25679292","totalSent":"23991214"},{"type":"XPUBAddress","name":"ltc1q2rs8e2xy7tr7c5e4zugqzwsry5dtt5wcdk4zv9","path":"m/84'/2'/0'/0/54","transfers":4,"decimals":8,"balance":"20000","totalReceived":"2009886","totalSent":"1989886"},{"type":"XPUBAddress","name":"ltc1q2j0k8v7aczdajd42g96h7gy4jef63feh77494u","path":"m/84'/2'/0'/0/58","transfers":3,"decimals":8,"balance":"10000","totalReceived":"11000","totalSent":"1000"},{"type":"XPUBAddress","name":"ltc1qxpa5d35hnj29nr8yn5g5t0zd3m4jwp8mwchc9c","path":"m/84'/2'/0'/0/59","transfers":1,"decimals":8,"balance":"100000","totalReceived":"100000","totalSent":"0"}]} diff --git a/mock/ext-api-data/nano-api.json b/mock/ext-api-data/nano-api.json new file mode 100644 index 000000000..98330dded --- /dev/null +++ b/mock/ext-api-data/nano-api.json @@ -0,0 +1,69 @@ +{ + "account": "nano_36e7qfxrpixge3xxujtpc87c77mn9ubu3bhywfjkr1trnubtd4qswwydhn9z", + "history": [ + { + "type": "send", + "account": "nano_1trqphog5noig7z888asnjejcie8z1iopxyepcjdo1atps8whxiuwd51ehbw", + "amount": "1083000821328155744662798729216", + "local_timestamp": "1576911471", + "height": "8", + "hash": "05A23A254272028F349BB7E74115A5101B2048786A5437D1EBBE8807CEFF1E82" + }, + { + "type": "receive", + "account": "nano_1trqphog5noig7z888asnjejcie8z1iopxyepcjdo1atps8whxiuwd51ehbw", + "amount": "1047300821328155744662798729216", + "local_timestamp": "1576911468", + "height": "7", + "hash": "13B8146F059C4D5695DCBCEEC750EAEDDDD8F436A6FAD569A107F2FAC0F899D5" + }, + { + "type": "receive", + "account": "nano_1trqphog5noig7z888asnjejcie8z1iopxyepcjdo1atps8whxiuwd51ehbw", + "amount": "34700000000000000000000000000", + "local_timestamp": "1576911454", + "height": "6", + "hash": "8A2A5840C9286B35D998F5AD535851750C1AFE7B0C7D3AA61E06A1628EDD0E94" + }, + { + "type": "receive", + "account": "nano_1trqphog5noig7z888asnjejcie8z1iopxyepcjdo1atps8whxiuwd51ehbw", + "amount": "1000000000000000000000000000", + "local_timestamp": "1575913533", + "height": "5", + "hash": "6816B5AC0594ED768CEC45F5DE25CBF0420300800B6C3C55E6749102F8B09C81" + }, + { + "type": "send", + "account": "nano_1trqphog5noig7z888asnjejcie8z1iopxyepcjdo1atps8whxiuwd51ehbw", + "amount": "1083000821328155744662798729216", + "local_timestamp": "1575498786", + "height": "4", + "hash": "D9F97A2AB82EDFAA7A23FFA3423B286A8DD361B5B9303C5E0262EB684162DFD6" + }, + { + "type": "receive", + "account": "nano_1trqphog5noig7z888asnjejcie8z1iopxyepcjdo1atps8whxiuwd51ehbw", + "amount": "713600821328155744662798729216", + "local_timestamp": "1575498271", + "height": "3", + "hash": "69F4616925EC95DC15D97037BD99E2E782C2D2A557D5CE11E7FBB4BB6FF617F5" + }, + { + "type": "receive", + "account": "nano_1trqphog5noig7z888asnjejcie8z1iopxyepcjdo1atps8whxiuwd51ehbw", + "amount": "234700000000000000000000000000", + "local_timestamp": "1575498125", + "height": "2", + "hash": "6CE398F84A6B3F71E41E843C34917DAC408990C8468EFBC36CFC04954B113A43" + }, + { + "type": "receive", + "account": "nano_1trqphog5noig7z888asnjejcie8z1iopxyepcjdo1atps8whxiuwd51ehbw", + "amount": "134700000000000000000000000000", + "local_timestamp": "1575498066", + "height": "1", + "hash": "586BB82BADA98D6F8E4639DA6884C6562141AB983D885780FA41F31F7A04EC18" + } + ] +} diff --git a/mock/ext-api-data/nano-api.request_json b/mock/ext-api-data/nano-api.request_json new file mode 100644 index 000000000..8021a609a --- /dev/null +++ b/mock/ext-api-data/nano-api.request_json @@ -0,0 +1,5 @@ +{ + "action": "account_history", + "account": "nano_36e7qfxrpixge3xxujtpc87c77mn9ubu3bhywfjkr1trnubtd4qswwydhn9z", + "count": "25" +} \ No newline at end of file diff --git a/mock/ext-api-data/nebulas-api_tx__a_n1RCYwrpLMpSpUCQ8QUDzGRg6B2PnY8R94a_p_0.json b/mock/ext-api-data/nebulas-api_tx__a_n1RCYwrpLMpSpUCQ8QUDzGRg6B2PnY8R94a_p_0.json new file mode 100644 index 000000000..cc9d4295c --- /dev/null +++ b/mock/ext-api-data/nebulas-api_tx__a_n1RCYwrpLMpSpUCQ8QUDzGRg6B2PnY8R94a_p_0.json @@ -0,0 +1,845 @@ +{ + "code": 0, + "msg": "success", + "data": { + "txnList": [ + { + "hash": "3afb557c68311d0a0045f4b7c3b2f1e96a128fdcd08e0d376a58f0c1f7df0959", + "block": { + "hash": "41895b3957647269a1d45fcde5b22a5f4c2b404f62e0b96ec5db44d0537aa293", + "height": 2857937, + "timestamp": null, + "parentHash": null, + "miner": null, + "txnCnt": 0, + "gasLimit": null, + "avgGasPrice": null, + "gasReward": null, + "currentTimestamp": null, + "timeDiff": null + }, + "from": { + "rank": null, + "hash": "n1RCYwrpLMpSpUCQ8QUDzGRg6B2PnY8R94a", + "alias": "", + "balance": "3784780000000000", + "percentage": null, + "txCnt": null, + "type": 0 + }, + "to": { + "rank": null, + "hash": "n1hiWG7Ce8HhTaJGzSJoAaJ9w1CJd7Do2rm", + "alias": "", + "balance": "200", + "percentage": null, + "txCnt": null, + "type": 1 + }, + "status": 1, + "value": "0", + "nonce": 15, + "timestamp": 1565358420000, + "type": "call", + "gasPrice": "20000000000", + "gasLimit": "50000", + "gasUsed": "20719", + "createdAt": 1565358648000, + "data": "{\"Function\":\"transfer\",\"Args\":\"[\\\"n1R6kbYGyb4vaX9ZKpjrFMd2Ry4CWhCV4B8\\\",\\\"266794000000\\\"]\"}", + "currentTimestamp": 1589366674461, + "timeDiff": 24008254461, + "contractAddress": "", + "executeError": "", + "events": null, + "tokenName": null, + "decimal": null, + "txFee": "414380000000000" + }, + { + "hash": "2ffedf0d8d1f85717edbcec32c6b4da43687a783f535b65f772775015aa0ec24", + "block": { + "hash": "84e0ba4e7a4e7c6a4a3cd6b4c4a2ddb576eba3415bd0cdeb002539450ee95d9c", + "height": 2851699, + "timestamp": null, + "parentHash": null, + "miner": null, + "txnCnt": 0, + "gasLimit": null, + "avgGasPrice": null, + "gasReward": null, + "currentTimestamp": null, + "timeDiff": null + }, + "from": { + "rank": null, + "hash": "n1RCYwrpLMpSpUCQ8QUDzGRg6B2PnY8R94a", + "alias": "", + "balance": "3784780000000000", + "percentage": null, + "txCnt": null, + "type": 0 + }, + "to": { + "rank": null, + "hash": "n1hiWG7Ce8HhTaJGzSJoAaJ9w1CJd7Do2rm", + "alias": "", + "balance": "200", + "percentage": null, + "txCnt": null, + "type": 1 + }, + "status": 1, + "value": "0", + "nonce": 14, + "timestamp": 1565264850000, + "type": "call", + "gasPrice": "20000000000", + "gasLimit": "50000", + "gasUsed": "20719", + "createdAt": 1565265078000, + "data": "{\"Function\":\"transfer\",\"Args\":\"[\\\"n1R6kbYGyb4vaX9ZKpjrFMd2Ry4CWhCV4B8\\\",\\\"366146000000\\\"]\"}", + "currentTimestamp": 1589366674461, + "timeDiff": 24101824461, + "contractAddress": "", + "executeError": "", + "events": null, + "tokenName": null, + "decimal": null, + "txFee": "414380000000000" + }, + { + "hash": "e80b921f5f275f0132608b9ea7e3c1b0e8509793f4c72ec9ea989687a715fb57", + "block": { + "hash": "e28ff13cbe3bd39dc3414f5b7c5ce0620955d27a582008a11382dc2c0d910103", + "height": 2769477, + "timestamp": null, + "parentHash": null, + "miner": null, + "txnCnt": 0, + "gasLimit": null, + "avgGasPrice": null, + "gasReward": null, + "currentTimestamp": null, + "timeDiff": null + }, + "from": { + "rank": null, + "hash": "n1RCYwrpLMpSpUCQ8QUDzGRg6B2PnY8R94a", + "alias": "", + "balance": "3784780000000000", + "percentage": null, + "txCnt": null, + "type": 0 + }, + "to": { + "rank": null, + "hash": "n1hiWG7Ce8HhTaJGzSJoAaJ9w1CJd7Do2rm", + "alias": "", + "balance": "200", + "percentage": null, + "txCnt": null, + "type": 1 + }, + "status": 1, + "value": "0", + "nonce": 13, + "timestamp": 1564027140000, + "type": "call", + "gasPrice": "20000000000", + "gasLimit": "50000", + "gasUsed": "20717", + "createdAt": 1564027360000, + "data": "{\"Function\":\"transfer\",\"Args\":\"[\\\"n1R6kbYGyb4vaX9ZKpjrFMd2Ry4CWhCV4B8\\\",\\\"66500000000\\\"]\"}", + "currentTimestamp": 1589366674461, + "timeDiff": 25339534461, + "contractAddress": "", + "executeError": "", + "events": null, + "tokenName": null, + "decimal": null, + "txFee": "414340000000000" + }, + { + "hash": "821e8833cfb757e434f7a16b95189289c8dc6c69ef068827e78b0f69e7bb5514", + "block": { + "hash": "c9b02c838c3bcd3d891233ec933840b625122a8ae6ff76961de1d75120a0374f", + "height": 2765282, + "timestamp": null, + "parentHash": null, + "miner": null, + "txnCnt": 0, + "gasLimit": null, + "avgGasPrice": null, + "gasReward": null, + "currentTimestamp": null, + "timeDiff": null + }, + "from": { + "rank": null, + "hash": "n1RCYwrpLMpSpUCQ8QUDzGRg6B2PnY8R94a", + "alias": "", + "balance": "3784780000000000", + "percentage": null, + "txCnt": null, + "type": 0 + }, + "to": { + "rank": null, + "hash": "n1hiWG7Ce8HhTaJGzSJoAaJ9w1CJd7Do2rm", + "alias": "", + "balance": "200", + "percentage": null, + "txCnt": null, + "type": 1 + }, + "status": 1, + "value": "0", + "nonce": 12, + "timestamp": 1563964215000, + "type": "call", + "gasPrice": "20000000000", + "gasLimit": "50000", + "gasUsed": "20717", + "createdAt": 1563964436000, + "data": "{\"Function\":\"transfer\",\"Args\":\"[\\\"n1R6kbYGyb4vaX9ZKpjrFMd2Ry4CWhCV4B8\\\",\\\"99100000000\\\"]\"}", + "currentTimestamp": 1589366674461, + "timeDiff": 25402459461, + "contractAddress": "", + "executeError": "", + "events": null, + "tokenName": null, + "decimal": null, + "txFee": "414340000000000" + }, + { + "hash": "e0c8342c894089927c2bbe8119605a472ad096184070da1c1591535975d067be", + "block": { + "hash": "5f0d55388f440868187b9f7942f0f8d9a76b91f16cc01bebcac66a59ec4ca500", + "height": 2735174, + "timestamp": null, + "parentHash": null, + "miner": null, + "txnCnt": 0, + "gasLimit": null, + "avgGasPrice": null, + "gasReward": null, + "currentTimestamp": null, + "timeDiff": null + }, + "from": { + "rank": null, + "hash": "n1RCYwrpLMpSpUCQ8QUDzGRg6B2PnY8R94a", + "alias": "", + "balance": "3784780000000000", + "percentage": null, + "txCnt": null, + "type": 0 + }, + "to": { + "rank": null, + "hash": "n1hiWG7Ce8HhTaJGzSJoAaJ9w1CJd7Do2rm", + "alias": "", + "balance": "200", + "percentage": null, + "txCnt": null, + "type": 1 + }, + "status": 1, + "value": "0", + "nonce": 11, + "timestamp": 1563511485000, + "type": "call", + "gasPrice": "20000000000", + "gasLimit": "50000", + "gasUsed": "20717", + "createdAt": 1563511705000, + "data": "{\"Function\":\"transfer\",\"Args\":\"[\\\"n1R6kbYGyb4vaX9ZKpjrFMd2Ry4CWhCV4B8\\\",\\\"45000000000\\\"]\"}", + "currentTimestamp": 1589366674461, + "timeDiff": 25855189461, + "contractAddress": "", + "executeError": "", + "events": null, + "tokenName": null, + "decimal": null, + "txFee": "414340000000000" + }, + { + "hash": "3517fba15592a0f69deb921e9e6510d002cb2cc639943042fc063c854c03cd94", + "block": { + "hash": "7262c28414cb2728f093030b59fc1dbe9570b861dc3e1c8874b7963c8bec7376", + "height": 2717106, + "timestamp": null, + "parentHash": null, + "miner": null, + "txnCnt": 0, + "gasLimit": null, + "avgGasPrice": null, + "gasReward": null, + "currentTimestamp": null, + "timeDiff": null + }, + "from": { + "rank": null, + "hash": "n1RCYwrpLMpSpUCQ8QUDzGRg6B2PnY8R94a", + "alias": "", + "balance": "3784780000000000", + "percentage": null, + "txCnt": null, + "type": 0 + }, + "to": { + "rank": null, + "hash": "n1hiWG7Ce8HhTaJGzSJoAaJ9w1CJd7Do2rm", + "alias": "", + "balance": "200", + "percentage": null, + "txCnt": null, + "type": 1 + }, + "status": 1, + "value": "0", + "nonce": 10, + "timestamp": 1563240465000, + "type": "call", + "gasPrice": "20000000000", + "gasLimit": "50000", + "gasUsed": "20717", + "createdAt": 1563240685000, + "data": "{\"Function\":\"transfer\",\"Args\":\"[\\\"n1R6kbYGyb4vaX9ZKpjrFMd2Ry4CWhCV4B8\\\",\\\"44300000000\\\"]\"}", + "currentTimestamp": 1589366674461, + "timeDiff": 26126209461, + "contractAddress": "", + "executeError": "", + "events": null, + "tokenName": null, + "decimal": null, + "txFee": "414340000000000" + }, + { + "hash": "477900d583540585ec39856d761fe200dee818d68312f0c79f9a67ab37f49712", + "block": { + "hash": "5bd043964e0a1e96cd3c92e3e21570e019671239cc187d72107841f720512e3a", + "height": 2705263, + "timestamp": null, + "parentHash": null, + "miner": null, + "txnCnt": 0, + "gasLimit": null, + "avgGasPrice": null, + "gasReward": null, + "currentTimestamp": null, + "timeDiff": null + }, + "from": { + "rank": null, + "hash": "n1RCYwrpLMpSpUCQ8QUDzGRg6B2PnY8R94a", + "alias": "", + "balance": "3784780000000000", + "percentage": null, + "txCnt": null, + "type": 0 + }, + "to": { + "rank": null, + "hash": "n1hiWG7Ce8HhTaJGzSJoAaJ9w1CJd7Do2rm", + "alias": "", + "balance": "200", + "percentage": null, + "txCnt": null, + "type": 1 + }, + "status": 1, + "value": "0", + "nonce": 9, + "timestamp": 1563062820000, + "type": "call", + "gasPrice": "20000000000", + "gasLimit": "50000", + "gasUsed": "20717", + "createdAt": 1563063040000, + "data": "{\"Function\":\"transfer\",\"Args\":\"[\\\"n1R6kbYGyb4vaX9ZKpjrFMd2Ry4CWhCV4B8\\\",\\\"66600000000\\\"]\"}", + "currentTimestamp": 1589366674461, + "timeDiff": 26303854461, + "contractAddress": "", + "executeError": "", + "events": null, + "tokenName": null, + "decimal": null, + "txFee": "414340000000000" + }, + { + "hash": "69e18ceda9310b922cadc2b7d9979d516045d342be20f2301850ebe9160bc336", + "block": { + "hash": "3d8c155854dc9a739d274ef4ff3a60f53da2225e6ac2e672f827d2212f2e608b", + "height": 2694665, + "timestamp": null, + "parentHash": null, + "miner": null, + "txnCnt": 0, + "gasLimit": null, + "avgGasPrice": null, + "gasReward": null, + "currentTimestamp": null, + "timeDiff": null + }, + "from": { + "rank": null, + "hash": "n1RCYwrpLMpSpUCQ8QUDzGRg6B2PnY8R94a", + "alias": "", + "balance": "3784780000000000", + "percentage": null, + "txCnt": null, + "type": 0 + }, + "to": { + "rank": null, + "hash": "n1hiWG7Ce8HhTaJGzSJoAaJ9w1CJd7Do2rm", + "alias": "", + "balance": "200", + "percentage": null, + "txCnt": null, + "type": 1 + }, + "status": 1, + "value": "0", + "nonce": 8, + "timestamp": 1562903850000, + "type": "call", + "gasPrice": "20000000000", + "gasLimit": "50000", + "gasUsed": "20717", + "createdAt": 1562904235000, + "data": "{\"Function\":\"transfer\",\"Args\":\"[\\\"n1R6kbYGyb4vaX9ZKpjrFMd2Ry4CWhCV4B8\\\",\\\"62600000000\\\"]\"}", + "currentTimestamp": 1589366674461, + "timeDiff": 26462824461, + "contractAddress": "", + "executeError": "", + "events": null, + "tokenName": null, + "decimal": null, + "txFee": "414340000000000" + }, + { + "hash": "5b8de6ea8ad09c42d3032047f4e2f43f4436576162b2ff27f9d9c87a6662e388", + "block": { + "hash": "034d985a2843214841caef93838291682687dcea5628b0499ed81bb01155627d", + "height": 2691184, + "timestamp": null, + "parentHash": null, + "miner": null, + "txnCnt": 0, + "gasLimit": null, + "avgGasPrice": null, + "gasReward": null, + "currentTimestamp": null, + "timeDiff": null + }, + "from": { + "rank": null, + "hash": "n1RCYwrpLMpSpUCQ8QUDzGRg6B2PnY8R94a", + "alias": "", + "balance": "3784780000000000", + "percentage": null, + "txCnt": null, + "type": 0 + }, + "to": { + "rank": null, + "hash": "n1hiWG7Ce8HhTaJGzSJoAaJ9w1CJd7Do2rm", + "alias": "", + "balance": "200", + "percentage": null, + "txCnt": null, + "type": 1 + }, + "status": 1, + "value": "0", + "nonce": 7, + "timestamp": 1562851635000, + "type": "call", + "gasPrice": "20000000000", + "gasLimit": "50000", + "gasUsed": "20719", + "createdAt": 1562851854000, + "data": "{\"Function\":\"transfer\",\"Args\":\"[\\\"n1R6kbYGyb4vaX9ZKpjrFMd2Ry4CWhCV4B8\\\",\\\"360000000000\\\"]\"}", + "currentTimestamp": 1589366674461, + "timeDiff": 26515039461, + "contractAddress": "", + "executeError": "", + "events": null, + "tokenName": null, + "decimal": null, + "txFee": "414380000000000" + }, + { + "hash": "ec7babae2ecc45474dbed9a0bb68b570b0e58321fb7ccf36d15f6f6f8aa0b86b", + "block": { + "hash": "f2f917d6337d03fcfb4f9f810e7168dac5b36dd62446f4c767a9ec13521e2767", + "height": 2691056, + "timestamp": null, + "parentHash": null, + "miner": null, + "txnCnt": 0, + "gasLimit": null, + "avgGasPrice": null, + "gasReward": null, + "currentTimestamp": null, + "timeDiff": null + }, + "from": { + "rank": null, + "hash": "n1RCYwrpLMpSpUCQ8QUDzGRg6B2PnY8R94a", + "alias": "", + "balance": "3784780000000000", + "percentage": null, + "txCnt": null, + "type": 0 + }, + "to": { + "rank": null, + "hash": "n1hiWG7Ce8HhTaJGzSJoAaJ9w1CJd7Do2rm", + "alias": "", + "balance": "200", + "percentage": null, + "txCnt": null, + "type": 1 + }, + "status": 1, + "value": "0", + "nonce": 6, + "timestamp": 1562849715000, + "type": "call", + "gasPrice": "20000000000", + "gasLimit": "50000", + "gasUsed": "20719", + "createdAt": 1562849934000, + "data": "{\"Function\":\"transfer\",\"Args\":\"[\\\"n1R6kbYGyb4vaX9ZKpjrFMd2Ry4CWhCV4B8\\\",\\\"186600000000\\\"]\"}", + "currentTimestamp": 1589366674461, + "timeDiff": 26516959461, + "contractAddress": "", + "executeError": "", + "events": null, + "tokenName": null, + "decimal": null, + "txFee": "414380000000000" + }, + { + "hash": "3e43a6e29a40e3eaed69bf20f256dba1e70c21beae56261259e79241aa43a5bd", + "block": { + "hash": "d3797ac98dd02768103c8340b7c00d8799f0f424648218656bd086897b602097", + "height": 2683417, + "timestamp": null, + "parentHash": null, + "miner": null, + "txnCnt": 0, + "gasLimit": null, + "avgGasPrice": null, + "gasReward": null, + "currentTimestamp": null, + "timeDiff": null + }, + "from": { + "rank": null, + "hash": "n1RCYwrpLMpSpUCQ8QUDzGRg6B2PnY8R94a", + "alias": "", + "balance": "3784780000000000", + "percentage": null, + "txCnt": null, + "type": 0 + }, + "to": { + "rank": null, + "hash": "n1hiWG7Ce8HhTaJGzSJoAaJ9w1CJd7Do2rm", + "alias": "", + "balance": "200", + "percentage": null, + "txCnt": null, + "type": 1 + }, + "status": 1, + "value": "0", + "nonce": 5, + "timestamp": 1562735130000, + "type": "call", + "gasPrice": "20000000000", + "gasLimit": "50000", + "gasUsed": "20719", + "createdAt": 1562735349000, + "data": "{\"Function\":\"transfer\",\"Args\":\"[\\\"n1R6kbYGyb4vaX9ZKpjrFMd2Ry4CWhCV4B8\\\",\\\"360000000000\\\"]\"}", + "currentTimestamp": 1589366674461, + "timeDiff": 26631544461, + "contractAddress": "", + "executeError": "", + "events": null, + "tokenName": null, + "decimal": null, + "txFee": "414380000000000" + }, + { + "hash": "2a93c599c49af9664ff949cca00cbaf210e0702e9e7ba1fc708fc8f786822146", + "block": { + "hash": "e095e6ba7e621c9a6411e56e097bc952eb58ce7aa1807189f502e7690b5e7c93", + "height": 2667467, + "timestamp": null, + "parentHash": null, + "miner": null, + "txnCnt": 0, + "gasLimit": null, + "avgGasPrice": null, + "gasReward": null, + "currentTimestamp": null, + "timeDiff": null + }, + "from": { + "rank": null, + "hash": "n1RCYwrpLMpSpUCQ8QUDzGRg6B2PnY8R94a", + "alias": "", + "balance": "3784780000000000", + "percentage": null, + "txCnt": null, + "type": 0 + }, + "to": { + "rank": null, + "hash": "n1hiWG7Ce8HhTaJGzSJoAaJ9w1CJd7Do2rm", + "alias": "", + "balance": "200", + "percentage": null, + "txCnt": null, + "type": 1 + }, + "status": 1, + "value": "0", + "nonce": 4, + "timestamp": 1562491605000, + "type": "call", + "gasPrice": "20000000000", + "gasLimit": "50000", + "gasUsed": "20719", + "createdAt": 1562491834000, + "data": "{\"Function\":\"transfer\",\"Args\":\"[\\\"n1R6kbYGyb4vaX9ZKpjrFMd2Ry4CWhCV4B8\\\",\\\"222200000000\\\"]\"}", + "currentTimestamp": 1589366674461, + "timeDiff": 26875069461, + "contractAddress": "", + "executeError": "", + "events": null, + "tokenName": null, + "decimal": null, + "txFee": "414380000000000" + }, + { + "hash": "60258c4568dd7abdca5c88c643af13658115958a707c22e0c3be0a81ccdbc415", + "block": { + "hash": "0943ddcc1c262579ef2a1490438c091e860ca0e84641e39bacb31ef9843a409b", + "height": 2666815, + "timestamp": null, + "parentHash": null, + "miner": null, + "txnCnt": 0, + "gasLimit": null, + "avgGasPrice": null, + "gasReward": null, + "currentTimestamp": null, + "timeDiff": null + }, + "from": { + "rank": null, + "hash": "n1RCYwrpLMpSpUCQ8QUDzGRg6B2PnY8R94a", + "alias": "", + "balance": "3784780000000000", + "percentage": null, + "txCnt": null, + "type": 0 + }, + "to": { + "rank": null, + "hash": "n1hiWG7Ce8HhTaJGzSJoAaJ9w1CJd7Do2rm", + "alias": "", + "balance": "200", + "percentage": null, + "txCnt": null, + "type": 1 + }, + "status": 1, + "value": "0", + "nonce": 3, + "timestamp": 1562481825000, + "type": "call", + "gasPrice": "20000000000", + "gasLimit": "50000", + "gasUsed": "20717", + "createdAt": 1562482139000, + "data": "{\"Function\":\"transfer\",\"Args\":\"[\\\"n1R6kbYGyb4vaX9ZKpjrFMd2Ry4CWhCV4B8\\\",\\\"55500000000\\\"]\"}", + "currentTimestamp": 1589366674461, + "timeDiff": 26884849461, + "contractAddress": "", + "executeError": "", + "events": null, + "tokenName": null, + "decimal": null, + "txFee": "414340000000000" + }, + { + "hash": "30a4b0d3e04a43dd5fab02e6f48033acf6481be8fc04e0dcbff577b1f3e32477", + "block": { + "hash": "9aca38686b913c7d30c07df83fee4a6e4de69c5ffbe71c3a47f9da89613db9a7", + "height": 2662772, + "timestamp": null, + "parentHash": null, + "miner": null, + "txnCnt": 0, + "gasLimit": null, + "avgGasPrice": null, + "gasReward": null, + "currentTimestamp": null, + "timeDiff": null + }, + "from": { + "rank": null, + "hash": "n1RCYwrpLMpSpUCQ8QUDzGRg6B2PnY8R94a", + "alias": "", + "balance": "3784780000000000", + "percentage": null, + "txCnt": null, + "type": 0 + }, + "to": { + "rank": null, + "hash": "n1hiWG7Ce8HhTaJGzSJoAaJ9w1CJd7Do2rm", + "alias": "", + "balance": "200", + "percentage": null, + "txCnt": null, + "type": 1 + }, + "status": 1, + "value": "0", + "nonce": 2, + "timestamp": 1562421180000, + "type": "call", + "gasPrice": "20000000000", + "gasLimit": "50000", + "gasUsed": "20717", + "createdAt": 1562421408000, + "data": "{\"Function\":\"transfer\",\"Args\":\"[\\\"n1R6kbYGyb4vaX9ZKpjrFMd2Ry4CWhCV4B8\\\",\\\"41200000000\\\"]\"}", + "currentTimestamp": 1589366674461, + "timeDiff": 26945494461, + "contractAddress": "", + "executeError": "", + "events": null, + "tokenName": null, + "decimal": null, + "txFee": "414340000000000" + }, + { + "hash": "3cd98a767d8f5eaa87c8ffa95adbde3a4c08236b49ab0296f04057491e4bd1a3", + "block": { + "hash": "9bb20444ae79a542af44ed64241a440759aa59363641fa1b7594266f6f16109d", + "height": 2659950, + "timestamp": null, + "parentHash": null, + "miner": null, + "txnCnt": 0, + "gasLimit": null, + "avgGasPrice": null, + "gasReward": null, + "currentTimestamp": null, + "timeDiff": null + }, + "from": { + "rank": null, + "hash": "n1RCYwrpLMpSpUCQ8QUDzGRg6B2PnY8R94a", + "alias": "", + "balance": "3784780000000000", + "percentage": null, + "txCnt": null, + "type": 0 + }, + "to": { + "rank": null, + "hash": "n1hiWG7Ce8HhTaJGzSJoAaJ9w1CJd7Do2rm", + "alias": "", + "balance": "200", + "percentage": null, + "txCnt": null, + "type": 1 + }, + "status": 1, + "value": "0", + "nonce": 1, + "timestamp": 1562378850000, + "type": "call", + "gasPrice": "20000000000", + "gasLimit": "50000", + "gasUsed": "20711", + "createdAt": 1562379080000, + "data": "{\"Function\":\"transfer\",\"Args\":\"[\\\"n1R6kbYGyb4vaX9ZKpjrFMd2Ry4CWhCV4B8\\\",\\\"116600000000\\\"]\"}", + "currentTimestamp": 1589366674461, + "timeDiff": 26987824461, + "contractAddress": "", + "executeError": "", + "events": null, + "tokenName": null, + "decimal": null, + "txFee": "414220000000000" + }, + { + "hash": "0d06074b64c37ed24a17162d1e0ef8a8e65122fc7758c90c969e61735bc4396a", + "block": { + "hash": "faf4eb93b1a571c709bf1871e1c142570d3f5aeb787d325eba9a34a6ca56144b", + "height": 2659949, + "timestamp": null, + "parentHash": null, + "miner": null, + "txnCnt": 0, + "gasLimit": null, + "avgGasPrice": null, + "gasReward": null, + "currentTimestamp": null, + "timeDiff": null + }, + "from": { + "rank": null, + "hash": "n1YDRkSbuzjRVYPbmGC9qULchXMeqS451Je", + "alias": "", + "balance": "37962400000000000000", + "percentage": null, + "txCnt": null, + "type": 0 + }, + "to": { + "rank": null, + "hash": "n1RCYwrpLMpSpUCQ8QUDzGRg6B2PnY8R94a", + "alias": "", + "balance": "3784780000000000", + "percentage": null, + "txCnt": null, + "type": 0 + }, + "status": 1, + "value": "10000000000000000", + "nonce": 210, + "timestamp": 1562378835000, + "type": "binary", + "gasPrice": "20000000000", + "gasLimit": "50000", + "gasUsed": "20000", + "createdAt": 1562379063000, + "data": "", + "currentTimestamp": 1589366674461, + "timeDiff": 26987839461, + "contractAddress": "", + "executeError": "", + "events": null, + "tokenName": null, + "decimal": null, + "txFee": "400000000000000" + } + ], + "totalPage": 1, + "maxDisplayCnt": 16, + "type": "address", + "currentPage": 0, + "txnCnt": 16 + } +} \ No newline at end of file diff --git a/mock/ext-api-data/nimiq-rpc.json b/mock/ext-api-data/nimiq-rpc.json new file mode 100644 index 000000000..613ddfd30 --- /dev/null +++ b/mock/ext-api-data/nimiq-rpc.json @@ -0,0 +1,51 @@ +{ + "jsonrpc": "2.0", + "result": [ + { + "hash": "e22d6f251c507a9083a1f654ad002e5cbf31f61e4e3ac5e38ed69b291c78aaec", + "blockHash": "544db1d7d4216c97a9c3658c71f1a3e00783b28316ddee2c2fc26a4cfb6ccdb0", + "blockNumber": 1082279, + "timestamp": 1588928787, + "confirmations": 8628, + "from": "def95e3bb528fef142b1d78fa656cd7f76339345", + "fromAddress": "NQ25 TTUM UEVM 53YF 2GMH SX7S CMND FVT3 74S5", + "to": "8b12a9a5a81bf52a9afb47a16b57d4c81c51fc07", + "toAddress": "NQ94 HC9A K9D8 3FSJ M6PT 8XGN NMXL R0E5 3Y07", + "value": 10000, + "fee": 0, + "data": "74657374", + "flags": 0 + }, + { + "hash": "8674d985ac1ea2a75fe9b35ed11d629cef8adfed50db6a5eb125351e622bb405", + "blockHash": "11b0a3aaf64119cfbc66b7fdb8c38d5734a7f50d5bbb0116ee579eb1de513c3f", + "blockNumber": 543545, + "timestamp": 1556458272, + "confirmations": 547362, + "from": "21c7fc976349d39188b3d239b3b86ab66daeafc2", + "fromAddress": "NQ32 473Y R5T3 979R 325K S8UT 7E3A NRNS VBX2", + "to": "8b12a9a5a81bf52a9afb47a16b57d4c81c51fc07", + "toAddress": "NQ94 HC9A K9D8 3FSJ M6PT 8XGN NMXL R0E5 3Y07", + "value": 42839, + "fee": 138, + "data": null, + "flags": 0 + }, + { + "hash": "c3c6e87cba620095a2aeb9898f07077d184e20a68f53798032857cc842dfb0c0", + "blockHash": "9b51f58b8ca881e2b182e1f544d09e4f1fe265b0f478fd41bf0128099013abd8", + "blockNumber": 354736, + "timestamp": 1545080725, + "confirmations": 736171, + "from": "e9a799c4fce6198cfb2eaacdeda5231078227d62", + "fromAddress": "NQ61 V6KR KH7U UQCQ RXRE MB6X T993 21U2 4YB2", + "to": "8b12a9a5a81bf52a9afb47a16b57d4c81c51fc07", + "toAddress": "NQ94 HC9A K9D8 3FSJ M6PT 8XGN NMXL R0E5 3Y07", + "value": 99808, + "fee": 192, + "data": "3c7363726970743e64656275676765723b3c2f7363726970743e", + "flags": 0 + } + ], + "id": 345 +} diff --git a/mock/ext-api-data/nimiq-rpc.request_json b/mock/ext-api-data/nimiq-rpc.request_json new file mode 100644 index 000000000..f347dd267 --- /dev/null +++ b/mock/ext-api-data/nimiq-rpc.request_json @@ -0,0 +1,9 @@ +{ + "jsonrpc": "2.0", + "method": "getTransactionsByAddress", + "params": [ + "NQ94HC9AK9D83FSJM6PT8XGNNMXLR0E53Y07", + "25" + ], + "id": 345 +} diff --git a/mock/ext-api-data/ontology-api_v2_addresses_AUyL4TZ1zFEcSKDJrjFnD7vsq5iFZMZqT7_transactions__page_number_1_page_size_20.json b/mock/ext-api-data/ontology-api_v2_addresses_AUyL4TZ1zFEcSKDJrjFnD7vsq5iFZMZqT7_transactions__page_number_1_page_size_20.json new file mode 100644 index 000000000..cb68c12eb --- /dev/null +++ b/mock/ext-api-data/ontology-api_v2_addresses_AUyL4TZ1zFEcSKDJrjFnD7vsq5iFZMZqT7_transactions__page_number_1_page_size_20.json @@ -0,0 +1,478 @@ +{ + "code": 0, + "msg": "SUCCESS", + "result": [ + { + "tx_hash": "d3be042ae21a313bc70fbfea62d11fb32731126101859a66f523e081c3fd429c", + "tx_type": 209, + "tx_time": 1582189609, + "block_height": 7836941, + "fee": "0.01", + "block_index": 1, + "confirm_flag": 1, + "transfers": [ + { + "amount": "0.4", + "from_address": "AUyL4TZ1zFEcSKDJrjFnD7vsq5iFZMZqT7", + "to_address": "Abm1FqnU4qur9bviXmrD5YnNixXGvMsi9R", + "asset_name": "ong", + "contract_hash": "0200000000000000000000000000000000000000" + }, + { + "amount": "0.01", + "from_address": "AUyL4TZ1zFEcSKDJrjFnD7vsq5iFZMZqT7", + "to_address": "AFmseVrdL9f9oyCzZefL9tG6UbviEH9ugK", + "asset_name": "ong", + "contract_hash": "0200000000000000000000000000000000000000" + } + ] + }, + { + "tx_hash": "5c9a5f708953ee6cd13623e9d3fd610530159fafe71a8d207d890ed7b97f3ced", + "tx_type": 209, + "tx_time": 1582188446, + "block_height": 7836832, + "fee": "0.01", + "block_index": 1, + "confirm_flag": 1, + "transfers": [ + { + "amount": "0.02", + "from_address": "AUyL4TZ1zFEcSKDJrjFnD7vsq5iFZMZqT7", + "to_address": "AUyL4TZ1zFEcSKDJrjFnD7vsq5iFZMZqT7", + "asset_name": "ong", + "contract_hash": "0200000000000000000000000000000000000000" + }, + { + "amount": "0.01", + "from_address": "AUyL4TZ1zFEcSKDJrjFnD7vsq5iFZMZqT7", + "to_address": "AFmseVrdL9f9oyCzZefL9tG6UbviEH9ugK", + "asset_name": "ong", + "contract_hash": "0200000000000000000000000000000000000000" + } + ] + }, + { + "tx_hash": "7e35568117aaed4e041d281087b2f47da91a4ac183c370d40040aa2b496d5878", + "tx_type": 209, + "tx_time": 1582122942, + "block_height": 7832679, + "fee": "0.01", + "block_index": 1, + "confirm_flag": 1, + "transfers": [ + { + "amount": "0.011074432", + "from_address": "AFmseVrdL9f9oyCzZefL9tG6UbvhUMqNMV", + "to_address": "AUyL4TZ1zFEcSKDJrjFnD7vsq5iFZMZqT7", + "asset_name": "ong", + "contract_hash": "0200000000000000000000000000000000000000" + }, + { + "amount": "0.01", + "from_address": "AUyL4TZ1zFEcSKDJrjFnD7vsq5iFZMZqT7", + "to_address": "AFmseVrdL9f9oyCzZefL9tG6UbviEH9ugK", + "asset_name": "ong", + "contract_hash": "0200000000000000000000000000000000000000" + } + ] + }, + { + "tx_hash": "0ae15301f25a5067c075a25e722f0624a813a1352363197de2dd5f61ebd2998d", + "tx_type": 209, + "tx_time": 1581924056, + "block_height": 7819845, + "fee": "0.01", + "block_index": 1, + "confirm_flag": 1, + "transfers": [ + { + "amount": "1", + "from_address": "AUyL4TZ1zFEcSKDJrjFnD7vsq5iFZMZqT7", + "to_address": "AUyL4TZ1zFEcSKDJrjFnD7vsq5iFZMZqT7", + "asset_name": "ont", + "contract_hash": "0100000000000000000000000000000000000000" + }, + { + "amount": "0.01", + "from_address": "AUyL4TZ1zFEcSKDJrjFnD7vsq5iFZMZqT7", + "to_address": "AFmseVrdL9f9oyCzZefL9tG6UbviEH9ugK", + "asset_name": "ong", + "contract_hash": "0200000000000000000000000000000000000000" + } + ] + }, + { + "tx_hash": "7703b0bdbd5dfc2aef18fca5e97e5111c6396afb2d47fd49d8e6e9b1883d9eae", + "tx_type": 209, + "tx_time": 1581923995, + "block_height": 7819841, + "fee": "0.01", + "block_index": 1, + "confirm_flag": 1, + "transfers": [ + { + "amount": "1", + "from_address": "AUyL4TZ1zFEcSKDJrjFnD7vsq5iFZMZqT7", + "to_address": "AUyL4TZ1zFEcSKDJrjFnD7vsq5iFZMZqT7", + "asset_name": "ont", + "contract_hash": "0100000000000000000000000000000000000000" + }, + { + "amount": "0.01", + "from_address": "AUyL4TZ1zFEcSKDJrjFnD7vsq5iFZMZqT7", + "to_address": "AFmseVrdL9f9oyCzZefL9tG6UbviEH9ugK", + "asset_name": "ong", + "contract_hash": "0200000000000000000000000000000000000000" + } + ] + }, + { + "tx_hash": "f06739a6cc0234594e2596c1157421340a5402d745c9bfee3d670b9412a5968d", + "tx_type": 209, + "tx_time": 1581923960, + "block_height": 7819838, + "fee": "0.01", + "block_index": 1, + "confirm_flag": 1, + "transfers": [ + { + "amount": "1", + "from_address": "AUyL4TZ1zFEcSKDJrjFnD7vsq5iFZMZqT7", + "to_address": "AUyL4TZ1zFEcSKDJrjFnD7vsq5iFZMZqT7", + "asset_name": "ont", + "contract_hash": "0100000000000000000000000000000000000000" + }, + { + "amount": "0.01", + "from_address": "AUyL4TZ1zFEcSKDJrjFnD7vsq5iFZMZqT7", + "to_address": "AFmseVrdL9f9oyCzZefL9tG6UbviEH9ugK", + "asset_name": "ong", + "contract_hash": "0200000000000000000000000000000000000000" + } + ] + }, + { + "tx_hash": "24a8ed27b5e9cbd05d3a7a7d0c9b4f6c7202506850fec9ceee61e3208bbad0bc", + "tx_type": 209, + "tx_time": 1581672488, + "block_height": 7802292, + "fee": "0.01", + "block_index": 1, + "confirm_flag": 1, + "transfers": [ + { + "amount": "3", + "from_address": "Abm1FqnU4qur9bviXmrD5YnNixXGvMsi9R", + "to_address": "AUyL4TZ1zFEcSKDJrjFnD7vsq5iFZMZqT7", + "asset_name": "ont", + "contract_hash": "0100000000000000000000000000000000000000" + } + ] + }, + { + "tx_hash": "b9fb8e42805e3d3f12bfc7dd3006cfbc87b566ce30a6e79306703ed54cfb0f9b", + "tx_type": 209, + "tx_time": 1581672381, + "block_height": 7802280, + "fee": "0.01", + "block_index": 1, + "confirm_flag": 1, + "transfers": [ + { + "amount": "1.088812264", + "from_address": "AFmseVrdL9f9oyCzZefL9tG6UbvhUMqNMV", + "to_address": "AUyL4TZ1zFEcSKDJrjFnD7vsq5iFZMZqT7", + "asset_name": "ong", + "contract_hash": "0200000000000000000000000000000000000000" + }, + { + "amount": "0.01", + "from_address": "AUyL4TZ1zFEcSKDJrjFnD7vsq5iFZMZqT7", + "to_address": "AFmseVrdL9f9oyCzZefL9tG6UbviEH9ugK", + "asset_name": "ong", + "contract_hash": "0200000000000000000000000000000000000000" + } + ] + }, + { + "tx_hash": "4eafca0304ec6dcc379d08ab02937c206b0cb4832bf1bebc74f12b0700ab4b95", + "tx_type": 209, + "tx_time": 1581672318, + "block_height": 7802274, + "fee": "0.01", + "block_index": 1, + "confirm_flag": 1, + "transfers": [ + { + "amount": "8", + "from_address": "AUyL4TZ1zFEcSKDJrjFnD7vsq5iFZMZqT7", + "to_address": "AUyL4TZ1zFEcSKDJrjFnD7vsq5iFZMZqT7", + "asset_name": "ont", + "contract_hash": "0100000000000000000000000000000000000000" + }, + { + "amount": "0.01", + "from_address": "AUyL4TZ1zFEcSKDJrjFnD7vsq5iFZMZqT7", + "to_address": "AFmseVrdL9f9oyCzZefL9tG6UbviEH9ugK", + "asset_name": "ong", + "contract_hash": "0200000000000000000000000000000000000000" + } + ] + }, + { + "tx_hash": "f16894191a43ab67d345157ef3dda6f1474a78bdecb1b6a48a70c67e07d5d729", + "tx_type": 209, + "tx_time": 1581672241, + "block_height": 7802270, + "fee": "0.01", + "block_index": 1, + "confirm_flag": 1, + "transfers": [ + { + "amount": "5", + "from_address": "AUyL4TZ1zFEcSKDJrjFnD7vsq5iFZMZqT7", + "to_address": "Abm1FqnU4qur9bviXmrD5YnNixXGvMsi9R", + "asset_name": "ong", + "contract_hash": "0200000000000000000000000000000000000000" + }, + { + "amount": "0.01", + "from_address": "AUyL4TZ1zFEcSKDJrjFnD7vsq5iFZMZqT7", + "to_address": "AFmseVrdL9f9oyCzZefL9tG6UbviEH9ugK", + "asset_name": "ong", + "contract_hash": "0200000000000000000000000000000000000000" + } + ] + }, + { + "tx_hash": "a27863c8a5161fb825afa011833f9321f9ee5d204f24725cc8495c167df95d72", + "tx_type": 209, + "tx_time": 1581672122, + "block_height": 7802264, + "fee": "0.01", + "block_index": 1, + "confirm_flag": 1, + "transfers": [ + { + "amount": "1", + "from_address": "AUyL4TZ1zFEcSKDJrjFnD7vsq5iFZMZqT7", + "to_address": "Abm1FqnU4qur9bviXmrD5YnNixXGvMsi9R", + "asset_name": "ont", + "contract_hash": "0100000000000000000000000000000000000000" + }, + { + "amount": "0.01", + "from_address": "AUyL4TZ1zFEcSKDJrjFnD7vsq5iFZMZqT7", + "to_address": "AFmseVrdL9f9oyCzZefL9tG6UbviEH9ugK", + "asset_name": "ong", + "contract_hash": "0200000000000000000000000000000000000000" + } + ] + }, + { + "tx_hash": "20867ce80fc89d6158bcf76d0e641da6fc15b0571ddeef1db673583c97619783", + "tx_type": 209, + "tx_time": 1581672070, + "block_height": 7802261, + "fee": "0.01", + "block_index": 1, + "confirm_flag": 1, + "transfers": [ + { + "amount": "1", + "from_address": "AUyL4TZ1zFEcSKDJrjFnD7vsq5iFZMZqT7", + "to_address": "Abm1FqnU4qur9bviXmrD5YnNixXGvMsi9R", + "asset_name": "ont", + "contract_hash": "0100000000000000000000000000000000000000" + }, + { + "amount": "0.01", + "from_address": "AUyL4TZ1zFEcSKDJrjFnD7vsq5iFZMZqT7", + "to_address": "AFmseVrdL9f9oyCzZefL9tG6UbviEH9ugK", + "asset_name": "ong", + "contract_hash": "0200000000000000000000000000000000000000" + } + ] + }, + { + "tx_hash": "dde76879ca254fa32485e705e40be7cf909cf214f1c6be6871351f44594c57c1", + "tx_type": 209, + "tx_time": 1564153943, + "block_height": 5924951, + "fee": "0.01", + "block_index": 2, + "confirm_flag": 1, + "transfers": [ + { + "amount": "1", + "from_address": "AUyL4TZ1zFEcSKDJrjFnD7vsq5iFZMZqT7", + "to_address": "AUyL4TZ1zFEcSKDJrjFnD7vsq5iFZMZqT7", + "asset_name": "ont", + "contract_hash": "0100000000000000000000000000000000000000" + }, + { + "amount": "0.01", + "from_address": "AUyL4TZ1zFEcSKDJrjFnD7vsq5iFZMZqT7", + "to_address": "AFmseVrdL9f9oyCzZefL9tG6UbviEH9ugK", + "asset_name": "ong", + "contract_hash": "0200000000000000000000000000000000000000" + } + ] + }, + { + "tx_hash": "936ee120a79f40f7a9e74ca3888a8551a6d7699c1043118ebc69dd84c4e24194", + "tx_type": 209, + "tx_time": 1564152570, + "block_height": 5924099, + "fee": "0.01", + "block_index": 1, + "confirm_flag": 1, + "transfers": [ + { + "amount": "1", + "from_address": "AUyL4TZ1zFEcSKDJrjFnD7vsq5iFZMZqT7", + "to_address": "AUyL4TZ1zFEcSKDJrjFnD7vsq5iFZMZqT7", + "asset_name": "ont", + "contract_hash": "0100000000000000000000000000000000000000" + }, + { + "amount": "0.01", + "from_address": "AUyL4TZ1zFEcSKDJrjFnD7vsq5iFZMZqT7", + "to_address": "AFmseVrdL9f9oyCzZefL9tG6UbviEH9ugK", + "asset_name": "ong", + "contract_hash": "0200000000000000000000000000000000000000" + } + ] + }, + { + "tx_hash": "25e89a33a79dd1763be5db1ea3cea8f484559df4c8d2141af4f1170bbfab10df", + "tx_type": 209, + "tx_time": 1564152252, + "block_height": 5924047, + "fee": "0.01", + "block_index": 1, + "confirm_flag": 1, + "transfers": [ + { + "amount": "1", + "from_address": "AUyL4TZ1zFEcSKDJrjFnD7vsq5iFZMZqT7", + "to_address": "AUyL4TZ1zFEcSKDJrjFnD7vsq5iFZMZqT7", + "asset_name": "ont", + "contract_hash": "0100000000000000000000000000000000000000" + }, + { + "amount": "0.01", + "from_address": "AUyL4TZ1zFEcSKDJrjFnD7vsq5iFZMZqT7", + "to_address": "AFmseVrdL9f9oyCzZefL9tG6UbviEH9ugK", + "asset_name": "ong", + "contract_hash": "0200000000000000000000000000000000000000" + } + ] + }, + { + "tx_hash": "8ce81e7e435f37201a358acbe9b8feb4e820e9a33a66533cbbacb6e92e270ce8", + "tx_type": 209, + "tx_time": 1558638754, + "block_height": 4081289, + "fee": "0.01", + "block_index": 1, + "confirm_flag": 1, + "transfers": [ + { + "amount": "1", + "from_address": "AUyL4TZ1zFEcSKDJrjFnD7vsq5iFZMZqT7", + "to_address": "Abm1FqnU4qur9bviXmrD5YnNixXGvMsi9R", + "asset_name": "ont", + "contract_hash": "0100000000000000000000000000000000000000" + }, + { + "amount": "0.01", + "from_address": "AUyL4TZ1zFEcSKDJrjFnD7vsq5iFZMZqT7", + "to_address": "AFmseVrdL9f9oyCzZefL9tG6UbviEH9ugK", + "asset_name": "ong", + "contract_hash": "0200000000000000000000000000000000000000" + } + ] + }, + { + "tx_hash": "c24bd2a5cf0d18716478a556fab43bf39aa87b914a5cc73d8882a9dc15e68510", + "tx_type": 209, + "tx_time": 1558638721, + "block_height": 4081280, + "fee": "0.01", + "block_index": 2, + "confirm_flag": 1, + "transfers": [ + { + "amount": "4.0801", + "from_address": "Abm1FqnU4qur9bviXmrD5YnNixXGvMsi9R", + "to_address": "AUyL4TZ1zFEcSKDJrjFnD7vsq5iFZMZqT7", + "asset_name": "ong", + "contract_hash": "0200000000000000000000000000000000000000" + } + ] + }, + { + "tx_hash": "076a3835937fca68d12ef08636e72ea95e7c0b4941b2290f34612e57520c7d4c", + "tx_type": 209, + "tx_time": 1558638699, + "block_height": 4081276, + "fee": "0.01", + "block_index": 1, + "confirm_flag": 1, + "transfers": [ + { + "amount": "4", + "from_address": "Abm1FqnU4qur9bviXmrD5YnNixXGvMsi9R", + "to_address": "AUyL4TZ1zFEcSKDJrjFnD7vsq5iFZMZqT7", + "asset_name": "ont", + "contract_hash": "0100000000000000000000000000000000000000" + } + ] + }, + { + "tx_hash": "d68ee61fca2e8d958c92c802b0dbb5aec41d037fc8d20ddf5aaebea6a48d7388", + "tx_type": 209, + "tx_time": 1558028977, + "block_height": 3910475, + "fee": "0.01", + "block_index": 1, + "confirm_flag": 1, + "transfers": [ + { + "amount": "1", + "from_address": "Abm1FqnU4qur9bviXmrD5YnNixXGvMsi9R", + "to_address": "AUyL4TZ1zFEcSKDJrjFnD7vsq5iFZMZqT7", + "asset_name": "ont", + "contract_hash": "0100000000000000000000000000000000000000" + } + ] + }, + { + "tx_hash": "d773150c3b2e4524cb8138a13528397c01436ece597056e9d86be8eee14c0902", + "tx_type": 209, + "tx_time": 1558028471, + "block_height": 3910415, + "fee": "0.01", + "block_index": 2, + "confirm_flag": 1, + "transfers": [ + { + "amount": "0.0001", + "from_address": "AUyL4TZ1zFEcSKDJrjFnD7vsq5iFZMZqT7", + "to_address": "Abm1FqnU4qur9bviXmrD5YnNixXGvMsi9R", + "asset_name": "ong", + "contract_hash": "0200000000000000000000000000000000000000" + }, + { + "amount": "0.01", + "from_address": "AUyL4TZ1zFEcSKDJrjFnD7vsq5iFZMZqT7", + "to_address": "AFmseVrdL9f9oyCzZefL9tG6UbviEH9ugK", + "asset_name": "ong", + "contract_hash": "0200000000000000000000000000000000000000" + } + ] + } + ] +} \ No newline at end of file diff --git a/mock/ext-api-data/opensea-api_api_v1_assets___collection_unstoppable-domains_limit_300_owner_0x84E79D544B4b13bC3560069cfD56A9D5bbE7521d.json b/mock/ext-api-data/opensea-api_api_v1_assets___collection_unstoppable-domains_limit_300_owner_0x84E79D544B4b13bC3560069cfD56A9D5bbE7521d.json new file mode 100644 index 000000000..412ba8d8e --- /dev/null +++ b/mock/ext-api-data/opensea-api_api_v1_assets___collection_unstoppable-domains_limit_300_owner_0x84E79D544B4b13bC3560069cfD56A9D5bbE7521d.json @@ -0,0 +1,252 @@ +{ + "assets": [ + { + "token_id": "107221826727469155718680588460379721284635325845036369130032935095484960793482", + "num_sales": 0, + "background_color": "4C47F7", + "image_url": "https://storage.opensea.io/files/fec912a0664aecaa908ee888177ebfc6.svg", + "image_preview_url": "https://lh3.googleusercontent.com/cqCHmaBgbAtaE5i-jRKLGbJy2C-AUnDXN8zpkw8JPKnqRNGXdMJme_ThTFL30mDN9u9piJ4ACcfHmmDAyaXfIocN=s250", + "image_thumbnail_url": "https://lh3.googleusercontent.com/cqCHmaBgbAtaE5i-jRKLGbJy2C-AUnDXN8zpkw8JPKnqRNGXdMJme_ThTFL30mDN9u9piJ4ACcfHmmDAyaXfIocN=s128", + "image_original_url": null, + "animation_url": null, + "animation_original_url": null, + "name": "sloth", + "description": "A .crypto blockchain domain. Use it to resolve your cryptocurrency addresses and decentralized websites.", + "external_link": "https://unstoppabledomains.com/search?searchTerm=sloth.crypto", + "asset_contract": { + "address": "0xd1e5b0ff1287aa9f9a268759062e4ab08b9dacbe", + "asset_contract_type": "non-fungible", + "created_date": "2019-12-10T08:55:01.176657", + "name": ".crypto", + "nft_version": "3.0", + "opensea_version": null, + "owner": null, + "schema_name": "ERC721", + "symbol": "", + "total_supply": null, + "description": "Simplify your crypto currency payments with human readable names and build censorship resistant websites. Purchase your blockchain domains today!", + "external_link": "https://unstoppabledomains.com/", + "image_url": "https://lh3.googleusercontent.com/Ak1PwcaxSjJmX2ZR4XN1GOYw1ZqQPlJo48FJaD_RHJykq9p_-lrmLDDv2x5cjgDncxJphoSkWL4hEPA_693aXHJB=s60", + "default_to_fiat": false, + "dev_buyer_fee_basis_points": 0, + "dev_seller_fee_basis_points": 0, + "only_proxied_transfers": false, + "opensea_buyer_fee_basis_points": 0, + "opensea_seller_fee_basis_points": 250, + "buyer_fee_basis_points": 0, + "seller_fee_basis_points": 250, + "payout_address": null + }, + "owner": { + "user": null, + "profile_img_url": "https://storage.googleapis.com/opensea-static/opensea-profile/6.png", + "address": "0x84e79d544b4b13bc3560069cfd56a9d5bbe7521d", + "config": "", + "discord_id": "" + }, + "permalink": "https://opensea.io/assets/0xd1e5b0ff1287aa9f9a268759062e4ab08b9dacbe/107221826727469155718680588460379721284635325845036369130032935095484960793482", + "collection": { + "banner_image_url": null, + "chat_url": null, + "created_date": "2019-12-10T08:55:01.591598", + "default_to_fiat": false, + "description": "Simplify your crypto currency payments with human readable names and build censorship resistant websites. Purchase your blockchain domains today!", + "dev_buyer_fee_basis_points": "0", + "dev_seller_fee_basis_points": "0", + "discord_url": null, + "display_data": { + "card_display_style": "padded", + "images": [ + "https://storage.opensea.io/0xd1e5b0ff1287aa9f9a268759062e4ab08b9dacbe/100260309576151364545964131889528085814542346820268672379352985861671742542725-1576285529.png", + "https://storage.opensea.io/0xd1e5b0ff1287aa9f9a268759062e4ab08b9dacbe/4421676099993643179128103015054658901819404648065294942165491120042640407039-1576285527.png", + "https://storage.opensea.io/0xd1e5b0ff1287aa9f9a268759062e4ab08b9dacbe/73695583292838981607767254059063047756835875089503078348607895437407313924749-1576285524.png", + "https://storage.opensea.io/0xd1e5b0ff1287aa9f9a268759062e4ab08b9dacbe/27205116107504397094907367426483105387345010197719784382188136305164707242210-1576285522.png", + "https://storage.opensea.io/0xd1e5b0ff1287aa9f9a268759062e4ab08b9dacbe/101523982898827340730362103529507400599025467135859971366386174116683457290786-1576285522.png", + "https://storage.opensea.io/0xd1e5b0ff1287aa9f9a268759062e4ab08b9dacbe/113871464558189091408051847721365479982421488926705310425753631895495013528420-1576285520.png" + ] + }, + "external_url": "https://unstoppabledomains.com/", + "featured": false, + "featured_image_url": "https://storage.googleapis.com/opensea-static/featured-images/unstoppable-domains-featured.png", + "hidden": false, + "safelist_request_status": "approved", + "image_url": "https://lh3.googleusercontent.com/Ak1PwcaxSjJmX2ZR4XN1GOYw1ZqQPlJo48FJaD_RHJykq9p_-lrmLDDv2x5cjgDncxJphoSkWL4hEPA_693aXHJB=s60", + "is_subject_to_whitelist": false, + "large_image_url": "https://lh3.googleusercontent.com/Ak1PwcaxSjJmX2ZR4XN1GOYw1ZqQPlJo48FJaD_RHJykq9p_-lrmLDDv2x5cjgDncxJphoSkWL4hEPA_693aXHJB", + "medium_username": null, + "name": "Unstoppable Domains", + "only_proxied_transfers": false, + "opensea_buyer_fee_basis_points": "0", + "opensea_seller_fee_basis_points": "250", + "payout_address": null, + "require_email": false, + "short_description": null, + "slug": "unstoppable-domains", + "telegram_url": null, + "twitter_username": null, + "wiki_url": null + }, + "decimals": 0, + "auctions": null, + "sell_orders": [], + "traits": [ + { + "trait_type": "level", + "value": 2, + "display_type": null, + "max_value": null, + "trait_count": 0, + "order": null + }, + { + "trait_type": "domain", + "value": "sloth.crypto", + "display_type": null, + "max_value": null, + "trait_count": 1, + "order": null + }, + { + "trait_type": "type", + "value": "standard", + "display_type": null, + "max_value": null, + "trait_count": 53754, + "order": null + } + ], + "last_sale": null, + "top_bid": null, + "current_price": null, + "current_escrow_price": null, + "listing_date": null, + "is_presale": false, + "transfer_fee_payment_token": null, + "transfer_fee": null + }, + { + "token_id": "39602885785430968515488172908991286516392379555774938600072517130912304722435", + "num_sales": 0, + "background_color": "4C47F7", + "image_url": "https://storage.opensea.io/files/a9d70320f34fb5fb5183d1a9913d2267.svg", + "image_preview_url": "https://lh3.googleusercontent.com/vbjIXUNL8ghOTEn7W6j_ALfwbFl4EOaYdqZjIwmtgdPQ92kzTd3jJjk7fsjJuW2IKkCT80JPuJ6PX_dChnOKI0yK=s250", + "image_thumbnail_url": "https://lh3.googleusercontent.com/vbjIXUNL8ghOTEn7W6j_ALfwbFl4EOaYdqZjIwmtgdPQ92kzTd3jJjk7fsjJuW2IKkCT80JPuJ6PX_dChnOKI0yK=s128", + "image_original_url": null, + "animation_url": null, + "animation_original_url": null, + "name": "vikmeup", + "description": "A .crypto blockchain domain. Use it to resolve your cryptocurrency addresses and decentralized websites.", + "external_link": "https://unstoppabledomains.com/search?searchTerm=vikmeup.crypto", + "asset_contract": { + "address": "0xd1e5b0ff1287aa9f9a268759062e4ab08b9dacbe", + "asset_contract_type": "non-fungible", + "created_date": "2019-12-10T08:55:01.176657", + "name": ".crypto", + "nft_version": "3.0", + "opensea_version": null, + "owner": null, + "schema_name": "ERC721", + "symbol": "", + "total_supply": null, + "description": "Simplify your crypto currency payments with human readable names and build censorship resistant websites. Purchase your blockchain domains today!", + "external_link": "https://unstoppabledomains.com/", + "image_url": "https://lh3.googleusercontent.com/Ak1PwcaxSjJmX2ZR4XN1GOYw1ZqQPlJo48FJaD_RHJykq9p_-lrmLDDv2x5cjgDncxJphoSkWL4hEPA_693aXHJB=s60", + "default_to_fiat": false, + "dev_buyer_fee_basis_points": 0, + "dev_seller_fee_basis_points": 0, + "only_proxied_transfers": false, + "opensea_buyer_fee_basis_points": 0, + "opensea_seller_fee_basis_points": 250, + "buyer_fee_basis_points": 0, + "seller_fee_basis_points": 250, + "payout_address": null + }, + "owner": { + "user": null, + "profile_img_url": "https://storage.googleapis.com/opensea-static/opensea-profile/6.png", + "address": "0x84e79d544b4b13bc3560069cfd56a9d5bbe7521d", + "config": "", + "discord_id": "" + }, + "permalink": "https://opensea.io/assets/0xd1e5b0ff1287aa9f9a268759062e4ab08b9dacbe/39602885785430968515488172908991286516392379555774938600072517130912304722435", + "collection": { + "banner_image_url": null, + "chat_url": null, + "created_date": "2019-12-10T08:55:01.591598", + "default_to_fiat": false, + "description": "Simplify your crypto currency payments with human readable names and build censorship resistant websites. Purchase your blockchain domains today!", + "dev_buyer_fee_basis_points": "0", + "dev_seller_fee_basis_points": "0", + "discord_url": null, + "display_data": { + "card_display_style": "padded", + "images": [ + "https://storage.opensea.io/0xd1e5b0ff1287aa9f9a268759062e4ab08b9dacbe/100260309576151364545964131889528085814542346820268672379352985861671742542725-1576285529.png", + "https://storage.opensea.io/0xd1e5b0ff1287aa9f9a268759062e4ab08b9dacbe/4421676099993643179128103015054658901819404648065294942165491120042640407039-1576285527.png", + "https://storage.opensea.io/0xd1e5b0ff1287aa9f9a268759062e4ab08b9dacbe/73695583292838981607767254059063047756835875089503078348607895437407313924749-1576285524.png", + "https://storage.opensea.io/0xd1e5b0ff1287aa9f9a268759062e4ab08b9dacbe/27205116107504397094907367426483105387345010197719784382188136305164707242210-1576285522.png", + "https://storage.opensea.io/0xd1e5b0ff1287aa9f9a268759062e4ab08b9dacbe/101523982898827340730362103529507400599025467135859971366386174116683457290786-1576285522.png", + "https://storage.opensea.io/0xd1e5b0ff1287aa9f9a268759062e4ab08b9dacbe/113871464558189091408051847721365479982421488926705310425753631895495013528420-1576285520.png" + ] + }, + "external_url": "https://unstoppabledomains.com/", + "featured": false, + "featured_image_url": "https://storage.googleapis.com/opensea-static/featured-images/unstoppable-domains-featured.png", + "hidden": false, + "safelist_request_status": "approved", + "image_url": "https://lh3.googleusercontent.com/Ak1PwcaxSjJmX2ZR4XN1GOYw1ZqQPlJo48FJaD_RHJykq9p_-lrmLDDv2x5cjgDncxJphoSkWL4hEPA_693aXHJB=s60", + "is_subject_to_whitelist": false, + "large_image_url": "https://lh3.googleusercontent.com/Ak1PwcaxSjJmX2ZR4XN1GOYw1ZqQPlJo48FJaD_RHJykq9p_-lrmLDDv2x5cjgDncxJphoSkWL4hEPA_693aXHJB", + "medium_username": null, + "name": "Unstoppable Domains", + "only_proxied_transfers": false, + "opensea_buyer_fee_basis_points": "0", + "opensea_seller_fee_basis_points": "250", + "payout_address": null, + "require_email": false, + "short_description": null, + "slug": "unstoppable-domains", + "telegram_url": null, + "twitter_username": null, + "wiki_url": null + }, + "decimals": 0, + "auctions": null, + "sell_orders": [], + "traits": [ + { + "trait_type": "level", + "value": 2, + "display_type": null, + "max_value": null, + "trait_count": 0, + "order": null + }, + { + "trait_type": "domain", + "value": "vikmeup.crypto", + "display_type": null, + "max_value": null, + "trait_count": 1, + "order": null + }, + { + "trait_type": "type", + "value": "standard", + "display_type": null, + "max_value": null, + "trait_count": 53754, + "order": null + } + ], + "last_sale": null, + "top_bid": null, + "current_price": null, + "current_escrow_price": null, + "listing_date": null, + "is_presale": false, + "transfer_fee_payment_token": null, + "transfer_fee": null + } + ] +} \ No newline at end of file diff --git a/mock/ext-api-data/opensea-api_api_v1_collections___asset_owner_0x84E79D544B4b13bC3560069cfD56A9D5bbE7521d_limit_1000.json b/mock/ext-api-data/opensea-api_api_v1_collections___asset_owner_0x84E79D544B4b13bC3560069cfD56A9D5bbE7521d_limit_1000.json new file mode 100644 index 000000000..7ca8e5f9d --- /dev/null +++ b/mock/ext-api-data/opensea-api_api_v1_collections___asset_owner_0x84E79D544B4b13bC3560069cfD56A9D5bbE7521d_limit_1000.json @@ -0,0 +1,620 @@ +[ + { + "primary_asset_contracts": [ + { + "address": "0x1d963688fe2209a98db35c67a041524822cf04ff", + "asset_contract_type": "non-fungible", + "created_date": "2019-01-23T02:17:28.643618", + "name": "MarbleCards", + "nft_version": "3.0", + "opensea_version": null, + "owner": 204604, + "schema_name": "ERC721", + "symbol": "MRBLNFT", + "total_supply": null, + "description": "Claim the most amazing web pages. Remember that every web page can only be marbled once and by one person only. Once a card is created, that URL is claimed forever. Now go create some classics!", + "external_link": "https://marble.cards", + "image_url": "https://lh3.googleusercontent.com/JHs53JRA6f3VcBqqORnoL4_q4kLDeZkDgZkmbY3iziyQQ14IRtP3mQglePCmHpXE_fit88FH8cAFMUA3j54mivAA=s60", + "default_to_fiat": false, + "dev_buyer_fee_basis_points": 0, + "dev_seller_fee_basis_points": 250, + "only_proxied_transfers": false, + "opensea_buyer_fee_basis_points": 0, + "opensea_seller_fee_basis_points": 250, + "buyer_fee_basis_points": 0, + "seller_fee_basis_points": 500, + "payout_address": "0xee68e4c594b96efc19a9d7d2a33901651ce967a2" + } + ], + "traits": { + "collection_id": { + "min": 31, + "max": 1240 + }, + "Collection ID": { + "min": 1, + "max": 5874 + }, + "level": { + "min": 1, + "max": 100 + } + }, + "stats": { + "seven_day_volume": 3.55387032921667, + "seven_day_change": 3.477981220593884, + "total_volume": 355.11668333704, + "count": 58646, + "num_owners": 1112, + "market_cap": 5091.571634292053, + "average_price": 0.163799208181292, + "items_sold": 2055 + }, + "banner_image_url": null, + "chat_url": null, + "created_date": "2019-04-26T22:13:21.421079", + "default_to_fiat": false, + "description": "Claim the most amazing web pages. Remember that every web page can only be marbled once and by one person only. Once a card is created, that URL is claimed forever. Now go create some classics!", + "dev_buyer_fee_basis_points": "0", + "dev_seller_fee_basis_points": "250", + "discord_url": null, + "display_data": { + "card_display_style": "contain", + "images": [ + "https://storage.opensea.io/0x1d963688fe2209a98db35c67a041524822cf04ff/18612-1552667321.png", + "https://storage.opensea.io/0x1d963688fe2209a98db35c67a041524822cf04ff/18905-1552770831.png", + "https://storage.opensea.io/0x1d963688fe2209a98db35c67a041524822cf04ff/18704-1552750420.png", + "https://storage.opensea.io/0x1d963688fe2209a98db35c67a041524822cf04ff/8829-1550886013.png", + "https://storage.opensea.io/0x1d963688fe2209a98db35c67a041524822cf04ff/18951-1552772148.png", + "https://storage.opensea.io/0x1d963688fe2209a98db35c67a041524822cf04ff/18950-1552772146.png" + ] + }, + "external_url": "https://marble.cards", + "featured": false, + "featured_image_url": "https://storage.opensea.io/0x1d963688fe2209a98db35c67a041524822cf04ff-featured-1556589463.png", + "hidden": false, + "safelist_request_status": "approved", + "image_url": "https://lh3.googleusercontent.com/JHs53JRA6f3VcBqqORnoL4_q4kLDeZkDgZkmbY3iziyQQ14IRtP3mQglePCmHpXE_fit88FH8cAFMUA3j54mivAA=s60", + "is_subject_to_whitelist": false, + "large_image_url": "https://lh3.googleusercontent.com/JHs53JRA6f3VcBqqORnoL4_q4kLDeZkDgZkmbY3iziyQQ14IRtP3mQglePCmHpXE_fit88FH8cAFMUA3j54mivAA", + "medium_username": null, + "name": "MarbleCards", + "only_proxied_transfers": false, + "opensea_buyer_fee_basis_points": "0", + "opensea_seller_fee_basis_points": "250", + "payout_address": "0xee68e4c594b96efc19a9d7d2a33901651ce967a2", + "require_email": false, + "short_description": "Claim websites as unique crypto collectibles", + "slug": "marblecards", + "telegram_url": null, + "twitter_username": null, + "wiki_url": null, + "owned_asset_count": 1 + }, + { + "primary_asset_contracts": [ + { + "address": "0x57f1887a8bf19b14fc0df6fd9b2acc9af147ea85", + "asset_contract_type": "non-fungible", + "created_date": "2019-05-08T21:59:29.327544", + "name": "ENS", + "nft_version": "3.0", + "opensea_version": null, + "owner": 279872, + "schema_name": "ERC721", + "symbol": "ENS", + "total_supply": null, + "description": "Ethereum Name Service (ENS) domains are secure domain names for the decentralized world. ENS domains provide a way for users to map human readable names to blockchain and non-blockchain resources, like Ethereum addresses, IPFS hashes, or website URLs. ENS domains can be bought and sold on secondary markets.", + "external_link": "https://ens.domains", + "image_url": "https://lh3.googleusercontent.com/0cOqWoYA7xL9CkUjGlxsjreSYBdrUBE0c6EO1COG4XE8UeP-Z30ckqUNiL872zHQHQU5MUNMNhfDpyXIP17hRSC5HQ=s60", + "default_to_fiat": false, + "dev_buyer_fee_basis_points": 0, + "dev_seller_fee_basis_points": 0, + "only_proxied_transfers": false, + "opensea_buyer_fee_basis_points": 0, + "opensea_seller_fee_basis_points": 250, + "buyer_fee_basis_points": 0, + "seller_fee_basis_points": 250, + "payout_address": "" + } + ], + "traits": { + "Length": { + "min": 3, + "max": 70 + } + }, + "stats": { + "seven_day_volume": 2.265, + "seven_day_change": -0.2688529157501554, + "total_volume": 6335.24578031905, + "count": 353624, + "num_owners": 30593, + "market_cap": 270232.0665581858, + "average_price": 0.710298405063446, + "items_sold": 8913 + }, + "banner_image_url": null, + "chat_url": null, + "created_date": "2019-05-08T21:59:36.282454", + "default_to_fiat": false, + "description": "Ethereum Name Service (ENS) domains are secure domain names for the decentralized world. ENS domains provide a way for users to map human readable names to blockchain and non-blockchain resources, like Ethereum addresses, IPFS hashes, or website URLs. ENS domains can be bought and sold on secondary markets.", + "dev_buyer_fee_basis_points": "0", + "dev_seller_fee_basis_points": "0", + "discord_url": null, + "display_data": { + "card_display_style": "cover", + "images": [ + "https://storage.opensea.io/0xfac7bea255a6990f749363002136af6556b31e04/26693679858283927161893791132395207263838168762475401800426021835398462679008-1565293871.png", + "https://storage.opensea.io/0xfac7bea255a6990f749363002136af6556b31e04/14216961695379335495094368768338390872453914418325715259759390099828279953313-1565293758.png", + "https://storage.opensea.io/0xfac7bea255a6990f749363002136af6556b31e04/28032727276679833339346855127845420552876278365164540739421161968857583632995-1565293757.png", + "https://storage.opensea.io/0xfac7bea255a6990f749363002136af6556b31e04/5939065732706496924433039736405736608461463576171087944642507927497598723058-1565293758.png", + "https://storage.opensea.io/0xfac7bea255a6990f749363002136af6556b31e04/8268680357553423178495517182551079885250260646681574205692425339615070583014-1565293756.png", + "https://storage.opensea.io/0xfac7bea255a6990f749363002136af6556b31e04/96156505551778134260224136134970011352406026760333505247707872912354314952431-1565293756.png" + ] + }, + "external_url": "https://ens.domains", + "featured": false, + "featured_image_url": "https://storage.googleapis.com/opensea-static/official-ens-logo.png", + "hidden": false, + "safelist_request_status": "approved", + "image_url": "https://lh3.googleusercontent.com/0cOqWoYA7xL9CkUjGlxsjreSYBdrUBE0c6EO1COG4XE8UeP-Z30ckqUNiL872zHQHQU5MUNMNhfDpyXIP17hRSC5HQ=s60", + "is_subject_to_whitelist": false, + "large_image_url": "https://lh3.googleusercontent.com/0cOqWoYA7xL9CkUjGlxsjreSYBdrUBE0c6EO1COG4XE8UeP-Z30ckqUNiL872zHQHQU5MUNMNhfDpyXIP17hRSC5HQ", + "medium_username": null, + "name": "Ethereum Name Service (ENS)", + "only_proxied_transfers": false, + "opensea_buyer_fee_basis_points": "0", + "opensea_seller_fee_basis_points": "250", + "payout_address": "", + "require_email": false, + "short_description": null, + "slug": "ens", + "telegram_url": null, + "twitter_username": null, + "wiki_url": null, + "owned_asset_count": 2 + }, + { + "primary_asset_contracts": [ + { + "address": "0x2fb5d7dda4f1f20f974a0fdd547c38674e8d940c", + "asset_contract_type": "non-fungible", + "created_date": "2019-10-24T11:06:57.511707", + "name": "KnightStory Item", + "nft_version": "3.0", + "opensea_version": null, + "owner": 1672886, + "schema_name": "ERC721", + "symbol": "", + "total_supply": "1", + "description": "Knight Story is an innovative mobile RPG powered by blockchain. The game is the second title of Biscuit; developed EOS Knights, the legendary blockchain game.", + "external_link": "https://knightstory.io", + "image_url": "https://lh3.googleusercontent.com/Hwr0JNz9lHdTeu3mZTawVun-BdKRf-zSpi5ZUDxirBbPs_-hW92qHfh25QcTzeGCPy0FRULooZyTJ6MlRh8qaq4=s60", + "default_to_fiat": false, + "dev_buyer_fee_basis_points": 0, + "dev_seller_fee_basis_points": 0, + "only_proxied_transfers": false, + "opensea_buyer_fee_basis_points": 0, + "opensea_seller_fee_basis_points": 250, + "buyer_fee_basis_points": 0, + "seller_fee_basis_points": 250, + "payout_address": "0x9702a479115788294232c384a5c1f42c881789fe" + } + ], + "traits": { + "attack": { + "min": 7, + "max": 5502 + }, + "attack (set)": { + "min": 60, + "max": 714 + }, + "defense": { + "min": 2, + "max": 2242 + }, + "defense (set)": { + "min": 70, + "max": 288 + }, + "hp": { + "min": 2, + "max": 5502 + }, + "hp (set)": { + "min": 60, + "max": 756 + }, + "luck": { + "min": 2, + "max": 1079 + }, + "luck (set)": { + "min": 40, + "max": 294 + }, + "magic_bean_purchase_bonus": { + "min": 2, + "max": 128 + }, + "None": { + "min": 0, + "max": 0 + }, + "score": { + "min": 28, + "max": 100 + } + }, + "stats": { + "seven_day_volume": 3.13785408582563, + "seven_day_change": -0.6247368483022884, + "total_volume": 565.839345302629, + "count": 40800, + "num_owners": 5830, + "market_cap": 1681.523681150229, + "average_price": 0.0315050942632965, + "items_sold": 17957 + }, + "banner_image_url": null, + "chat_url": null, + "created_date": "2019-10-24T11:06:58.609791", + "default_to_fiat": false, + "description": "Knight Story is an innovative mobile RPG powered by blockchain. The game is the second title of Biscuit; developed EOS Knights, the legendary blockchain game.", + "dev_buyer_fee_basis_points": "0", + "dev_seller_fee_basis_points": "0", + "discord_url": null, + "display_data": { + "card_display_style": "padded", + "images": [ + "https://storage.opensea.io/0x2fb5d7dda4f1f20f974a0fdd547c38674e8d940c/1-1571915237.svg", + "https://storage.opensea.io/0x2fb5d7dda4f1f20f974a0fdd547c38674e8d940c/2-1571982585.svg", + "https://storage.opensea.io/0x2fb5d7dda4f1f20f974a0fdd547c38674e8d940c/6-1571984918.svg", + "https://storage.opensea.io/0x2fb5d7dda4f1f20f974a0fdd547c38674e8d940c/5-1571984898.svg", + "https://storage.opensea.io/0x2fb5d7dda4f1f20f974a0fdd547c38674e8d940c/4-1571984887.svg", + "https://storage.opensea.io/0x2fb5d7dda4f1f20f974a0fdd547c38674e8d940c/3-1571984879.svg" + ] + }, + "external_url": "https://knightstory.io", + "featured": false, + "featured_image_url": null, + "hidden": false, + "safelist_request_status": "approved", + "image_url": "https://lh3.googleusercontent.com/Hwr0JNz9lHdTeu3mZTawVun-BdKRf-zSpi5ZUDxirBbPs_-hW92qHfh25QcTzeGCPy0FRULooZyTJ6MlRh8qaq4=s60", + "is_subject_to_whitelist": false, + "large_image_url": "https://lh3.googleusercontent.com/Hwr0JNz9lHdTeu3mZTawVun-BdKRf-zSpi5ZUDxirBbPs_-hW92qHfh25QcTzeGCPy0FRULooZyTJ6MlRh8qaq4", + "medium_username": null, + "name": "KnightStory", + "only_proxied_transfers": false, + "opensea_buyer_fee_basis_points": "0", + "opensea_seller_fee_basis_points": "250", + "payout_address": "0x9702a479115788294232c384a5c1f42c881789fe", + "require_email": false, + "short_description": null, + "slug": "knightstory", + "telegram_url": null, + "twitter_username": null, + "wiki_url": null, + "owned_asset_count": 1 + }, + { + "primary_asset_contracts": [ + { + "address": "0xd1e5b0ff1287aa9f9a268759062e4ab08b9dacbe", + "asset_contract_type": "non-fungible", + "created_date": "2019-12-10T08:55:01.176657", + "name": ".crypto", + "nft_version": "3.0", + "opensea_version": null, + "owner": null, + "schema_name": "ERC721", + "symbol": "", + "total_supply": null, + "description": "Simplify your crypto currency payments with human readable names and build censorship resistant websites. Purchase your blockchain domains today!", + "external_link": "https://unstoppabledomains.com/", + "image_url": "https://lh3.googleusercontent.com/Ak1PwcaxSjJmX2ZR4XN1GOYw1ZqQPlJo48FJaD_RHJykq9p_-lrmLDDv2x5cjgDncxJphoSkWL4hEPA_693aXHJB=s60", + "default_to_fiat": false, + "dev_buyer_fee_basis_points": 0, + "dev_seller_fee_basis_points": 0, + "only_proxied_transfers": false, + "opensea_buyer_fee_basis_points": 0, + "opensea_seller_fee_basis_points": 250, + "buyer_fee_basis_points": 0, + "seller_fee_basis_points": 250, + "payout_address": null + } + ], + "traits": { + "length": { + "min": 2, + "max": 34 + }, + "level": { + "min": 1, + "max": 3 + } + }, + "stats": { + "seven_day_volume": 3.97, + "seven_day_change": -0.17774740068762512, + "total_volume": 53.6400785864631, + "count": 57702, + "num_owners": 4456, + "market_cap": 13647.67704, + "average_price": 0.102562291752319, + "items_sold": 523 + }, + "banner_image_url": null, + "chat_url": null, + "created_date": "2019-12-10T08:55:01.591598", + "default_to_fiat": false, + "description": "Simplify your crypto currency payments with human readable names and build censorship resistant websites. Purchase your blockchain domains today!", + "dev_buyer_fee_basis_points": "0", + "dev_seller_fee_basis_points": "0", + "discord_url": null, + "display_data": { + "card_display_style": "padded", + "images": [ + "https://storage.opensea.io/0xd1e5b0ff1287aa9f9a268759062e4ab08b9dacbe/100260309576151364545964131889528085814542346820268672379352985861671742542725-1576285529.png", + "https://storage.opensea.io/0xd1e5b0ff1287aa9f9a268759062e4ab08b9dacbe/4421676099993643179128103015054658901819404648065294942165491120042640407039-1576285527.png", + "https://storage.opensea.io/0xd1e5b0ff1287aa9f9a268759062e4ab08b9dacbe/73695583292838981607767254059063047756835875089503078348607895437407313924749-1576285524.png", + "https://storage.opensea.io/0xd1e5b0ff1287aa9f9a268759062e4ab08b9dacbe/27205116107504397094907367426483105387345010197719784382188136305164707242210-1576285522.png", + "https://storage.opensea.io/0xd1e5b0ff1287aa9f9a268759062e4ab08b9dacbe/101523982898827340730362103529507400599025467135859971366386174116683457290786-1576285522.png", + "https://storage.opensea.io/0xd1e5b0ff1287aa9f9a268759062e4ab08b9dacbe/113871464558189091408051847721365479982421488926705310425753631895495013528420-1576285520.png" + ] + }, + "external_url": "https://unstoppabledomains.com/", + "featured": false, + "featured_image_url": "https://storage.googleapis.com/opensea-static/featured-images/unstoppable-domains-featured.png", + "hidden": false, + "safelist_request_status": "approved", + "image_url": "https://lh3.googleusercontent.com/Ak1PwcaxSjJmX2ZR4XN1GOYw1ZqQPlJo48FJaD_RHJykq9p_-lrmLDDv2x5cjgDncxJphoSkWL4hEPA_693aXHJB=s60", + "is_subject_to_whitelist": false, + "large_image_url": "https://lh3.googleusercontent.com/Ak1PwcaxSjJmX2ZR4XN1GOYw1ZqQPlJo48FJaD_RHJykq9p_-lrmLDDv2x5cjgDncxJphoSkWL4hEPA_693aXHJB", + "medium_username": null, + "name": "Unstoppable Domains", + "only_proxied_transfers": false, + "opensea_buyer_fee_basis_points": "0", + "opensea_seller_fee_basis_points": "250", + "payout_address": null, + "require_email": false, + "short_description": null, + "slug": "unstoppable-domains", + "telegram_url": null, + "twitter_username": null, + "wiki_url": null, + "owned_asset_count": 2 + }, + { + "primary_asset_contracts": [ + { + "address": "0xfaafdc07907ff5120a76b34b731b278c38d6043c", + "asset_contract_type": "semi-fungible", + "created_date": "2019-08-02T23:43:14.666153", + "name": "Enjin", + "nft_version": null, + "opensea_version": null, + "owner": null, + "schema_name": "ERC1155", + "symbol": "", + "total_supply": null, + "description": "Enjin assets are unique digital ERC1155 assets used in a variety of games in the Enjin multiverse.", + "external_link": "https://enjinx.io/", + "image_url": "https://lh3.googleusercontent.com/pz9RPxNoHxFTJNNySYV5bXjsWlajAiDiI1A5m5OvUaS1fd8N64yViclbRQqM8HViBTIUPrYgQ-w49h36NHL0D1Y=s60", + "default_to_fiat": false, + "dev_buyer_fee_basis_points": 0, + "dev_seller_fee_basis_points": 0, + "only_proxied_transfers": false, + "opensea_buyer_fee_basis_points": 0, + "opensea_seller_fee_basis_points": 250, + "buyer_fee_basis_points": 0, + "seller_fee_basis_points": 250, + "payout_address": null + } + ], + "traits": {}, + "stats": { + "seven_day_volume": 1.8128, + "seven_day_change": 410.99999999999994, + "total_volume": 286.747475213277, + "count": 34146, + "num_owners": 29436, + "market_cap": 3499.0797333333308, + "average_price": 0.216576116108433, + "items_sold": 1316 + }, + "banner_image_url": null, + "chat_url": null, + "created_date": "2019-12-15T03:51:34.864843", + "default_to_fiat": false, + "description": "The season of giving is upon us, and we come bearing gifts! Join us in the spirit of giving to receive one of our first-ever Binance Collectibles! “HO HO HODL: Binance Collectibles Series 1.”", + "dev_buyer_fee_basis_points": "0", + "dev_seller_fee_basis_points": "0", + "discord_url": null, + "display_data": { + "card_display_style": "contain", + "images": [ + "https://storage.opensea.io/0xfaafdc07907ff5120a76b34b731b278c38d6043c/50885195465617477053098479556454830685103047942629492242239710623321420727762-1576342335.jpg", + "https://storage.opensea.io/0xfaafdc07907ff5120a76b34b731b278c38d6043c/50885195465617477053098479556454830685103047942629492242239710623321420726407-1576341423.jpg", + "https://storage.opensea.io/0xfaafdc07907ff5120a76b34b731b278c38d6043c/50885195465617477053098479556454830685103047942629492242239710623321420727252-1576342120.jpg", + "https://storage.opensea.io/0xfaafdc07907ff5120a76b34b731b278c38d6043c/50885195465617477053098479556454830685103047942629492242239710623321420727146-1576342000.jpg", + "https://storage.opensea.io/0xfaafdc07907ff5120a76b34b731b278c38d6043c/50885195465617477053098479556454830685103047942629492242239710623321420727063-1576341986.jpg", + "https://storage.opensea.io/0xfaafdc07907ff5120a76b34b731b278c38d6043c/50885195465617477053098479556454830685103047942629492242239710623321420727778-1576342346.jpg" + ] + }, + "external_url": "https://www.binance.com/en/blog/411120468693135360/Earn-a-Guaranteed-Binance-NFT--HO-HO-HODL-Binance-Collectibles-Series-1", + "featured": false, + "featured_image_url": null, + "hidden": false, + "safelist_request_status": "approved", + "image_url": "https://lh3.googleusercontent.com/vbRXgbAGZVvBQw5q-qmV0tF3HHKCJeomBz5oHFTehsv2q6xuY7UyndXSWgCWqj2GGJM77DLFP-vLNVnaKYnVoD8=s60", + "is_subject_to_whitelist": false, + "large_image_url": "https://lh3.googleusercontent.com/vbRXgbAGZVvBQw5q-qmV0tF3HHKCJeomBz5oHFTehsv2q6xuY7UyndXSWgCWqj2GGJM77DLFP-vLNVnaKYnVoD8", + "medium_username": null, + "name": "Binance", + "only_proxied_transfers": false, + "opensea_buyer_fee_basis_points": "0", + "opensea_seller_fee_basis_points": "250", + "payout_address": null, + "require_email": false, + "short_description": null, + "slug": "binance", + "telegram_url": null, + "twitter_username": null, + "wiki_url": null, + "owned_asset_count": 4 + }, + { + "primary_asset_contracts": [ + { + "address": "0x3eea5bf894236f4b7a6f1451bca89a9c91f49719", + "asset_contract_type": "non-fungible", + "created_date": "2019-12-24T15:08:28.581742", + "name": "Trust Collectible", + "nft_version": "3.0", + "opensea_version": null, + "owner": 1982280, + "schema_name": "ERC721", + "symbol": "", + "total_supply": "25", + "description": "Your friendly talkative crypto app.", + "external_link": "https://trustwallet.com", + "image_url": "https://storage.opensea.io/trust-collectible-1577200601.png", + "default_to_fiat": false, + "dev_buyer_fee_basis_points": 0, + "dev_seller_fee_basis_points": 0, + "only_proxied_transfers": false, + "opensea_buyer_fee_basis_points": 0, + "opensea_seller_fee_basis_points": 250, + "buyer_fee_basis_points": 0, + "seller_fee_basis_points": 250, + "payout_address": null + } + ], + "traits": { + "generation": { + "min": 1, + "max": 1 + }, + "level": { + "min": 2, + "max": 2 + } + }, + "stats": { + "seven_day_volume": 0, + "seven_day_change": 0, + "total_volume": 1.12728594516888, + "count": 50, + "num_owners": 22, + "market_cap": 0, + "average_price": 0.0230049142148904, + "items_sold": 47 + }, + "banner_image_url": null, + "chat_url": null, + "created_date": "2019-12-24T15:08:28.833176", + "default_to_fiat": false, + "description": "Your friendly talkative crypto app.", + "dev_buyer_fee_basis_points": "0", + "dev_seller_fee_basis_points": "0", + "discord_url": null, + "display_data": { + "card_display_style": "cover", + "images": [ + "https://storage.opensea.io/0x3eea5bf894236f4b7a6f1451bca89a9c91f49719/1-1577200113.png", + "https://storage.opensea.io/0x3eea5bf894236f4b7a6f1451bca89a9c91f49719/25-1577200136.png", + "https://storage.opensea.io/0x3eea5bf894236f4b7a6f1451bca89a9c91f49719/24-1577200136.png", + "https://storage.opensea.io/0x3eea5bf894236f4b7a6f1451bca89a9c91f49719/21-1577200135.png", + "https://storage.opensea.io/0x3eea5bf894236f4b7a6f1451bca89a9c91f49719/23-1577200135.png", + "https://storage.opensea.io/0x3eea5bf894236f4b7a6f1451bca89a9c91f49719/22-1577200133.png" + ] + }, + "external_url": "https://trustwallet.com", + "featured": false, + "featured_image_url": null, + "hidden": false, + "safelist_request_status": "approved", + "image_url": "https://storage.opensea.io/trust-collectible-1577200601.png", + "is_subject_to_whitelist": false, + "large_image_url": "https://storage.opensea.io/trust-collectible-large-1577200602.png", + "medium_username": null, + "name": "Trust Collectibles", + "only_proxied_transfers": false, + "opensea_buyer_fee_basis_points": "0", + "opensea_seller_fee_basis_points": "250", + "payout_address": null, + "require_email": false, + "short_description": null, + "slug": "trust-collectible", + "telegram_url": null, + "twitter_username": null, + "wiki_url": null, + "owned_asset_count": 1 + }, + { + "primary_asset_contracts": [], + "traits": { + "length": { + "min": 7, + "max": 18 + }, + "level": { + "min": 2, + "max": 2 + } + }, + "stats": { + "seven_day_volume": 0.5486, + "seven_day_change": -0.7875680705545889, + "total_volume": 5.74316958623246, + "count": 14148, + "num_owners": 8485, + "market_cap": 193.4627697762295, + "average_price": 0.0136742133005535, + "items_sold": 420 + }, + "banner_image_url": null, + "chat_url": null, + "created_date": "2020-04-13T20:06:38.168795", + "default_to_fiat": false, + "description": "Simplify your crypto currency payments with human readable names and build censorship resistant websites. Purchase your blockchain domains today!", + "dev_buyer_fee_basis_points": "0", + "dev_seller_fee_basis_points": "0", + "discord_url": null, + "display_data": { + "card_display_style": "padded", + "images": [ + "https://storage.opensea.io/0xd1e5b0ff1287aa9f9a268759062e4ab08b9dacbe/100260309576151364545964131889528085814542346820268672379352985861671742542725-1576285529.png", + "https://storage.opensea.io/0xd1e5b0ff1287aa9f9a268759062e4ab08b9dacbe/4421676099993643179128103015054658901819404648065294942165491120042640407039-1576285527.png", + "https://storage.opensea.io/0xd1e5b0ff1287aa9f9a268759062e4ab08b9dacbe/73695583292838981607767254059063047756835875089503078348607895437407313924749-1576285524.png", + "https://storage.opensea.io/0xd1e5b0ff1287aa9f9a268759062e4ab08b9dacbe/27205116107504397094907367426483105387345010197719784382188136305164707242210-1576285522.png", + "https://storage.opensea.io/0xd1e5b0ff1287aa9f9a268759062e4ab08b9dacbe/101523982898827340730362103529507400599025467135859971366386174116683457290786-1576285522.png", + "https://storage.opensea.io/0xd1e5b0ff1287aa9f9a268759062e4ab08b9dacbe/113871464558189091408051847721365479982421488926705310425753631895495013528420-1576285520.png" + ] + }, + "external_url": "https://unstoppabledomains.com/", + "featured": false, + "featured_image_url": "https://storage.googleapis.com/opensea-static/featured-images/unstoppable-domains-featured.png", + "hidden": false, + "safelist_request_status": "approved", + "image_url": "https://lh3.googleusercontent.com/Ak1PwcaxSjJmX2ZR4XN1GOYw1ZqQPlJo48FJaD_RHJykq9p_-lrmLDDv2x5cjgDncxJphoSkWL4hEPA_693aXHJB=s60", + "is_subject_to_whitelist": false, + "large_image_url": "https://lh3.googleusercontent.com/Ak1PwcaxSjJmX2ZR4XN1GOYw1ZqQPlJo48FJaD_RHJykq9p_-lrmLDDv2x5cjgDncxJphoSkWL4hEPA_693aXHJB", + "medium_username": null, + "name": "Unstoppable Domains Animals", + "only_proxied_transfers": false, + "opensea_buyer_fee_basis_points": "0", + "opensea_seller_fee_basis_points": "250", + "payout_address": null, + "require_email": false, + "short_description": null, + "slug": "unstoppable-domains-animals", + "telegram_url": null, + "twitter_username": null, + "wiki_url": null, + "owned_asset_count": 1 + } +] \ No newline at end of file diff --git a/mock/ext-api-data/poa-api_tokens__address_0x0875BCab22dE3d02402bc38aEe4104e1239374a7.json b/mock/ext-api-data/poa-api_tokens__address_0x0875BCab22dE3d02402bc38aEe4104e1239374a7.json new file mode 100644 index 000000000..f696f03f9 --- /dev/null +++ b/mock/ext-api-data/poa-api_tokens__address_0x0875BCab22dE3d02402bc38aEe4104e1239374a7.json @@ -0,0 +1 @@ +{"total":1,"docs":[{"address":"0xADFE00d92e5A16e773891F59780e6e54f40B532e","name":"Viktor Coin","decimals":0,"symbol":"VIK"}]} \ No newline at end of file diff --git a/mock/ext-api-data/poa-api_transactions__address_0x55798eCbF17ce1241d543c22dCE46134c13b4bc0.json b/mock/ext-api-data/poa-api_transactions__address_0x55798eCbF17ce1241d543c22dCE46134c13b4bc0.json new file mode 100644 index 000000000..d84956613 --- /dev/null +++ b/mock/ext-api-data/poa-api_transactions__address_0x55798eCbF17ce1241d543c22dCE46134c13b4bc0.json @@ -0,0 +1 @@ +{"docs":[{"operations":[{"transactionId":"0x544f5c54ad3c0b048ae81ef6f14507f934c4e53031bb2d39e074871c22f5ff9d-0","contract":{"address":"0xab2f2dd3120de530d38936ee09a74a6d17e3da44","decimals":18,"name":"GeonCoin","symbol":"GC","totalSupply":"100000000000000000000000000","updatedAt":"2020-02-26T23:41:29.763Z"},"from":"0x55798eCbF17ce1241d543c22dCE46134c13b4bc0","to":"0xE87E46032847e097F5bB51404d19A0449c704EE8","type":"token_transfer","value":"1000000000000000000","id":null}],"contract":null,"_id":"0x544f5c54ad3c0b048ae81ef6f14507f934c4e53031bb2d39e074871c22f5ff9d","blockNumber":14115901,"time":1584448420,"nonce":1,"from":"0x55798eCbF17ce1241d543c22dCE46134c13b4bc0","to":"0xAb2f2Dd3120dE530d38936EE09A74a6d17e3Da44","value":"0","gas":"120000","gasPrice":"1000000000","gasUsed":"78484","input":"0xb88a3f725e70c38d1d03b5568e2f4d1600000000000000000000000000000000000000000000000000000000000000000000000000000000000000000de0b6b3a7640000","error":"","id":"0x544f5c54ad3c0b048ae81ef6f14507f934c4e53031bb2d39e074871c22f5ff9d","timeStamp":"1584448420"},{"operations":[],"contract":null,"_id":"0xcde1f2c3a262012f624065f167616db3160e763f4938ccfa0fcc742d5725eae2","blockNumber":14115900,"time":1584448415,"nonce":109291,"from":"0x628cF7150f8242b20B2ADB064D27183D2a026130","to":"0x55798eCbF17ce1241d543c22dCE46134c13b4bc0","value":"600000000000000","gas":"120000","gasPrice":"1000000000","gasUsed":"21000","input":"0x","error":"","id":"0xcde1f2c3a262012f624065f167616db3160e763f4938ccfa0fcc742d5725eae2","timeStamp":"1584448415"},{"operations":[],"contract":null,"_id":"0x90ef177d3448d379560218f99657027661a7238fb62c793dc2a7091a0d0d88e8","blockNumber":14115899,"time":1584448410,"nonce":0,"from":"0x55798eCbF17ce1241d543c22dCE46134c13b4bc0","to":"0xE87E46032847e097F5bB51404d19A0449c704EE8","value":"0","gas":"120000","gasPrice":"1000000000","gasUsed":"100890","input":"0x1e76c9445e70c38d1d03b5568e2f4d160000000000000000000000000000000000000000","error":"","id":"0x90ef177d3448d379560218f99657027661a7238fb62c793dc2a7091a0d0d88e8","timeStamp":"1584448410"},{"operations":[],"contract":null,"_id":"0x6fbe91787b01664f99ea928fb1a314aed4fcd777a9fae063ed74b838315120c3","blockNumber":14115898,"time":1584448405,"nonce":109290,"from":"0x628cF7150f8242b20B2ADB064D27183D2a026130","to":"0x55798eCbF17ce1241d543c22dCE46134c13b4bc0","value":"600000000000000","gas":"120000","gasPrice":"1000000000","gasUsed":"21000","input":"0x","error":"","id":"0x6fbe91787b01664f99ea928fb1a314aed4fcd777a9fae063ed74b838315120c3","timeStamp":"1584448405"},{"operations":[{"transactionId":"0x19ccc1fbaaf57ea72a5269d1b06630bffeb9ec0a8f0c64c6919f773c4d920312-0","contract":{"address":"0xab2f2dd3120de530d38936ee09a74a6d17e3da44","decimals":18,"name":"GeonCoin","symbol":"GC","totalSupply":"100000000000000000000000000","updatedAt":"2020-02-26T23:41:29.763Z"},"from":"0x4808A49bFB7527C142eb2C5b5718CeF432223ae7","to":"0x55798eCbF17ce1241d543c22dCE46134c13b4bc0","type":"token_transfer","value":"1000000000000000000","id":null}],"contract":null,"_id":"0x19ccc1fbaaf57ea72a5269d1b06630bffeb9ec0a8f0c64c6919f773c4d920312","blockNumber":14115844,"time":1584448120,"nonce":129540,"from":"0x4808A49bFB7527C142eb2C5b5718CeF432223ae7","to":"0xAb2f2Dd3120dE530d38936EE09A74a6d17e3Da44","value":"0","gas":"120000","gasPrice":"1000000000","gasUsed":"37088","input":"0xa9059cbb00000000000000000000000055798ecbf17ce1241d543c22dce46134c13b4bc00000000000000000000000000000000000000000000000000de0b6b3a7640000","error":"","id":"0x19ccc1fbaaf57ea72a5269d1b06630bffeb9ec0a8f0c64c6919f773c4d920312","timeStamp":"1584448120"},{"operations":[{"transactionId":"0xf538a2a6a604a7183f131795e81a913522fb94de578aecb87feb0ffb75729afa-0","contract":{"address":"0xab2f2dd3120de530d38936ee09a74a6d17e3da44","decimals":18,"name":"GeonCoin","symbol":"GC","totalSupply":"100000000000000000000000000","updatedAt":"2020-02-26T23:41:29.763Z"},"from":"0xcB8EDB02bb1f3b96f895D878DF2946a9809c0a8a","to":"0x55798eCbF17ce1241d543c22dCE46134c13b4bc0","type":"token_transfer","value":"1000000000000000000","id":null}],"contract":null,"_id":"0xf538a2a6a604a7183f131795e81a913522fb94de578aecb87feb0ffb75729afa","blockNumber":14103004,"time":1584379885,"nonce":130365,"from":"0xcB8EDB02bb1f3b96f895D878DF2946a9809c0a8a","to":"0xAb2f2Dd3120dE530d38936EE09A74a6d17e3Da44","value":"0","gas":"120000","gasPrice":"1000000000","gasUsed":"52088","input":"0xa9059cbb00000000000000000000000055798ecbf17ce1241d543c22dce46134c13b4bc00000000000000000000000000000000000000000000000000de0b6b3a7640000","error":"","id":"0xf538a2a6a604a7183f131795e81a913522fb94de578aecb87feb0ffb75729afa","timeStamp":"1584379885"},{"operations":[{"transactionId":"0x1150040f9f94353a144bfdefcd5691627b87bf4c70470ea9fe4c440edfd6a6eb-0","contract":{"address":"0xab2f2dd3120de530d38936ee09a74a6d17e3da44","decimals":18,"name":"GeonCoin","symbol":"GC","totalSupply":"100000000000000000000000000","updatedAt":"2020-02-26T23:41:29.763Z"},"from":"0xEfc020194845183A387475c4663CB314a22C4758","to":"0x55798eCbF17ce1241d543c22dCE46134c13b4bc0","type":"token_transfer","value":"1000000000000000000","id":null}],"contract":null,"_id":"0x1150040f9f94353a144bfdefcd5691627b87bf4c70470ea9fe4c440edfd6a6eb","blockNumber":14103004,"time":1584379885,"nonce":130048,"from":"0xEfc020194845183A387475c4663CB314a22C4758","to":"0xAb2f2Dd3120dE530d38936EE09A74a6d17e3Da44","value":"0","gas":"120000","gasPrice":"1000000000","gasUsed":"37088","input":"0xa9059cbb00000000000000000000000055798ecbf17ce1241d543c22dce46134c13b4bc00000000000000000000000000000000000000000000000000de0b6b3a7640000","error":"","id":"0x1150040f9f94353a144bfdefcd5691627b87bf4c70470ea9fe4c440edfd6a6eb","timeStamp":"1584379885"}],"total":7} \ No newline at end of file diff --git a/mock/ext-api-data/qtum-api_v2_address_QZJbNrGT3cZ1J1AEHtgH3JWM7uLBNAejLZ__details_txs.json b/mock/ext-api-data/qtum-api_v2_address_QZJbNrGT3cZ1J1AEHtgH3JWM7uLBNAejLZ__details_txs.json new file mode 100644 index 000000000..625ec5eca --- /dev/null +++ b/mock/ext-api-data/qtum-api_v2_address_QZJbNrGT3cZ1J1AEHtgH3JWM7uLBNAejLZ__details_txs.json @@ -0,0 +1,330 @@ +{ + "page": 1, + "totalPages": 1, + "itemsOnPage": 1000, + "address": "QZJbNrGT3cZ1J1AEHtgH3JWM7uLBNAejLZ", + "balance": "234243932", + "totalReceived": "43569601542", + "totalSent": "43335357610", + "unconfirmedBalance": "0", + "unconfirmedTxs": 0, + "txs": 6, + "transactions": [ + { + "txid": "fba987ecdac9307827d48776eb808050347b31bbc2ed2dbbc1d957d0c5c5213b", + "version": 1, + "vin": [ + { + "txid": "62438bb658856c3a08b89ca80e199e7031f98956ea86a135f5d6306660230f67", + "sequence": 4294967294, + "n": 0, + "addresses": [ + "QZJbNrGT3cZ1J1AEHtgH3JWM7uLBNAejLZ" + ], + "isAddress": true, + "value": "235357610", + "hex": "48304502210099cd42a938de9b5ab1b5f7770cc99a9b5ab935e63911a13276510e9b1983c107022034f6d45e5ae6ce13b839427b91f2d0d98c7894610d5fe5d7aaa7e1ce2911627e01210317cfe4e8b0e35f4c2c561921fe019910e3ddbe78d500a8ff546cf1843f723764" + } + ], + "vout": [ + { + "value": "1000000", + "n": 0, + "hex": "76a914816e451a8afb6753d6617633cc8d9785fd33599c88ac", + "addresses": [ + "QYQMNjZ7iaJXRJnVAE11MzCFCwre7Fw9qZ" + ], + "isAddress": true + }, + { + "value": "234243932", + "n": 1, + "hex": "76a9148b4f969602a4579f9c982e7d30c3a06e2f0cacc888ac", + "addresses": [ + "QZJbNrGT3cZ1J1AEHtgH3JWM7uLBNAejLZ" + ], + "isAddress": true + } + ], + "blockHash": "bd1c23ed73b801db65cda1e4c576812da2687e6cd71a33d3f03440b15c8d28b3", + "blockHeight": 602733, + "confirmations": 4804, + "blockTime": 1588752224, + "value": "235243932", + "valueIn": "235357610", + "fees": "113678", + "hex": "0100000001670f23606630d6f535a186ea5689f931709e190ea89cb8083a6c8558b68b4362000000006b48304502210099cd42a938de9b5ab1b5f7770cc99a9b5ab935e63911a13276510e9b1983c107022034f6d45e5ae6ce13b839427b91f2d0d98c7894610d5fe5d7aaa7e1ce2911627e01210317cfe4e8b0e35f4c2c561921fe019910e3ddbe78d500a8ff546cf1843f723764feffffff0240420f00000000001976a914816e451a8afb6753d6617633cc8d9785fd33599c88ac5c47f60d000000001976a9148b4f969602a4579f9c982e7d30c3a06e2f0cacc888ac00000000" + }, + { + "txid": "62438bb658856c3a08b89ca80e199e7031f98956ea86a135f5d6306660230f67", + "version": 1, + "vin": [ + { + "txid": "782e18a7b1bf612972e773fd6ccdcbe0c4514c661c31a7942f5dcd4807c5ab68", + "sequence": 4294967293, + "n": 0, + "addresses": [ + "QWLQSMPF5WKAqhXxePJvjUJNjxDHrPCbjB" + ], + "isAddress": true, + "value": "100000", + "hex": "483045022100b660d73ff3bd7cc52d1052b933828cc2bb23b7a94500dff4bf00d5640ff4951702206ac6ecdaf3818dc57d54f8e860bbf212846200ccb2d1a323bf5b59868dcba872012102d7062f4af80f3a31f67c928e141627d807f0641b0bb0d466f4a62ee31230aa1e" + }, + { + "txid": "80b7c6bcba625ad4abb69f7e92521a782681e984982408d40ad35a24b3f78297", + "sequence": 4294967294, + "n": 1, + "addresses": [ + "QgqVXuCCN1m4Hfb9HCkrzbgUSkoodKsrVY" + ], + "isAddress": true, + "value": "100000", + "hex": "48304502210090ea4a4aac51d8734ad9ffecf0e5c14be50a8941b8cac6a492c002a0be99e5e102203550b52b7ad546adf8b1e5ed00b7aa755cc296d4bd61004b2ace43bfe0007d17012103692f9ee47370b3a70e8d7b6ac36c705b2d3296bb37c0f02e15158f3a6001ce5b" + }, + { + "txid": "9c3a6eb9fa07868a2e59530fe2aa3ea29a21d3818a70343097adbe571ee2f0be", + "sequence": 4294967292, + "n": 2, + "addresses": [ + "QSEXLG5qct47UtMHiXNg2Y27KSDSAEHJp9" + ], + "isAddress": true, + "value": "10000000", + "hex": "473044022055806e0939aa734d296ac364d4edf430bcd4fc15a377d35205362d09f7367d8e02202cc4e691c31ece66abb9adcd20bf8e3f500a2254edaaf2c241529cee670972440121025249520b3d48efd435e6cc30c9af238d054461d51f8beeaf75c4de50a647acbc" + }, + { + "txid": "9c3a6eb9fa07868a2e59530fe2aa3ea29a21d3818a70343097adbe571ee2f0be", + "vout": 1, + "sequence": 4294967291, + "n": 3, + "addresses": [ + "Qfw9Poi2c4gGEkAAuVyG21PsBmNGsmZKFC" + ], + "isAddress": true, + "value": "225494620", + "hex": "483045022100e9d2126507af25eed231d27db52794bf6dc67c33800ebafd99b44b13394e1a2d02206b5abdce728114fa75624cd50d70f3c7da77c5b00433fa306b203e4bfb7d96320121020d708ba820b87e195b5790fa2723033cfec259ce5af4270a431cd7297d7704d3" + } + ], + "vout": [ + { + "value": "235357610", + "n": 0, + "spent": true, + "hex": "76a9148b4f969602a4579f9c982e7d30c3a06e2f0cacc888ac", + "addresses": [ + "QZJbNrGT3cZ1J1AEHtgH3JWM7uLBNAejLZ" + ], + "isAddress": true + } + ], + "blockHash": "6e71fa96ca29a6e4cbd10defaa4fc69ff09adec45fc666d82afade3f75206cc1", + "blockHeight": 563426, + "confirmations": 44111, + "blockTime": 1583720608, + "value": "235357610", + "valueIn": "235694620", + "fees": "337010", + "hex": "010000000468abc50748cd5d2f94a7311c664c51c4e0cbcd6cfd73e7722961bfb1a7182e78000000006b483045022100b660d73ff3bd7cc52d1052b933828cc2bb23b7a94500dff4bf00d5640ff4951702206ac6ecdaf3818dc57d54f8e860bbf212846200ccb2d1a323bf5b59868dcba872012102d7062f4af80f3a31f67c928e141627d807f0641b0bb0d466f4a62ee31230aa1efdffffff9782f7b3245ad30ad408249884e98126781a52927e9fb6abd45a62babcc6b780000000006b48304502210090ea4a4aac51d8734ad9ffecf0e5c14be50a8941b8cac6a492c002a0be99e5e102203550b52b7ad546adf8b1e5ed00b7aa755cc296d4bd61004b2ace43bfe0007d17012103692f9ee47370b3a70e8d7b6ac36c705b2d3296bb37c0f02e15158f3a6001ce5bfeffffffbef0e21e57bead973034708a81d3219aa23eaae20f53592e8a8607fab96e3a9c000000006a473044022055806e0939aa734d296ac364d4edf430bcd4fc15a377d35205362d09f7367d8e02202cc4e691c31ece66abb9adcd20bf8e3f500a2254edaaf2c241529cee670972440121025249520b3d48efd435e6cc30c9af238d054461d51f8beeaf75c4de50a647acbcfcffffffbef0e21e57bead973034708a81d3219aa23eaae20f53592e8a8607fab96e3a9c010000006b483045022100e9d2126507af25eed231d27db52794bf6dc67c33800ebafd99b44b13394e1a2d02206b5abdce728114fa75624cd50d70f3c7da77c5b00433fa306b203e4bfb7d96320121020d708ba820b87e195b5790fa2723033cfec259ce5af4270a431cd7297d7704d3fbffffff01aa45070e000000001976a9148b4f969602a4579f9c982e7d30c3a06e2f0cacc888ac00000000" + }, + { + "txid": "ef335bef783551cb054acd220555f1588cc4b03c0f47cc0839220c81d3ceb88d", + "version": 1, + "vin": [ + { + "txid": "506d07570d75914d5bd319d591374fb9cd1633f5c8b3cc800387e104298e8a62", + "vout": 1, + "sequence": 4294967294, + "n": 0, + "addresses": [ + "QfLtauKWxzF6pDf2ceXJe5oqizNHVMBneH" + ], + "isAddress": true, + "value": "198984808", + "hex": "4830450221008676b34896a922ac913b0922319f98ab4bb5223f479c19d62b92f0f187b2759d02204e6c2f57337f9b3ef262e2262b3e04a971635c450fbe4278db8b2b25e5a816540121027f67fba269482ce4eecfbcc31e7acefaf17a8cb3b4f7ccfb5447c71688e1081e" + }, + { + "txid": "e22c3e2ea4d285b71a73c41cdbb51f7c75d80b6f473e7f4aade6df5bf8771942", + "sequence": 4294967292, + "n": 1, + "addresses": [ + "QZJbNrGT3cZ1J1AEHtgH3JWM7uLBNAejLZ" + ], + "isAddress": true, + "value": "43000000000", + "hex": "483045022100e33513c3a4251a92af231c1d3e3bec9d13be2289c1fb203cb0096c6c073a8b840220206f696ee4e38da215f0b1e2c9d2005f085b8bb967d030caa70439046df64d4601210317cfe4e8b0e35f4c2c561921fe019910e3ddbe78d500a8ff546cf1843f723764" + } + ], + "vout": [ + { + "value": "43000000000", + "n": 0, + "spent": true, + "hex": "76a91455c89563888363b725aa0ebd8191a2e9ea54474d88ac", + "addresses": [ + "QURZqPoBfuXXoHDkCHCvhGJa1DP2Ahj1KX" + ], + "isAddress": true + }, + { + "value": "198831468", + "n": 1, + "spent": true, + "hex": "76a914bb29ba1df86d8507e0de32f187fe401cc3817fc388ac", + "addresses": [ + "QdfcTR3TQHjGHcKLiHmiPLRfVPFRWazJPg" + ], + "isAddress": true + } + ], + "blockHash": "918141389623f4f880b1ba279bb70ee91de6a005e1a9d523d21a66e8c55f0502", + "blockHeight": 393505, + "confirmations": 214032, + "blockTime": 1560879520, + "value": "43198831468", + "valueIn": "43198984808", + "fees": "153340", + "hex": "0100000002628a8e2904e1870380ccb3c8f53316cdb94f3791d519d35b4d91750d57076d50010000006b4830450221008676b34896a922ac913b0922319f98ab4bb5223f479c19d62b92f0f187b2759d02204e6c2f57337f9b3ef262e2262b3e04a971635c450fbe4278db8b2b25e5a816540121027f67fba269482ce4eecfbcc31e7acefaf17a8cb3b4f7ccfb5447c71688e1081efeffffff421977f85bdfe6ad4a7f3e476f0bd8757c1fb5db1cc4731ab785d2a42e3e2ce2000000006b483045022100e33513c3a4251a92af231c1d3e3bec9d13be2289c1fb203cb0096c6c073a8b840220206f696ee4e38da215f0b1e2c9d2005f085b8bb967d030caa70439046df64d4601210317cfe4e8b0e35f4c2c561921fe019910e3ddbe78d500a8ff546cf1843f723764fcffffff0200eeff020a0000001976a91455c89563888363b725aa0ebd8191a2e9ea54474d88ac6cedd90b000000001976a914bb29ba1df86d8507e0de32f187fe401cc3817fc388ac00000000" + }, + { + "txid": "e22c3e2ea4d285b71a73c41cdbb51f7c75d80b6f473e7f4aade6df5bf8771942", + "version": 1, + "vin": [ + { + "txid": "ee3b548dbe40fc15cb48fe297b2fa17f1bfffb5a91836bc25674f23b18156ab4", + "vout": 1, + "n": 0, + "addresses": [ + "QZsgcV5SxtrCxjyP5mXAmVosMKrxbEWFfL" + ], + "isAddress": true, + "value": "55000000000", + "hex": "473044022045cd6c3831cb6c0f33b2e3d05940b8205c6293c96f81cfbccc0c29c631dd2a2e0220263bd13fff18d75d45b15f1102118b28001bde09de38f4c5f9c5c5b6f27781c2012102817713bf5592a19279ed887fe88b04173c3844ecc6adf3f75213734b8cecbda4" + } + ], + "vout": [ + { + "value": "43000000000", + "n": 0, + "spent": true, + "hex": "76a9148b4f969602a4579f9c982e7d30c3a06e2f0cacc888ac", + "addresses": [ + "QZJbNrGT3cZ1J1AEHtgH3JWM7uLBNAejLZ" + ], + "isAddress": true + }, + { + "value": "11999907792", + "n": 1, + "spent": true, + "hex": "76a914ccdab9a8e80f5c1b7f8eabbc9a8f5a00754d000a88ac", + "addresses": [ + "QfH9yjB4tEGd8jK1YY4JvXtT5TdaCGX7Rt" + ], + "isAddress": true + } + ], + "blockHash": "ce003cd41af05d06ef406e4798d3d8fc3113ae028336a92e22ea93ab5a73ea4a", + "blockHeight": 390495, + "confirmations": 217042, + "blockTime": 1560449520, + "value": "54999907792", + "valueIn": "55000000000", + "fees": "92208", + "hex": "0100000001b46a15183bf27456c26b83915afbff1b7fa12f7b29fe48cb15fc40be8d543bee010000006a473044022045cd6c3831cb6c0f33b2e3d05940b8205c6293c96f81cfbccc0c29c631dd2a2e0220263bd13fff18d75d45b15f1102118b28001bde09de38f4c5f9c5c5b6f27781c2012102817713bf5592a19279ed887fe88b04173c3844ecc6adf3f75213734b8cecbda4000000000200eeff020a0000001976a9148b4f969602a4579f9c982e7d30c3a06e2f0cacc888acd00f40cb020000001976a914ccdab9a8e80f5c1b7f8eabbc9a8f5a00754d000a88ac00000000" + }, + { + "txid": "1c5aea829cb18e507d3a1eccb99db5744a9ff086ed87cc97d696231954ce7635", + "version": 1, + "vin": [ + { + "txid": "f09b2b7577dbf154f2c027ad8f1bb51e4c9917e809856be513e7b8067f6d888e", + "sequence": 4294967294, + "n": 0, + "addresses": [ + "QZJbNrGT3cZ1J1AEHtgH3JWM7uLBNAejLZ" + ], + "isAddress": true, + "value": "100000000", + "hex": "4730440220009bc2bb9bd0782aa38bfb3e9093d49fdfb31e4067a956adad2f888e9438e06b02206d7c5d60afffdb3685fced33d24ba9a6466a35b3aa933e4b1ffdd6ba8d23d57901210317cfe4e8b0e35f4c2c561921fe019910e3ddbe78d500a8ff546cf1843f723764" + } + ], + "vout": [ + { + "value": "10000000", + "n": 0, + "spent": true, + "hex": "76a9146285651ee6abb6788c39df4ecb89f97345cbfa2588ac", + "addresses": [ + "QVav8YbUUwQq6yFCrkafW79Uv3NUMHT66n" + ], + "isAddress": true + }, + { + "value": "89780102", + "n": 1, + "spent": true, + "hex": "76a914ca1b74b3ae2a8e655487e131dbb820717c20610e88ac", + "addresses": [ + "Qf2dViTrEcWm7CawDDoDduzBrgRL3DnFWH" + ], + "isAddress": true + } + ], + "blockHash": "d61a1de7b586fee13bc44cd3ae0fa0392d6d9d75d7d3c7273481dfa2069eb9ab", + "blockHeight": 369474, + "confirmations": 238063, + "blockTime": 1557440448, + "value": "99780102", + "valueIn": "100000000", + "fees": "219898", + "hex": "01000000018e886d7f06b8e713e56b8509e817994c1eb51b8fad27c0f254f1db77752b9bf0000000006a4730440220009bc2bb9bd0782aa38bfb3e9093d49fdfb31e4067a956adad2f888e9438e06b02206d7c5d60afffdb3685fced33d24ba9a6466a35b3aa933e4b1ffdd6ba8d23d57901210317cfe4e8b0e35f4c2c561921fe019910e3ddbe78d500a8ff546cf1843f723764feffffff0280969800000000001976a9146285651ee6abb6788c39df4ecb89f97345cbfa2588ac86ef5905000000001976a914ca1b74b3ae2a8e655487e131dbb820717c20610e88ac00000000" + }, + { + "txid": "f09b2b7577dbf154f2c027ad8f1bb51e4c9917e809856be513e7b8067f6d888e", + "version": 1, + "vin": [ + { + "txid": "3600156226ed9f04379dcf72795542d9b4de9d88b374b82b825497ff92e52830", + "vout": 1, + "n": 0, + "addresses": [ + "QUN6caK4ZEPLEoA3ZMC2oSR2kf6RCfGA9B" + ], + "isAddress": true, + "value": "109000000", + "hex": "483045022100cf97578c211296f9e3aa8e7718c7ec4a6fc240b46c29216f664fd68fdd81ec5202201a27971ba5e52b758a8295c870f037a67f20aab306a264e6249dd4f61705634401210360e37f3d88db15a76ffdb30179fc3a67e0fa320e8c6a82bbd93a8e40af30d963" + } + ], + "vout": [ + { + "value": "100000000", + "n": 0, + "spent": true, + "hex": "76a9148b4f969602a4579f9c982e7d30c3a06e2f0cacc888ac", + "addresses": [ + "QZJbNrGT3cZ1J1AEHtgH3JWM7uLBNAejLZ" + ], + "isAddress": true + }, + { + "value": "8789820", + "n": 1, + "spent": true, + "hex": "76a91406ee9fbb22cc53a5190b0eddf26ed33d66a6ebfa88ac", + "addresses": [ + "QMEe2LEsZRLjf4UNuxkgMBHwkMB2zJuWjo" + ], + "isAddress": true + } + ], + "blockHash": "c23063e7715537c96898e8fe956bc45c98e0fb17c415ebdbbbb78f3ba8106494", + "blockHeight": 367729, + "confirmations": 239808, + "blockTime": 1557190080, + "value": "108789820", + "valueIn": "109000000", + "fees": "210180", + "hex": "01000000013028e592ff9754822bb874b3889ddeb4d942557972cf9d37049fed2662150036010000006b483045022100cf97578c211296f9e3aa8e7718c7ec4a6fc240b46c29216f664fd68fdd81ec5202201a27971ba5e52b758a8295c870f037a67f20aab306a264e6249dd4f61705634401210360e37f3d88db15a76ffdb30179fc3a67e0fa320e8c6a82bbd93a8e40af30d963000000000200e1f505000000001976a9148b4f969602a4579f9c982e7d30c3a06e2f0cacc888ac3c1f8600000000001976a91406ee9fbb22cc53a5190b0eddf26ed33d66a6ebfa88ac00000000" + } + ] +} diff --git a/mock/ext-api-data/qtum-api_v2_xpub_xpub6CvFuU1yPwHjMekXqgEZjcQy22ZWiKgRUY6yAneNNyk1trZhV6ZBFSY8Vt2wygTXTVHBkfi4n823vm79yiw42w6xTL2UjKyh2W9V88sXoNd__details_txs.json b/mock/ext-api-data/qtum-api_v2_xpub_xpub6CvFuU1yPwHjMekXqgEZjcQy22ZWiKgRUY6yAneNNyk1trZhV6ZBFSY8Vt2wygTXTVHBkfi4n823vm79yiw42w6xTL2UjKyh2W9V88sXoNd__details_txs.json new file mode 100644 index 000000000..e4d220739 --- /dev/null +++ b/mock/ext-api-data/qtum-api_v2_xpub_xpub6CvFuU1yPwHjMekXqgEZjcQy22ZWiKgRUY6yAneNNyk1trZhV6ZBFSY8Vt2wygTXTVHBkfi4n823vm79yiw42w6xTL2UjKyh2W9V88sXoNd__details_txs.json @@ -0,0 +1,1842 @@ +{ + "page": 1, + "totalPages": 1, + "itemsOnPage": 1000, + "address": "xpub6CvFuU1yPwHjMekXqgEZjcQy22ZWiKgRUY6yAneNNyk1trZhV6ZBFSY8Vt2wygTXTVHBkfi4n823vm79yiw42w6xTL2UjKyh2W9V88sXoNd", + "balance": "234243932", + "totalReceived": "79147977228", + "totalSent": "78913733296", + "unconfirmedBalance": "0", + "unconfirmedTxs": 0, + "txs": 38, + "transactions": [ + { + "txid": "fba987ecdac9307827d48776eb808050347b31bbc2ed2dbbc1d957d0c5c5213b", + "version": 1, + "vin": [ + { + "txid": "62438bb658856c3a08b89ca80e199e7031f98956ea86a135f5d6306660230f67", + "sequence": 4294967294, + "n": 0, + "addresses": [ + "QZJbNrGT3cZ1J1AEHtgH3JWM7uLBNAejLZ" + ], + "isAddress": true, + "value": "235357610", + "hex": "48304502210099cd42a938de9b5ab1b5f7770cc99a9b5ab935e63911a13276510e9b1983c107022034f6d45e5ae6ce13b839427b91f2d0d98c7894610d5fe5d7aaa7e1ce2911627e01210317cfe4e8b0e35f4c2c561921fe019910e3ddbe78d500a8ff546cf1843f723764" + } + ], + "vout": [ + { + "value": "1000000", + "n": 0, + "hex": "76a914816e451a8afb6753d6617633cc8d9785fd33599c88ac", + "addresses": [ + "QYQMNjZ7iaJXRJnVAE11MzCFCwre7Fw9qZ" + ], + "isAddress": true + }, + { + "value": "234243932", + "n": 1, + "hex": "76a9148b4f969602a4579f9c982e7d30c3a06e2f0cacc888ac", + "addresses": [ + "QZJbNrGT3cZ1J1AEHtgH3JWM7uLBNAejLZ" + ], + "isAddress": true + } + ], + "blockHash": "bd1c23ed73b801db65cda1e4c576812da2687e6cd71a33d3f03440b15c8d28b3", + "blockHeight": 602733, + "confirmations": 4804, + "blockTime": 1588752224, + "value": "235243932", + "valueIn": "235357610", + "fees": "113678", + "hex": "0100000001670f23606630d6f535a186ea5689f931709e190ea89cb8083a6c8558b68b4362000000006b48304502210099cd42a938de9b5ab1b5f7770cc99a9b5ab935e63911a13276510e9b1983c107022034f6d45e5ae6ce13b839427b91f2d0d98c7894610d5fe5d7aaa7e1ce2911627e01210317cfe4e8b0e35f4c2c561921fe019910e3ddbe78d500a8ff546cf1843f723764feffffff0240420f00000000001976a914816e451a8afb6753d6617633cc8d9785fd33599c88ac5c47f60d000000001976a9148b4f969602a4579f9c982e7d30c3a06e2f0cacc888ac00000000" + }, + { + "txid": "62438bb658856c3a08b89ca80e199e7031f98956ea86a135f5d6306660230f67", + "version": 1, + "vin": [ + { + "txid": "782e18a7b1bf612972e773fd6ccdcbe0c4514c661c31a7942f5dcd4807c5ab68", + "sequence": 4294967293, + "n": 0, + "addresses": [ + "QWLQSMPF5WKAqhXxePJvjUJNjxDHrPCbjB" + ], + "isAddress": true, + "value": "100000", + "hex": "483045022100b660d73ff3bd7cc52d1052b933828cc2bb23b7a94500dff4bf00d5640ff4951702206ac6ecdaf3818dc57d54f8e860bbf212846200ccb2d1a323bf5b59868dcba872012102d7062f4af80f3a31f67c928e141627d807f0641b0bb0d466f4a62ee31230aa1e" + }, + { + "txid": "80b7c6bcba625ad4abb69f7e92521a782681e984982408d40ad35a24b3f78297", + "sequence": 4294967294, + "n": 1, + "addresses": [ + "QgqVXuCCN1m4Hfb9HCkrzbgUSkoodKsrVY" + ], + "isAddress": true, + "value": "100000", + "hex": "48304502210090ea4a4aac51d8734ad9ffecf0e5c14be50a8941b8cac6a492c002a0be99e5e102203550b52b7ad546adf8b1e5ed00b7aa755cc296d4bd61004b2ace43bfe0007d17012103692f9ee47370b3a70e8d7b6ac36c705b2d3296bb37c0f02e15158f3a6001ce5b" + }, + { + "txid": "9c3a6eb9fa07868a2e59530fe2aa3ea29a21d3818a70343097adbe571ee2f0be", + "sequence": 4294967292, + "n": 2, + "addresses": [ + "QSEXLG5qct47UtMHiXNg2Y27KSDSAEHJp9" + ], + "isAddress": true, + "value": "10000000", + "hex": "473044022055806e0939aa734d296ac364d4edf430bcd4fc15a377d35205362d09f7367d8e02202cc4e691c31ece66abb9adcd20bf8e3f500a2254edaaf2c241529cee670972440121025249520b3d48efd435e6cc30c9af238d054461d51f8beeaf75c4de50a647acbc" + }, + { + "txid": "9c3a6eb9fa07868a2e59530fe2aa3ea29a21d3818a70343097adbe571ee2f0be", + "vout": 1, + "sequence": 4294967291, + "n": 3, + "addresses": [ + "Qfw9Poi2c4gGEkAAuVyG21PsBmNGsmZKFC" + ], + "isAddress": true, + "value": "225494620", + "hex": "483045022100e9d2126507af25eed231d27db52794bf6dc67c33800ebafd99b44b13394e1a2d02206b5abdce728114fa75624cd50d70f3c7da77c5b00433fa306b203e4bfb7d96320121020d708ba820b87e195b5790fa2723033cfec259ce5af4270a431cd7297d7704d3" + } + ], + "vout": [ + { + "value": "235357610", + "n": 0, + "spent": true, + "hex": "76a9148b4f969602a4579f9c982e7d30c3a06e2f0cacc888ac", + "addresses": [ + "QZJbNrGT3cZ1J1AEHtgH3JWM7uLBNAejLZ" + ], + "isAddress": true + } + ], + "blockHash": "6e71fa96ca29a6e4cbd10defaa4fc69ff09adec45fc666d82afade3f75206cc1", + "blockHeight": 563426, + "confirmations": 44111, + "blockTime": 1583720608, + "value": "235357610", + "valueIn": "235694620", + "fees": "337010", + "hex": "010000000468abc50748cd5d2f94a7311c664c51c4e0cbcd6cfd73e7722961bfb1a7182e78000000006b483045022100b660d73ff3bd7cc52d1052b933828cc2bb23b7a94500dff4bf00d5640ff4951702206ac6ecdaf3818dc57d54f8e860bbf212846200ccb2d1a323bf5b59868dcba872012102d7062f4af80f3a31f67c928e141627d807f0641b0bb0d466f4a62ee31230aa1efdffffff9782f7b3245ad30ad408249884e98126781a52927e9fb6abd45a62babcc6b780000000006b48304502210090ea4a4aac51d8734ad9ffecf0e5c14be50a8941b8cac6a492c002a0be99e5e102203550b52b7ad546adf8b1e5ed00b7aa755cc296d4bd61004b2ace43bfe0007d17012103692f9ee47370b3a70e8d7b6ac36c705b2d3296bb37c0f02e15158f3a6001ce5bfeffffffbef0e21e57bead973034708a81d3219aa23eaae20f53592e8a8607fab96e3a9c000000006a473044022055806e0939aa734d296ac364d4edf430bcd4fc15a377d35205362d09f7367d8e02202cc4e691c31ece66abb9adcd20bf8e3f500a2254edaaf2c241529cee670972440121025249520b3d48efd435e6cc30c9af238d054461d51f8beeaf75c4de50a647acbcfcffffffbef0e21e57bead973034708a81d3219aa23eaae20f53592e8a8607fab96e3a9c010000006b483045022100e9d2126507af25eed231d27db52794bf6dc67c33800ebafd99b44b13394e1a2d02206b5abdce728114fa75624cd50d70f3c7da77c5b00433fa306b203e4bfb7d96320121020d708ba820b87e195b5790fa2723033cfec259ce5af4270a431cd7297d7704d3fbffffff01aa45070e000000001976a9148b4f969602a4579f9c982e7d30c3a06e2f0cacc888ac00000000" + }, + { + "txid": "9c3a6eb9fa07868a2e59530fe2aa3ea29a21d3818a70343097adbe571ee2f0be", + "version": 1, + "vin": [ + { + "txid": "1d597a91e1810fdbfcb712c11c4776f5384ab4e7bd94a2fdc6538b9afdc1e6d0", + "vout": 1, + "sequence": 4294967292, + "n": 0, + "addresses": [ + "QZsdyvpJnczcDPJoySkNTaSh8VP8XAXeMz" + ], + "isAddress": true, + "value": "235607620", + "hex": "4730440220679ad69958629be2516a0d93457ba24f154fd42e23a4f3f2896272fe97940eed0220395098fa364232f74440e50043d6b2868829cb11faf56057d12f68f4bac82bdc0121036ea9140776d2e6a3ec7dd32b9795b47cf592e90e4159f7db793019b069e78b46" + } + ], + "vout": [ + { + "value": "10000000", + "n": 0, + "spent": true, + "hex": "76a9143dc1aae7701ab1f7be54fc69808c092ddb5a574088ac", + "addresses": [ + "QSEXLG5qct47UtMHiXNg2Y27KSDSAEHJp9" + ], + "isAddress": true + }, + { + "value": "225494620", + "n": 1, + "spent": true, + "hex": "76a914d40a0b271f69b1d2f43f60c540325c9039b4a05588ac", + "addresses": [ + "Qfw9Poi2c4gGEkAAuVyG21PsBmNGsmZKFC" + ], + "isAddress": true + } + ], + "blockHash": "a7a05f41f5f07faa5d3ca2cf5fb7de6a0cf46bc4ee465028ceda72ea5e6b5669", + "blockHeight": 479076, + "confirmations": 128461, + "blockTime": 1572922480, + "value": "235494620", + "valueIn": "235607620", + "fees": "113000", + "hex": "0100000001d0e6c1fd9a8b53c6fda294bde7b44a38f576471cc112b7fcdb0f81e1917a591d010000006a4730440220679ad69958629be2516a0d93457ba24f154fd42e23a4f3f2896272fe97940eed0220395098fa364232f74440e50043d6b2868829cb11faf56057d12f68f4bac82bdc0121036ea9140776d2e6a3ec7dd32b9795b47cf592e90e4159f7db793019b069e78b46fcffffff0280969800000000001976a9143dc1aae7701ab1f7be54fc69808c092ddb5a574088ac5cc6700d000000001976a914d40a0b271f69b1d2f43f60c540325c9039b4a05588ac00000000" + }, + { + "txid": "1d597a91e1810fdbfcb712c11c4776f5384ab4e7bd94a2fdc6538b9afdc1e6d0", + "version": 1, + "vin": [ + { + "txid": "782e18a7b1bf612972e773fd6ccdcbe0c4514c661c31a7942f5dcd4807c5ab68", + "vout": 1, + "n": 0, + "addresses": [ + "QT9VzxtbfiRSHzvGGqVk7XV4KAaSrb6L64" + ], + "isAddress": true, + "value": "245721298", + "hex": "483045022100d72a93beb503651f314d8cc384241142edde4083552c5e4701206fbb511e667602204994bef93808f562025a5f9b1e8f4e6d13a3a3a2f40b242f0e039163ae273d450121026067645fac1c14839ceb89d0c234cf1cb2a6b5a457c2f7784d25497942ec0e24" + } + ], + "vout": [ + { + "value": "10000000", + "n": 0, + "hex": "76a9143e4772f3e2ab9bbda5a0074f060a61161660443888ac", + "addresses": [ + "QSHHbZLJjaBaoUfDga44xX9miUJA29ccAa" + ], + "isAddress": true + }, + { + "value": "235607620", + "n": 1, + "spent": true, + "hex": "76a914918f7d459ed814895ebf60819ae860c514483c7a88ac", + "addresses": [ + "QZsdyvpJnczcDPJoySkNTaSh8VP8XAXeMz" + ], + "isAddress": true + } + ], + "blockHash": "2538360f74c1f5b8ee89ce05c8c09395bb41528853bdf75c532456045452b525", + "blockHeight": 452291, + "confirmations": 155246, + "blockTime": 1569265040, + "value": "245607620", + "valueIn": "245721298", + "fees": "113678", + "hex": "010000000168abc50748cd5d2f94a7311c664c51c4e0cbcd6cfd73e7722961bfb1a7182e78010000006b483045022100d72a93beb503651f314d8cc384241142edde4083552c5e4701206fbb511e667602204994bef93808f562025a5f9b1e8f4e6d13a3a3a2f40b242f0e039163ae273d450121026067645fac1c14839ceb89d0c234cf1cb2a6b5a457c2f7784d25497942ec0e24000000000280969800000000001976a9143e4772f3e2ab9bbda5a0074f060a61161660443888ac44160b0e000000001976a914918f7d459ed814895ebf60819ae860c514483c7a88ac00000000" + }, + { + "txid": "782e18a7b1bf612972e773fd6ccdcbe0c4514c661c31a7942f5dcd4807c5ab68", + "version": 1, + "vin": [ + { + "txid": "80b7c6bcba625ad4abb69f7e92521a782681e984982408d40ad35a24b3f78297", + "vout": 1, + "n": 0, + "addresses": [ + "QZw82ithbXQn6suPSFQJLxRVkCB5K7Lgct" + ], + "isAddress": true, + "value": "246047298", + "hex": "483045022100bebae6823f790dabee59584c40b4ff6f972f4644bf4e5b0568ba37aa1e16d5b602200ef27e41cb3713cebf39c99eab63e6db929ab1661b7a355762586521e7337cc101210226bfcb7cc0017a6467f7a6fb15e5eb6534afd071d2e2f9ab8f7c0165dc716799" + } + ], + "vout": [ + { + "value": "100000", + "n": 0, + "spent": true, + "hex": "76a9146abee92e5a38197d7b84a3bdf0c0ee38fa2b025a88ac", + "addresses": [ + "QWLQSMPF5WKAqhXxePJvjUJNjxDHrPCbjB" + ], + "isAddress": true + }, + { + "value": "245721298", + "n": 1, + "spent": true, + "hex": "76a91447c699e0f98138c82043ec652151d2f96620990f88ac", + "addresses": [ + "QT9VzxtbfiRSHzvGGqVk7XV4KAaSrb6L64" + ], + "isAddress": true + } + ], + "blockHash": "578aaf4f10edb65830fcc6d040750a7b8ea936f9138432a9bac983b4fe38a2d4", + "blockHeight": 441535, + "confirmations": 166002, + "blockTime": 1567735504, + "value": "245821298", + "valueIn": "246047298", + "fees": "226000", + "hex": "01000000019782f7b3245ad30ad408249884e98126781a52927e9fb6abd45a62babcc6b780010000006b483045022100bebae6823f790dabee59584c40b4ff6f972f4644bf4e5b0568ba37aa1e16d5b602200ef27e41cb3713cebf39c99eab63e6db929ab1661b7a355762586521e7337cc101210226bfcb7cc0017a6467f7a6fb15e5eb6534afd071d2e2f9ab8f7c0165dc7167990000000002a0860100000000001976a9146abee92e5a38197d7b84a3bdf0c0ee38fa2b025a88acd268a50e000000001976a91447c699e0f98138c82043ec652151d2f96620990f88ac00000000" + }, + { + "txid": "80b7c6bcba625ad4abb69f7e92521a782681e984982408d40ad35a24b3f78297", + "version": 1, + "vin": [ + { + "txid": "ce4e5b96472dd80cbc89dc9d9e9be23c0375605b9c8c1256ea0541c09fc79c68", + "n": 0, + "addresses": [ + "QUPmkCzWkLtMfWvjKEStpgqMADQjbDhxbn" + ], + "isAddress": true, + "value": "246373298", + "hex": "4730440220506172cf296bc5b7de8da3f840b579bd7b08ba664241b096cf6b4a6206d5fa3002205bc16a044e653605ed225a10c32ebf2fee95f04c216e77cbcfae8be8c36184bc01210255dedfd7fa97011c00833682c70f09ab0b750a5e204c73bcb7233c6bf592fe93" + } + ], + "vout": [ + { + "value": "100000", + "n": 0, + "spent": true, + "hex": "76a914ddf07c38931968ef5540ab424c1911297199a02088ac", + "addresses": [ + "QgqVXuCCN1m4Hfb9HCkrzbgUSkoodKsrVY" + ], + "isAddress": true + }, + { + "value": "246047298", + "n": 1, + "spent": true, + "hex": "76a91492382692505ccb0bae2864b8e878f0f017ffcad888ac", + "addresses": [ + "QZw82ithbXQn6suPSFQJLxRVkCB5K7Lgct" + ], + "isAddress": true + } + ], + "blockHash": "b7d8a4eee2cfc6d7ba0e152a3602f44f81cb34305daea7754e268e312f59da33", + "blockHeight": 441450, + "confirmations": 166087, + "blockTime": 1567723664, + "value": "246147298", + "valueIn": "246373298", + "fees": "226000", + "hex": "0100000001689cc79fc04105ea56128c9c5b6075033ce29b9e9ddc89bc0cd82d47965b4ece000000006a4730440220506172cf296bc5b7de8da3f840b579bd7b08ba664241b096cf6b4a6206d5fa3002205bc16a044e653605ed225a10c32ebf2fee95f04c216e77cbcfae8be8c36184bc01210255dedfd7fa97011c00833682c70f09ab0b750a5e204c73bcb7233c6bf592fe930000000002a0860100000000001976a914ddf07c38931968ef5540ab424c1911297199a02088ac4262aa0e000000001976a91492382692505ccb0bae2864b8e878f0f017ffcad888ac00000000" + }, + { + "txid": "ce4e5b96472dd80cbc89dc9d9e9be23c0375605b9c8c1256ea0541c09fc79c68", + "version": 1, + "vin": [ + { + "txid": "8433c6693d7771c515c5f1fb4e986a519979646b0ad291f6e8285a436eae6e77", + "n": 0, + "addresses": [ + "QLbzywq3JhTyzgMEnuQnAYHLxwXqr1Bv1y" + ], + "isAddress": true, + "value": "9889260", + "hex": "483045022100948d374e9148f549b215ef747fb22cd344b6cdb6250dd40b8fafebad4faa08c302200a5c69c7bbbc8d95aa957c9ba685436a8bc908d6929982a061d316c38382fbad0121035b43e656315335c7ab54661999c9471117234fcf7d37122b13e7563fbf0a0310" + }, + { + "txid": "7ee828de99e80017e210630a730e433dd05133d16efee0a6ebdd94c7140d33b8", + "n": 1, + "addresses": [ + "QhQxEbempk1agy7moRTwtedwciQxmPGqYZ" + ], + "isAddress": true, + "value": "10000000", + "hex": "483045022100af5a18452175a9ea7531428c7438589ef7cd6d1411f5553b8e2a50c7e5f558fc02207e4eb03f44c6b1540fafb7703ba90009c3431ec4c3603defb95e667dd6b5639a012103c9f314eefa81257877d5454256f5274f3e34cfd6130a7c745bd7bf8716a959f3" + }, + { + "txid": "80fe00fff38f8960db42f980bb0e1d163c4ef66c523c0bc8d396bdb8c40d9fde", + "n": 2, + "addresses": [ + "QcZDgRGkqxQGRZwpEhE2yGQbtwPMrKftcr" + ], + "isAddress": true, + "value": "99905728", + "hex": "47304402205819d69e0fe9c289379503c10db60f7452940885e3392e2d701db736ac7081b402202164e3de6275ecb9a5213f6fa3910e2cf6d3f72f31fdc7ba189bb121e8d8c27a0121034de1f3056ca8955db8c603d111a50f385199a2a5c386bd4bd270f22130fa4ba3" + }, + { + "txid": "151bfd09793a61e570a10e2e9a255b67687555dc7d042244bd84d5342dd75a96", + "vout": 1, + "n": 3, + "addresses": [ + "Qa9QnPPQkXuATT1oftnMxfk3yDbC6PeCvC" + ], + "isAddress": true, + "value": "127214310", + "hex": "483045022100e9ff37e8464654e16810047ff39504a5073996c2b74f3f0b766f836af42ac07b022045b8ac22c407e7f4a8ee146c07d612bc77bbeeaafc4bad58a7c9cc67c2b3ffb9012103437362508cfb7dba11a47eeb7c7ec016a2419c1212fb8c554fd27c9b5b0980b6" + } + ], + "vout": [ + { + "value": "246373298", + "n": 0, + "spent": true, + "hex": "76a9145571b1af28985745be76ab7d17ba22041707ae0e88ac", + "addresses": [ + "QUPmkCzWkLtMfWvjKEStpgqMADQjbDhxbn" + ], + "isAddress": true + } + ], + "blockHash": "262401097f9ff78c40407e583661ac67be2eba9f0f19b01de2a141083e079cb1", + "blockHeight": 439829, + "confirmations": 167708, + "blockTime": 1567495648, + "value": "246373298", + "valueIn": "247009298", + "fees": "636000", + "hex": "0100000004776eae6e435a28e8f691d20a6b647999516a984efbf1c515c571773d69c63384000000006b483045022100948d374e9148f549b215ef747fb22cd344b6cdb6250dd40b8fafebad4faa08c302200a5c69c7bbbc8d95aa957c9ba685436a8bc908d6929982a061d316c38382fbad0121035b43e656315335c7ab54661999c9471117234fcf7d37122b13e7563fbf0a031000000000b8330d14c794ddeba6e0fe6ed13351d03d430e730a6310e21700e899de28e87e000000006b483045022100af5a18452175a9ea7531428c7438589ef7cd6d1411f5553b8e2a50c7e5f558fc02207e4eb03f44c6b1540fafb7703ba90009c3431ec4c3603defb95e667dd6b5639a012103c9f314eefa81257877d5454256f5274f3e34cfd6130a7c745bd7bf8716a959f300000000de9f0dc4b8bd96d3c80b3c526cf64e3c161d0ebb80f942db60898ff3ff00fe80000000006a47304402205819d69e0fe9c289379503c10db60f7452940885e3392e2d701db736ac7081b402202164e3de6275ecb9a5213f6fa3910e2cf6d3f72f31fdc7ba189bb121e8d8c27a0121034de1f3056ca8955db8c603d111a50f385199a2a5c386bd4bd270f22130fa4ba300000000965ad72d34d584bd4422047ddc557568675b259a2e0ea170e5613a7909fd1b15010000006b483045022100e9ff37e8464654e16810047ff39504a5073996c2b74f3f0b766f836af42ac07b022045b8ac22c407e7f4a8ee146c07d612bc77bbeeaafc4bad58a7c9cc67c2b3ffb9012103437362508cfb7dba11a47eeb7c7ec016a2419c1212fb8c554fd27c9b5b0980b60000000001b25baf0e000000001976a9145571b1af28985745be76ab7d17ba22041707ae0e88ac00000000" + }, + { + "txid": "80fe00fff38f8960db42f980bb0e1d163c4ef66c523c0bc8d396bdb8c40d9fde", + "version": 1, + "vin": [ + { + "txid": "151bfd09793a61e570a10e2e9a255b67687555dc7d042244bd84d5342dd75a96", + "sequence": 4294967294, + "n": 0, + "addresses": [ + "QS9jjFyKa7vKVAvvQk68sk29Cq2kvrK1Hq" + ], + "isAddress": true, + "value": "100000000", + "hex": "47304402205e7d194cc6e73636ecf5765ece58ae05b2c96fd9d5b798e4fb7d187a9e80febb022003e50c9b0158a85ab9d26a0646d19331b7df0ab2bc0da2c481fbc883c83f922d0121032ea5359007513b35753e5221dddc38b063db93a187d2cbf6789a01dfc84611fc" + } + ], + "vout": [ + { + "value": "99905728", + "n": 0, + "spent": true, + "hex": "76a914aefc17db4cd14c4d9164c776ecd87bbeb4bd89fe88ac", + "addresses": [ + "QcZDgRGkqxQGRZwpEhE2yGQbtwPMrKftcr" + ], + "isAddress": true + } + ], + "blockHash": "8e030c2397afaf82a09af90c1e1efb689e3c7c47f1d8c2ebba09bd96992c1ef9", + "blockHeight": 429870, + "confirmations": 177667, + "blockTime": 1566071072, + "value": "99905728", + "valueIn": "100000000", + "fees": "94272", + "hex": "0100000001965ad72d34d584bd4422047ddc557568675b259a2e0ea170e5613a7909fd1b15000000006a47304402205e7d194cc6e73636ecf5765ece58ae05b2c96fd9d5b798e4fb7d187a9e80febb022003e50c9b0158a85ab9d26a0646d19331b7df0ab2bc0da2c481fbc883c83f922d0121032ea5359007513b35753e5221dddc38b063db93a187d2cbf6789a01dfc84611fcfeffffff01c070f405000000001976a914aefc17db4cd14c4d9164c776ecd87bbeb4bd89fe88ac00000000" + }, + { + "txid": "151bfd09793a61e570a10e2e9a255b67687555dc7d042244bd84d5342dd75a96", + "version": 1, + "vin": [ + { + "txid": "abcfcb76238977f7a456a86c9fb4dbcff9da781db93b2992c40d4a2e97a2b2a1", + "vout": 1, + "n": 0, + "addresses": [ + "QcZDgRGkqxQGRZwpEhE2yGQbtwPMrKftcr" + ], + "isAddress": true, + "value": "227440310", + "hex": "483045022100f133955b319de6ee167d49f77dbe49869206b27815b8a196a33162039c0eb28002206ad29c34667078876547fedbd35d9f9b3a5d45022d12a40deef0c3ebc293d2340121034de1f3056ca8955db8c603d111a50f385199a2a5c386bd4bd270f22130fa4ba3" + } + ], + "vout": [ + { + "value": "100000000", + "n": 0, + "spent": true, + "hex": "76a9143cd9ef95a8f822932f2afb20993dd4325c42123288ac", + "addresses": [ + "QS9jjFyKa7vKVAvvQk68sk29Cq2kvrK1Hq" + ], + "isAddress": true + }, + { + "value": "127214310", + "n": 1, + "spent": true, + "hex": "76a914948b207393388b47023f5561f2d21235cb31bb7788ac", + "addresses": [ + "Qa9QnPPQkXuATT1oftnMxfk3yDbC6PeCvC" + ], + "isAddress": true + } + ], + "blockHash": "a295d2da8738dcb13ae2e23041fdba6c6b18b3e5ab8bd0ea73d8e131170b5cb1", + "blockHeight": 429869, + "confirmations": 177668, + "blockTime": 1566070960, + "value": "227214310", + "valueIn": "227440310", + "fees": "226000", + "hex": "0100000001a1b2a2972e4a0dc492293bb91d78daf9cfdbb49f6ca856a4f777892376cbcfab010000006b483045022100f133955b319de6ee167d49f77dbe49869206b27815b8a196a33162039c0eb28002206ad29c34667078876547fedbd35d9f9b3a5d45022d12a40deef0c3ebc293d2340121034de1f3056ca8955db8c603d111a50f385199a2a5c386bd4bd270f22130fa4ba3000000000200e1f505000000001976a9143cd9ef95a8f822932f2afb20993dd4325c42123288ace6229507000000001976a914948b207393388b47023f5561f2d21235cb31bb7788ac00000000" + }, + { + "txid": "8433c6693d7771c515c5f1fb4e986a519979646b0ad291f6e8285a436eae6e77", + "version": 1, + "vin": [ + { + "txid": "abcfcb76238977f7a456a86c9fb4dbcff9da781db93b2992c40d4a2e97a2b2a1", + "sequence": 4294967294, + "n": 0, + "addresses": [ + "QYQMNjZ7iaJXRJnVAE11MzCFCwre7Fw9qZ" + ], + "isAddress": true, + "value": "10000000", + "hex": "483045022100cc9a5ea14c568d646ca12debf9ebbe52c18c9521c3a56d3c1c68072302d0033c0220030de3c9fa1cb9d731616a204a34db259600d643bbb8536d60647aab3c9c3e340121028417e67c7627b28deb97d9eba306f60ad9f56f28ab9c2918ffb4f9cb1655131c" + } + ], + "vout": [ + { + "value": "9889260", + "n": 0, + "spent": true, + "hex": "76a9140000ba9b707dd9aa3aa14174cea6c42ac0d7478a88ac", + "addresses": [ + "QLbzywq3JhTyzgMEnuQnAYHLxwXqr1Bv1y" + ], + "isAddress": true + } + ], + "blockHash": "d117c8f87bf1328d993b6b5578bb69add612b98a289c3802637c16644f85177d", + "blockHeight": 399982, + "confirmations": 207555, + "blockTime": 1561806784, + "value": "9889260", + "valueIn": "10000000", + "fees": "110740", + "hex": "0100000001a1b2a2972e4a0dc492293bb91d78daf9cfdbb49f6ca856a4f777892376cbcfab000000006b483045022100cc9a5ea14c568d646ca12debf9ebbe52c18c9521c3a56d3c1c68072302d0033c0220030de3c9fa1cb9d731616a204a34db259600d643bbb8536d60647aab3c9c3e340121028417e67c7627b28deb97d9eba306f60ad9f56f28ab9c2918ffb4f9cb1655131cfeffffff01ece59600000000001976a9140000ba9b707dd9aa3aa14174cea6c42ac0d7478a88ac00000000" + }, + { + "txid": "abcfcb76238977f7a456a86c9fb4dbcff9da781db93b2992c40d4a2e97a2b2a1", + "version": 1, + "vin": [ + { + "txid": "7ee828de99e80017e210630a730e433dd05133d16efee0a6ebdd94c7140d33b8", + "vout": 1, + "sequence": 4294967293, + "n": 0, + "addresses": [ + "QMyP1kj8x2bPiC3Yrirv5wChafRvCdgqVR" + ], + "isAddress": true, + "value": "237551050", + "hex": "47304402201899d3b36561a2472a37061a706c31da8b37725591ede822da40a5b58b469af602206a8eaa1141badd3cdad6a559a39ecf5f74aba459cadd41b10cf7b8ab8246b9be012103bbaedda0fc7212f6ae36c6f118ceaad821693b68b9016b25e85b0e1d320abedb" + } + ], + "vout": [ + { + "value": "10000000", + "n": 0, + "spent": true, + "hex": "76a914816e451a8afb6753d6617633cc8d9785fd33599c88ac", + "addresses": [ + "QYQMNjZ7iaJXRJnVAE11MzCFCwre7Fw9qZ" + ], + "isAddress": true + }, + { + "value": "227440310", + "n": 1, + "spent": true, + "hex": "76a914aefc17db4cd14c4d9164c776ecd87bbeb4bd89fe88ac", + "addresses": [ + "QcZDgRGkqxQGRZwpEhE2yGQbtwPMrKftcr" + ], + "isAddress": true + } + ], + "blockHash": "869311ff5fd04b0786f93c18e556cc01f229e29eb7ae049977454b770150efbb", + "blockHeight": 399839, + "confirmations": 207698, + "blockTime": 1561786736, + "value": "237440310", + "valueIn": "237551050", + "fees": "110740", + "hex": "0100000001b8330d14c794ddeba6e0fe6ed13351d03d430e730a6310e21700e899de28e87e010000006a47304402201899d3b36561a2472a37061a706c31da8b37725591ede822da40a5b58b469af602206a8eaa1141badd3cdad6a559a39ecf5f74aba459cadd41b10cf7b8ab8246b9be012103bbaedda0fc7212f6ae36c6f118ceaad821693b68b9016b25e85b0e1d320abedbfdffffff0280969800000000001976a914816e451a8afb6753d6617633cc8d9785fd33599c88acb6768e0d000000001976a914aefc17db4cd14c4d9164c776ecd87bbeb4bd89fe88ac00000000" + }, + { + "txid": "7ee828de99e80017e210630a730e433dd05133d16efee0a6ebdd94c7140d33b8", + "version": 1, + "vin": [ + { + "txid": "672cec4ecac82121424347aa17af0cee984cd62c77bb1f38d100acc200377b92", + "n": 0, + "addresses": [ + "QUFxdPbEwYK119NiorpWMR64yaQb8sdFJv" + ], + "isAddress": true, + "value": "247661790", + "hex": "463043021f01f8f944c31521e2be368f04c007e1bd54c204676ead74ec17e740f58ed7b302200707f009a240c94348bedf3861e816fac3498fefc1f5740d9f21ac12d951f441012103361b872338e22f1813d052d3244aec7df9a0b06540ba3b701e2e454ca3fd70fc" + } + ], + "vout": [ + { + "value": "10000000", + "n": 0, + "spent": true, + "hex": "76a914e444805cfdf15b96b60952475723969e9322126588ac", + "addresses": [ + "QhQxEbempk1agy7moRTwtedwciQxmPGqYZ" + ], + "isAddress": true + }, + { + "value": "237551050", + "n": 1, + "spent": true, + "hex": "76a9140f03fb09f60fa04543e1d448ebd9610d4fa6876488ac", + "addresses": [ + "QMyP1kj8x2bPiC3Yrirv5wChafRvCdgqVR" + ], + "isAddress": true + } + ], + "blockHash": "9cdb9e6de87027fe2361d943701d28824265a99af193fa592e82c84cf0883d44", + "blockHeight": 399714, + "confirmations": 207823, + "blockTime": 1561769088, + "value": "247551050", + "valueIn": "247661790", + "fees": "110740", + "hex": "0100000001927b3700c2ac00d1381fbb772cd64c98ee0caf17aa4743422121c8ca4eec2c670000000069463043021f01f8f944c31521e2be368f04c007e1bd54c204676ead74ec17e740f58ed7b302200707f009a240c94348bedf3861e816fac3498fefc1f5740d9f21ac12d951f441012103361b872338e22f1813d052d3244aec7df9a0b06540ba3b701e2e454ca3fd70fc000000000280969800000000001976a914e444805cfdf15b96b60952475723969e9322126588accabd280e000000001976a9140f03fb09f60fa04543e1d448ebd9610d4fa6876488ac00000000" + }, + { + "txid": "672cec4ecac82121424347aa17af0cee984cd62c77bb1f38d100acc200377b92", + "version": 1, + "vin": [ + { + "txid": "7c3dd204f1f1b4ebb4a25e50f045123c718c296d5e2ffd5e0ad6a595c941a4b5", + "n": 0, + "addresses": [ + "QTQzku6DnxmwY7auEpZ5ReWhkpCyDb6SCY" + ], + "isAddress": true, + "value": "247755870", + "hex": "483045022100918f5efd86345de92d939572f92207e86afbc0c37a5c2cc1b5842b9ce192da0c02206bb03600e9fb1a32588093cb84ebef61a15c2e0e49499a08b85f79dac6c27d79012103c450d0f844424f8315166aba49a33ad036b7387e6b7d97568bcf71ccaac33fe9" + } + ], + "vout": [ + { + "value": "247661790", + "n": 0, + "spent": true, + "hex": "76a91453f7735ae364912de8ba1e98700f1e6b0211da0e88ac", + "addresses": [ + "QUFxdPbEwYK119NiorpWMR64yaQb8sdFJv" + ], + "isAddress": true + } + ], + "blockHash": "e1cbfe22ed9777c979c4703bb84dc7d7b957df927cb8dd71c79ba300c9f6beef", + "blockHeight": 399654, + "confirmations": 207883, + "blockTime": 1561760288, + "value": "247661790", + "valueIn": "247755870", + "fees": "94080", + "hex": "0100000001b5a441c995a5d60a5efd2f5e6d298c713c1245f0505ea2b4ebb4f1f104d23d7c000000006b483045022100918f5efd86345de92d939572f92207e86afbc0c37a5c2cc1b5842b9ce192da0c02206bb03600e9fb1a32588093cb84ebef61a15c2e0e49499a08b85f79dac6c27d79012103c450d0f844424f8315166aba49a33ad036b7387e6b7d97568bcf71ccaac33fe90000000001de04c30e000000001976a91453f7735ae364912de8ba1e98700f1e6b0211da0e88ac00000000" + }, + { + "txid": "7c3dd204f1f1b4ebb4a25e50f045123c718c296d5e2ffd5e0ad6a595c941a4b5", + "version": 1, + "vin": [ + { + "txid": "72fbc53fb360cc0620d8ba7afa3962fcf262c3484d7a0717dc1585df3d26516e", + "vout": 1, + "sequence": 4294967293, + "n": 0, + "addresses": [ + "Qffiov6Qpv2mguHJ8w1EgGWtCbE7JT5Th5" + ], + "isAddress": true, + "value": "4909600", + "hex": "47304402205049e57262c1774be9ad3ed35ef6986700c33f440e794be55dd451ddcc0f73ae02207bd1988f5fe5e27efd2e30400b3c99460489c11c73e5ae688f73ecf1b8e00098012103f0aaded07fe7d6fa752e7df6ae09df638192f0865bfb3388dfe8fd57682103e1" + }, + { + "txid": "233b7b7648a38b3d362f21c675ae5d3bd9109715639007131d45c83466fea7e7", + "sequence": 4294967294, + "n": 1, + "addresses": [ + "QUVMiuKoMV8aoTcU2YvJysRbQK7WZb7sCr" + ], + "isAddress": true, + "value": "242992878", + "hex": "47304402203b014a9e9d45b0479c0c270ed98fb7ceb1930e3f9f54447a910f611a3d3e188c022050764a1c4b02a51301aab97f8b1ee5be73fae74a5538c2a1367d254015e8b96601210224e25c02201d7e39527f5f271b01185d1a718f9af3da52a8fe3f5cec796c40e1" + } + ], + "vout": [ + { + "value": "247755870", + "n": 0, + "spent": true, + "hex": "76a9144ab4d8976ea36f098e46686c1edf953a443f957b88ac", + "addresses": [ + "QTQzku6DnxmwY7auEpZ5ReWhkpCyDb6SCY" + ], + "isAddress": true + } + ], + "blockHash": "427bb2df63e8b9ee5099cfd129143acd785bce0d824b58b69615f39226f783d4", + "blockHeight": 398295, + "confirmations": 209242, + "blockTime": 1561566016, + "value": "247755870", + "valueIn": "247902478", + "fees": "146608", + "hex": "01000000026e51263ddf8515dc17077a4d48c362f2fc6239fa7abad82006cc60b33fc5fb72010000006a47304402205049e57262c1774be9ad3ed35ef6986700c33f440e794be55dd451ddcc0f73ae02207bd1988f5fe5e27efd2e30400b3c99460489c11c73e5ae688f73ecf1b8e00098012103f0aaded07fe7d6fa752e7df6ae09df638192f0865bfb3388dfe8fd57682103e1fdffffffe7a7fe6634c8451d13079063159710d93b5dae75c6212f363d8ba348767b3b23000000006a47304402203b014a9e9d45b0479c0c270ed98fb7ceb1930e3f9f54447a910f611a3d3e188c022050764a1c4b02a51301aab97f8b1ee5be73fae74a5538c2a1367d254015e8b96601210224e25c02201d7e39527f5f271b01185d1a718f9af3da52a8fe3f5cec796c40e1feffffff015e74c40e000000001976a9144ab4d8976ea36f098e46686c1edf953a443f957b88ac00000000" + }, + { + "txid": "72fbc53fb360cc0620d8ba7afa3962fcf262c3484d7a0717dc1585df3d26516e", + "version": 1, + "vin": [ + { + "txid": "b7b6dd1d0a79f8d982d61d857445bdd05b4b7786b87445148071656f0aa23342", + "n": 0, + "addresses": [ + "QePvvosxwadDcnJZDrsfDikJrs4ZgbZniR" + ], + "isAddress": true, + "value": "10000000", + "hex": "483045022100be31157bea8b8540a84f212427e8d167186d15d10f60e1b6c6f0f4a1513204280220194848b7d3c1633ef113df3affab3432bc69ce7d7c3ce150da448f824724aed8012102b7526f57a2a1a25c8fac4ea88991162d0e11402bc9b6a147b7328345e5748a53" + } + ], + "vout": [ + { + "value": "5000000", + "n": 0, + "spent": true, + "hex": "76a9148890ed0efb68ed04eb8c29a2615eac20c44f13c188ac", + "addresses": [ + "QZ45d2KP5wXCh8BrPXG8u71Ewxjh2m4hmi" + ], + "isAddress": true + }, + { + "value": "4909600", + "n": 1, + "spent": true, + "hex": "76a914d11f483db486c73246c7d78a56282ae92594356a88ac", + "addresses": [ + "Qffiov6Qpv2mguHJ8w1EgGWtCbE7JT5Th5" + ], + "isAddress": true + } + ], + "blockHash": "76416e44f8a26cd0effeb92f16c8e75a71b15e42cd14c0c0b8e7678b51c14d44", + "blockHeight": 398206, + "confirmations": 209331, + "blockTime": 1561553136, + "value": "9909600", + "valueIn": "10000000", + "fees": "90400", + "hex": "01000000014233a20a6f657180144574b886774b5bd0bd4574851dd682d9f8790a1dddb6b7000000006b483045022100be31157bea8b8540a84f212427e8d167186d15d10f60e1b6c6f0f4a1513204280220194848b7d3c1633ef113df3affab3432bc69ce7d7c3ce150da448f824724aed8012102b7526f57a2a1a25c8fac4ea88991162d0e11402bc9b6a147b7328345e5748a530000000002404b4c00000000001976a9148890ed0efb68ed04eb8c29a2615eac20c44f13c188ac20ea4a00000000001976a914d11f483db486c73246c7d78a56282ae92594356a88ac00000000" + }, + { + "txid": "b7b6dd1d0a79f8d982d61d857445bdd05b4b7786b87445148071656f0aa23342", + "version": 1, + "vin": [ + { + "txid": "ef3b2f934b96df6d11d327710b1f18bc146b1eb420fa73ad17f068d0ce751f7e", + "n": 0, + "addresses": [ + "QV1LG9Wntr3JQKUSodXwaUojLG1DLVfCnT" + ], + "isAddress": true, + "value": "45600000", + "hex": "483045022100a25f1466a3680826f46ccf38f4fbd99185a696106fa479b545da5059c9d950c602200a0dc3f696040685cc9b391d1a7ac4508c1987aac130776f957323ca97b5dcf0012103a3fceb1dba0f312cfdb0c87e3f5409ae502e2748a3af990659ceeb0924b757d8" + } + ], + "vout": [ + { + "value": "10000000", + "n": 0, + "spent": true, + "hex": "76a914c32a9e08a1d9178e68c3d067d228e48705d4268c88ac", + "addresses": [ + "QePvvosxwadDcnJZDrsfDikJrs4ZgbZniR" + ], + "isAddress": true + }, + { + "value": "35509600", + "n": 1, + "spent": true, + "hex": "76a91402ad7daabbda4deae283b97ab080852d36ed39b288ac", + "addresses": [ + "QLr9J3K3wbzxRYobsSLj7s2xvMwnCsHpLc" + ], + "isAddress": true + } + ], + "blockHash": "366d09f073da682b518e15da7c19dfc5abe4ed574353895b8a0c3d25a8a998ca", + "blockHeight": 398193, + "confirmations": 209344, + "blockTime": 1561551200, + "value": "45509600", + "valueIn": "45600000", + "fees": "90400", + "hex": "01000000017e1f75ced068f017ad73fa20b41e6b14bc181f0b7127d3116ddf964b932f3bef000000006b483045022100a25f1466a3680826f46ccf38f4fbd99185a696106fa479b545da5059c9d950c602200a0dc3f696040685cc9b391d1a7ac4508c1987aac130776f957323ca97b5dcf0012103a3fceb1dba0f312cfdb0c87e3f5409ae502e2748a3af990659ceeb0924b757d8000000000280969800000000001976a914c32a9e08a1d9178e68c3d067d228e48705d4268c88ac60d51d02000000001976a91402ad7daabbda4deae283b97ab080852d36ed39b288ac00000000" + }, + { + "txid": "233b7b7648a38b3d362f21c675ae5d3bd9109715639007131d45c83466fea7e7", + "version": 1, + "vin": [ + { + "txid": "ef3b2f934b96df6d11d327710b1f18bc146b1eb420fa73ad17f068d0ce751f7e", + "vout": 1, + "sequence": 4294967294, + "n": 0, + "addresses": [ + "QZ2VsubSNp9X9KbXCmwixzuRsFRZRi83Hb" + ], + "isAddress": true, + "value": "44308018", + "hex": "48304502210091da65c9c91407f0ec5fd3e6bc293e64d731f645e4f11ad2d8f5ed923e364dd902202c9e3bb8c2739f4b938d4c48804cd31db13a4397cae80800c98a98d59e59ba6a012102ca5ca40559a929d01cae26d3a591dc9d2baa4d90e8f9054b7884e5fdb1491f4b" + }, + { + "txid": "ef335bef783551cb054acd220555f1588cc4b03c0f47cc0839220c81d3ceb88d", + "vout": 1, + "sequence": 4294967293, + "n": 1, + "addresses": [ + "QdfcTR3TQHjGHcKLiHmiPLRfVPFRWazJPg" + ], + "isAddress": true, + "value": "198831468", + "hex": "483045022100855f6ffbd4720594a8d1fc881166b96faea86d25e8037bb502a7bafa74ea64b302201bf166370062e1fda50142ace2fb35f6ce1bac9f23a242483ae6a6036baf0ce0012103eacf72d93e33e03143ef74989f8d3299f30504d6fdd5ec5d5ff0da9251dd3a16" + } + ], + "vout": [ + { + "value": "242992878", + "n": 0, + "spent": true, + "hex": "76a9145680230ab546f13b6ba46d3d0d8dfaa39194886588ac", + "addresses": [ + "QUVMiuKoMV8aoTcU2YvJysRbQK7WZb7sCr" + ], + "isAddress": true + } + ], + "blockHash": "256af676be21e85a05e3da797466ce3cade2eb0ddae11fecea1254ba75a7542a", + "blockHeight": 398165, + "confirmations": 209372, + "blockTime": 1561547200, + "value": "242992878", + "valueIn": "243139486", + "fees": "146608", + "hex": "01000000027e1f75ced068f017ad73fa20b41e6b14bc181f0b7127d3116ddf964b932f3bef010000006b48304502210091da65c9c91407f0ec5fd3e6bc293e64d731f645e4f11ad2d8f5ed923e364dd902202c9e3bb8c2739f4b938d4c48804cd31db13a4397cae80800c98a98d59e59ba6a012102ca5ca40559a929d01cae26d3a591dc9d2baa4d90e8f9054b7884e5fdb1491f4bfeffffff8db8ced3810c223908cc470f3cb0c48c58f1550522cd4a05cb513578ef5b33ef010000006b483045022100855f6ffbd4720594a8d1fc881166b96faea86d25e8037bb502a7bafa74ea64b302201bf166370062e1fda50142ace2fb35f6ce1bac9f23a242483ae6a6036baf0ce0012103eacf72d93e33e03143ef74989f8d3299f30504d6fdd5ec5d5ff0da9251dd3a16fdffffff01eec67b0e000000001976a9145680230ab546f13b6ba46d3d0d8dfaa39194886588ac00000000" + }, + { + "txid": "ef335bef783551cb054acd220555f1588cc4b03c0f47cc0839220c81d3ceb88d", + "version": 1, + "vin": [ + { + "txid": "506d07570d75914d5bd319d591374fb9cd1633f5c8b3cc800387e104298e8a62", + "vout": 1, + "sequence": 4294967294, + "n": 0, + "addresses": [ + "QfLtauKWxzF6pDf2ceXJe5oqizNHVMBneH" + ], + "isAddress": true, + "value": "198984808", + "hex": "4830450221008676b34896a922ac913b0922319f98ab4bb5223f479c19d62b92f0f187b2759d02204e6c2f57337f9b3ef262e2262b3e04a971635c450fbe4278db8b2b25e5a816540121027f67fba269482ce4eecfbcc31e7acefaf17a8cb3b4f7ccfb5447c71688e1081e" + }, + { + "txid": "e22c3e2ea4d285b71a73c41cdbb51f7c75d80b6f473e7f4aade6df5bf8771942", + "sequence": 4294967292, + "n": 1, + "addresses": [ + "QZJbNrGT3cZ1J1AEHtgH3JWM7uLBNAejLZ" + ], + "isAddress": true, + "value": "43000000000", + "hex": "483045022100e33513c3a4251a92af231c1d3e3bec9d13be2289c1fb203cb0096c6c073a8b840220206f696ee4e38da215f0b1e2c9d2005f085b8bb967d030caa70439046df64d4601210317cfe4e8b0e35f4c2c561921fe019910e3ddbe78d500a8ff546cf1843f723764" + } + ], + "vout": [ + { + "value": "43000000000", + "n": 0, + "spent": true, + "hex": "76a91455c89563888363b725aa0ebd8191a2e9ea54474d88ac", + "addresses": [ + "QURZqPoBfuXXoHDkCHCvhGJa1DP2Ahj1KX" + ], + "isAddress": true + }, + { + "value": "198831468", + "n": 1, + "spent": true, + "hex": "76a914bb29ba1df86d8507e0de32f187fe401cc3817fc388ac", + "addresses": [ + "QdfcTR3TQHjGHcKLiHmiPLRfVPFRWazJPg" + ], + "isAddress": true + } + ], + "blockHash": "918141389623f4f880b1ba279bb70ee91de6a005e1a9d523d21a66e8c55f0502", + "blockHeight": 393505, + "confirmations": 214032, + "blockTime": 1560879520, + "value": "43198831468", + "valueIn": "43198984808", + "fees": "153340", + "hex": "0100000002628a8e2904e1870380ccb3c8f53316cdb94f3791d519d35b4d91750d57076d50010000006b4830450221008676b34896a922ac913b0922319f98ab4bb5223f479c19d62b92f0f187b2759d02204e6c2f57337f9b3ef262e2262b3e04a971635c450fbe4278db8b2b25e5a816540121027f67fba269482ce4eecfbcc31e7acefaf17a8cb3b4f7ccfb5447c71688e1081efeffffff421977f85bdfe6ad4a7f3e476f0bd8757c1fb5db1cc4731ab785d2a42e3e2ce2000000006b483045022100e33513c3a4251a92af231c1d3e3bec9d13be2289c1fb203cb0096c6c073a8b840220206f696ee4e38da215f0b1e2c9d2005f085b8bb967d030caa70439046df64d4601210317cfe4e8b0e35f4c2c561921fe019910e3ddbe78d500a8ff546cf1843f723764fcffffff0200eeff020a0000001976a91455c89563888363b725aa0ebd8191a2e9ea54474d88ac6cedd90b000000001976a914bb29ba1df86d8507e0de32f187fe401cc3817fc388ac00000000" + }, + { + "txid": "e22c3e2ea4d285b71a73c41cdbb51f7c75d80b6f473e7f4aade6df5bf8771942", + "version": 1, + "vin": [ + { + "txid": "ee3b548dbe40fc15cb48fe297b2fa17f1bfffb5a91836bc25674f23b18156ab4", + "vout": 1, + "n": 0, + "addresses": [ + "QZsgcV5SxtrCxjyP5mXAmVosMKrxbEWFfL" + ], + "isAddress": true, + "value": "55000000000", + "hex": "473044022045cd6c3831cb6c0f33b2e3d05940b8205c6293c96f81cfbccc0c29c631dd2a2e0220263bd13fff18d75d45b15f1102118b28001bde09de38f4c5f9c5c5b6f27781c2012102817713bf5592a19279ed887fe88b04173c3844ecc6adf3f75213734b8cecbda4" + } + ], + "vout": [ + { + "value": "43000000000", + "n": 0, + "spent": true, + "hex": "76a9148b4f969602a4579f9c982e7d30c3a06e2f0cacc888ac", + "addresses": [ + "QZJbNrGT3cZ1J1AEHtgH3JWM7uLBNAejLZ" + ], + "isAddress": true + }, + { + "value": "11999907792", + "n": 1, + "spent": true, + "hex": "76a914ccdab9a8e80f5c1b7f8eabbc9a8f5a00754d000a88ac", + "addresses": [ + "QfH9yjB4tEGd8jK1YY4JvXtT5TdaCGX7Rt" + ], + "isAddress": true + } + ], + "blockHash": "ce003cd41af05d06ef406e4798d3d8fc3113ae028336a92e22ea93ab5a73ea4a", + "blockHeight": 390495, + "confirmations": 217042, + "blockTime": 1560449520, + "value": "54999907792", + "valueIn": "55000000000", + "fees": "92208", + "hex": "0100000001b46a15183bf27456c26b83915afbff1b7fa12f7b29fe48cb15fc40be8d543bee010000006a473044022045cd6c3831cb6c0f33b2e3d05940b8205c6293c96f81cfbccc0c29c631dd2a2e0220263bd13fff18d75d45b15f1102118b28001bde09de38f4c5f9c5c5b6f27781c2012102817713bf5592a19279ed887fe88b04173c3844ecc6adf3f75213734b8cecbda4000000000200eeff020a0000001976a9148b4f969602a4579f9c982e7d30c3a06e2f0cacc888acd00f40cb020000001976a914ccdab9a8e80f5c1b7f8eabbc9a8f5a00754d000a88ac00000000" + }, + { + "txid": "ef3b2f934b96df6d11d327710b1f18bc146b1eb420fa73ad17f068d0ce751f7e", + "version": 1, + "vin": [ + { + "txid": "f81a7df95b23bdf45b8c575d07199cb7c3e46e84704412174c0eb38820459311", + "n": 0, + "addresses": [ + "QeUBhueTQt35s4BMRWvPcX3RCguSe2Ghf1" + ], + "isAddress": true, + "value": "90000000", + "hex": "47304402200ea13a1f081a5176d5c3ab8fcbc1b494fc0645fa0841fa354572487054ed95ee02200d0fd71fd6cf3031b86e15dafedc7ff85ca6f03412822c4c2a1e97c08a01f293012103a5acc1412252845944273732db657873b8241d005cdc8b7133636b4399d45b51" + } + ], + "vout": [ + { + "value": "45600000", + "n": 0, + "spent": true, + "hex": "76a9145c2b655a026e05d034505a47671a5a66cf3b1df688ac", + "addresses": [ + "QV1LG9Wntr3JQKUSodXwaUojLG1DLVfCnT" + ], + "isAddress": true + }, + { + "value": "44308018", + "n": 1, + "spent": true, + "hex": "76a914884457adbc0ff5a2007f43075c0414dd0753b5ec88ac", + "addresses": [ + "QZ2VsubSNp9X9KbXCmwixzuRsFRZRi83Hb" + ], + "isAddress": true + } + ], + "blockHash": "8fe138b14146bd34a4ede23ee13d2ab9f47fbd847bcac5aeef19e9c56ff917cf", + "blockHeight": 386238, + "confirmations": 221299, + "blockTime": 1559838400, + "value": "89908018", + "valueIn": "90000000", + "fees": "91982", + "hex": "01000000011193452088b30e4c17124470846ee4c3b79c19075d578c5bf4bd235bf97d1af8000000006a47304402200ea13a1f081a5176d5c3ab8fcbc1b494fc0645fa0841fa354572487054ed95ee02200d0fd71fd6cf3031b86e15dafedc7ff85ca6f03412822c4c2a1e97c08a01f293012103a5acc1412252845944273732db657873b8241d005cdc8b7133636b4399d45b51000000000200cdb702000000001976a9145c2b655a026e05d034505a47671a5a66cf3b1df688ac3216a402000000001976a914884457adbc0ff5a2007f43075c0414dd0753b5ec88ac00000000" + }, + { + "txid": "506d07570d75914d5bd319d591374fb9cd1633f5c8b3cc800387e104298e8a62", + "version": 1, + "vin": [ + { + "txid": "4e496fac305dbce97d96c067a4cbfaa7b5d4614d6c4041985c7dc89e99dd49cd", + "vout": 1, + "n": 0, + "addresses": [ + "QeFgFiCejVjBxRThhJ4ebRgmNXonzZkMfr" + ], + "isAddress": true, + "value": "599077016", + "hex": "473044022031fd10b86e02461dc593781f4c97d3d8e2892a802ff92b02b26ad67b780209a202205566b0ac15596893575d2fb762a082c6528c3047070b2d52c33690f3e90886c0012103f7505ebaded33df0549d5f84bfd176e94087216c34e7116c8c9348a201296b78" + } + ], + "vout": [ + { + "value": "400000000", + "n": 0, + "spent": true, + "hex": "76a9147453245910621e861271929af6b7154903f7a23188ac", + "addresses": [ + "QXD46Mh1rb1xvBvSamatQPfX3yv1M2shfe" + ], + "isAddress": true + }, + { + "value": "198984808", + "n": 1, + "spent": true, + "hex": "76a914cd8f8a0948e351270ee6b3fdc59622a372a7d85d88ac", + "addresses": [ + "QfLtauKWxzF6pDf2ceXJe5oqizNHVMBneH" + ], + "isAddress": true + } + ], + "blockHash": "082a3673444c4fc291d69a94717cf50c5fedebcf9321f311d4078f5f0915a1b3", + "blockHeight": 371887, + "confirmations": 235650, + "blockTime": 1557782304, + "value": "598984808", + "valueIn": "599077016", + "fees": "92208", + "hex": "0100000001cd49dd999ec87d5c9841406c4d61d4b5a7facba467c0967de9bc5d30ac6f494e010000006a473044022031fd10b86e02461dc593781f4c97d3d8e2892a802ff92b02b26ad67b780209a202205566b0ac15596893575d2fb762a082c6528c3047070b2d52c33690f3e90886c0012103f7505ebaded33df0549d5f84bfd176e94087216c34e7116c8c9348a201296b7800000000020084d717000000001976a9147453245910621e861271929af6b7154903f7a23188ac6844dc0b000000001976a914cd8f8a0948e351270ee6b3fdc59622a372a7d85d88ac00000000" + }, + { + "txid": "4e496fac305dbce97d96c067a4cbfaa7b5d4614d6c4041985c7dc89e99dd49cd", + "version": 1, + "vin": [ + { + "txid": "fd8f486538844c2ba61fcf19d2474d213f3b69bbc596e383a3df0b2a872be397", + "vout": 1, + "n": 0, + "addresses": [ + "QjCpHnT38X5e6cxqcTjNxYSKGqt71xydcG" + ], + "isAddress": true, + "value": "999169224", + "hex": "47304402205c7773681fd9219e2767e6562c2db4494ba5849ced0c587933c02995a31b6f820220008306c7e3e5a8ac9d10c0b5b7f51ca984292366d6026044dc7c187fda653283012103c8c65394bbcd25f8d8170603e004ee4aea13779d56772ae6b2eeb19459c1885e" + } + ], + "vout": [ + { + "value": "400000000", + "n": 0, + "spent": true, + "hex": "76a91430a20d6d186573efcb02ce987a4b122d2b2ae9ec88ac", + "addresses": [ + "QR38g7Dr4uHgNGV2WDN4FZ7zHWFAuseVcf" + ], + "isAddress": true + }, + { + "value": "599077016", + "n": 1, + "spent": true, + "hex": "76a914c19b0a513721b10aab8ba0a94cafcb41888c87aa88ac", + "addresses": [ + "QeFgFiCejVjBxRThhJ4ebRgmNXonzZkMfr" + ], + "isAddress": true + } + ], + "blockHash": "4c458211bf8dedc0bb0709171c26d7acd8ab966ae771686a48b4fafc23f61575", + "blockHeight": 371880, + "confirmations": 235657, + "blockTime": 1557781552, + "value": "999077016", + "valueIn": "999169224", + "fees": "92208", + "hex": "010000000197e32b872a0bdfa383e396c5bb693b3f214d47d219cf1fa62b4c843865488ffd010000006a47304402205c7773681fd9219e2767e6562c2db4494ba5849ced0c587933c02995a31b6f820220008306c7e3e5a8ac9d10c0b5b7f51ca984292366d6026044dc7c187fda653283012103c8c65394bbcd25f8d8170603e004ee4aea13779d56772ae6b2eeb19459c1885e00000000020084d717000000001976a91430a20d6d186573efcb02ce987a4b122d2b2ae9ec88ac9830b523000000001976a914c19b0a513721b10aab8ba0a94cafcb41888c87aa88ac00000000" + }, + { + "txid": "fd8f486538844c2ba61fcf19d2474d213f3b69bbc596e383a3df0b2a872be397", + "version": 1, + "vin": [ + { + "txid": "1aaecf66a34809ee22046be8bddf93207c8fc9b0213b3ab1d0ea3ce4f2f6880a", + "vout": 1, + "n": 0, + "addresses": [ + "QZofPF8hq3JoRpSmKAk3SVJhDaRxTydqrS" + ], + "isAddress": true, + "value": "1799261432", + "hex": "47304402205d9dd4efacdd8daadebc20e0f1ca9d27a669d7117a0fca3e816c6b4b6ed10a66022051962a17fb71fbb0609454ecd01fc39f5ec3db767a03d36c5f6757f94a8ee58401210272ba28d3e42d8ad70125456d39cd57b2fac15d7ebd5bf2cb5d25a9b8b7684e38" + } + ], + "vout": [ + { + "value": "800000000", + "n": 0, + "spent": true, + "hex": "76a9144d606371996c3627fb7ff801b4e60d139a73c14c88ac", + "addresses": [ + "QTf7cFrSjNAvP9guENBPTGkHmrXaBienwL" + ], + "isAddress": true + }, + { + "value": "999169224", + "n": 1, + "spent": true, + "hex": "76a914f7e92115bb48ad0010eb71968a8d3baf62a960b488ac", + "addresses": [ + "QjCpHnT38X5e6cxqcTjNxYSKGqt71xydcG" + ], + "isAddress": true + } + ], + "blockHash": "8b58575304b5a00df0a390ec07148cc96fef7ba7500bf2df533b3a6ea82a3859", + "blockHeight": 371877, + "confirmations": 235660, + "blockTime": 1557780768, + "value": "1799169224", + "valueIn": "1799261432", + "fees": "92208", + "hex": "01000000010a88f6f2e43cead0b13a3b21b0c98f7c2093dfbde86b0422ee0948a366cfae1a010000006a47304402205d9dd4efacdd8daadebc20e0f1ca9d27a669d7117a0fca3e816c6b4b6ed10a66022051962a17fb71fbb0609454ecd01fc39f5ec3db767a03d36c5f6757f94a8ee58401210272ba28d3e42d8ad70125456d39cd57b2fac15d7ebd5bf2cb5d25a9b8b7684e3800000000020008af2f000000001976a9144d606371996c3627fb7ff801b4e60d139a73c14c88acc81c8e3b000000001976a914f7e92115bb48ad0010eb71968a8d3baf62a960b488ac00000000" + }, + { + "txid": "1aaecf66a34809ee22046be8bddf93207c8fc9b0213b3ab1d0ea3ce4f2f6880a", + "version": 1, + "vin": [ + { + "txid": "faad61481f064446da34de34da9bc1c8f69f13083fbb8021600366f76a7b3475", + "vout": 1, + "n": 0, + "addresses": [ + "QZofPF8hq3JoRpSmKAk3SVJhDaRxTydqrS" + ], + "isAddress": true, + "value": "2199353640", + "hex": "483045022100d536d10736799426259dd17c5eeee98362b2b542b6c1418ac18e15cd66110709022035b4a2ce1ce7ad3978e4fdb69ef9369bfebbc3183c5964fc138a4dfdc7a183d301210272ba28d3e42d8ad70125456d39cd57b2fac15d7ebd5bf2cb5d25a9b8b7684e38" + } + ], + "vout": [ + { + "value": "400000000", + "n": 0, + "spent": true, + "hex": "76a9141f9b560a954cffd6cb305ce7ba963b516222f57488ac", + "addresses": [ + "QPV79BoKoNW4mW29U9BS7n82BDY44Z5Q7r" + ], + "isAddress": true + }, + { + "value": "1799261432", + "n": 1, + "spent": true, + "hex": "76a91490cefeee5907b57694e1e07e21bc93ad5a57675488ac", + "addresses": [ + "QZofPF8hq3JoRpSmKAk3SVJhDaRxTydqrS" + ], + "isAddress": true + } + ], + "blockHash": "81e08d0c8b36d1997465d157c31b285154661523247a3d41c11a5f0dc6250bc3", + "blockHeight": 371874, + "confirmations": 235663, + "blockTime": 1557780480, + "value": "2199261432", + "valueIn": "2199353640", + "fees": "92208", + "hex": "010000000175347b6af76603602180bb3f08139ff6c8c19bda34de34da4644061f4861adfa010000006b483045022100d536d10736799426259dd17c5eeee98362b2b542b6c1418ac18e15cd66110709022035b4a2ce1ce7ad3978e4fdb69ef9369bfebbc3183c5964fc138a4dfdc7a183d301210272ba28d3e42d8ad70125456d39cd57b2fac15d7ebd5bf2cb5d25a9b8b7684e3800000000020084d717000000001976a9141f9b560a954cffd6cb305ce7ba963b516222f57488acf88c3e6b000000001976a91490cefeee5907b57694e1e07e21bc93ad5a57675488ac00000000" + }, + { + "txid": "faad61481f064446da34de34da9bc1c8f69f13083fbb8021600366f76a7b3475", + "version": 1, + "vin": [ + { + "txid": "a6ccccbcd705751a1dcd2ffd7ad8e8ce400b3185121a67203115065ee4170628", + "vout": 1, + "n": 0, + "addresses": [ + "Qj35M7dSFHzRXPXrB2wAARpG7VUDdxdHCC" + ], + "isAddress": true, + "value": "2599445848", + "hex": "48304502210081206aae11555093d37ff11fcf03bf30175ec7107863ee9af3a286554c8e0db60220273c23796c213aa6afc4396ca1d16a801be76e10073bed917b01512090f13653012102133f6d9cf3aeb04891b6047aa869f5c80f526f5b2d5ad38cdaaff70f5277e158" + } + ], + "vout": [ + { + "value": "400000000", + "n": 0, + "spent": true, + "hex": "76a91468e132870bec77acd4731ec49ead03f99548a8d488ac", + "addresses": [ + "QWAYAEhgTjrFpSENigkRBSWqZQhJNUrX7i" + ], + "isAddress": true + }, + { + "value": "2199353640", + "n": 1, + "spent": true, + "hex": "76a91490cefeee5907b57694e1e07e21bc93ad5a57675488ac", + "addresses": [ + "QZofPF8hq3JoRpSmKAk3SVJhDaRxTydqrS" + ], + "isAddress": true + } + ], + "blockHash": "81e08d0c8b36d1997465d157c31b285154661523247a3d41c11a5f0dc6250bc3", + "blockHeight": 371874, + "confirmations": 235663, + "blockTime": 1557780480, + "value": "2599353640", + "valueIn": "2599445848", + "fees": "92208", + "hex": "0100000001280617e45e06153120671a1285310b40cee8d87afd2fcd1d1a7505d7bccccca6010000006b48304502210081206aae11555093d37ff11fcf03bf30175ec7107863ee9af3a286554c8e0db60220273c23796c213aa6afc4396ca1d16a801be76e10073bed917b01512090f13653012102133f6d9cf3aeb04891b6047aa869f5c80f526f5b2d5ad38cdaaff70f5277e15800000000020084d717000000001976a91468e132870bec77acd4731ec49ead03f99548a8d488ac28791783000000001976a91490cefeee5907b57694e1e07e21bc93ad5a57675488ac00000000" + }, + { + "txid": "a6ccccbcd705751a1dcd2ffd7ad8e8ce400b3185121a67203115065ee4170628", + "version": 1, + "vin": [ + { + "txid": "e48cb1618e8e0a689c6dc13cb5ddf919d79eeaa6c52f759a264045005c75ba3f", + "vout": 1, + "n": 0, + "addresses": [ + "QP6j9eg3afB4WMz1y9wLKez1J4aiC1wdpX" + ], + "isAddress": true, + "value": "2999538056", + "hex": "483045022100f18d78e8108ee38cdca476ec6d58555ae143a23d2f8cf53cc0e10047cb4565c702207021fa4d40704aae3652aca1292c968d45a91164046ab328b67fc15dbdd6f990012103ff3def0371177a677a5b4e8f77d0b8ddaf8285ab38e9225d0124bfd7b3614126" + } + ], + "vout": [ + { + "value": "400000000", + "n": 0, + "spent": true, + "hex": "76a91455ad628bd3280f7a25c6ffe632219969efd52e1288ac", + "addresses": [ + "QUR1FbrT5a7sjM7RZRWKvh9hKFdAvcStoM" + ], + "isAddress": true + }, + { + "value": "2599445848", + "n": 1, + "spent": true, + "hex": "76a914f61189f709c22ae8b15cf521047f04d52766096988ac", + "addresses": [ + "Qj35M7dSFHzRXPXrB2wAARpG7VUDdxdHCC" + ], + "isAddress": true + } + ], + "blockHash": "c15bc1dea688280b438487c7e861cbe5771bf86294a715450a52a145119e556f", + "blockHeight": 371865, + "confirmations": 235672, + "blockTime": 1557779168, + "value": "2999445848", + "valueIn": "2999538056", + "fees": "92208", + "hex": "01000000013fba755c004540269a752fc5a6ea9ed719f9ddb53cc16d9c680a8e8e61b18ce4010000006b483045022100f18d78e8108ee38cdca476ec6d58555ae143a23d2f8cf53cc0e10047cb4565c702207021fa4d40704aae3652aca1292c968d45a91164046ab328b67fc15dbdd6f990012103ff3def0371177a677a5b4e8f77d0b8ddaf8285ab38e9225d0124bfd7b361412600000000020084d717000000001976a91455ad628bd3280f7a25c6ffe632219969efd52e1288ac5865f09a000000001976a914f61189f709c22ae8b15cf521047f04d52766096988ac00000000" + }, + { + "txid": "e48cb1618e8e0a689c6dc13cb5ddf919d79eeaa6c52f759a264045005c75ba3f", + "version": 1, + "vin": [ + { + "txid": "2ece10754c7b21581762f0c97ba75c70ea4c27014c57c99e275fdcb3a81e4a82", + "vout": 1, + "n": 0, + "addresses": [ + "QbA1vmoTn9g2SWMEGxrwgMj4YJZBZjPM64" + ], + "isAddress": true, + "value": "3399630264", + "hex": "4730440220183d1378b64a7d45fa8161cc0009a02fa77ad64242f565a31df2739053d9cb5c02203e36d6e37251667f0fac98592537942fe4e7fca1b808a67cb1b7900ca6e66f530121020d5851125e817ce3476cf3df60f90fccd817886bbbeedab75f047c901eec800b" + } + ], + "vout": [ + { + "value": "400000000", + "n": 0, + "hex": "76a914d58637b5bc95ffd1c2b1394280d799806eb6e26788ac", + "addresses": [ + "Qg4zpmAYHDX2sqvNZvwcK6mXP2rYkx5HVy" + ], + "isAddress": true + }, + { + "value": "2999538056", + "n": 1, + "spent": true, + "hex": "76a9141b5fd3b1e5334f58da46d494098d984f997349cc88ac", + "addresses": [ + "QP6j9eg3afB4WMz1y9wLKez1J4aiC1wdpX" + ], + "isAddress": true + } + ], + "blockHash": "44bf2daa6095c2de48be35afb02c534709d8dee1618436efa2e87ac5bbeb32b2", + "blockHeight": 371863, + "confirmations": 235674, + "blockTime": 1557778720, + "value": "3399538056", + "valueIn": "3399630264", + "fees": "92208", + "hex": "0100000001824a1ea8b3dc5f279ec9574c01274cea705ca77bc9f0621758217b4c7510ce2e010000006a4730440220183d1378b64a7d45fa8161cc0009a02fa77ad64242f565a31df2739053d9cb5c02203e36d6e37251667f0fac98592537942fe4e7fca1b808a67cb1b7900ca6e66f530121020d5851125e817ce3476cf3df60f90fccd817886bbbeedab75f047c901eec800b00000000020084d717000000001976a914d58637b5bc95ffd1c2b1394280d799806eb6e26788ac8851c9b2000000001976a9141b5fd3b1e5334f58da46d494098d984f997349cc88ac00000000" + }, + { + "txid": "2ece10754c7b21581762f0c97ba75c70ea4c27014c57c99e275fdcb3a81e4a82", + "version": 1, + "vin": [ + { + "txid": "a5b112b2c4637f8f9d6c8d7f4bf5f4fb9760f57b96a16f21043c07a28614ecab", + "vout": 1, + "n": 0, + "addresses": [ + "QdWQyQ22AH15vFAduR5vXL96gy6jKGe83u" + ], + "isAddress": true, + "value": "3799722698", + "hex": "47304402201440eb1ec302b54d9a9335db3ec24dfce76f3d9d1d90850c8320a8570c94448702203e3aa49e12213fbcc6c177defea3100d9396bcb574405f9cca35758b439f84380121039083fb8237a9e073eb0f5e369fe4fe9e2d1680546b1d0843a7bc4fa28bb16ac2" + } + ], + "vout": [ + { + "value": "400000000", + "n": 0, + "spent": true, + "hex": "76a914dc68b2824d8b7f295d1f90846e34828afec326fe88ac", + "addresses": [ + "QghQBzp524R83f9H1yUwyBU4vWXuS5D3R4" + ], + "isAddress": true + }, + { + "value": "3399630264", + "n": 1, + "spent": true, + "hex": "76a9149fa096fba1a39f90fb14918a2e3fc83f6210060d88ac", + "addresses": [ + "QbA1vmoTn9g2SWMEGxrwgMj4YJZBZjPM64" + ], + "isAddress": true + } + ], + "blockHash": "b77d614d5ce54da3fa16bbdbffd019d50219f76cd355b8bda644db3da2321fc1", + "blockHeight": 371860, + "confirmations": 235677, + "blockTime": 1557778304, + "value": "3799630264", + "valueIn": "3799722698", + "fees": "92434", + "hex": "0100000001abec1486a2073c04216fa1967bf56097fbf4f54b7f8d6c9d8f7f63c4b212b1a5010000006a47304402201440eb1ec302b54d9a9335db3ec24dfce76f3d9d1d90850c8320a8570c94448702203e3aa49e12213fbcc6c177defea3100d9396bcb574405f9cca35758b439f84380121039083fb8237a9e073eb0f5e369fe4fe9e2d1680546b1d0843a7bc4fa28bb16ac200000000020084d717000000001976a914dc68b2824d8b7f295d1f90846e34828afec326fe88acb83da2ca000000001976a9149fa096fba1a39f90fb14918a2e3fc83f6210060d88ac00000000" + }, + { + "txid": "b828e72bfa1641a3b4f84c7ed123d0380a09108446b09b84516782cb40f05510", + "version": 1, + "vin": [ + { + "txid": "f787ea119a618193cb9faa653aa5629b1c6c84b0927779c93d20c346d9adf4ee", + "vout": 1, + "n": 0, + "addresses": [ + "QdWQyQ22AH15vFAduR5vXL96gy6jKGe83u" + ], + "isAddress": true, + "value": "4599907566", + "hex": "4730440220363dfb0b54b2ca3ee4bb8fdac4bf494913ef9f44f42a09a1936f795ba22fc7fe0220484772160ea280fbdc5b8a7f912a41dad6a8bc850f8dfcc97956a4271a476eec0121039083fb8237a9e073eb0f5e369fe4fe9e2d1680546b1d0843a7bc4fa28bb16ac2" + } + ], + "vout": [ + { + "value": "400000000", + "n": 0, + "spent": true, + "hex": "76a914a5dca0220e76f6cfc31c23d0763c4242d9f00fd088ac", + "addresses": [ + "QbiyuHEi7fzL97A7dfemXeJT7bjoj54ECs" + ], + "isAddress": true + }, + { + "value": "4199815132", + "n": 1, + "spent": true, + "hex": "76a914b96c65d540e98f1675427557987528f18c3a75f388ac", + "addresses": [ + "QdWQyQ22AH15vFAduR5vXL96gy6jKGe83u" + ], + "isAddress": true + } + ], + "blockHash": "4d25fc06d734cbc35872193bbe104981abf6c8bdd29cbbc697a16456e4e98f40", + "blockHeight": 371858, + "confirmations": 235679, + "blockTime": 1557778208, + "value": "4599815132", + "valueIn": "4599907566", + "fees": "92434", + "hex": "0100000001eef4add946c3203dc9797792b0846c1c9b62a53a65aa9fcb9381619a11ea87f7010000006a4730440220363dfb0b54b2ca3ee4bb8fdac4bf494913ef9f44f42a09a1936f795ba22fc7fe0220484772160ea280fbdc5b8a7f912a41dad6a8bc850f8dfcc97956a4271a476eec0121039083fb8237a9e073eb0f5e369fe4fe9e2d1680546b1d0843a7bc4fa28bb16ac200000000020084d717000000001976a914a5dca0220e76f6cfc31c23d0763c4242d9f00fd088acdc1754fa000000001976a914b96c65d540e98f1675427557987528f18c3a75f388ac00000000" + }, + { + "txid": "a5b112b2c4637f8f9d6c8d7f4bf5f4fb9760f57b96a16f21043c07a28614ecab", + "version": 1, + "vin": [ + { + "txid": "b828e72bfa1641a3b4f84c7ed123d0380a09108446b09b84516782cb40f05510", + "vout": 1, + "n": 0, + "addresses": [ + "QdWQyQ22AH15vFAduR5vXL96gy6jKGe83u" + ], + "isAddress": true, + "value": "4199815132", + "hex": "48304502210097597fd831bc8adaabf3751f183ee835d654a731ca187c8105a16381ed081c68022059ff6f13efbcdf20b0ea369907139d88f8f356ec9013b48594192bf3649072650121039083fb8237a9e073eb0f5e369fe4fe9e2d1680546b1d0843a7bc4fa28bb16ac2" + } + ], + "vout": [ + { + "value": "400000000", + "n": 0, + "spent": true, + "hex": "76a914cb13b0ee6e66b4db48fbeb595cde818ece2d097288ac", + "addresses": [ + "Qf7ksQRm1qrQe5KzEBjzm6zNdsTnk2udm8" + ], + "isAddress": true + }, + { + "value": "3799722698", + "n": 1, + "spent": true, + "hex": "76a914b96c65d540e98f1675427557987528f18c3a75f388ac", + "addresses": [ + "QdWQyQ22AH15vFAduR5vXL96gy6jKGe83u" + ], + "isAddress": true + } + ], + "blockHash": "4d25fc06d734cbc35872193bbe104981abf6c8bdd29cbbc697a16456e4e98f40", + "blockHeight": 371858, + "confirmations": 235679, + "blockTime": 1557778208, + "value": "4199722698", + "valueIn": "4199815132", + "fees": "92434", + "hex": "01000000011055f040cb826751849bb0468410090a38d023d17e4cf8b4a34116fa2be728b8010000006b48304502210097597fd831bc8adaabf3751f183ee835d654a731ca187c8105a16381ed081c68022059ff6f13efbcdf20b0ea369907139d88f8f356ec9013b48594192bf3649072650121039083fb8237a9e073eb0f5e369fe4fe9e2d1680546b1d0843a7bc4fa28bb16ac200000000020084d717000000001976a914cb13b0ee6e66b4db48fbeb595cde818ece2d097288acca2a7be2000000001976a914b96c65d540e98f1675427557987528f18c3a75f388ac00000000" + }, + { + "txid": "f787ea119a618193cb9faa653aa5629b1c6c84b0927779c93d20c346d9adf4ee", + "version": 1, + "vin": [ + { + "txid": "dfa44eb9994c1f44eb95efe2a7da492e87073ae96a3c3dd73555f61ce12e8320", + "vout": 1, + "n": 0, + "addresses": [ + "QaQvBedwizcQvX5pYFWEsnmDgZZ5jioA5m" + ], + "isAddress": true, + "value": "5000000000", + "hex": "483045022100f93275ba52e26f3a0ae2e45b233a6b03084494defe5f30e1d0ccc7935d0dc98d02206b9f26e31e5e3e36c39e472b41bda30c887b4febfc53ce2e38a8ff22464243170121020d89d58933b209f209c0a1edf40d051efb30753b9c250d8dc08fb864228b4c8c" + } + ], + "vout": [ + { + "value": "400000000", + "n": 0, + "spent": true, + "hex": "76a9145866765bb56403a71f9d542bd81ea4a69492e42888ac", + "addresses": [ + "QUfQKPTGwKY3UzXcPEGnX41vC1hprTr4qS" + ], + "isAddress": true + }, + { + "value": "4599907566", + "n": 1, + "spent": true, + "hex": "76a914b96c65d540e98f1675427557987528f18c3a75f388ac", + "addresses": [ + "QdWQyQ22AH15vFAduR5vXL96gy6jKGe83u" + ], + "isAddress": true + } + ], + "blockHash": "4d25fc06d734cbc35872193bbe104981abf6c8bdd29cbbc697a16456e4e98f40", + "blockHeight": 371858, + "confirmations": 235679, + "blockTime": 1557778208, + "value": "4999907566", + "valueIn": "5000000000", + "fees": "92434", + "hex": "010000000120832ee11cf65535d73d3c6ae93a07872e49daa7e2ef95eb441f4c99b94ea4df010000006b483045022100f93275ba52e26f3a0ae2e45b233a6b03084494defe5f30e1d0ccc7935d0dc98d02206b9f26e31e5e3e36c39e472b41bda30c887b4febfc53ce2e38a8ff22464243170121020d89d58933b209f209c0a1edf40d051efb30753b9c250d8dc08fb864228b4c8c00000000020084d717000000001976a9145866765bb56403a71f9d542bd81ea4a69492e42888acee042d12010000001976a914b96c65d540e98f1675427557987528f18c3a75f388ac00000000" + }, + { + "txid": "dfa44eb9994c1f44eb95efe2a7da492e87073ae96a3c3dd73555f61ce12e8320", + "version": 2, + "lockTime": 371847, + "vin": [ + { + "txid": "575487400aba81153c17789a5b23ee38fbb6cc49e1802be441f565b85b806e29", + "vout": 1, + "sequence": 4294967293, + "n": 0, + "addresses": [ + "QZBSG69TdoMNAAktaYFSpRzUKPMLNDQe4G" + ], + "isAddress": true, + "value": "23999851200", + "hex": "4730440220451f9a63166e695b6330ca2295129ac4b4d183753714e6e6f8b5aa2ace71841c02202302f8fa125424ced1dcdbbb2bff9736e58053080bf713d5f2e749e1f7027fe90121037025f8084201f448efd299c3be6d2559f02c7de1284d1efdcff680e623267816" + } + ], + "vout": [ + { + "value": "18999761200", + "n": 0, + "spent": true, + "hex": "76a91489f510fd9bd058b5f9e24059125f209d42efbe9a88ac", + "addresses": [ + "QZBSG69TdoMNAAktaYFSpRzUKPMLNDQe4G" + ], + "isAddress": true + }, + { + "value": "5000000000", + "n": 1, + "spent": true, + "hex": "76a9149779e8b2ef497557df77466c8c3c9193a43a7e2888ac", + "addresses": [ + "QaQvBedwizcQvX5pYFWEsnmDgZZ5jioA5m" + ], + "isAddress": true + } + ], + "blockHash": "f59bcf04c02890c625601b89a7e48fa4765c54f7ac186d302e1773a9170246d3", + "blockHeight": 371848, + "confirmations": 235689, + "blockTime": 1557776944, + "value": "23999761200", + "valueIn": "23999851200", + "fees": "90000", + "hex": "0200000001296e805bb865f541e42b80e149ccb6fb38ee235b9a78173c1581ba0a40875457010000006a4730440220451f9a63166e695b6330ca2295129ac4b4d183753714e6e6f8b5aa2ace71841c02202302f8fa125424ced1dcdbbb2bff9736e58053080bf713d5f2e749e1f7027fe90121037025f8084201f448efd299c3be6d2559f02c7de1284d1efdcff680e623267816fdffffff023059796c040000001976a91489f510fd9bd058b5f9e24059125f209d42efbe9a88ac00f2052a010000001976a9149779e8b2ef497557df77466c8c3c9193a43a7e2888ac87ac0500" + }, + { + "txid": "f81a7df95b23bdf45b8c575d07199cb7c3e46e84704412174c0eb38820459311", + "version": 1, + "vin": [ + { + "txid": "22121f29131b2219948e63b8aaac0573641f604c5b88e1fe28f9861f63051f5f", + "sequence": 4294967294, + "n": 0, + "addresses": [ + "QVav8YbUUwQq6yFCrkafW79Uv3NUMHT66n" + ], + "isAddress": true, + "value": "12555500", + "hex": "463043021f214ac8d3f6dab3ff4ed5cd862b52c582a829e6cecc8f8440e71e564dc174c90220526805a30f1e3959d9a6c16a9d06c34382dbfe2d26ec5b7a15db580f21c415ec0121023608e446e04c777b55ce0253a99d90d8c6902dab7f37b0b2e29b507849259e74" + }, + { + "txid": "b195994e3c56842a751b89a6c5daf6c286245b0b74b707412e2ff8dc753b1ca4", + "sequence": 4294967293, + "n": 1, + "addresses": [ + "QVav8YbUUwQq6yFCrkafW79Uv3NUMHT66n" + ], + "isAddress": true, + "value": "86483292", + "hex": "47304402207abf586a08f5bcff70a20a69b9bef6c137ace8f9745c045399a08e852d806a8a02207f8dfa6805db6ae119014a2e3732db8a145588b241076989793efd46b8a6a7bf0121023608e446e04c777b55ce0253a99d90d8c6902dab7f37b0b2e29b507849259e74" + } + ], + "vout": [ + { + "value": "90000000", + "n": 0, + "spent": true, + "hex": "76a914c3f89deaed494671b8be39cf3f0dfb90f9906ee588ac", + "addresses": [ + "QeUBhueTQt35s4BMRWvPcX3RCguSe2Ghf1" + ], + "isAddress": true + }, + { + "value": "8736600", + "n": 1, + "spent": true, + "hex": "76a9141bfd274c127df9c5002b1ca194410625cc363a9188ac", + "addresses": [ + "QP9ycthVwbF3xwVpLCcorC7uD6xya3ooKw" + ], + "isAddress": true + } + ], + "blockHash": "dd516586cac95af3fa14d3059f22ceaa23068692f91560dd2e2446eae88a0011", + "blockHeight": 369836, + "confirmations": 237701, + "blockTime": 1557491568, + "value": "98736600", + "valueIn": "99038792", + "fees": "302192", + "hex": "01000000025f1f05631f86f928fee1885b4c601f647305acaab8638e9419221b13291f12220000000069463043021f214ac8d3f6dab3ff4ed5cd862b52c582a829e6cecc8f8440e71e564dc174c90220526805a30f1e3959d9a6c16a9d06c34382dbfe2d26ec5b7a15db580f21c415ec0121023608e446e04c777b55ce0253a99d90d8c6902dab7f37b0b2e29b507849259e74feffffffa41c3b75dcf82f2e4107b7740b5b2486c2f6dac5a6891b752a84563c4e9995b1000000006a47304402207abf586a08f5bcff70a20a69b9bef6c137ace8f9745c045399a08e852d806a8a02207f8dfa6805db6ae119014a2e3732db8a145588b241076989793efd46b8a6a7bf0121023608e446e04c777b55ce0253a99d90d8c6902dab7f37b0b2e29b507849259e74fdffffff02804a5d05000000001976a914c3f89deaed494671b8be39cf3f0dfb90f9906ee588ac584f8500000000001976a9141bfd274c127df9c5002b1ca194410625cc363a9188ac00000000" + }, + { + "txid": "b195994e3c56842a751b89a6c5daf6c286245b0b74b707412e2ff8dc753b1ca4", + "version": 1, + "vin": [ + { + "txid": "143ec0b4f7a144aaeded1749739060d7c1c6d21ff463ea4fef95df357946adf6", + "sequence": 4294967294, + "n": 0, + "addresses": [ + "QeUBhueTQt35s4BMRWvPcX3RCguSe2Ghf1" + ], + "isAddress": true, + "value": "9780554", + "hex": "47304402207811d40f485915e1423d9996d38243958ab4768c96c4a8046261e57ae058c7f602203ad4371113afbd43cb805e39a90796c1bbad38054a856c5b9db9477542dfe140012103a5acc1412252845944273732db657873b8241d005cdc8b7133636b4399d45b51" + }, + { + "txid": "22121f29131b2219948e63b8aaac0573641f604c5b88e1fe28f9861f63051f5f", + "vout": 1, + "sequence": 4294967293, + "n": 1, + "addresses": [ + "QiE5pqKaWD6KuKJG1XqqaSuKscqw68WPDj" + ], + "isAddress": true, + "value": "77004930", + "hex": "47304402200dedf8c4f423ad6a5ba54aad47d7da0d6a89d5ebf8106a5725a1d54508c3ee4502203ca16b0c2d6fc903ba8e678c9634d31b4edf8be5b31103e7e7464b6784dc7b830121025c0fa32e88a54b3b57d8043f508bc58bcd0db113900b1c38e4e641e7bdf69837" + } + ], + "vout": [ + { + "value": "86483292", + "n": 0, + "spent": true, + "hex": "76a9146285651ee6abb6788c39df4ecb89f97345cbfa2588ac", + "addresses": [ + "QVav8YbUUwQq6yFCrkafW79Uv3NUMHT66n" + ], + "isAddress": true + } + ], + "blockHash": "cc770fb40122f9b7ebdaa9878ec78acd5a9e89a2410e9a7dd47e4b22c5817b29", + "blockHeight": 369831, + "confirmations": 237706, + "blockTime": 1557490880, + "value": "86483292", + "valueIn": "86785484", + "fees": "302192", + "hex": "0100000002f6ad467935df95ef4fea63f41fd2c6c1d76090734917ededaa44a1f7b4c03e14000000006a47304402207811d40f485915e1423d9996d38243958ab4768c96c4a8046261e57ae058c7f602203ad4371113afbd43cb805e39a90796c1bbad38054a856c5b9db9477542dfe140012103a5acc1412252845944273732db657873b8241d005cdc8b7133636b4399d45b51feffffff5f1f05631f86f928fee1885b4c601f647305acaab8638e9419221b13291f1222010000006a47304402200dedf8c4f423ad6a5ba54aad47d7da0d6a89d5ebf8106a5725a1d54508c3ee4502203ca16b0c2d6fc903ba8e678c9634d31b4edf8be5b31103e7e7464b6784dc7b830121025c0fa32e88a54b3b57d8043f508bc58bcd0db113900b1c38e4e641e7bdf69837fdffffff015ca12705000000001976a9146285651ee6abb6788c39df4ecb89f97345cbfa2588ac00000000" + }, + { + "txid": "22121f29131b2219948e63b8aaac0573641f604c5b88e1fe28f9861f63051f5f", + "version": 1, + "vin": [ + { + "txid": "1c5aea829cb18e507d3a1eccb99db5744a9ff086ed87cc97d696231954ce7635", + "vout": 1, + "sequence": 4294967294, + "n": 0, + "addresses": [ + "Qf2dViTrEcWm7CawDDoDduzBrgRL3DnFWH" + ], + "isAddress": true, + "value": "89780102", + "hex": "483045022100d97be84585f063ebf9faf117728255db551c75e87c0d570cfd2fbd2ea47c969102200b50b8c4367981de9b26fb84b757ef88b40976b1a4ad0c1a54d58e67fa575200012102e75ea870219ec7bd72ea790e85459f367c11d82f7cffd72fdcd41943adb56817" + } + ], + "vout": [ + { + "value": "12555500", + "n": 0, + "spent": true, + "hex": "76a9146285651ee6abb6788c39df4ecb89f97345cbfa2588ac", + "addresses": [ + "QVav8YbUUwQq6yFCrkafW79Uv3NUMHT66n" + ], + "isAddress": true + }, + { + "value": "77004930", + "n": 1, + "spent": true, + "hex": "76a914ed2e633dc9806a955b0f637d682c5629ceaa2e8988ac", + "addresses": [ + "QiE5pqKaWD6KuKJG1XqqaSuKscqw68WPDj" + ], + "isAddress": true + } + ], + "blockHash": "7bf6daddf9d2fa6c0c57fc4b2e7696ccfefc65d5f6d52a4d5dba4741bdcb762b", + "blockHeight": 369490, + "confirmations": 238047, + "blockTime": 1557443008, + "value": "89560430", + "valueIn": "89780102", + "fees": "219672", + "hex": "01000000013576ce54192396d697cc87ed86f09f4a74b59db9cc1e3a7d508eb19c82ea5a1c010000006b483045022100d97be84585f063ebf9faf117728255db551c75e87c0d570cfd2fbd2ea47c969102200b50b8c4367981de9b26fb84b757ef88b40976b1a4ad0c1a54d58e67fa575200012102e75ea870219ec7bd72ea790e85459f367c11d82f7cffd72fdcd41943adb56817feffffff02ec94bf00000000001976a9146285651ee6abb6788c39df4ecb89f97345cbfa2588ac82009704000000001976a914ed2e633dc9806a955b0f637d682c5629ceaa2e8988ac00000000" + }, + { + "txid": "143ec0b4f7a144aaeded1749739060d7c1c6d21ff463ea4fef95df357946adf6", + "version": 1, + "vin": [ + { + "txid": "1c5aea829cb18e507d3a1eccb99db5744a9ff086ed87cc97d696231954ce7635", + "sequence": 4294967294, + "n": 0, + "addresses": [ + "QVav8YbUUwQq6yFCrkafW79Uv3NUMHT66n" + ], + "isAddress": true, + "value": "10000000", + "hex": "473044022043e99b1a4859135e6a9e4e03e239036a3724711e8e525872ba2679a3af864b80022004aefa4b0412126418080098baa5207b2b2c31b9c0086f495dc35f870e466cc10121023608e446e04c777b55ce0253a99d90d8c6902dab7f37b0b2e29b507849259e74" + } + ], + "vout": [ + { + "value": "9780554", + "n": 0, + "spent": true, + "hex": "76a914c3f89deaed494671b8be39cf3f0dfb90f9906ee588ac", + "addresses": [ + "QeUBhueTQt35s4BMRWvPcX3RCguSe2Ghf1" + ], + "isAddress": true + } + ], + "blockHash": "b64d9b0074e95e0aeecf4ef6b844b57bbdbe2a2fe9d0587606aaf4ba065f04e0", + "blockHeight": 369485, + "confirmations": 238052, + "blockTime": 1557441920, + "value": "9780554", + "valueIn": "10000000", + "fees": "219446", + "hex": "01000000013576ce54192396d697cc87ed86f09f4a74b59db9cc1e3a7d508eb19c82ea5a1c000000006a473044022043e99b1a4859135e6a9e4e03e239036a3724711e8e525872ba2679a3af864b80022004aefa4b0412126418080098baa5207b2b2c31b9c0086f495dc35f870e466cc10121023608e446e04c777b55ce0253a99d90d8c6902dab7f37b0b2e29b507849259e74feffffff014a3d9500000000001976a914c3f89deaed494671b8be39cf3f0dfb90f9906ee588ac00000000" + }, + { + "txid": "1c5aea829cb18e507d3a1eccb99db5744a9ff086ed87cc97d696231954ce7635", + "version": 1, + "vin": [ + { + "txid": "f09b2b7577dbf154f2c027ad8f1bb51e4c9917e809856be513e7b8067f6d888e", + "sequence": 4294967294, + "n": 0, + "addresses": [ + "QZJbNrGT3cZ1J1AEHtgH3JWM7uLBNAejLZ" + ], + "isAddress": true, + "value": "100000000", + "hex": "4730440220009bc2bb9bd0782aa38bfb3e9093d49fdfb31e4067a956adad2f888e9438e06b02206d7c5d60afffdb3685fced33d24ba9a6466a35b3aa933e4b1ffdd6ba8d23d57901210317cfe4e8b0e35f4c2c561921fe019910e3ddbe78d500a8ff546cf1843f723764" + } + ], + "vout": [ + { + "value": "10000000", + "n": 0, + "spent": true, + "hex": "76a9146285651ee6abb6788c39df4ecb89f97345cbfa2588ac", + "addresses": [ + "QVav8YbUUwQq6yFCrkafW79Uv3NUMHT66n" + ], + "isAddress": true + }, + { + "value": "89780102", + "n": 1, + "spent": true, + "hex": "76a914ca1b74b3ae2a8e655487e131dbb820717c20610e88ac", + "addresses": [ + "Qf2dViTrEcWm7CawDDoDduzBrgRL3DnFWH" + ], + "isAddress": true + } + ], + "blockHash": "d61a1de7b586fee13bc44cd3ae0fa0392d6d9d75d7d3c7273481dfa2069eb9ab", + "blockHeight": 369474, + "confirmations": 238063, + "blockTime": 1557440448, + "value": "99780102", + "valueIn": "100000000", + "fees": "219898", + "hex": "01000000018e886d7f06b8e713e56b8509e817994c1eb51b8fad27c0f254f1db77752b9bf0000000006a4730440220009bc2bb9bd0782aa38bfb3e9093d49fdfb31e4067a956adad2f888e9438e06b02206d7c5d60afffdb3685fced33d24ba9a6466a35b3aa933e4b1ffdd6ba8d23d57901210317cfe4e8b0e35f4c2c561921fe019910e3ddbe78d500a8ff546cf1843f723764feffffff0280969800000000001976a9146285651ee6abb6788c39df4ecb89f97345cbfa2588ac86ef5905000000001976a914ca1b74b3ae2a8e655487e131dbb820717c20610e88ac00000000" + }, + { + "txid": "f09b2b7577dbf154f2c027ad8f1bb51e4c9917e809856be513e7b8067f6d888e", + "version": 1, + "vin": [ + { + "txid": "3600156226ed9f04379dcf72795542d9b4de9d88b374b82b825497ff92e52830", + "vout": 1, + "n": 0, + "addresses": [ + "QUN6caK4ZEPLEoA3ZMC2oSR2kf6RCfGA9B" + ], + "isAddress": true, + "value": "109000000", + "hex": "483045022100cf97578c211296f9e3aa8e7718c7ec4a6fc240b46c29216f664fd68fdd81ec5202201a27971ba5e52b758a8295c870f037a67f20aab306a264e6249dd4f61705634401210360e37f3d88db15a76ffdb30179fc3a67e0fa320e8c6a82bbd93a8e40af30d963" + } + ], + "vout": [ + { + "value": "100000000", + "n": 0, + "spent": true, + "hex": "76a9148b4f969602a4579f9c982e7d30c3a06e2f0cacc888ac", + "addresses": [ + "QZJbNrGT3cZ1J1AEHtgH3JWM7uLBNAejLZ" + ], + "isAddress": true + }, + { + "value": "8789820", + "n": 1, + "spent": true, + "hex": "76a91406ee9fbb22cc53a5190b0eddf26ed33d66a6ebfa88ac", + "addresses": [ + "QMEe2LEsZRLjf4UNuxkgMBHwkMB2zJuWjo" + ], + "isAddress": true + } + ], + "blockHash": "c23063e7715537c96898e8fe956bc45c98e0fb17c415ebdbbbb78f3ba8106494", + "blockHeight": 367729, + "confirmations": 239808, + "blockTime": 1557190080, + "value": "108789820", + "valueIn": "109000000", + "fees": "210180", + "hex": "01000000013028e592ff9754822bb874b3889ddeb4d942557972cf9d37049fed2662150036010000006b483045022100cf97578c211296f9e3aa8e7718c7ec4a6fc240b46c29216f664fd68fdd81ec5202201a27971ba5e52b758a8295c870f037a67f20aab306a264e6249dd4f61705634401210360e37f3d88db15a76ffdb30179fc3a67e0fa320e8c6a82bbd93a8e40af30d963000000000200e1f505000000001976a9148b4f969602a4579f9c982e7d30c3a06e2f0cacc888ac3c1f8600000000001976a91406ee9fbb22cc53a5190b0eddf26ed33d66a6ebfa88ac00000000" + } + ], + "usedTokens": 33, + "tokens": [ + { + "type": "XPUBAddress", + "name": "QZJbNrGT3cZ1J1AEHtgH3JWM7uLBNAejLZ", + "path": "m/44'/2301'/0'/0/0", + "transfers": 6, + "decimals": 8, + "balance": "234243932", + "totalReceived": "43569601542", + "totalSent": "43335357610" + } + ] +} diff --git a/mock/ext-api-data/ravencoin-api_v2_address_RGkwvrUors8DtmhKy5bddFwRCTZaunjpvo__details_txs.json b/mock/ext-api-data/ravencoin-api_v2_address_RGkwvrUors8DtmhKy5bddFwRCTZaunjpvo__details_txs.json new file mode 100644 index 000000000..a80745d3a --- /dev/null +++ b/mock/ext-api-data/ravencoin-api_v2_address_RGkwvrUors8DtmhKy5bddFwRCTZaunjpvo__details_txs.json @@ -0,0 +1,110 @@ +{ + "page": 1, + "totalPages": 1, + "itemsOnPage": 1000, + "address": "RGkwvrUors8DtmhKy5bddFwRCTZaunjpvo", + "balance": "0", + "totalReceived": "8525568094", + "totalSent": "8525568094", + "unconfirmedBalance": "0", + "unconfirmedTxs": 0, + "txs": 2, + "transactions": [ + { + "txid": "fc226aad6fc28e1204b747042e8c8b25f5d28424b9669bd162ba6a0149df2f71", + "version": 2, + "lockTime": 1201754, + "vin": [ + { + "txid": "1222cb57d31bfb439e94080266c33ebb0134cdb90999a9fad99455d09a15159b", + "sequence": 4294967294, + "n": 0, + "addresses": [ + "RGkwvrUors8DtmhKy5bddFwRCTZaunjpvo" + ], + "isAddress": true, + "value": "8525568094", + "hex": "483045022100dc56832c815e7294dd51c7bb1ba342af80f5d25c3bc44c9689a55ccd94d18d01022063d3420930736fb1c1ab9a851ec0d1ff01dc906c66685b35972e3ab26b2d5d040121032dd4ba9d193e1912a6b48bd5642cb3579415ebabfc61e9fec9690fcd466dea15" + } + ], + "vout": [ + { + "value": "78460623", + "n": 0, + "spent": true, + "hex": "76a9141657456724a83ca9e4c4cc0b65c98b6ffdba5bae88ac", + "addresses": [ + "RBKKVSR79YjBSGBE5pymUCaa871qogE5aY" + ], + "isAddress": true + }, + { + "value": "8446853390", + "n": 1, + "spent": true, + "hex": "76a9142e664ae2c04d6292d50bcd65b644553eea7d7f1388ac", + "addresses": [ + "RDWXhkQyUkgmumGbzdR6JetLChVzUbStRq" + ], + "isAddress": true + } + ], + "blockHash": "000000000000244f2e3f48b9c6767465d0611995047368a06fbc28bde79d8ec6", + "blockHeight": 1201755, + "confirmations": 28073, + "blockTime": 1587702273, + "value": "8525314013", + "valueIn": "8525568094", + "fees": "254081", + "hex": "02000000019b15159ad05594d9faa99909b9cd3401bb3ec3660208949e43fb1bd357cb2212000000006b483045022100dc56832c815e7294dd51c7bb1ba342af80f5d25c3bc44c9689a55ccd94d18d01022063d3420930736fb1c1ab9a851ec0d1ff01dc906c66685b35972e3ab26b2d5d040121032dd4ba9d193e1912a6b48bd5642cb3579415ebabfc61e9fec9690fcd466dea15feffffff02cf36ad04000000001976a9141657456724a83ca9e4c4cc0b65c98b6ffdba5bae88ac0ec178f7010000001976a9142e664ae2c04d6292d50bcd65b644553eea7d7f1388ac5a561200" + }, + { + "txid": "1222cb57d31bfb439e94080266c33ebb0134cdb90999a9fad99455d09a15159b", + "version": 2, + "lockTime": 1201750, + "vin": [ + { + "txid": "003d748c2c3541535093e840b4c5e54b966915eb522bac06028bc8d1376e1e63", + "sequence": 4294967294, + "n": 0, + "addresses": [ + "R9kyoRBmiF89o5ACFXF4EY7GawGjURP1Z5" + ], + "isAddress": true, + "value": "8530842427", + "hex": "47304402207ea927cfb1c7d8e14b067aa5b892cfde8b7b96b8bd95866b906c13e168581fd20220423bee1c4e25f66cc5ac27d94a33540307edb2a9a8874e800a1e1f875194dabf012103ded5613a24b22a8dc0c416f3ac4b436372a5b581b42e2d45f00fbd042cb066f1" + } + ], + "vout": [ + { + "value": "8525568094", + "n": 0, + "spent": true, + "hex": "76a9145208b754b23169797a19e0ffaa9041ab5e29b9ef88ac", + "addresses": [ + "RGkwvrUors8DtmhKy5bddFwRCTZaunjpvo" + ], + "isAddress": true + }, + { + "value": "5020252", + "n": 1, + "spent": true, + "hex": "76a914bb7590eef377d63adcda0d080073035ad9a86bfc88ac", + "addresses": [ + "RSNPH2YPN69PNRj6BYq4V3orCyC7nahG9R" + ], + "isAddress": true + } + ], + "blockHash": "00000000000003efc9fb9dd4d5deb4e6ca393266191771d5d2e2426a191e69b3", + "blockHeight": 1201752, + "confirmations": 28076, + "blockTime": 1587701825, + "value": "8530588346", + "valueIn": "8530842427", + "fees": "254081", + "hex": "0200000001631e6e37d1c88b0206ac2b52eb1569964be5c5b440e893505341352c8c743d00000000006a47304402207ea927cfb1c7d8e14b067aa5b892cfde8b7b96b8bd95866b906c13e168581fd20220423bee1c4e25f66cc5ac27d94a33540307edb2a9a8874e800a1e1f875194dabf012103ded5613a24b22a8dc0c416f3ac4b436372a5b581b42e2d45f00fbd042cb066f1feffffff025ed829fc010000001976a9145208b754b23169797a19e0ffaa9041ab5e29b9ef88ac5c9a4c00000000001976a914bb7590eef377d63adcda0d080073035ad9a86bfc88ac56561200" + } + ] +} diff --git a/mock/ext-api-data/ravencoin-api_v2_xpub_xpub6BrkWQHMnuGcvKowEn2hpvnZ41SiCsu38mgFThKU3nMzPUN9r9C26puf18rfVdHH3nDwSkeMgsjVniNDKUk5arxekekGpNyVLsWihYAfC5B__details_txs.json b/mock/ext-api-data/ravencoin-api_v2_xpub_xpub6BrkWQHMnuGcvKowEn2hpvnZ41SiCsu38mgFThKU3nMzPUN9r9C26puf18rfVdHH3nDwSkeMgsjVniNDKUk5arxekekGpNyVLsWihYAfC5B__details_txs.json new file mode 100644 index 000000000..a802a4ce7 --- /dev/null +++ b/mock/ext-api-data/ravencoin-api_v2_xpub_xpub6BrkWQHMnuGcvKowEn2hpvnZ41SiCsu38mgFThKU3nMzPUN9r9C26puf18rfVdHH3nDwSkeMgsjVniNDKUk5arxekekGpNyVLsWihYAfC5B__details_txs.json @@ -0,0 +1,393 @@ +{ + "page": 1, + "totalPages": 1, + "itemsOnPage": 1000, + "address": "xpub6BrkWQHMnuGcvKowEn2hpvnZ41SiCsu38mgFThKU3nMzPUN9r9C26puf18rfVdHH3nDwSkeMgsjVniNDKUk5arxekekGpNyVLsWihYAfC5B", + "balance": "299445646", + "totalReceived": "2599356720", + "totalSent": "2299911074", + "unconfirmedBalance": "0", + "unconfirmedTxs": 0, + "txs": 8, + "transactions": [ + { + "txid": "5d22e5a84b0eb054b623fdc3caf88a60eaa646dc97922f06d325aa8d6f18c564", + "version": 1, + "vin": [ + { + "txid": "baa2ee45ad8b9922a9db3fdcc22f8c3b5257dc81fef609800e7bd138748b6977", + "sequence": 4294967294, + "n": 0, + "addresses": [ + "RHhtrB8eUZuTp8m8HVEyGidEiSkSz5CRdM" + ], + "isAddress": true, + "value": "299456974", + "hex": "47304402204d44f9873e894314746557e4e7ba74e9436d7fa81986d0386684179d8acb77fe02206ff207862b3badbd41cc2ab584ff334410ab2bd089c6c4a1f6ffa59ce2b5d7da012102d34aee6afc67a1b86789beadf0ef2ed7dd5665776b734c0a4dba727bf532bd59" + } + ], + "vout": [ + { + "value": "299445646", + "n": 0, + "hex": "76a91469a82a3f4a8441d7eb0805e9c1ca421761eb456588ac", + "addresses": [ + "RJurUyAqde3GLkDgkTzAuHHMbdMPMqfBsz" + ], + "isAddress": true + } + ], + "blockHash": "00000000000013c420937088dd9b69e5ef38c2c1e544828d222c1e8998d1358a", + "blockHeight": 843530, + "confirmations": 386298, + "blockTime": 1566071064, + "value": "299445646", + "valueIn": "299456974", + "fees": "11328", + "hex": "010000000177698b7438d17b0e8009f6fe81dc57523b8c2fc2dc3fdba922998bad45eea2ba000000006a47304402204d44f9873e894314746557e4e7ba74e9436d7fa81986d0386684179d8acb77fe02206ff207862b3badbd41cc2ab584ff334410ab2bd089c6c4a1f6ffa59ce2b5d7da012102d34aee6afc67a1b86789beadf0ef2ed7dd5665776b734c0a4dba727bf532bd59feffffff018e2dd911000000001976a91469a82a3f4a8441d7eb0805e9c1ca421761eb456588ac00000000" + }, + { + "txid": "baa2ee45ad8b9922a9db3fdcc22f8c3b5257dc81fef609800e7bd138748b6977", + "version": 1, + "vin": [ + { + "txid": "0f517fd0d4e86070fdff40e95f5202a1b343f75d3168842feb2e8fd6f1be0ef9", + "n": 0, + "addresses": [ + "RJurUyAqde3GLkDgkTzAuHHMbdMPMqfBsz" + ], + "isAddress": true, + "value": "9990400", + "hex": "483045022100d8e3598c4d8829b39433c43d4a4c3c438754e8fa77284e1de606233b954770f2022034eb8b6ab6ca103f613d14ccc38fc6aea7bc8661dbff87b0c576b4712d202b3a012102ee0d81b0e40adde804683388953c9cef6276703a3d26e65f9f3433dff0b82dba" + }, + { + "txid": "b9db035506eaeb0de0dbc98a277c29f41c08317515538c79cdc542d759918004", + "vout": 1, + "n": 1, + "addresses": [ + "RGG4nwkVgFSpy5wdZVKkKFySUCz8N35B5L" + ], + "isAddress": true, + "value": "89988700", + "hex": "473044022075c8f6c3ce3de19c86bbaa845871e25af82ea40bb3793896e657dccbd350209a022033b983ef8733a74ca8e977e08c4ded3a027a800dedbe8aa65a06bca0dc87d09b012103d66703c2448791bcb6828c060de9c568853aa43a753ed227a1f14d70612d3144" + }, + { + "txid": "44172def2b5f799963adf28f0a3129e6f7910c8bc5ad09ad0e8155da24748d25", + "vout": 1, + "n": 2, + "addresses": [ + "RHj2wiQ8tDhJZKsNKsf48WzxAj2pVnhEnX" + ], + "isAddress": true, + "value": "199965874", + "hex": "4730440220601d4e0d8bc03cf5064dad0316cf61d996ec507aa92105711a0d480a561d9bbb02200acaf5ff2deed01fca255caeaeb63925097bad740adbfd952ab0df66fbfa8552012102eff42496547e74666a392bf8399072dc289ae1d1e835a1c7068650a76be44709" + } + ], + "vout": [ + { + "value": "299456974", + "n": 0, + "spent": true, + "hex": "76a9145c6d05bdca691ab3acfd59ad1a70e55aea1cece388ac", + "addresses": [ + "RHhtrB8eUZuTp8m8HVEyGidEiSkSz5CRdM" + ], + "isAddress": true + } + ], + "blockHash": "0000000000006c4af5eab913f98e03bb3ff45c8b580b88cbeba39b0748ec6f8c", + "blockHeight": 843527, + "confirmations": 386301, + "blockTime": 1566070929, + "value": "299456974", + "valueIn": "299944974", + "fees": "488000", + "hex": "0100000003f90ebef1d68f2eeb2f8468315df743b3a102525fe940fffd7060e8d4d07f510f000000006b483045022100d8e3598c4d8829b39433c43d4a4c3c438754e8fa77284e1de606233b954770f2022034eb8b6ab6ca103f613d14ccc38fc6aea7bc8661dbff87b0c576b4712d202b3a012102ee0d81b0e40adde804683388953c9cef6276703a3d26e65f9f3433dff0b82dba0000000004809159d742c5cd798c53157531081cf4297c278ac9dbe00debea065503dbb9010000006a473044022075c8f6c3ce3de19c86bbaa845871e25af82ea40bb3793896e657dccbd350209a022033b983ef8733a74ca8e977e08c4ded3a027a800dedbe8aa65a06bca0dc87d09b012103d66703c2448791bcb6828c060de9c568853aa43a753ed227a1f14d70612d314400000000258d7424da55810ead09adc58b0c91f7e629310a8ff2ad6399795f2bef2d1744010000006a4730440220601d4e0d8bc03cf5064dad0316cf61d996ec507aa92105711a0d480a561d9bbb02200acaf5ff2deed01fca255caeaeb63925097bad740adbfd952ab0df66fbfa8552012102eff42496547e74666a392bf8399072dc289ae1d1e835a1c7068650a76be447090000000001ce59d911000000001976a9145c6d05bdca691ab3acfd59ad1a70e55aea1cece388ac00000000" + }, + { + "txid": "0f517fd0d4e86070fdff40e95f5202a1b343f75d3168842feb2e8fd6f1be0ef9", + "version": 1, + "vin": [ + { + "txid": "b9db035506eaeb0de0dbc98a277c29f41c08317515538c79cdc542d759918004", + "n": 0, + "addresses": [ + "RArA49JQFoQZPZRUJqbnE6tp8fVRmAp8v7" + ], + "isAddress": true, + "value": "10000000", + "hex": "4830450221009370c852500b17d02ad9cc2f539a7b56fa237ccd108ec39b2e914fa9fdcde95e02203a730d6431a5e4ada7580644f0fc68ec57fc4e3519d8656e70790239bf12e6b501210214632a2120dc88ae7624ccb3e63534ae3c1d84aefe9f1b72ee23ba9876e3cbc6" + } + ], + "vout": [ + { + "value": "9990400", + "n": 0, + "spent": true, + "hex": "76a91469a82a3f4a8441d7eb0805e9c1ca421761eb456588ac", + "addresses": [ + "RJurUyAqde3GLkDgkTzAuHHMbdMPMqfBsz" + ], + "isAddress": true + } + ], + "blockHash": "00000000000060b0a773ca5f98d4dfdfab1610d62c85f367aee85768852ba5f6", + "blockHeight": 741026, + "confirmations": 488802, + "blockTime": 1559880464, + "value": "9990400", + "valueIn": "10000000", + "fees": "9600", + "hex": "010000000104809159d742c5cd798c53157531081cf4297c278ac9dbe00debea065503dbb9000000006b4830450221009370c852500b17d02ad9cc2f539a7b56fa237ccd108ec39b2e914fa9fdcde95e02203a730d6431a5e4ada7580644f0fc68ec57fc4e3519d8656e70790239bf12e6b501210214632a2120dc88ae7624ccb3e63534ae3c1d84aefe9f1b72ee23ba9876e3cbc6000000000100719800000000001976a91469a82a3f4a8441d7eb0805e9c1ca421761eb456588ac00000000" + }, + { + "txid": "b9db035506eaeb0de0dbc98a277c29f41c08317515538c79cdc542d759918004", + "version": 1, + "vin": [ + { + "txid": "10fb44c72200ff042b545c29969ca85943f55e33897823580a19b40fc10159f4", + "sequence": 4294967294, + "n": 0, + "addresses": [ + "RG5LjQjL9GWjYoAQSQQVwoLeErG1UZMP3h" + ], + "isAddress": true, + "value": "100000000", + "hex": "473044022013aa396845c905d35d5f8cbd404c51f5246cd529e36ac15a723dbdd1058683dd02201d7f6fd12afc6284cca0d94dcea0606b5c1dc8121c40daed9192e0487baf161a012103041042bb05c5baa1e3783999835a37625403f9cbb89ec91fd643b9ffdfe03f3f" + } + ], + "vout": [ + { + "value": "10000000", + "n": 0, + "spent": true, + "hex": "76a914113429cb4f5bd3d5825e1d521ae7cde85c9d21e188ac", + "addresses": [ + "RArA49JQFoQZPZRUJqbnE6tp8fVRmAp8v7" + ], + "isAddress": true + }, + { + "value": "89988700", + "n": 1, + "spent": true, + "hex": "76a9144c9261f9db4a82b622a7233feeb8058b738fb77088ac", + "addresses": [ + "RGG4nwkVgFSpy5wdZVKkKFySUCz8N35B5L" + ], + "isAddress": true + } + ], + "blockHash": "00000000000012c02a6248d62b3f0c0a99ed28db6be7e8b6618148b59562900f", + "blockHeight": 741022, + "confirmations": 488806, + "blockTime": 1559880370, + "value": "99988700", + "valueIn": "100000000", + "fees": "11300", + "hex": "0100000001f45901c10fb4190a58237889335ef54359a89c96295c542b04ff0022c744fb10000000006a473044022013aa396845c905d35d5f8cbd404c51f5246cd529e36ac15a723dbdd1058683dd02201d7f6fd12afc6284cca0d94dcea0606b5c1dc8121c40daed9192e0487baf161a012103041042bb05c5baa1e3783999835a37625403f9cbb89ec91fd643b9ffdfe03f3ffeffffff0280969800000000001976a914113429cb4f5bd3d5825e1d521ae7cde85c9d21e188ac5c1e5d05000000001976a9144c9261f9db4a82b622a7233feeb8058b738fb77088ac00000000" + }, + { + "txid": "44172def2b5f799963adf28f0a3129e6f7910c8bc5ad09ad0e8155da24748d25", + "version": 1, + "vin": [ + { + "txid": "10fb44c72200ff042b545c29969ca85943f55e33897823580a19b40fc10159f4", + "vout": 1, + "n": 0, + "addresses": [ + "R9in1jQ6JzYZSQABXnD5fr4xtEp5FpjnMr" + ], + "isAddress": true, + "value": "399977400", + "hex": "483045022100c104df759924b7e90a4c82f4767bd6667f10f86e9a88027832acab3b926fe764022021e1b3847b7951c3139c18d23d24f17385ac5a43c48ede235981f59c6cd45ccd01210390b9600abc44b0ce8a33f89f9d52d95aa472b3933000489fd53c12fb6dc82239" + } + ], + "vout": [ + { + "value": "200000000", + "n": 0, + "spent": true, + "hex": "76a91493a42b17108b467ca6d63171b3c8d1bd58f0989888ac", + "addresses": [ + "RNjr5L6TqoyiwBQp7kYFr4Yk5AsC8kkS6p" + ], + "isAddress": true + }, + { + "value": "199965874", + "n": 1, + "spent": true, + "hex": "76a9145ca432386ab4cf862f9b87f32fb334149e1ba40088ac", + "addresses": [ + "RHj2wiQ8tDhJZKsNKsf48WzxAj2pVnhEnX" + ], + "isAddress": true + } + ], + "blockHash": "0000000000003c4fb53bc5f505be6266d00ec058e15a3a0b6e24cacf5664622d", + "blockHeight": 739791, + "confirmations": 490037, + "blockTime": 1559805482, + "value": "399965874", + "valueIn": "399977400", + "fees": "11526", + "hex": "0100000001f45901c10fb4190a58237889335ef54359a89c96295c542b04ff0022c744fb10010000006b483045022100c104df759924b7e90a4c82f4767bd6667f10f86e9a88027832acab3b926fe764022021e1b3847b7951c3139c18d23d24f17385ac5a43c48ede235981f59c6cd45ccd01210390b9600abc44b0ce8a33f89f9d52d95aa472b3933000489fd53c12fb6dc82239000000000200c2eb0b000000001976a91493a42b17108b467ca6d63171b3c8d1bd58f0989888acb23ceb0b000000001976a9145ca432386ab4cf862f9b87f32fb334149e1ba40088ac00000000" + }, + { + "txid": "10fb44c72200ff042b545c29969ca85943f55e33897823580a19b40fc10159f4", + "version": 1, + "vin": [ + { + "txid": "9490bbc470862a5d8cd7f7c6c83a0cd4516d124a54b169f5d9f4e5ad6b2f05e7", + "vout": 1, + "n": 0, + "addresses": [ + "RQu6oko5Laega15FQSfhYTFAQPdWJt7MAg" + ], + "isAddress": true, + "value": "499988700", + "hex": "47304402205e63f89393bc37cab8c82b3f1bfece7b1e15a21a569bb2862db0b5d9ce5eddc3022075d1ba913743f309e8c4278155aabab48b2edd6f28ba78205b56695cb248330d01210272f8247a32b3a8d50d502a7a484132509480d6ca180305f541042d815f1949c8" + } + ], + "vout": [ + { + "value": "100000000", + "n": 0, + "spent": true, + "hex": "76a9144a8b1cc5b6b4c61a66e29cdc4732d757f8b0b7c188ac", + "addresses": [ + "RG5LjQjL9GWjYoAQSQQVwoLeErG1UZMP3h" + ], + "isAddress": true + }, + { + "value": "399977400", + "n": 1, + "spent": true, + "hex": "76a91404d6b9f2268317e71889161c9f7430824b753e0e88ac", + "addresses": [ + "R9in1jQ6JzYZSQABXnD5fr4xtEp5FpjnMr" + ], + "isAddress": true + } + ], + "blockHash": "00000000000056a3b549a9e967d9a19af10e0a0227c2e33b3b087c18a6119049", + "blockHeight": 739591, + "confirmations": 490237, + "blockTime": 1559793642, + "value": "499977400", + "valueIn": "499988700", + "fees": "11300", + "hex": "0100000001e7052f6bade5f4d9f569b1544a126d51d40c3ac8c6f7d78c5d2a8670c4bb9094010000006a47304402205e63f89393bc37cab8c82b3f1bfece7b1e15a21a569bb2862db0b5d9ce5eddc3022075d1ba913743f309e8c4278155aabab48b2edd6f28ba78205b56695cb248330d01210272f8247a32b3a8d50d502a7a484132509480d6ca180305f541042d815f1949c8000000000200e1f505000000001976a9144a8b1cc5b6b4c61a66e29cdc4732d757f8b0b7c188acb82bd717000000001976a91404d6b9f2268317e71889161c9f7430824b753e0e88ac00000000" + }, + { + "txid": "9490bbc470862a5d8cd7f7c6c83a0cd4516d124a54b169f5d9f4e5ad6b2f05e7", + "version": 1, + "vin": [ + { + "txid": "3abc0a2a29dc20cbf828a5de9f7cb64f3343456efe257af9557a4365be279924", + "vout": 1, + "n": 0, + "addresses": [ + "RVG4EpTdouq8ui29pgrAAYfWYtzC5Gzn8h" + ], + "isAddress": true, + "value": "1000000000", + "hex": "473044022045d0fb08baa997552568132bc448854714bc2727a7e03d86eb96161cc83096f20220097e682ee7400b634a0f469a7d9450ce5d382e72aaf2ec0003fd362112f1c08b0121026c437d2701fdb8120793e23898b28eff9d0173413626b48970a2ad620beaf737" + } + ], + "vout": [ + { + "value": "500000000", + "n": 0, + "hex": "76a914e2f5abd0a8de78fd4c3ac1e363be073cd87a1a5b88ac", + "addresses": [ + "RVyF6QC7XYqEP4ZThVowJGeZg5Q5p683nV" + ], + "isAddress": true + }, + { + "value": "499988700", + "n": 1, + "spent": true, + "hex": "76a914ab5475f4b0dc2ebf15f4ba2c0371ed1a8f05285488ac", + "addresses": [ + "RQu6oko5Laega15FQSfhYTFAQPdWJt7MAg" + ], + "isAddress": true + } + ], + "blockHash": "0000000000002943f769a119d1095ccd49738e9036a17e0bea19ab052f8a00b2", + "blockHeight": 737804, + "confirmations": 492024, + "blockTime": 1559685656, + "value": "999988700", + "valueIn": "1000000000", + "fees": "11300", + "hex": "0100000001249927be65437a55f97a25fe6e4543334fb67c9fdea528f8cb20dc292a0abc3a010000006a473044022045d0fb08baa997552568132bc448854714bc2727a7e03d86eb96161cc83096f20220097e682ee7400b634a0f469a7d9450ce5d382e72aaf2ec0003fd362112f1c08b0121026c437d2701fdb8120793e23898b28eff9d0173413626b48970a2ad620beaf73700000000020065cd1d000000001976a914e2f5abd0a8de78fd4c3ac1e363be073cd87a1a5b88acdc38cd1d000000001976a914ab5475f4b0dc2ebf15f4ba2c0371ed1a8f05285488ac00000000" + }, + { + "txid": "3abc0a2a29dc20cbf828a5de9f7cb64f3343456efe257af9557a4365be279924", + "version": 2, + "lockTime": 737700, + "vin": [ + { + "txid": "5f0f926ff2ee476c68b4446050605417c138477492efc58ce98988691b209906", + "vout": 1, + "sequence": 4294967294, + "n": 0, + "addresses": [ + "RVyF6QC7XYqEP4ZThVowJGeZg5Q5p683nV" + ], + "isAddress": true, + "value": "75499982022", + "hex": "483045022100a051cb8c2115b357d3bcbc2c067f841950024b6d029f5db596ea3d7978decf5d0220311088ae96aee032bd569c43582f31567dd419dd4f52ee5681c6b109e4184cb0012103176b9b14d363adf505b5e88f3682e966bab243c7ddc142d627ba4da5b7b43f40" + } + ], + "vout": [ + { + "value": "74499965072", + "n": 0, + "spent": true, + "hex": "76a914360823f5332cc0e0e963b0cefc81177fe1d1c9e288ac", + "addresses": [ + "RECtKV2R2Fm23UK252pxaHD1tPrzpSdiLN" + ], + "isAddress": true + }, + { + "value": "1000000000", + "n": 1, + "spent": true, + "hex": "76a914db2b8e380a550bc0fc4f0274b2421e1483f5305388ac", + "addresses": [ + "RVG4EpTdouq8ui29pgrAAYfWYtzC5Gzn8h" + ], + "isAddress": true + } + ], + "blockHash": "00000000000010983316addc1b38cbb32d7e31e85861b8cfdee7fd9e222f4c29", + "blockHeight": 737702, + "confirmations": 492126, + "blockTime": 1559679617, + "value": "75499965072", + "valueIn": "75499982022", + "fees": "16950", + "hex": "02000000010699201b698889e98cc5ef92744738c1175460506044b4686c47eef26f920f5f010000006b483045022100a051cb8c2115b357d3bcbc2c067f841950024b6d029f5db596ea3d7978decf5d0220311088ae96aee032bd569c43582f31567dd419dd4f52ee5681c6b109e4184cb0012103176b9b14d363adf505b5e88f3682e966bab243c7ddc142d627ba4da5b7b43f40feffffff0290408b58110000001976a914360823f5332cc0e0e963b0cefc81177fe1d1c9e288ac00ca9a3b000000001976a914db2b8e380a550bc0fc4f0274b2421e1483f5305388aca4410b00" + } + ], + "usedTokens": 7, + "tokens": [ + { + "type": "XPUBAddress", + "name": "RJurUyAqde3GLkDgkTzAuHHMbdMPMqfBsz", + "path": "m/44'/175'/0'/0/2", + "transfers": 3, + "decimals": 8, + "balance": "299445646", + "totalReceived": "309436046", + "totalSent": "9990400" + } + ] +} diff --git a/mock/ext-api-data/ripple-api_accounts_rMQ98K56yXJbDGv49ZSmW51sLn94Xe1mu1_transactions__descending_false_limit_25_type_Payment.json b/mock/ext-api-data/ripple-api_accounts_rMQ98K56yXJbDGv49ZSmW51sLn94Xe1mu1_transactions__descending_false_limit_25_type_Payment.json new file mode 100644 index 000000000..0ad523398 --- /dev/null +++ b/mock/ext-api-data/ripple-api_accounts_rMQ98K56yXJbDGv49ZSmW51sLn94Xe1mu1_transactions__descending_false_limit_25_type_Payment.json @@ -0,0 +1,1977 @@ +{ + "result": "success", + "count": 23, + "transactions": [ + { + "hash": "40279A3DE51148BD41409DADF29DE8DCCD50F5AEE30840827B2C4C81C4E36505", + "ledger_index": 34698103, + "date": "2017-12-01T22:45:30+00:00", + "tx": { + "TransactionType": "Payment", + "Flags": 2147483648, + "Sequence": 21, + "LastLedgerSequence": 34698105, + "Amount": "100000000", + "Fee": "3115", + "SigningPubKey": "03807050F9E271B2E49B0FF658362EF37DBFDD31435E610B6E11C52879DF8A9907", + "TxnSignature": "3045022100D14057AA2A868F54FC7CA2E44C8310D9A944446580EAA45936A75CFFDD00425602205CCBFACB55AB0F5B02659F1EBE619FC04DE75B0227C8EB148DC6D08CABBAB072", + "Account": "rGSxFjoqmWz54PycrgQBQ5dB6e7TUpMxzq", + "Destination": "rMQ98K56yXJbDGv49ZSmW51sLn94Xe1mu1", + "Memos": [ + { + "Memo": { + "MemoType": "636C69656E74", + "MemoFormat": "7274312E342E332D31332D6735383261336135" + } + } + ] + }, + "meta": { + "TransactionIndex": 20, + "AffectedNodes": [ + { + "CreatedNode": { + "LedgerEntryType": "AccountRoot", + "LedgerIndex": "564241023DCB6F74760910F17F78B179AEC159C701BBACD99A1D3259D77D3CFF", + "NewFields": { + "Sequence": 1, + "Balance": "100000000", + "Account": "rMQ98K56yXJbDGv49ZSmW51sLn94Xe1mu1" + } + } + }, + { + "ModifiedNode": { + "LedgerEntryType": "AccountRoot", + "PreviousTxnLgrSeq": 34698098, + "PreviousTxnID": "7040A099F51E0DC386B909FB4C01DCCF23CB61D3D05B0EC562C01359FB60C754", + "LedgerIndex": "D242D4E3501E5829AB003BA788CF361D4717419D9653304E556A14C6166847E8", + "PreviousFields": { + "Sequence": 21, + "Balance": "1999935364" + }, + "FinalFields": { + "Flags": 0, + "Sequence": 22, + "OwnerCount": 0, + "Balance": "1899932249", + "Account": "rGSxFjoqmWz54PycrgQBQ5dB6e7TUpMxzq" + } + } + } + ], + "TransactionResult": "tesSUCCESS", + "delivered_amount": "100000000" + } + }, + { + "hash": "89BB38F93A332F89A22B0DDFE2373FB66F904F564D4EEA3EAB79EA2CCD142DE0", + "ledger_index": 34801077, + "date": "2017-12-05T22:24:42+00:00", + "tx": { + "TransactionType": "Payment", + "Flags": 2147483648, + "Sequence": 2, + "LastLedgerSequence": 34850332, + "Amount": "2000000", + "Fee": "5000", + "SigningPubKey": "", + "Account": "rMQ98K56yXJbDGv49ZSmW51sLn94Xe1mu1", + "Destination": "r4MoybfgCHDoUByYyMejimaX6a8CEtWtav", + "Signers": [ + { + "Signer": { + "SigningPubKey": "0320ECD5569CAFA4E23147BE238DBFB268DB3B5A502ED339387AC7DCA0ADC6FB90", + "TxnSignature": "30440220530CEB333AB1F3D03D2BDE957D769CD764C20A4AE6D31F4FDDD9F7E6447E65E902202FDEAC35D24C94BE3F4FDF1705535D1BBCA49E3B3409EE2F44BCDD72CDE66689", + "Account": "re3LGjhrCvthtWWwrfKbVJjXN9PYDeQDJ" + } + }, + { + "Signer": { + "SigningPubKey": "03E51671887C1DE935B5F48DA56EB0A460678FF14E197A1142861150EAEEF6F56D", + "TxnSignature": "304402205232E208689892834FD2409EA4532D8AACF29BD24099470A32A71A544489BE17022034C91DE535FD9CB971EADC701EE6DC17474CD4C67C462B795C19B514FB70517E", + "Account": "rkPA5RwLVPnJgpcsrzYvHwx1HVfDb6zD3" + } + }, + { + "Signer": { + "SigningPubKey": "03807050F9E271B2E49B0FF658362EF37DBFDD31435E610B6E11C52879DF8A9907", + "TxnSignature": "3045022100CE4727E645B359E15B8AFBDFB9123DCECDDC83C95CDB033CDB8A4BC97EB8C92102207610F3E01D4C08880C6269282CA162360F23BAD5860BBDC9B82BCA478DC6B0A5", + "Account": "rGSxFjoqmWz54PycrgQBQ5dB6e7TUpMxzq" + } + }, + { + "Signer": { + "SigningPubKey": "02259BC18378FD3C99B92C4A41ABA65B62333980DDF28F1F60EF8EF0B5CE7AD93D", + "TxnSignature": "3045022100F87262FA9D04A71349C731C938DB07DE9E7BE6B644B9B57A954A5165F8BC473A02206642A14066965FC99EBB362D0A95C008E49BD5EAC3FCC8151E2F70866002C773", + "Account": "rHH2gS6XikKoEt9i1xAxEBvXLHKFr7oLn8" + } + } + ] + }, + "meta": { + "TransactionIndex": 5, + "AffectedNodes": [ + { + "ModifiedNode": { + "LedgerEntryType": "AccountRoot", + "PreviousTxnLgrSeq": 34747555, + "PreviousTxnID": "0B3A832DC409E51D53651839C89A05CF52293F83A0E431820C71575C390522E1", + "LedgerIndex": "564241023DCB6F74760910F17F78B179AEC159C701BBACD99A1D3259D77D3CFF", + "PreviousFields": { + "Sequence": 2, + "Balance": "99999000" + }, + "FinalFields": { + "Flags": 0, + "Sequence": 3, + "OwnerCount": 10, + "Balance": "97994000", + "Account": "rMQ98K56yXJbDGv49ZSmW51sLn94Xe1mu1" + } + } + }, + { + "ModifiedNode": { + "LedgerEntryType": "AccountRoot", + "PreviousTxnLgrSeq": 34747567, + "PreviousTxnID": "6E26453E4AB713B55DD6EFC69D38D02D1433B54E3D2D5B9FF0EB936FAAA538DB", + "LedgerIndex": "FEBE44D92D1D8AED643BDCC2BF821581A986E99DA3B79EADAEDB69485139FE6A", + "PreviousFields": { + "Balance": "99999000" + }, + "FinalFields": { + "Flags": 0, + "Sequence": 2, + "OwnerCount": 10, + "Balance": "101999000", + "Account": "r4MoybfgCHDoUByYyMejimaX6a8CEtWtav" + } + } + } + ], + "TransactionResult": "tesSUCCESS", + "delivered_amount": "2000000" + } + }, + { + "hash": "BB94F2DD534A1B15B4D2B9E74FF08E09F577252EC1C4B6CCFB277280BDB5ED82", + "ledger_index": 34801321, + "date": "2017-12-05T22:38:50+00:00", + "tx": { + "TransactionType": "Payment", + "Flags": 2147483648, + "Sequence": 2, + "LastLedgerSequence": 34850325, + "Amount": "2000000", + "Fee": "5000", + "SigningPubKey": "", + "Account": "rMhkqz3DeU7GUUJKGZofusbrTwZe6bDyb1", + "Destination": "rMQ98K56yXJbDGv49ZSmW51sLn94Xe1mu1", + "Signers": [ + { + "Signer": { + "SigningPubKey": "03807050F9E271B2E49B0FF658362EF37DBFDD31435E610B6E11C52879DF8A9907", + "TxnSignature": "3045022100B66CB56AD3BACD2C7C3FBDC73BCC4745E7980FF4CF3716EDECF3C6DE5F671F2F0220576676FFAE610289645E9264F60608A32D6B352F84056EA1505FE378BA8E8FF0", + "Account": "rGSxFjoqmWz54PycrgQBQ5dB6e7TUpMxzq" + } + }, + { + "Signer": { + "SigningPubKey": "02259BC18378FD3C99B92C4A41ABA65B62333980DDF28F1F60EF8EF0B5CE7AD93D", + "TxnSignature": "30440220108F386906930DE078810A36A84D8EF454A9C06ED97652A17E2708543E453ABC0220697642287225A17A697E3958A51DB939D6EEC25C9E4AEC523EB1753FA68244C8", + "Account": "rHH2gS6XikKoEt9i1xAxEBvXLHKFr7oLn8" + } + }, + { + "Signer": { + "SigningPubKey": "02FA11725F6F4E28C2E1617CC60C3A43161270A6B0C8B8DAB68265E7CFC27E0E4A", + "TxnSignature": "3044022022BFED134FA36E16A3FA2A11919F6D902B6FB9E9CE97CD8208EEBFB9AA7B25DB022076F470946D630A5C167696F57E6443E92DA259C3958D9452CDBB303F3F749559", + "Account": "rLW75SfEdnGVsa3fTFkSaDTzXuFapwNYtf" + } + }, + { + "Signer": { + "SigningPubKey": "03797EFEC20C8DBF46C20FCC75AB22168AAC34D9E18BFD81C3CC007DC80C389686", + "TxnSignature": "30440220427F5DCE2F3E5C30605AE5414FE9CBC48C82EFF27BB1236EFEC8FFACF8287F730220797C738418785FE3C9D0BEAC43DDC9D762707198E0D267B16E64BB6D3F81D93D", + "Account": "rMY6Wm2RWQLN4d3Jjz15MKP74GJWVQE2pb" + } + } + ] + }, + "meta": { + "TransactionIndex": 35, + "AffectedNodes": [ + { + "ModifiedNode": { + "LedgerEntryType": "AccountRoot", + "PreviousTxnLgrSeq": 34801077, + "PreviousTxnID": "89BB38F93A332F89A22B0DDFE2373FB66F904F564D4EEA3EAB79EA2CCD142DE0", + "LedgerIndex": "564241023DCB6F74760910F17F78B179AEC159C701BBACD99A1D3259D77D3CFF", + "PreviousFields": { + "Balance": "97994000" + }, + "FinalFields": { + "Flags": 0, + "Sequence": 3, + "OwnerCount": 10, + "Balance": "99994000", + "Account": "rMQ98K56yXJbDGv49ZSmW51sLn94Xe1mu1" + } + } + }, + { + "ModifiedNode": { + "LedgerEntryType": "AccountRoot", + "PreviousTxnLgrSeq": 34801295, + "PreviousTxnID": "5994761CBFD0B4E393FBC3169DFBA916C622EF755E9BD03EB404383688F2E859", + "LedgerIndex": "973C8CBC506C0AA2860EC4C1BD32D7BE2BB32FDD011160147797AA1BA0D79AD2", + "PreviousFields": { + "Sequence": 2, + "Balance": "101999000" + }, + "FinalFields": { + "Flags": 0, + "Sequence": 3, + "OwnerCount": 10, + "Balance": "99994000", + "Account": "rMhkqz3DeU7GUUJKGZofusbrTwZe6bDyb1" + } + } + } + ], + "TransactionResult": "tesSUCCESS", + "delivered_amount": "2000000" + } + }, + { + "hash": "ED6B5936B5A2A1262E6A4DAE0AFB03974225D4BDED9711E270BBDB47D0B8249F", + "ledger_index": 34854791, + "date": "2017-12-08T00:44:11+00:00", + "tx": { + "TransactionType": "Payment", + "Flags": 2147483648, + "Sequence": 2, + "LastLedgerSequence": 34854794, + "Amount": "5935129579981200", + "Fee": "12", + "SigningPubKey": "02845A18021ACCA975FCA9CAAFE6FFD984E89920B21E0CC62101EBC899D7136B11", + "TxnSignature": "304402205A88126CCD486C0A248D0E2124542C507E773119E7D96D918E2BFB9A620217DD022045B5EC2D99DCCEC5727B24B7E724002970C9516B3C38D5644D1FEC16196DD4EC", + "Account": "rLj2CTJC8xPzCRPD2ymPbq2t1BDLj79hd4", + "Destination": "rMQ98K56yXJbDGv49ZSmW51sLn94Xe1mu1", + "Memos": [ + { + "Memo": { + "MemoType": "636C69656E74", + "MemoFormat": "7274312E342E332D31332D6735383261336135" + } + } + ] + }, + "meta": { + "TransactionIndex": 13, + "AffectedNodes": [ + { + "ModifiedNode": { + "LedgerEntryType": "AccountRoot", + "PreviousTxnLgrSeq": 34823711, + "PreviousTxnID": "C85812AB8A17DEE78DA6A47DF7DBD2ACDEC1E35467AFD5AEEA0D572D91342158", + "LedgerIndex": "564241023DCB6F74760910F17F78B179AEC159C701BBACD99A1D3259D77D3CFF", + "PreviousFields": { + "Balance": "99993000" + }, + "FinalFields": { + "Flags": 1048576, + "Sequence": 4, + "OwnerCount": 10, + "Balance": "5935129679974200", + "Account": "rMQ98K56yXJbDGv49ZSmW51sLn94Xe1mu1" + } + } + }, + { + "ModifiedNode": { + "LedgerEntryType": "AccountRoot", + "PreviousTxnLgrSeq": 34854778, + "PreviousTxnID": "65F95B73BC08A63E003417D9D42AB4E4A6E0E98FB4C4D92DA02EDB246F1DEDCB", + "LedgerIndex": "65515504E366E1A8C7A4E1DDAB03ADB015328166B443B62ADCEB8A662F816D7F", + "PreviousFields": { + "Sequence": 2, + "Balance": "5935129600973791" + }, + "FinalFields": { + "Flags": 0, + "Sequence": 3, + "OwnerCount": 0, + "Balance": "20992579", + "Account": "rLj2CTJC8xPzCRPD2ymPbq2t1BDLj79hd4" + } + } + } + ], + "TransactionResult": "tesSUCCESS", + "delivered_amount": "5935129579981200" + } + }, + { + "hash": "E1094E64564CC70D2B4B0D3F6E0DC3C101E929FBD16E8F508FCBE2E41EF09495", + "ledger_index": 34948434, + "date": "2017-12-11T16:17:30+00:00", + "tx": { + "TransactionType": "Payment", + "Flags": 2147483648, + "Sequence": 4, + "LastLedgerSequence": 34980940, + "Amount": "100000000000000", + "Fee": "5000", + "SigningPubKey": "", + "Account": "rMQ98K56yXJbDGv49ZSmW51sLn94Xe1mu1", + "Destination": "rBg2FuZT91C52Nny68houguJ4vt5x1o91m", + "Signers": [ + { + "Signer": { + "SigningPubKey": "0320ECD5569CAFA4E23147BE238DBFB268DB3B5A502ED339387AC7DCA0ADC6FB90", + "TxnSignature": "304402205E1E8CF7021500849FAF97295ADBB329FF2ADDFC6FDABF0983B50A70585416740220365A8C9BBECA2B5DC1C7E9020364396B93731117BBE208BFC2CFA1239B6D4232", + "Account": "re3LGjhrCvthtWWwrfKbVJjXN9PYDeQDJ" + } + }, + { + "Signer": { + "SigningPubKey": "03807050F9E271B2E49B0FF658362EF37DBFDD31435E610B6E11C52879DF8A9907", + "TxnSignature": "304402204D32B8B2C3122F3DE3AD7381C862527965D970DED74769EE77011FFADE22724302205F8898582A227A98A4EBD3A4D042E84258FD74B641B6FB71742E9C54592FA77B", + "Account": "rGSxFjoqmWz54PycrgQBQ5dB6e7TUpMxzq" + } + }, + { + "Signer": { + "SigningPubKey": "02FA11725F6F4E28C2E1617CC60C3A43161270A6B0C8B8DAB68265E7CFC27E0E4A", + "TxnSignature": "304402200EBC30457CC1315EC2031F1C4CF079E7ECE57911241DF370E568C1F4B68D834102207026BEF17503ADF13DC4360A9F4B0D3BDCDA9DAF9FCD654E2FDBE6F772A905F8", + "Account": "rLW75SfEdnGVsa3fTFkSaDTzXuFapwNYtf" + } + }, + { + "Signer": { + "SigningPubKey": "03797EFEC20C8DBF46C20FCC75AB22168AAC34D9E18BFD81C3CC007DC80C389686", + "TxnSignature": "304502210083EDE50767AEBF460F974B883D394BC9E29609ED52E5383FCBCB16FC3B6FFFE6022020BEF22E7B90A8DF42186AFBCD85EB0E104991EA210B83068C1AAD7DF72615ED", + "Account": "rMY6Wm2RWQLN4d3Jjz15MKP74GJWVQE2pb" + } + } + ] + }, + "meta": { + "TransactionIndex": 1, + "AffectedNodes": [ + { + "ModifiedNode": { + "LedgerEntryType": "AccountRoot", + "PreviousTxnLgrSeq": 34854791, + "PreviousTxnID": "ED6B5936B5A2A1262E6A4DAE0AFB03974225D4BDED9711E270BBDB47D0B8249F", + "LedgerIndex": "564241023DCB6F74760910F17F78B179AEC159C701BBACD99A1D3259D77D3CFF", + "PreviousFields": { + "Sequence": 4, + "Balance": "5935129679974200" + }, + "FinalFields": { + "Flags": 1048576, + "Sequence": 5, + "OwnerCount": 10, + "Balance": "5835129679969200", + "Account": "rMQ98K56yXJbDGv49ZSmW51sLn94Xe1mu1" + } + } + }, + { + "ModifiedNode": { + "LedgerEntryType": "AccountRoot", + "PreviousTxnLgrSeq": 34880318, + "PreviousTxnID": "E9D4B5D93501B38DE6289EC0C8AEABFA820EE553BDD2AC427A62B3F985389656", + "LedgerIndex": "D474EB4E1F06E4266166832B3611A7E40B0C814CA742E5169BD5880569BCA9D2", + "PreviousFields": { + "Balance": "803134818019" + }, + "FinalFields": { + "Flags": 0, + "Sequence": 155, + "OwnerCount": 2, + "Balance": "100803134818019", + "Account": "rBg2FuZT91C52Nny68houguJ4vt5x1o91m" + } + } + } + ], + "TransactionResult": "tesSUCCESS", + "delivered_amount": "100000000000000" + } + }, + { + "hash": "BAD994A5569F12A74520BD34226EE1EBEAF44C6DF3B375A0A1F1ADD39DE714DA", + "ledger_index": 35031684, + "date": "2017-12-14T22:32:51+00:00", + "tx": { + "TransactionType": "Payment", + "Flags": 2147483648, + "Sequence": 5, + "LastLedgerSequence": 35109461, + "Amount": "150000000000000", + "Fee": "5000", + "SigningPubKey": "", + "Account": "rMQ98K56yXJbDGv49ZSmW51sLn94Xe1mu1", + "Destination": "rBg2FuZT91C52Nny68houguJ4vt5x1o91m", + "Signers": [ + { + "Signer": { + "SigningPubKey": "0320ECD5569CAFA4E23147BE238DBFB268DB3B5A502ED339387AC7DCA0ADC6FB90", + "TxnSignature": "304402201C4D57AAF4B7BF40D17E69AAC69A24027972E44F53504009476E2947B744EB070220431E71A1305BEDFCD753EF766ABC8980D06BAA4E66341339905623F9DD808772", + "Account": "re3LGjhrCvthtWWwrfKbVJjXN9PYDeQDJ" + } + }, + { + "Signer": { + "SigningPubKey": "02259BC18378FD3C99B92C4A41ABA65B62333980DDF28F1F60EF8EF0B5CE7AD93D", + "TxnSignature": "30450221009070A61B831B6C253135165292ADA9546294F8CD3A752698CCF77319F5391B4B02201FA22DAA1D28071AE70F52AF595A225FD1A5798D078227DACD6E4B7C99C1AA87", + "Account": "rHH2gS6XikKoEt9i1xAxEBvXLHKFr7oLn8" + } + }, + { + "Signer": { + "SigningPubKey": "02FA11725F6F4E28C2E1617CC60C3A43161270A6B0C8B8DAB68265E7CFC27E0E4A", + "TxnSignature": "30450221008B48D6367E7FE75518B71D2B2FBAC2555488275DB504BE4E5C27EFB2758CE3EE02200EEC265DF81D5D2ED0181BA5E02BF77D9E81DE5E4749D235ECBAE6226E0AC70C", + "Account": "rLW75SfEdnGVsa3fTFkSaDTzXuFapwNYtf" + } + }, + { + "Signer": { + "SigningPubKey": "03797EFEC20C8DBF46C20FCC75AB22168AAC34D9E18BFD81C3CC007DC80C389686", + "TxnSignature": "304402207F09AF57ED924E0184B7212E74CC9C8E999A5D444BA8E87975CDE252B116961D02207C329A50A41B733E26375F1F4207C0FDB76E073A990705127756594F09B41655", + "Account": "rMY6Wm2RWQLN4d3Jjz15MKP74GJWVQE2pb" + } + } + ] + }, + "meta": { + "TransactionIndex": 26, + "AffectedNodes": [ + { + "ModifiedNode": { + "LedgerEntryType": "AccountRoot", + "PreviousTxnLgrSeq": 34948434, + "PreviousTxnID": "E1094E64564CC70D2B4B0D3F6E0DC3C101E929FBD16E8F508FCBE2E41EF09495", + "LedgerIndex": "564241023DCB6F74760910F17F78B179AEC159C701BBACD99A1D3259D77D3CFF", + "PreviousFields": { + "Sequence": 5, + "Balance": "5835129679969200" + }, + "FinalFields": { + "Flags": 1048576, + "Sequence": 6, + "OwnerCount": 10, + "Balance": "5685129679964200", + "Account": "rMQ98K56yXJbDGv49ZSmW51sLn94Xe1mu1" + } + } + }, + { + "ModifiedNode": { + "LedgerEntryType": "AccountRoot", + "PreviousTxnLgrSeq": 35007021, + "PreviousTxnID": "B5D64155C19AFEA28E8C6B33C77FCC525443503A730E10269FC3A21BB2E3D370", + "LedgerIndex": "D474EB4E1F06E4266166832B3611A7E40B0C814CA742E5169BD5880569BCA9D2", + "PreviousFields": { + "Balance": "15802434798483" + }, + "FinalFields": { + "Flags": 0, + "Sequence": 159, + "OwnerCount": 2, + "Balance": "165802434798483", + "Account": "rBg2FuZT91C52Nny68houguJ4vt5x1o91m" + } + } + } + ], + "TransactionResult": "tesSUCCESS", + "delivered_amount": "150000000000000" + } + }, + { + "hash": "44E2BA90CF6AAD90832E5DA22BCB7C8A6E1A55C903909E45333D227BECF6FB51", + "ledger_index": 36055443, + "date": "2018-01-23T23:58:22+00:00", + "tx": { + "TransactionType": "Payment", + "Flags": 2147483648, + "Sequence": 5, + "LastLedgerSequence": 36055452, + "Amount": "1000000", + "Fee": "10", + "SigningPubKey": "0231975D7489F0C1E1D871A27F23DF1BAFE53055FA7ADDCB95F6E923B1710D6C05", + "TxnSignature": "304402207926EFE3A77E7A17087B54DD0FD7BE6BAF7AE0E025ECB532336CBCB6CF5DFAB002202B9EA53763FEE3D4742E419035D23448DDDC646116B37BA65183DAAE1C5B2F6C", + "Account": "rNuSNt1mAkGK5HBTDJN2Q2vD23YyaEEmSU", + "Destination": "rMQ98K56yXJbDGv49ZSmW51sLn94Xe1mu1" + }, + "meta": { + "TransactionIndex": 6, + "AffectedNodes": [ + { + "ModifiedNode": { + "LedgerEntryType": "AccountRoot", + "PreviousTxnLgrSeq": 35929929, + "PreviousTxnID": "521A8B08E2D4DE06C5B4B78541ADAA18157288FB4160BA93E465CC530306A831", + "LedgerIndex": "0F5E84C137AF95199945D4DC676259E34E7BD2AB36FF7D2200DE42EED496E135", + "PreviousFields": { + "Sequence": 5, + "Balance": "35018854314" + }, + "FinalFields": { + "Flags": 0, + "Sequence": 6, + "OwnerCount": 0, + "Balance": "35017854304", + "Account": "rNuSNt1mAkGK5HBTDJN2Q2vD23YyaEEmSU" + } + } + }, + { + "ModifiedNode": { + "LedgerEntryType": "AccountRoot", + "PreviousTxnLgrSeq": 35031684, + "PreviousTxnID": "BAD994A5569F12A74520BD34226EE1EBEAF44C6DF3B375A0A1F1ADD39DE714DA", + "LedgerIndex": "564241023DCB6F74760910F17F78B179AEC159C701BBACD99A1D3259D77D3CFF", + "PreviousFields": { + "Balance": "5685129679964200" + }, + "FinalFields": { + "Flags": 1048576, + "Sequence": 6, + "OwnerCount": 10, + "Balance": "5685129680964200", + "Account": "rMQ98K56yXJbDGv49ZSmW51sLn94Xe1mu1" + } + } + } + ], + "TransactionResult": "tesSUCCESS", + "delivered_amount": "1000000" + } + }, + { + "hash": "4E4509305CAF71A3D0A56ED4B1E9732BF2A8CD42633FA271EC71CA3B76519EF2", + "ledger_index": 38026583, + "date": "2018-04-17T14:54:21+00:00", + "tx": { + "TransactionType": "Payment", + "Flags": 2147483648, + "Sequence": 28, + "LastLedgerSequence": 38026585, + "Amount": "1000000", + "Fee": "12", + "SendMax": { + "value": "0.0000202", + "currency": "XPD", + "issuer": "rLedgerMAX4v6YjDTbKdccP2wPbN1XhdcX" + }, + "SigningPubKey": "03740D0995283EF783A5EE2BB6EE93214FF91970AA509A02B9C55E133127FA609D", + "TxnSignature": "304402202D1D145250404A9E50FDDB301B57D1456FF5AE7EA7287C6EC3DB4324CFC5BA0F022017BF0C16A9AA46631AC0FE3910D9DB02DCE33B52B713D1B2CF6002F9ADA343DF", + "Account": "rLedgerMAX4v6YjDTbKdccP2wPbN1XhdcX", + "Destination": "rMQ98K56yXJbDGv49ZSmW51sLn94Xe1mu1", + "Memos": [ + { + "Memo": { + "MemoData": "4F666665722058504420504F205B50726963653A20353030303020585250207C204D696E204F726465722031205850445D" + } + }, + { + "Memo": { + "MemoType": "636C69656E74", + "MemoData": "50616C6164696E73" + } + } + ], + "Paths": [ + [ + { + "account": "rMCa3o92WJDHDw7GLZiP85Pp3ZRkb87xUp" + }, + { + "account": "rfhzYEqyDBiKkdpPUbSdnuEenqbmfJCys5" + }, + { + "currency": "XRP" + } + ] + ] + }, + "meta": { + "TransactionIndex": 29, + "AffectedNodes": [ + { + "ModifiedNode": { + "LedgerEntryType": "AccountRoot", + "PreviousTxnLgrSeq": 37981254, + "PreviousTxnID": "4559199AC5B4CDC4B2C9A880077E404C462E8E3312477950D8D61CFAE896BA11", + "LedgerIndex": "19CC29FF4382B5DE428F57AB7F892FAED220EC2A3E0B00A358D680BEDFE49A4B", + "PreviousFields": { + "Sequence": 28, + "AccountTxnID": "4559199AC5B4CDC4B2C9A880077E404C462E8E3312477950D8D61CFAE896BA11", + "Balance": "32099568" + }, + "FinalFields": { + "Flags": 4063232, + "Sequence": 29, + "OwnerCount": 2, + "EmailHash": "0068272433B9D73CC20F6D0856D0FF49", + "AccountTxnID": "4E4509305CAF71A3D0A56ED4B1E9732BF2A8CD42633FA271EC71CA3B76519EF2", + "Balance": "32099556", + "Domain": "7872702E6964", + "Account": "rLedgerMAX4v6YjDTbKdccP2wPbN1XhdcX", + "RegularKey": "rMCa3o92WJDHDw7GLZiP85Pp3ZRkb87xUp" + } + } + }, + { + "ModifiedNode": { + "LedgerEntryType": "AccountRoot", + "PreviousTxnLgrSeq": 38019315, + "PreviousTxnID": "ECA6CD39DB1BFFE6EFD92749747AEEE8C84978D5CCE2DBD52ADAC970B96DF714", + "LedgerIndex": "532740BCCCE8E47CAC62FED0E786BE6C33BDB1E28AF490CA93FA7A9287085524", + "PreviousFields": { + "Balance": "232960771" + }, + "FinalFields": { + "Flags": 11141120, + "Sequence": 602, + "TransferRate": 1150000000, + "OwnerCount": 41, + "EmailHash": "3A362880A9CCDF7AD417264EC76C7E31", + "AccountTxnID": "ECA6CD39DB1BFFE6EFD92749747AEEE8C84978D5CCE2DBD52ADAC970B96DF714", + "Balance": "231960771", + "Domain": "6C6564676572636861696E2E776F726C64", + "Account": "rMCa3o92WJDHDw7GLZiP85Pp3ZRkb87xUp", + "RegularKey": "rfhzYEqyDBiKkdpPUbSdnuEenqbmfJCys5", + "TickSize": 15 + } + } + }, + { + "ModifiedNode": { + "LedgerEntryType": "AccountRoot", + "PreviousTxnLgrSeq": 36055443, + "PreviousTxnID": "44E2BA90CF6AAD90832E5DA22BCB7C8A6E1A55C903909E45333D227BECF6FB51", + "LedgerIndex": "564241023DCB6F74760910F17F78B179AEC159C701BBACD99A1D3259D77D3CFF", + "PreviousFields": { + "Balance": "5685129680964200" + }, + "FinalFields": { + "Flags": 1048576, + "Sequence": 6, + "OwnerCount": 10, + "Balance": "5685129681964200", + "Account": "rMQ98K56yXJbDGv49ZSmW51sLn94Xe1mu1" + } + } + }, + { + "ModifiedNode": { + "LedgerEntryType": "Offer", + "PreviousTxnLgrSeq": 38018992, + "PreviousTxnID": "1706DDDBEEFF5479E8678F6D4546854B5DDAB384855ED912874B123091C56B32", + "LedgerIndex": "90618276E00443F08D6D62BF7D4B2DD4961D7F3EB1474EE9A88B7FD38EA634E6", + "PreviousFields": { + "TakerPays": { + "value": "10499.99936829082", + "currency": "XPD", + "issuer": "rfhzYEqyDBiKkdpPUbSdnuEenqbmfJCys5" + }, + "TakerGets": "524999968414541" + }, + "FinalFields": { + "Flags": 131072, + "Sequence": 421, + "BookNode": "0000000000000000", + "OwnerNode": "0000000000000001", + "BookDirectory": "7253BA4DA83003DCEEC2641ACEA931976B842A44510176E94A071AFD498D0000", + "TakerPays": { + "value": "10499.99934829082", + "currency": "XPD", + "issuer": "rfhzYEqyDBiKkdpPUbSdnuEenqbmfJCys5" + }, + "TakerGets": "524999967414541", + "Account": "rMCa3o92WJDHDw7GLZiP85Pp3ZRkb87xUp" + } + } + }, + { + "ModifiedNode": { + "LedgerEntryType": "RippleState", + "PreviousTxnLgrSeq": 37934707, + "PreviousTxnID": "26A9A0E390DCC9D5C9C781FC8CB6FB4B4760DB3925BBCB40D1DE3335CA82C859", + "LedgerIndex": "A1D3A25D09EA8AB50E92FEC2EF8B2027C474EE82ABBBB501FD18F524A7D9BB60", + "PreviousFields": { + "Balance": { + "value": "10", + "currency": "XPD", + "issuer": "rrrrrrrrrrrrrrrrrrrrBZbvji" + } + }, + "FinalFields": { + "Flags": 65536, + "LowQualityIn": 1000000000, + "LowNode": "0000000000000000", + "HighNode": "0000000000000001", + "Balance": { + "value": "9.99998", + "currency": "XPD", + "issuer": "rrrrrrrrrrrrrrrrrrrrBZbvji" + }, + "LowLimit": { + "value": "1000000", + "currency": "XPD", + "issuer": "rLedgerMAX4v6YjDTbKdccP2wPbN1XhdcX" + }, + "HighLimit": { + "value": "0", + "currency": "XPD", + "issuer": "rMCa3o92WJDHDw7GLZiP85Pp3ZRkb87xUp" + } + } + } + } + ], + "TransactionResult": "tesSUCCESS", + "delivered_amount": "1000000" + } + }, + { + "hash": "68BD7AA168163BEBA43956C0946CC87041CD72368B040F4933E6429B903A882F", + "ledger_index": 38474522, + "date": "2018-05-06T19:22:32+00:00", + "tx": { + "TransactionType": "Payment", + "Flags": 2147483648, + "Sequence": 1, + "DestinationTag": 42, + "LastLedgerSequence": 38474527, + "Amount": "1000", + "Fee": "10", + "SigningPubKey": "033C35B83EF461CA4F63CD442A3A7E4D0D1738ADD84E00AF197E2731AB1635CFB3", + "TxnSignature": "3045022100B9E241B0DC68177B0A4E26A6E8D1C2E68F8BA1B4591865746BFC6FAA2038426102203B395FBC424E0D3B8DF03ADD1A81319D987223EDD6959B68ADFE2184F896AE0A", + "Account": "rBYtAxpyfGQzRdCnUY7eUQY5auXJwDFx8J", + "Destination": "rMQ98K56yXJbDGv49ZSmW51sLn94Xe1mu1" + }, + "meta": { + "TransactionIndex": 0, + "AffectedNodes": [ + { + "ModifiedNode": { + "LedgerEntryType": "AccountRoot", + "PreviousTxnLgrSeq": 37761110, + "PreviousTxnID": "681BA318358ADAA87AA3395E3732B852A8400BB32170ED3F1C2A4D84E92BC805", + "LedgerIndex": "1DFECA815C5F6EE0BEA0FA51F051FCDAE16CCBC0C2A78646EE31E24E86A5FE9E", + "PreviousFields": { + "Sequence": 1, + "Balance": "16589493322" + }, + "FinalFields": { + "Flags": 0, + "Sequence": 2, + "OwnerCount": 0, + "Balance": "16589492312", + "Account": "rBYtAxpyfGQzRdCnUY7eUQY5auXJwDFx8J" + } + } + }, + { + "ModifiedNode": { + "LedgerEntryType": "AccountRoot", + "PreviousTxnLgrSeq": 38026583, + "PreviousTxnID": "4E4509305CAF71A3D0A56ED4B1E9732BF2A8CD42633FA271EC71CA3B76519EF2", + "LedgerIndex": "564241023DCB6F74760910F17F78B179AEC159C701BBACD99A1D3259D77D3CFF", + "PreviousFields": { + "Balance": "5685129681964200" + }, + "FinalFields": { + "Flags": 1048576, + "Sequence": 6, + "OwnerCount": 10, + "Balance": "5685129681965200", + "Account": "rMQ98K56yXJbDGv49ZSmW51sLn94Xe1mu1" + } + } + } + ], + "TransactionResult": "tesSUCCESS", + "delivered_amount": "1000" + } + }, + { + "hash": "FF6C1181F4EE3848B527A5432CAC42E65B24FD203BE126B15D41BA31816AB89E", + "ledger_index": 39575337, + "date": "2018-06-23T01:45:32+00:00", + "tx": { + "TransactionType": "Payment", + "Flags": 2147483648, + "Sequence": 88, + "LastLedgerSequence": 39575341, + "Amount": "1000000", + "Fee": "15", + "SigningPubKey": "03F1B487CA869E2A9A1BE170E0C1907E1AE7B9E2B7264D7452FA2ADF7E063D3A0F", + "TxnSignature": "304402204E40395CF9ABE61A1EADE83F987693F09C6D37EFD85F5A4B768FB4C4F992488602207B2618EADC36687DB9B448727426BA83B1B4596D08DF75D1D171AA5243C8BF2D", + "Account": "rK7aFKgWd1xeqhsPNPrfUbKnfttxNvCp9E", + "Destination": "rMQ98K56yXJbDGv49ZSmW51sLn94Xe1mu1", + "Memos": [ + { + "Memo": { + "MemoType": "636C69656E74", + "MemoData": "67617465687562", + "MemoFormat": "746578742F706C61696E" + } + } + ] + }, + "meta": { + "TransactionIndex": 4, + "AffectedNodes": [ + { + "ModifiedNode": { + "LedgerEntryType": "AccountRoot", + "PreviousTxnLgrSeq": 38474522, + "PreviousTxnID": "68BD7AA168163BEBA43956C0946CC87041CD72368B040F4933E6429B903A882F", + "LedgerIndex": "564241023DCB6F74760910F17F78B179AEC159C701BBACD99A1D3259D77D3CFF", + "PreviousFields": { + "Balance": "5685129681965200" + }, + "FinalFields": { + "Flags": 1048576, + "Sequence": 6, + "OwnerCount": 10, + "Balance": "5685129682965200", + "Account": "rMQ98K56yXJbDGv49ZSmW51sLn94Xe1mu1" + } + } + }, + { + "ModifiedNode": { + "LedgerEntryType": "AccountRoot", + "PreviousTxnLgrSeq": 39575141, + "PreviousTxnID": "DF2598973FA88D3B460A0461D577DADF1382882C775B2F04B023CF960C2A44BD", + "LedgerIndex": "6585D8808EC6A8B8263C7EBCA9806B4050DD299917571885FC9269FE68624B73", + "PreviousFields": { + "Sequence": 88, + "Balance": "263623032400" + }, + "FinalFields": { + "Flags": 0, + "Sequence": 89, + "OwnerCount": 9, + "Balance": "263622032385", + "Account": "rK7aFKgWd1xeqhsPNPrfUbKnfttxNvCp9E" + } + } + } + ], + "TransactionResult": "tesSUCCESS", + "delivered_amount": "1000000" + } + }, + { + "hash": "2E773CE9FAA04594B8F2465FFAD4FE932BC8E2218EF8875D3AE8A8670F9779CF", + "ledger_index": 41827297, + "date": "2018-09-27T15:32:51+00:00", + "tx": { + "TransactionType": "Payment", + "Flags": 2147483648, + "Sequence": 6, + "LastLedgerSequence": 41925142, + "Amount": "500000000000000", + "Fee": "5000", + "SigningPubKey": "", + "Account": "rMQ98K56yXJbDGv49ZSmW51sLn94Xe1mu1", + "Destination": "rNuF65SoNFRgi7KomddPeSpLhdB2Y7RnsN", + "Signers": [ + { + "Signer": { + "SigningPubKey": "03807050F9E271B2E49B0FF658362EF37DBFDD31435E610B6E11C52879DF8A9907", + "TxnSignature": "3045022100A0AF71912B1E7D2C6CA3625761901A2DA573C79EFA04136DFCC5AEC9DEFD72750220655751B42DEDB60D5AE46CA36C10952D237145939118ADB7730D1857146E894B", + "Account": "rGSxFjoqmWz54PycrgQBQ5dB6e7TUpMxzq" + } + }, + { + "Signer": { + "SigningPubKey": "02259BC18378FD3C99B92C4A41ABA65B62333980DDF28F1F60EF8EF0B5CE7AD93D", + "TxnSignature": "304502210080DC88DA724AC2986BFB5164177C970C5EDB989634C89F4098DA96E9936C6A4C0220718AC23377BAC42AD23833F962D1CEF034D43A0B9346B80E4F8AB28D5BACE933", + "Account": "rHH2gS6XikKoEt9i1xAxEBvXLHKFr7oLn8" + } + }, + { + "Signer": { + "SigningPubKey": "02FA11725F6F4E28C2E1617CC60C3A43161270A6B0C8B8DAB68265E7CFC27E0E4A", + "TxnSignature": "304402204E514E447801FBBA6A8737952ECC307389624378EEB0DCCF55340202638A969A0220488919E2675AD88D4503C87B20EC1C93FFA64E70F9D438B526EEFEE1803A26FB", + "Account": "rLW75SfEdnGVsa3fTFkSaDTzXuFapwNYtf" + } + }, + { + "Signer": { + "SigningPubKey": "03797EFEC20C8DBF46C20FCC75AB22168AAC34D9E18BFD81C3CC007DC80C389686", + "TxnSignature": "3045022100A410BCCB1A705AB06910FC92A584D6808EE6CCA8D2BDA84F6C4C229D2DAFA0150220479BB0D656E8153DDFEA1D8D012C1190FCAC306D3C6F1E8FB902110038815725", + "Account": "rMY6Wm2RWQLN4d3Jjz15MKP74GJWVQE2pb" + } + } + ] + }, + "meta": { + "TransactionIndex": 6, + "AffectedNodes": [ + { + "ModifiedNode": { + "LedgerEntryType": "AccountRoot", + "PreviousTxnLgrSeq": 39575337, + "PreviousTxnID": "FF6C1181F4EE3848B527A5432CAC42E65B24FD203BE126B15D41BA31816AB89E", + "LedgerIndex": "564241023DCB6F74760910F17F78B179AEC159C701BBACD99A1D3259D77D3CFF", + "PreviousFields": { + "Sequence": 6, + "Balance": "5685129682965200" + }, + "FinalFields": { + "Flags": 1048576, + "Sequence": 7, + "OwnerCount": 10, + "Balance": "5185129682960200", + "Account": "rMQ98K56yXJbDGv49ZSmW51sLn94Xe1mu1" + } + } + }, + { + "ModifiedNode": { + "LedgerEntryType": "AccountRoot", + "PreviousTxnLgrSeq": 34823700, + "PreviousTxnID": "10096291E3C8D5A63E7FD5A839E52BDBBCA849042426D433F85B4AA549FF9E7C", + "LedgerIndex": "9E77AE4FC38D9A41794A008692545B5402F5C251A4838D5CC2A2842598329A64", + "PreviousFields": { + "Balance": "99993000" + }, + "FinalFields": { + "Flags": 1048576, + "Sequence": 4, + "OwnerCount": 10, + "Balance": "500000099993000", + "Account": "rNuF65SoNFRgi7KomddPeSpLhdB2Y7RnsN" + } + } + } + ], + "TransactionResult": "tesSUCCESS", + "delivered_amount": "500000000000000" + } + }, + { + "hash": "6A3A36EAC8CC9EB65828D584E570A43988870A91ECD32A3C8EAD898EACCC1B1C", + "ledger_index": 43012867, + "date": "2018-11-16T01:35:41+00:00", + "tx": { + "TransactionType": "Payment", + "Flags": 2147483648, + "Sequence": 7, + "LastLedgerSequence": 43068883, + "Amount": "200000000000000", + "Fee": "5000", + "SigningPubKey": "", + "Account": "rMQ98K56yXJbDGv49ZSmW51sLn94Xe1mu1", + "Destination": "rNfwFmsgBRrtqQDcWtFAJMzK2P1yCs7XPy", + "Signers": [ + { + "Signer": { + "SigningPubKey": "0320ECD5569CAFA4E23147BE238DBFB268DB3B5A502ED339387AC7DCA0ADC6FB90", + "TxnSignature": "304502210095330DE1E672CF92E644A4DFB89C6ED7FEB80683092AD556E101ABE70BEEBCAC022028A25E06B26E29D9A76E8324065300055D7CE05B17AB8D11ACBE69F3F7460E08", + "Account": "re3LGjhrCvthtWWwrfKbVJjXN9PYDeQDJ" + } + }, + { + "Signer": { + "SigningPubKey": "03807050F9E271B2E49B0FF658362EF37DBFDD31435E610B6E11C52879DF8A9907", + "TxnSignature": "3045022100FFBFBD1D305376CC20F792E1F9C7F8FA501F6B1FE8D568E90B7DF78A6C0035E9022026D5B318122E68ED89D709368A27E8A689D39E1D03AF0584288BE5405E7D82CB", + "Account": "rGSxFjoqmWz54PycrgQBQ5dB6e7TUpMxzq" + } + }, + { + "Signer": { + "SigningPubKey": "02FA11725F6F4E28C2E1617CC60C3A43161270A6B0C8B8DAB68265E7CFC27E0E4A", + "TxnSignature": "304402206D5EF7AA9D5E2C9B85A0E0FBC1594ADC5C4CFA9266BA207620F66E78DE200676022026CC3128337A013A29D18A23465090E36C68F7ADBED92AD7E4118EB686714598", + "Account": "rLW75SfEdnGVsa3fTFkSaDTzXuFapwNYtf" + } + }, + { + "Signer": { + "SigningPubKey": "03797EFEC20C8DBF46C20FCC75AB22168AAC34D9E18BFD81C3CC007DC80C389686", + "TxnSignature": "3045022100BED21F950C0C2CED2C0EC9287E6A84AEB49618CCA847EA611674AF5039889906022031CB7A499BE9AE962F0C02EF38A47BFE9B2A7029214D7338C692F81C7B08B986", + "Account": "rMY6Wm2RWQLN4d3Jjz15MKP74GJWVQE2pb" + } + } + ] + }, + "meta": { + "TransactionIndex": 9, + "AffectedNodes": [ + { + "ModifiedNode": { + "LedgerEntryType": "AccountRoot", + "PreviousTxnLgrSeq": 42961397, + "PreviousTxnID": "C08998F3FDE4B6B569234D829B493EF1EC366EF4CF247DFC9AF30368D5AE3027", + "LedgerIndex": "42B63458984812E176A0B79A65BED3CDF103FCAD451C33E4976137EF2CE9D21F", + "PreviousFields": { + "Flags": 65536, + "Balance": "57995900" + }, + "FinalFields": { + "Flags": 0, + "Sequence": 6, + "OwnerCount": 0, + "Balance": "200000057995900", + "Account": "rNfwFmsgBRrtqQDcWtFAJMzK2P1yCs7XPy", + "RegularKey": "racz6fAfyMp7PDGiwSqAxgg9kA5xUpe8gz" + } + } + }, + { + "ModifiedNode": { + "LedgerEntryType": "AccountRoot", + "PreviousTxnLgrSeq": 41827297, + "PreviousTxnID": "2E773CE9FAA04594B8F2465FFAD4FE932BC8E2218EF8875D3AE8A8670F9779CF", + "LedgerIndex": "564241023DCB6F74760910F17F78B179AEC159C701BBACD99A1D3259D77D3CFF", + "PreviousFields": { + "Sequence": 7, + "Balance": "5185129682960200" + }, + "FinalFields": { + "Flags": 1048576, + "Sequence": 8, + "OwnerCount": 10, + "Balance": "4985129682955200", + "Account": "rMQ98K56yXJbDGv49ZSmW51sLn94Xe1mu1" + } + } + } + ], + "TransactionResult": "tesSUCCESS", + "delivered_amount": "200000000000000" + } + }, + { + "hash": "F9BD43ACE9F2510743C9A293345FF1C821D76C7A3013F4DF3FBDD75114F92D44", + "ledger_index": 43012937, + "date": "2018-11-16T01:40:02+00:00", + "tx": { + "TransactionType": "Payment", + "Flags": 2147483648, + "Sequence": 8, + "LastLedgerSequence": 43068937, + "Amount": "760000000000000", + "Fee": "5000", + "SigningPubKey": "", + "Account": "rMQ98K56yXJbDGv49ZSmW51sLn94Xe1mu1", + "Destination": "rhyp1uMC9Xyj3Px8amUH3xVv6tbjYJkojs", + "Signers": [ + { + "Signer": { + "SigningPubKey": "0320ECD5569CAFA4E23147BE238DBFB268DB3B5A502ED339387AC7DCA0ADC6FB90", + "TxnSignature": "3045022100BC3B33F91561A5C415A4FBC30C79F099367AB83772926CA4251F2E2AC91D5AC002207D3F708F9074A0092B42D0F5DAAEE3A88D3B3DC4DCD206538890ADCAF10D80E3", + "Account": "re3LGjhrCvthtWWwrfKbVJjXN9PYDeQDJ" + } + }, + { + "Signer": { + "SigningPubKey": "03807050F9E271B2E49B0FF658362EF37DBFDD31435E610B6E11C52879DF8A9907", + "TxnSignature": "3045022100CE5488B682E7463E13E648D264F0541B06C8EC41EEFFE985B27D5D685EF0E39E0220273DFEEDF0B40C3691F194D4F20180977281E1C17F016645DEC50D2A8A72E57B", + "Account": "rGSxFjoqmWz54PycrgQBQ5dB6e7TUpMxzq" + } + }, + { + "Signer": { + "SigningPubKey": "02FA11725F6F4E28C2E1617CC60C3A43161270A6B0C8B8DAB68265E7CFC27E0E4A", + "TxnSignature": "304502210087851F0C4E9F6AFD27F654A1B4C8D30CCDF267870D3E8F5C8F2D2AE3CA4E954902203FA729BE8752DC64F096EB89A27C3AD6BF402C9B436192E864DAB1B13FA8A141", + "Account": "rLW75SfEdnGVsa3fTFkSaDTzXuFapwNYtf" + } + }, + { + "Signer": { + "SigningPubKey": "03797EFEC20C8DBF46C20FCC75AB22168AAC34D9E18BFD81C3CC007DC80C389686", + "TxnSignature": "3045022100EAA85F6D82FE3F7CEAB63F30B5B01AF8BE9EF688B6EE4294A9A5E1A0E53452D202203A2CBC14B83C61C4A0A4F9335C1F173D52E42D70AFCDEDE0DB648A7A7A0A8BCF", + "Account": "rMY6Wm2RWQLN4d3Jjz15MKP74GJWVQE2pb" + } + } + ] + }, + "meta": { + "TransactionIndex": 27, + "AffectedNodes": [ + { + "ModifiedNode": { + "LedgerEntryType": "AccountRoot", + "PreviousTxnLgrSeq": 43012867, + "PreviousTxnID": "6A3A36EAC8CC9EB65828D584E570A43988870A91ECD32A3C8EAD898EACCC1B1C", + "LedgerIndex": "564241023DCB6F74760910F17F78B179AEC159C701BBACD99A1D3259D77D3CFF", + "PreviousFields": { + "Sequence": 8, + "Balance": "4985129682955200" + }, + "FinalFields": { + "Flags": 1048576, + "Sequence": 9, + "OwnerCount": 10, + "Balance": "4225129682950200", + "Account": "rMQ98K56yXJbDGv49ZSmW51sLn94Xe1mu1" + } + } + }, + { + "ModifiedNode": { + "LedgerEntryType": "AccountRoot", + "PreviousTxnLgrSeq": 34823650, + "PreviousTxnID": "78D8E1FC5F061F9EFC24DE0F4BEC430CC5F23E9EE8744B5C809275A0D4395E51", + "LedgerIndex": "F6398B7FDCC804AFC061E644C2E526C781AC54A9F0EDB3D2DF8508670BDC87BE", + "PreviousFields": { + "Balance": "99993000" + }, + "FinalFields": { + "Flags": 1048576, + "Sequence": 4, + "OwnerCount": 10, + "Balance": "760000099993000", + "Account": "rhyp1uMC9Xyj3Px8amUH3xVv6tbjYJkojs" + } + } + } + ], + "TransactionResult": "tesSUCCESS", + "delivered_amount": "760000000000000" + } + }, + { + "hash": "0E9ADE6EA164548849FCCD7DB93AF4DCEA2650F937CF544807B46AB839A76426", + "ledger_index": 43367293, + "date": "2018-11-30T21:21:11+00:00", + "tx": { + "TransactionType": "Payment", + "Flags": 2147483648, + "Sequence": 9, + "LastLedgerSequence": 43550023, + "Amount": "709565665000000", + "Fee": "5000", + "SigningPubKey": "", + "Account": "rMQ98K56yXJbDGv49ZSmW51sLn94Xe1mu1", + "Destination": "rNuF65SoNFRgi7KomddPeSpLhdB2Y7RnsN", + "Signers": [ + { + "Signer": { + "SigningPubKey": "0320ECD5569CAFA4E23147BE238DBFB268DB3B5A502ED339387AC7DCA0ADC6FB90", + "TxnSignature": "3045022100CB347DA08FE8DCFA6FEA5A64036E892D6837A2893FFC5AD8EC91BE5933960D9902203C4B28958F694C15489FFF7496EC48F8973A658EE200FBA65AA121F51FE64FF9", + "Account": "re3LGjhrCvthtWWwrfKbVJjXN9PYDeQDJ" + } + }, + { + "Signer": { + "SigningPubKey": "03807050F9E271B2E49B0FF658362EF37DBFDD31435E610B6E11C52879DF8A9907", + "TxnSignature": "304402207D15DB35E497D7830F567EEDD48F1B156088EE41ABC8653F33FAF756E8EE8FE302201C20B51FEBCED36EDB3CD320E9C18AA268DE5B9C930961673197FBD2FCDE5D0C", + "Account": "rGSxFjoqmWz54PycrgQBQ5dB6e7TUpMxzq" + } + }, + { + "Signer": { + "SigningPubKey": "029A7A9E7A6175690C6E3D46EBBA33DA9EBF096EB5942E21C4A8C98F5606E6E6B8", + "TxnSignature": "3044022006824AAD9BF45AD9013E9C62905887C8A8FCC391909D841A683E47AB3163543D02201CD4A299228B7E5B5788E66C2538700C403662DD22A700E85299BBAB9116F158", + "Account": "rHH2gS6XikKoEt9i1xAxEBvXLHKFr7oLn8" + } + }, + { + "Signer": { + "SigningPubKey": "03797EFEC20C8DBF46C20FCC75AB22168AAC34D9E18BFD81C3CC007DC80C389686", + "TxnSignature": "3045022100FA1B7353DD93E05D273C07B2FDBD13539A43F53D14C09F70478ED963B18F05D80220750EADFC4DF068EB2D9C3B62D1A709BAD0FB1D91861A7A266310E90ECD6FA83D", + "Account": "rMY6Wm2RWQLN4d3Jjz15MKP74GJWVQE2pb" + } + } + ] + }, + "meta": { + "TransactionIndex": 10, + "AffectedNodes": [ + { + "ModifiedNode": { + "LedgerEntryType": "AccountRoot", + "PreviousTxnLgrSeq": 43012937, + "PreviousTxnID": "F9BD43ACE9F2510743C9A293345FF1C821D76C7A3013F4DF3FBDD75114F92D44", + "LedgerIndex": "564241023DCB6F74760910F17F78B179AEC159C701BBACD99A1D3259D77D3CFF", + "PreviousFields": { + "Sequence": 9, + "Balance": "4225129682950200" + }, + "FinalFields": { + "Flags": 1048576, + "Sequence": 10, + "OwnerCount": 10, + "Balance": "3515564017945200", + "Account": "rMQ98K56yXJbDGv49ZSmW51sLn94Xe1mu1" + } + } + }, + { + "ModifiedNode": { + "LedgerEntryType": "AccountRoot", + "PreviousTxnLgrSeq": 42002657, + "PreviousTxnID": "6B260AA7CC3C51CBC1C7A3986F1A84B11E76C8C457D55669E2A45281A9706242", + "LedgerIndex": "9E77AE4FC38D9A41794A008692545B5402F5C251A4838D5CC2A2842598329A64", + "PreviousFields": { + "Balance": "392224236973000" + }, + "FinalFields": { + "Flags": 1048576, + "Sequence": 8, + "OwnerCount": 10, + "Balance": "1101789901973000", + "Account": "rNuF65SoNFRgi7KomddPeSpLhdB2Y7RnsN" + } + } + } + ], + "TransactionResult": "tesSUCCESS", + "delivered_amount": "709565665000000" + } + }, + { + "hash": "5581E189FDBA282D55FBED3936C25FACE36DBCA7F731E0BEEF2EE9BF737A5855", + "ledger_index": 43374095, + "date": "2018-12-01T04:06:11+00:00", + "tx": { + "TransactionType": "Payment", + "SourceTag": 5913, + "Sequence": 3585, + "DestinationTag": 0, + "LastLedgerSequence": 43374098, + "Amount": "5890", + "Fee": "12", + "SigningPubKey": "03DF3AB842EB1B57F0A848CD7CC2CFD35F66E4AD0625EEACFFE72A45E4D13E49AB", + "TxnSignature": "304502210086004E950E55F238EA0E108B066FE8F71BB079A25D78A32BF37F0F81AFFD3A0B022035234292D4C6D3B78178C17E54BFD418A864CB08B9D9CA71A64F6BEE24F6D1C0", + "Account": "rPEPPER7kfTD9w2To4CQk6UCfuHM9c6GDY", + "Destination": "rMQ98K56yXJbDGv49ZSmW51sLn94Xe1mu1", + "Memos": [ + { + "Memo": { + "MemoType": "587270546970426F744E6F7465", + "MemoData": "5365636F6E64617279204C697175696469747920506F6F6C206E6F74206C6F636B656420696E20657363726F773F203230304D2052656C65617365642040354D2F706572206F6E2031737420616E64203135746820666F722032304D6F6E746873207374617274696E672031322F3230313820536F757263656420686572652E207E53616D49616D" + } + } + ] + }, + "meta": { + "TransactionIndex": 5, + "AffectedNodes": [ + { + "ModifiedNode": { + "LedgerEntryType": "AccountRoot", + "PreviousTxnLgrSeq": 43373864, + "PreviousTxnID": "BC8809D9499F8EE41BC3AEE2710D3342DDD815174F659F9B6897264095DC6518", + "LedgerIndex": "44EF183C00DFCB5DAF505684AA7967C83F42C085EBA6B271E5349CB12C3D5965", + "PreviousFields": { + "Sequence": 3585, + "Balance": "9405394584" + }, + "FinalFields": { + "Flags": 131072, + "Sequence": 3586, + "OwnerCount": 51, + "EmailHash": "833237B8665D2F4E00135E8DE646589F", + "Balance": "9405388682", + "Domain": "787270746970626F742E636F6D", + "Account": "rPEPPER7kfTD9w2To4CQk6UCfuHM9c6GDY" + } + } + }, + { + "ModifiedNode": { + "LedgerEntryType": "AccountRoot", + "PreviousTxnLgrSeq": 43367293, + "PreviousTxnID": "0E9ADE6EA164548849FCCD7DB93AF4DCEA2650F937CF544807B46AB839A76426", + "LedgerIndex": "564241023DCB6F74760910F17F78B179AEC159C701BBACD99A1D3259D77D3CFF", + "PreviousFields": { + "Balance": "3515564017945200" + }, + "FinalFields": { + "Flags": 1048576, + "Sequence": 10, + "OwnerCount": 10, + "Balance": "3515564017951090", + "Account": "rMQ98K56yXJbDGv49ZSmW51sLn94Xe1mu1" + } + } + } + ], + "TransactionResult": "tesSUCCESS", + "delivered_amount": "5890" + } + }, + { + "hash": "04B9FFC2AB5F5FDC95D1BCE94AD229D1046149DAEC6807326BED1B4A5D8D0862", + "ledger_index": 43707148, + "date": "2018-12-15T04:24:02+00:00", + "tx": { + "TransactionType": "Payment", + "Flags": 2147483648, + "Sequence": 3, + "LastLedgerSequence": 43707157, + "Amount": "1000000", + "Fee": "10", + "SigningPubKey": "03ED3E890B17383F9CD91562087184E27509657B1276A22BE2EA968F8A47490592", + "TxnSignature": "3044022061B2FBCF22EFF32182CA4EDAB00870E9B5A548C63893B517DC3A54E00CA9F5F602207A671E3D9218A38497EAF53F10A66F8CF6484ED4F6574FA371A72565651C95FC", + "Account": "rDJ8NURUAxq3MDS8xAZNCx45VH159m2RW3", + "Destination": "rMQ98K56yXJbDGv49ZSmW51sLn94Xe1mu1" + }, + "meta": { + "TransactionIndex": 1, + "AffectedNodes": [ + { + "ModifiedNode": { + "LedgerEntryType": "AccountRoot", + "PreviousTxnLgrSeq": 43706798, + "PreviousTxnID": "97089534B6586ECED80AC176FE8CA26ACB3B6981BD48590EA9213322F09C3F26", + "LedgerIndex": "1F55D96C737869F0D45E7D46A012B22D0171D159BA3F30D3A6C4E00BA7D28E59", + "PreviousFields": { + "Sequence": 3, + "Balance": "239999990" + }, + "FinalFields": { + "Flags": 0, + "Sequence": 4, + "OwnerCount": 0, + "Balance": "238999980", + "Account": "rDJ8NURUAxq3MDS8xAZNCx45VH159m2RW3" + } + } + }, + { + "ModifiedNode": { + "LedgerEntryType": "AccountRoot", + "PreviousTxnLgrSeq": 43374095, + "PreviousTxnID": "5581E189FDBA282D55FBED3936C25FACE36DBCA7F731E0BEEF2EE9BF737A5855", + "LedgerIndex": "564241023DCB6F74760910F17F78B179AEC159C701BBACD99A1D3259D77D3CFF", + "PreviousFields": { + "Balance": "3515564017951090" + }, + "FinalFields": { + "Flags": 1048576, + "Sequence": 10, + "OwnerCount": 10, + "Balance": "3515564018951090", + "Account": "rMQ98K56yXJbDGv49ZSmW51sLn94Xe1mu1" + } + } + } + ], + "TransactionResult": "tesSUCCESS", + "delivered_amount": "1000000" + } + }, + { + "hash": "B89145E7420FCDCBB5795C0161619FA53F790ED72F14C03A2473346EC864824A", + "ledger_index": 44108034, + "date": "2019-01-01T17:05:02+00:00", + "tx": { + "TransactionType": "Payment", + "Flags": 2147483648, + "Sequence": 7, + "LastLedgerSequence": 44334798, + "Amount": "1108302303980000", + "Fee": "500", + "SigningPubKey": "", + "Account": "r93oSNBKuFjuKt8GxhF8VYaGzzwsNDPaX5", + "Destination": "rMQ98K56yXJbDGv49ZSmW51sLn94Xe1mu1", + "Signers": [ + { + "Signer": { + "SigningPubKey": "0320ECD5569CAFA4E23147BE238DBFB268DB3B5A502ED339387AC7DCA0ADC6FB90", + "TxnSignature": "3045022100985C236B3356C45664401C08BA779E27C73FDB4EE2DF71E0DAB74D1437D6B8C602207DC8B6B15D72CFD324569BBD5B722FD8830EE92CF6BBAF31497FDE782C19CD97", + "Account": "re3LGjhrCvthtWWwrfKbVJjXN9PYDeQDJ" + } + }, + { + "Signer": { + "SigningPubKey": "03807050F9E271B2E49B0FF658362EF37DBFDD31435E610B6E11C52879DF8A9907", + "TxnSignature": "304402205700D610EDD0CF37809CD51C194657E1B28FB54C71B00743142E020189A7EE5D022071338D4E10F4F20722B5A222165AA6E0E22EB28EBE0C18ACB2F54F99A4C2BB17", + "Account": "rGSxFjoqmWz54PycrgQBQ5dB6e7TUpMxzq" + } + }, + { + "Signer": { + "SigningPubKey": "02FA11725F6F4E28C2E1617CC60C3A43161270A6B0C8B8DAB68265E7CFC27E0E4A", + "TxnSignature": "3045022100E1702141044877476C982DE6CCB1CE5AE328E38218046D7A25CD6C9C4CD3C8E6022006ADFB93730214FC7B94712220840B37AB288B720DB48AAFE5B25B512835A507", + "Account": "rLW75SfEdnGVsa3fTFkSaDTzXuFapwNYtf" + } + }, + { + "Signer": { + "SigningPubKey": "03797EFEC20C8DBF46C20FCC75AB22168AAC34D9E18BFD81C3CC007DC80C389686", + "TxnSignature": "30440220667B90CF533DA0A0C32D7E593B0F406B08CE8BB3D68C35D3549FDE6B2CE1AA0F022012854E0FC110F5013650F30B8BB144C435189C8D46ECA8E2789A609EA7CF7871", + "Account": "rMY6Wm2RWQLN4d3Jjz15MKP74GJWVQE2pb" + } + } + ] + }, + "meta": { + "TransactionIndex": 4, + "AffectedNodes": [ + { + "ModifiedNode": { + "LedgerEntryType": "AccountRoot", + "PreviousTxnLgrSeq": 43707148, + "PreviousTxnID": "04B9FFC2AB5F5FDC95D1BCE94AD229D1046149DAEC6807326BED1B4A5D8D0862", + "LedgerIndex": "564241023DCB6F74760910F17F78B179AEC159C701BBACD99A1D3259D77D3CFF", + "PreviousFields": { + "Balance": "3515564018951090" + }, + "FinalFields": { + "Flags": 1048576, + "Sequence": 10, + "OwnerCount": 10, + "Balance": "4623866322931090", + "Account": "rMQ98K56yXJbDGv49ZSmW51sLn94Xe1mu1" + } + } + }, + { + "ModifiedNode": { + "LedgerEntryType": "AccountRoot", + "PreviousTxnLgrSeq": 43702504, + "PreviousTxnID": "6EE150A056061F4DDB77D8AF282DB9F5ABDD9F244CF09B020BAF5DFFE014E668", + "LedgerIndex": "8E329FA7CCE1E2F0CB9D14D6647D2368B7F68080AE4D7D589FFA7E70F2B80017", + "PreviousFields": { + "Sequence": 7, + "Balance": "2080000078978000" + }, + "FinalFields": { + "Flags": 1048576, + "Sequence": 8, + "OwnerCount": 10, + "Balance": "971697774997500", + "Account": "r93oSNBKuFjuKt8GxhF8VYaGzzwsNDPaX5" + } + } + } + ], + "TransactionResult": "tesSUCCESS", + "delivered_amount": "1108302303980000" + } + }, + { + "hash": "63429809CA00D66A3C7317876E8E21D14E4E1C5C3EEEA42D5E5F7B0C44A10C82", + "ledger_index": 44108075, + "date": "2019-01-01T17:07:42+00:00", + "tx": { + "TransactionType": "Payment", + "Flags": 2147483648, + "Sequence": 10, + "LastLedgerSequence": 44334747, + "Amount": "107866784000000", + "Fee": "500", + "SigningPubKey": "", + "Account": "rMQ98K56yXJbDGv49ZSmW51sLn94Xe1mu1", + "Destination": "rNuF65SoNFRgi7KomddPeSpLhdB2Y7RnsN", + "Signers": [ + { + "Signer": { + "SigningPubKey": "0320ECD5569CAFA4E23147BE238DBFB268DB3B5A502ED339387AC7DCA0ADC6FB90", + "TxnSignature": "304402204465A4271C16C5494F2E36A2F4CC344CB215B0840BFDAA8AB87F8BF155ADC87202201BE337A394182F8023B397E87050677F33075BF077079239C655639B6D06424B", + "Account": "re3LGjhrCvthtWWwrfKbVJjXN9PYDeQDJ" + } + }, + { + "Signer": { + "SigningPubKey": "03807050F9E271B2E49B0FF658362EF37DBFDD31435E610B6E11C52879DF8A9907", + "TxnSignature": "3045022100889EA900F6E3F408C60797FBB3B3E6AC45A9ED19052B61DE328BF71F84992A69022066639B85840097339D054A7253A7E6FEBA639AB9F30029ACE487CB15F093B632", + "Account": "rGSxFjoqmWz54PycrgQBQ5dB6e7TUpMxzq" + } + }, + { + "Signer": { + "SigningPubKey": "02FA11725F6F4E28C2E1617CC60C3A43161270A6B0C8B8DAB68265E7CFC27E0E4A", + "TxnSignature": "30440220455D940A2F8FC47BE3C31E58748FCCB351F6AA1F7B7EBD509051F2B9D8B7685B0220212B9D978CB36EA0DFE372D5A4C2D06DFCD24F1384A89A24A30072DAE9B6F87E", + "Account": "rLW75SfEdnGVsa3fTFkSaDTzXuFapwNYtf" + } + }, + { + "Signer": { + "SigningPubKey": "03797EFEC20C8DBF46C20FCC75AB22168AAC34D9E18BFD81C3CC007DC80C389686", + "TxnSignature": "30450221009FF3ECC2BC7BD67F9B506C03D5E9FA3B22D58DF343DB57F4AE9046980E101E0D0220088C96E2E1275F6A611B7EC007118F4CB1529796020658BF6D12C23EC78EE111", + "Account": "rMY6Wm2RWQLN4d3Jjz15MKP74GJWVQE2pb" + } + } + ] + }, + "meta": { + "TransactionIndex": 7, + "AffectedNodes": [ + { + "ModifiedNode": { + "LedgerEntryType": "AccountRoot", + "PreviousTxnLgrSeq": 44108034, + "PreviousTxnID": "B89145E7420FCDCBB5795C0161619FA53F790ED72F14C03A2473346EC864824A", + "LedgerIndex": "564241023DCB6F74760910F17F78B179AEC159C701BBACD99A1D3259D77D3CFF", + "PreviousFields": { + "Sequence": 10, + "Balance": "4623866322931090" + }, + "FinalFields": { + "Flags": 1048576, + "Sequence": 11, + "OwnerCount": 10, + "Balance": "4515999538930590", + "Account": "rMQ98K56yXJbDGv49ZSmW51sLn94Xe1mu1" + } + } + }, + { + "ModifiedNode": { + "LedgerEntryType": "AccountRoot", + "PreviousTxnLgrSeq": 43927137, + "PreviousTxnID": "976861787CFA9CA97456849C0092BBE795F1BBFA5153D3FD6E6EDCF2AF7D2E0F", + "LedgerIndex": "9E77AE4FC38D9A41794A008692545B5402F5C251A4838D5CC2A2842598329A64", + "PreviousFields": { + "Balance": "941106818023790" + }, + "FinalFields": { + "Flags": 1048576, + "Sequence": 11, + "OwnerCount": 10, + "Balance": "1048973602023790", + "Account": "rNuF65SoNFRgi7KomddPeSpLhdB2Y7RnsN" + } + } + } + ], + "TransactionResult": "tesSUCCESS", + "delivered_amount": "107866784000000" + } + }, + { + "hash": "9224129EC239ADB8C8659C711DFF9D364367FA79C1F7BC36C8F2AC664C50C0C1", + "ledger_index": 44115937, + "date": "2019-01-02T01:29:10+00:00", + "tx": { + "TransactionType": "Payment", + "SourceTag": 4112, + "Sequence": 4793, + "DestinationTag": 0, + "LastLedgerSequence": 44115940, + "Amount": "1", + "Fee": "12", + "SigningPubKey": "03DF3AB842EB1B57F0A848CD7CC2CFD35F66E4AD0625EEACFFE72A45E4D13E49AB", + "TxnSignature": "3045022100CD28E00906245332F2E65A84860F8D78B369E430399D0DB4243CA336FB1C17D502207947318F7809B8025AFE9F4EBEE6798FE11C73AD6CF58DDC08FB0F60DCEA8902", + "Account": "rPEPPER7kfTD9w2To4CQk6UCfuHM9c6GDY", + "Destination": "rMQ98K56yXJbDGv49ZSmW51sLn94Xe1mu1", + "Memos": [ + { + "Memo": { + "MemoType": "587270546970426F744E6F7465", + "MemoData": "5468652040526970706C654E696E6A612077617320686572652121" + } + } + ] + }, + "meta": { + "TransactionIndex": 0, + "AffectedNodes": [ + { + "ModifiedNode": { + "LedgerEntryType": "AccountRoot", + "PreviousTxnLgrSeq": 44115921, + "PreviousTxnID": "A10B3A39BAC7FAFABBF0091F175DB7325B1F6B404EB403CDA37FF80581B243AB", + "LedgerIndex": "44EF183C00DFCB5DAF505684AA7967C83F42C085EBA6B271E5349CB12C3D5965", + "PreviousFields": { + "Sequence": 4793, + "Balance": "13529497722" + }, + "FinalFields": { + "Flags": 131072, + "Sequence": 4794, + "OwnerCount": 66, + "EmailHash": "833237B8665D2F4E00135E8DE646589F", + "Balance": "13529497709", + "Domain": "787270746970626F742E636F6D", + "Account": "rPEPPER7kfTD9w2To4CQk6UCfuHM9c6GDY" + } + } + }, + { + "ModifiedNode": { + "LedgerEntryType": "AccountRoot", + "PreviousTxnLgrSeq": 44108075, + "PreviousTxnID": "63429809CA00D66A3C7317876E8E21D14E4E1C5C3EEEA42D5E5F7B0C44A10C82", + "LedgerIndex": "564241023DCB6F74760910F17F78B179AEC159C701BBACD99A1D3259D77D3CFF", + "PreviousFields": { + "Balance": "4515999538930590" + }, + "FinalFields": { + "Flags": 1048576, + "Sequence": 11, + "OwnerCount": 10, + "Balance": "4515999538930591", + "Account": "rMQ98K56yXJbDGv49ZSmW51sLn94Xe1mu1" + } + } + } + ], + "TransactionResult": "tesSUCCESS", + "delivered_amount": "1" + } + }, + { + "hash": "665E556F663246371F3BDD0E319B0BD65C8546B359E17B5C0785A1D0D3934E22", + "ledger_index": 44644540, + "date": "2019-01-24T22:51:10+00:00", + "tx": { + "TransactionType": "Payment", + "Flags": 2147483648, + "Sequence": 11, + "LastLedgerSequence": 44867434, + "Amount": "105000000", + "Fee": "500", + "SigningPubKey": "", + "Account": "rMQ98K56yXJbDGv49ZSmW51sLn94Xe1mu1", + "Destination": "rUEchj8k8jvVXKGhfVYvrs5ntVEtc5F2hK", + "Signers": [ + { + "Signer": { + "SigningPubKey": "03807050F9E271B2E49B0FF658362EF37DBFDD31435E610B6E11C52879DF8A9907", + "TxnSignature": "3045022100828E4EA1AEA3DBB9C5E01237DA78C613727BA1B2699867E3E26643EF9DD6AC9B02203D7C0C3810AB7E9F8494C8D02B81903F76AF0781CA0C91DF53A47E07997FB11F", + "Account": "rGSxFjoqmWz54PycrgQBQ5dB6e7TUpMxzq" + } + }, + { + "Signer": { + "SigningPubKey": "029A7A9E7A6175690C6E3D46EBBA33DA9EBF096EB5942E21C4A8C98F5606E6E6B8", + "TxnSignature": "3045022100E1D7E415924E30CA08329256396B4E11E5C8DBEE95D8521FAC4F60662E1CC020022009EEDFF57949AAF640FA8AC204E7AC099D41EE31976BD4FAF7410706DD31BFA5", + "Account": "rHH2gS6XikKoEt9i1xAxEBvXLHKFr7oLn8" + } + }, + { + "Signer": { + "SigningPubKey": "03797EFEC20C8DBF46C20FCC75AB22168AAC34D9E18BFD81C3CC007DC80C389686", + "TxnSignature": "3044022071028401D9E77304284AA5A136033DFB069F78E78383D1E705B5A60ACC0A4DA302205867226D428048BC4965F8A846D47BE20667E390213218C63380F82DBC64DAF6", + "Account": "rMY6Wm2RWQLN4d3Jjz15MKP74GJWVQE2pb" + } + }, + { + "Signer": { + "SigningPubKey": "0368CFF85FEF68857A445A3F51FFC6119F2A113C9590E898351CE49F61BA71E6E8", + "TxnSignature": "3045022100B86A960BB4B35B187ED74A6898942A1A040212E1368B8B12061C1C2E208969C60220284FF751E41865A6F704A077E29CFCB55DEC6E302CFB978E1F3776B188A0F249", + "Account": "rP5xpZ5KzPih69fLhG3NYvZEDfLmSEViUk" + } + } + ] + }, + "meta": { + "TransactionIndex": 3, + "AffectedNodes": [ + { + "CreatedNode": { + "LedgerEntryType": "AccountRoot", + "LedgerIndex": "459E688FB21500B75D59CBFA49EB4C17C54E81D32A7A69CF1910691AB6AA4DCC", + "NewFields": { + "Sequence": 1, + "Balance": "105000000", + "Account": "rUEchj8k8jvVXKGhfVYvrs5ntVEtc5F2hK" + } + } + }, + { + "ModifiedNode": { + "LedgerEntryType": "AccountRoot", + "PreviousTxnLgrSeq": 44115937, + "PreviousTxnID": "9224129EC239ADB8C8659C711DFF9D364367FA79C1F7BC36C8F2AC664C50C0C1", + "LedgerIndex": "564241023DCB6F74760910F17F78B179AEC159C701BBACD99A1D3259D77D3CFF", + "PreviousFields": { + "Sequence": 11, + "Balance": "4515999538930591" + }, + "FinalFields": { + "Flags": 1048576, + "Sequence": 12, + "OwnerCount": 10, + "Balance": "4515999433930091", + "Account": "rMQ98K56yXJbDGv49ZSmW51sLn94Xe1mu1" + } + } + } + ], + "TransactionResult": "tesSUCCESS", + "delivered_amount": "105000000" + } + }, + { + "hash": "AB83FFE7B46FF4E44BC084DFBEBBCFAA09913770766CCBFC0B1858E8195CE94E", + "ledger_index": 44734265, + "date": "2019-01-28T18:57:50+00:00", + "tx": { + "TransactionType": "Payment", + "Flags": 2147483648, + "Sequence": 12, + "LastLedgerSequence": 44913163, + "Amount": "392834642660000", + "Fee": "500", + "SigningPubKey": "", + "Account": "rMQ98K56yXJbDGv49ZSmW51sLn94Xe1mu1", + "Destination": "rUEchj8k8jvVXKGhfVYvrs5ntVEtc5F2hK", + "Signers": [ + { + "Signer": { + "SigningPubKey": "03807050F9E271B2E49B0FF658362EF37DBFDD31435E610B6E11C52879DF8A9907", + "TxnSignature": "304402204DFFC9AE5E85D59DF9CF7B1D5E4C4338FE2EC20FC66704AEC2F184677F33BC960220023580FD9BB17860E77B2D5D96D404DC387CA49C564E1DFF486D6F0206703E6A", + "Account": "rGSxFjoqmWz54PycrgQBQ5dB6e7TUpMxzq" + } + }, + { + "Signer": { + "SigningPubKey": "029A7A9E7A6175690C6E3D46EBBA33DA9EBF096EB5942E21C4A8C98F5606E6E6B8", + "TxnSignature": "3045022100BC7EB6E8AFC95E6FE75DE1790027CE425DB6684D59B9411383205DA4CECAD464022036BF1E5CBA757C0B74BE3F9133FD8F5BEF46D42130259443DE845DEB8650CEE7", + "Account": "rHH2gS6XikKoEt9i1xAxEBvXLHKFr7oLn8" + } + }, + { + "Signer": { + "SigningPubKey": "03797EFEC20C8DBF46C20FCC75AB22168AAC34D9E18BFD81C3CC007DC80C389686", + "TxnSignature": "304402206F15B3D3F5E5C2E397D232656417B7A79B22EB11B29997A7135D3EBE471B40A9022054F5525D5ECD2C6B681C60DD9ACA6AB8D6B10107FE8C5DDE483786FA8ECAE9F2", + "Account": "rMY6Wm2RWQLN4d3Jjz15MKP74GJWVQE2pb" + } + }, + { + "Signer": { + "SigningPubKey": "0368CFF85FEF68857A445A3F51FFC6119F2A113C9590E898351CE49F61BA71E6E8", + "TxnSignature": "304402201A72F38B0B70A8AB788C561B10B686E0FC99096F625DF224153B0F71DC31BB7F022060FD53CF1892F27A24597FF9E77696058650CA978B91603740F91C81DE0C5282", + "Account": "rP5xpZ5KzPih69fLhG3NYvZEDfLmSEViUk" + } + } + ] + }, + "meta": { + "TransactionIndex": 10, + "AffectedNodes": [ + { + "ModifiedNode": { + "LedgerEntryType": "AccountRoot", + "PreviousTxnLgrSeq": 44644540, + "PreviousTxnID": "665E556F663246371F3BDD0E319B0BD65C8546B359E17B5C0785A1D0D3934E22", + "LedgerIndex": "459E688FB21500B75D59CBFA49EB4C17C54E81D32A7A69CF1910691AB6AA4DCC", + "PreviousFields": { + "Balance": "105000000" + }, + "FinalFields": { + "Flags": 0, + "Sequence": 1, + "OwnerCount": 0, + "Balance": "392834747660000", + "Account": "rUEchj8k8jvVXKGhfVYvrs5ntVEtc5F2hK" + } + } + }, + { + "ModifiedNode": { + "LedgerEntryType": "AccountRoot", + "PreviousTxnLgrSeq": 44644540, + "PreviousTxnID": "665E556F663246371F3BDD0E319B0BD65C8546B359E17B5C0785A1D0D3934E22", + "LedgerIndex": "564241023DCB6F74760910F17F78B179AEC159C701BBACD99A1D3259D77D3CFF", + "PreviousFields": { + "Sequence": 12, + "Balance": "4515999433930091" + }, + "FinalFields": { + "Flags": 1048576, + "Sequence": 13, + "OwnerCount": 10, + "Balance": "4123164791269591", + "Account": "rMQ98K56yXJbDGv49ZSmW51sLn94Xe1mu1" + } + } + } + ], + "TransactionResult": "tesSUCCESS", + "delivered_amount": "392834642660000" + } + }, + { + "hash": "20F2F95E4612296B1A82CC72F0DC53C9EAA8DA1557A0D0AD6C1E3BCA7E67E7CE", + "ledger_index": 44734671, + "date": "2019-01-28T19:22:50+00:00", + "tx": { + "TransactionType": "Payment", + "Flags": 2147483648, + "Sequence": 13, + "LastLedgerSequence": 44913253, + "Amount": "392834642660000", + "Fee": "500", + "SigningPubKey": "", + "Account": "rMQ98K56yXJbDGv49ZSmW51sLn94Xe1mu1", + "Destination": "rUEchj8k8jvVXKGhfVYvrs5ntVEtc5F2hK", + "Signers": [ + { + "Signer": { + "SigningPubKey": "03807050F9E271B2E49B0FF658362EF37DBFDD31435E610B6E11C52879DF8A9907", + "TxnSignature": "30440220247A6624588612C73EEC2CD5F8D0A74E7FF7EE36E1ECFFF413703E928654824702205E9F5DB179A9146331935C5B5762AAAE52AE09EFDDEFDA6C596A53AE870464D2", + "Account": "rGSxFjoqmWz54PycrgQBQ5dB6e7TUpMxzq" + } + }, + { + "Signer": { + "SigningPubKey": "029A7A9E7A6175690C6E3D46EBBA33DA9EBF096EB5942E21C4A8C98F5606E6E6B8", + "TxnSignature": "304402201DFB1E6C459753DAAD5AA6D0D44501D5D1B067F18733E2DE23F3DA9E6F4A03E602201BD890DCDDA34E8304C7C29209EAAB3C34DE07C9FD4CF2537848EA4CA02FA1BB", + "Account": "rHH2gS6XikKoEt9i1xAxEBvXLHKFr7oLn8" + } + }, + { + "Signer": { + "SigningPubKey": "03797EFEC20C8DBF46C20FCC75AB22168AAC34D9E18BFD81C3CC007DC80C389686", + "TxnSignature": "304402205E1D7DE31B9E88848E370AD7D5D77FF16CED0807A3514918BA41718040A9721F02207A832DA5575C0B66B9FF0AC6C1C0BFAF15359727221A97D2027A69CFDA953297", + "Account": "rMY6Wm2RWQLN4d3Jjz15MKP74GJWVQE2pb" + } + }, + { + "Signer": { + "SigningPubKey": "0368CFF85FEF68857A445A3F51FFC6119F2A113C9590E898351CE49F61BA71E6E8", + "TxnSignature": "304402204BB844E6102A40079C9616AB888C7332F000353665B4FA972525B261DB3DDED6022018586112E834D6BC3A2A2151A4F39304B1357EB11617EE84ED55D862D7978E7C", + "Account": "rP5xpZ5KzPih69fLhG3NYvZEDfLmSEViUk" + } + } + ] + }, + "meta": { + "TransactionIndex": 2, + "AffectedNodes": [ + { + "ModifiedNode": { + "LedgerEntryType": "AccountRoot", + "PreviousTxnLgrSeq": 44734265, + "PreviousTxnID": "AB83FFE7B46FF4E44BC084DFBEBBCFAA09913770766CCBFC0B1858E8195CE94E", + "LedgerIndex": "459E688FB21500B75D59CBFA49EB4C17C54E81D32A7A69CF1910691AB6AA4DCC", + "PreviousFields": { + "Balance": "392834747660000" + }, + "FinalFields": { + "Flags": 0, + "Sequence": 1, + "OwnerCount": 0, + "Balance": "785669390320000", + "Account": "rUEchj8k8jvVXKGhfVYvrs5ntVEtc5F2hK" + } + } + }, + { + "ModifiedNode": { + "LedgerEntryType": "AccountRoot", + "PreviousTxnLgrSeq": 44734265, + "PreviousTxnID": "AB83FFE7B46FF4E44BC084DFBEBBCFAA09913770766CCBFC0B1858E8195CE94E", + "LedgerIndex": "564241023DCB6F74760910F17F78B179AEC159C701BBACD99A1D3259D77D3CFF", + "PreviousFields": { + "Sequence": 13, + "Balance": "4123164791269591" + }, + "FinalFields": { + "Flags": 1048576, + "Sequence": 14, + "OwnerCount": 10, + "Balance": "3730330148609091", + "Account": "rMQ98K56yXJbDGv49ZSmW51sLn94Xe1mu1" + } + } + } + ], + "TransactionResult": "tesSUCCESS", + "delivered_amount": "392834642660000" + } + }, + { + "hash": "000BC2AFC047BE45C43886109720F44B6F3F2434D59B1A16A9B2B4FC9B9C5A13", + "ledger_index": 51969362, + "date": "2019-12-11T00:00:01+00:00", + "tx": { + "TransactionType": "Payment", + "Flags": 2147483648, + "Sequence": 14, + "LastLedgerSequence": 52151515, + "Amount": "220303137120000", + "Fee": "5000", + "SigningPubKey": "", + "Account": "rMQ98K56yXJbDGv49ZSmW51sLn94Xe1mu1", + "Destination": "r3a8tn1ubcP13np3giaLYzkmVKfnhLP2BL", + "Signers": [ + { + "Signer": { + "SigningPubKey": "03807050F9E271B2E49B0FF658362EF37DBFDD31435E610B6E11C52879DF8A9907", + "TxnSignature": "3045022100BC1FBB9457B5A8684AACA1E949DB2640CE1D0C9907AA060D334655F4162D27D0022028DD17C6E2AAD9863D2FA7BE7F0D80D4181CB9B9349371959E5DB2D69BF662D3", + "Account": "rGSxFjoqmWz54PycrgQBQ5dB6e7TUpMxzq" + } + }, + { + "Signer": { + "SigningPubKey": "029A7A9E7A6175690C6E3D46EBBA33DA9EBF096EB5942E21C4A8C98F5606E6E6B8", + "TxnSignature": "3044022014FA8252577C836D14D796B59C74F377A23EE1D335AEB68ED21A4BF5D4D05BBE022054361EEC50A8F3C4A4AF4EFE61C83B399F7B5240C42C2FD4BBBCEAB1CFF138B4", + "Account": "rHH2gS6XikKoEt9i1xAxEBvXLHKFr7oLn8" + } + }, + { + "Signer": { + "SigningPubKey": "03797EFEC20C8DBF46C20FCC75AB22168AAC34D9E18BFD81C3CC007DC80C389686", + "TxnSignature": "3045022100B407D26B1A4ABAA6C0BC9C99EDB0DCB280852EF21974D82C8C8E5866FB08187A02207255B8CD26CCEFD8ACA1DD63A767CCC127AE6EA2115CC2F89D1B798EBFA3316C", + "Account": "rMY6Wm2RWQLN4d3Jjz15MKP74GJWVQE2pb" + } + }, + { + "Signer": { + "SigningPubKey": "0368CFF85FEF68857A445A3F51FFC6119F2A113C9590E898351CE49F61BA71E6E8", + "TxnSignature": "3045022100A0A5FD62D9EC81D1F0C5474A7EEB31C45423D647764B352F947617C383CD9E6902201896720DB3B9876FE56DEA05E4F75B3F90A20B3A5EF95E39703F80F5166BD1F6", + "Account": "rP5xpZ5KzPih69fLhG3NYvZEDfLmSEViUk" + } + } + ] + }, + "meta": { + "TransactionIndex": 0, + "AffectedNodes": [ + { + "ModifiedNode": { + "LedgerEntryType": "AccountRoot", + "PreviousTxnLgrSeq": 51901464, + "PreviousTxnID": "607A53B712B938B1475D194EC4F3318E6EC4BACD430D6C5437AA4018F1754A2A", + "LedgerIndex": "45806910346E5E79AE202994014742DEDA552A6197C19E03C4DC5C5466A00DB2", + "PreviousFields": { + "Balance": "120000000" + }, + "FinalFields": { + "Flags": 0, + "Sequence": 2, + "OwnerCount": 0, + "Balance": "220303257120000", + "Account": "r3a8tn1ubcP13np3giaLYzkmVKfnhLP2BL" + } + } + }, + { + "ModifiedNode": { + "LedgerEntryType": "AccountRoot", + "PreviousTxnLgrSeq": 44734671, + "PreviousTxnID": "20F2F95E4612296B1A82CC72F0DC53C9EAA8DA1557A0D0AD6C1E3BCA7E67E7CE", + "LedgerIndex": "564241023DCB6F74760910F17F78B179AEC159C701BBACD99A1D3259D77D3CFF", + "PreviousFields": { + "Sequence": 14, + "Balance": "3730330148609091" + }, + "FinalFields": { + "Flags": 1048576, + "Sequence": 15, + "OwnerCount": 10, + "Balance": "3510027011484091", + "Account": "rMQ98K56yXJbDGv49ZSmW51sLn94Xe1mu1" + } + } + } + ], + "TransactionResult": "tesSUCCESS", + "delivered_amount": "220303137120000" + } + } + ] +} \ No newline at end of file diff --git a/mock/ext-api-data/stellar-api_accounts_GDKIJJIKXLOM2NRMPNQZUUYK24ZPVFC6426GZAEP3KUK6KEJLACCWNMX_payments__limit_25_order_desc.json b/mock/ext-api-data/stellar-api_accounts_GDKIJJIKXLOM2NRMPNQZUUYK24ZPVFC6426GZAEP3KUK6KEJLACCWNMX_payments__limit_25_order_desc.json new file mode 100644 index 000000000..2cecc0b5e --- /dev/null +++ b/mock/ext-api-data/stellar-api_accounts_GDKIJJIKXLOM2NRMPNQZUUYK24ZPVFC6426GZAEP3KUK6KEJLACCWNMX_payments__limit_25_order_desc.json @@ -0,0 +1,792 @@ +{ + "_links": { + "self": { + "href": "https://horizon.stellar.org/accounts/GDKIJJIKXLOM2NRMPNQZUUYK24ZPVFC6426GZAEP3KUK6KEJLACCWNMX/payments?cursor=\u0026limit=25\u0026order=desc" + }, + "next": { + "href": "https://horizon.stellar.org/accounts/GDKIJJIKXLOM2NRMPNQZUUYK24ZPVFC6426GZAEP3KUK6KEJLACCWNMX/payments?cursor=99566434367078401\u0026limit=25\u0026order=desc" + }, + "prev": { + "href": "https://horizon.stellar.org/accounts/GDKIJJIKXLOM2NRMPNQZUUYK24ZPVFC6426GZAEP3KUK6KEJLACCWNMX/payments?cursor=126805490620608513\u0026limit=25\u0026order=asc" + } + }, + "_embedded": { + "records": [ + { + "_links": { + "self": { + "href": "https://horizon.stellar.org/operations/126805490620608513" + }, + "transaction": { + "href": "https://horizon.stellar.org/transactions/9fbf86268628fc41da6c984a764793f43bcac3b92ed2add6c87ecd0c9fe4d648" + }, + "effects": { + "href": "https://horizon.stellar.org/operations/126805490620608513/effects" + }, + "succeeds": { + "href": "https://horizon.stellar.org/effects?order=desc\u0026cursor=126805490620608513" + }, + "precedes": { + "href": "https://horizon.stellar.org/effects?order=asc\u0026cursor=126805490620608513" + } + }, + "id": "126805490620608513", + "paging_token": "126805490620608513", + "transaction_successful": true, + "source_account": "GCTUYXRTC2OPWWUCE6KBQEJTDFALN6BWHUXT3IHCXMTHW5K46NJCVHYN", + "type": "payment", + "type_i": 1, + "created_at": "2020-05-06T16:52:06Z", + "transaction_hash": "9fbf86268628fc41da6c984a764793f43bcac3b92ed2add6c87ecd0c9fe4d648", + "asset_type": "native", + "from": "GCTUYXRTC2OPWWUCE6KBQEJTDFALN6BWHUXT3IHCXMTHW5K46NJCVHYN", + "to": "GDKIJJIKXLOM2NRMPNQZUUYK24ZPVFC6426GZAEP3KUK6KEJLACCWNMX", + "amount": "8354897.0000000" + }, + { + "_links": { + "self": { + "href": "https://horizon.stellar.org/operations/126804090461483009" + }, + "transaction": { + "href": "https://horizon.stellar.org/transactions/b8a8a1df708ff34b0db62551fd2fe6ee9dcbdd2167b0c1460d4eee4d091c7389" + }, + "effects": { + "href": "https://horizon.stellar.org/operations/126804090461483009/effects" + }, + "succeeds": { + "href": "https://horizon.stellar.org/effects?order=desc\u0026cursor=126804090461483009" + }, + "precedes": { + "href": "https://horizon.stellar.org/effects?order=asc\u0026cursor=126804090461483009" + } + }, + "id": "126804090461483009", + "paging_token": "126804090461483009", + "transaction_successful": true, + "source_account": "GB76DZDZQRUGK3KEINZM6YDZI5OPVAP6UTIZKZIFNTRMG5T7UC5IRVRE", + "type": "payment", + "type_i": 1, + "created_at": "2020-05-06T16:21:22Z", + "transaction_hash": "b8a8a1df708ff34b0db62551fd2fe6ee9dcbdd2167b0c1460d4eee4d091c7389", + "asset_type": "native", + "from": "GB76DZDZQRUGK3KEINZM6YDZI5OPVAP6UTIZKZIFNTRMG5T7UC5IRVRE", + "to": "GDKIJJIKXLOM2NRMPNQZUUYK24ZPVFC6426GZAEP3KUK6KEJLACCWNMX", + "amount": "119470463.0000000" + }, + { + "_links": { + "self": { + "href": "https://horizon.stellar.org/operations/126755664705576961" + }, + "transaction": { + "href": "https://horizon.stellar.org/transactions/0a0c5de254df371f62c4eab051bc602abb54fe888aa8af157430dba4671d0534" + }, + "effects": { + "href": "https://horizon.stellar.org/operations/126755664705576961/effects" + }, + "succeeds": { + "href": "https://horizon.stellar.org/effects?order=desc\u0026cursor=126755664705576961" + }, + "precedes": { + "href": "https://horizon.stellar.org/effects?order=asc\u0026cursor=126755664705576961" + } + }, + "id": "126755664705576961", + "paging_token": "126755664705576961", + "transaction_successful": true, + "source_account": "GCTUYXRTC2OPWWUCE6KBQEJTDFALN6BWHUXT3IHCXMTHW5K46NJCVHYN", + "type": "payment", + "type_i": 1, + "created_at": "2020-05-05T23:08:29Z", + "transaction_hash": "0a0c5de254df371f62c4eab051bc602abb54fe888aa8af157430dba4671d0534", + "asset_type": "native", + "from": "GCTUYXRTC2OPWWUCE6KBQEJTDFALN6BWHUXT3IHCXMTHW5K46NJCVHYN", + "to": "GDKIJJIKXLOM2NRMPNQZUUYK24ZPVFC6426GZAEP3KUK6KEJLACCWNMX", + "amount": "5.0000000" + }, + { + "_links": { + "self": { + "href": "https://horizon.stellar.org/operations/126341642743132161" + }, + "transaction": { + "href": "https://horizon.stellar.org/transactions/a9b7c2eb386c3a26e3e8dd3a5fcb38ce888d7dc8397d447ac60891e58a3bbd19" + }, + "effects": { + "href": "https://horizon.stellar.org/operations/126341642743132161/effects" + }, + "succeeds": { + "href": "https://horizon.stellar.org/effects?order=desc\u0026cursor=126341642743132161" + }, + "precedes": { + "href": "https://horizon.stellar.org/effects?order=asc\u0026cursor=126341642743132161" + } + }, + "id": "126341642743132161", + "paging_token": "126341642743132161", + "transaction_successful": true, + "source_account": "GDKIJJIKXLOM2NRMPNQZUUYK24ZPVFC6426GZAEP3KUK6KEJLACCWNMX", + "type": "payment", + "type_i": 1, + "created_at": "2020-04-29T17:54:59Z", + "transaction_hash": "a9b7c2eb386c3a26e3e8dd3a5fcb38ce888d7dc8397d447ac60891e58a3bbd19", + "asset_type": "native", + "from": "GDKIJJIKXLOM2NRMPNQZUUYK24ZPVFC6426GZAEP3KUK6KEJLACCWNMX", + "to": "GCQZSPJVBQ5Q2PLDZAFB2MQ7VKVE6G7YL3HDRADQZYZ7X65OH4PUYZFS", + "amount": "2868852.0000000" + }, + { + "_links": { + "self": { + "href": "https://horizon.stellar.org/operations/126020495153016833" + }, + "transaction": { + "href": "https://horizon.stellar.org/transactions/ce389b4dc50a4a8d60424223876168a88dd890b11790d032ed2c462d89451552" + }, + "effects": { + "href": "https://horizon.stellar.org/operations/126020495153016833/effects" + }, + "succeeds": { + "href": "https://horizon.stellar.org/effects?order=desc\u0026cursor=126020495153016833" + }, + "precedes": { + "href": "https://horizon.stellar.org/effects?order=asc\u0026cursor=126020495153016833" + } + }, + "id": "126020495153016833", + "paging_token": "126020495153016833", + "transaction_successful": true, + "source_account": "GDKIJJIKXLOM2NRMPNQZUUYK24ZPVFC6426GZAEP3KUK6KEJLACCWNMX", + "type": "payment", + "type_i": 1, + "created_at": "2020-04-25T01:01:33Z", + "transaction_hash": "ce389b4dc50a4a8d60424223876168a88dd890b11790d032ed2c462d89451552", + "asset_type": "native", + "from": "GDKIJJIKXLOM2NRMPNQZUUYK24ZPVFC6426GZAEP3KUK6KEJLACCWNMX", + "to": "GCGVWRW5MHZW5OB2IR6RRFYBG5NV4BXUT5GYBRH2E3FD3TVYVINA72KM", + "amount": "3000000.0000000" + }, + { + "_links": { + "self": { + "href": "https://horizon.stellar.org/operations/125936425463291905" + }, + "transaction": { + "href": "https://horizon.stellar.org/transactions/31042b47c4377175553d967a5c6e39aaf980a54bad9b270e4fdf08baee1031d7" + }, + "effects": { + "href": "https://horizon.stellar.org/operations/125936425463291905/effects" + }, + "succeeds": { + "href": "https://horizon.stellar.org/effects?order=desc\u0026cursor=125936425463291905" + }, + "precedes": { + "href": "https://horizon.stellar.org/effects?order=asc\u0026cursor=125936425463291905" + } + }, + "id": "125936425463291905", + "paging_token": "125936425463291905", + "transaction_successful": true, + "source_account": "GDV4KECLSZLKRVH4ZTWVAS4I3W2LPAPV66ADFFUZKGIVOTK6GMKGJT53", + "type": "payment", + "type_i": 1, + "created_at": "2020-04-23T19:25:51Z", + "transaction_hash": "31042b47c4377175553d967a5c6e39aaf980a54bad9b270e4fdf08baee1031d7", + "asset_type": "native", + "from": "GDV4KECLSZLKRVH4ZTWVAS4I3W2LPAPV66ADFFUZKGIVOTK6GMKGJT53", + "to": "GDKIJJIKXLOM2NRMPNQZUUYK24ZPVFC6426GZAEP3KUK6KEJLACCWNMX", + "amount": "64113700.0000000" + }, + { + "_links": { + "self": { + "href": "https://horizon.stellar.org/operations/125936279434747905" + }, + "transaction": { + "href": "https://horizon.stellar.org/transactions/3b711a9204bafe25b1cd99643a65e02b77af6c5f6d6f6b33fee4d7bee9455b4c" + }, + "effects": { + "href": "https://horizon.stellar.org/operations/125936279434747905/effects" + }, + "succeeds": { + "href": "https://horizon.stellar.org/effects?order=desc\u0026cursor=125936279434747905" + }, + "precedes": { + "href": "https://horizon.stellar.org/effects?order=asc\u0026cursor=125936279434747905" + } + }, + "id": "125936279434747905", + "paging_token": "125936279434747905", + "transaction_successful": true, + "source_account": "GDV4KECLSZLKRVH4ZTWVAS4I3W2LPAPV66ADFFUZKGIVOTK6GMKGJT53", + "type": "payment", + "type_i": 1, + "created_at": "2020-04-23T19:22:48Z", + "transaction_hash": "3b711a9204bafe25b1cd99643a65e02b77af6c5f6d6f6b33fee4d7bee9455b4c", + "asset_type": "native", + "from": "GDV4KECLSZLKRVH4ZTWVAS4I3W2LPAPV66ADFFUZKGIVOTK6GMKGJT53", + "to": "GDKIJJIKXLOM2NRMPNQZUUYK24ZPVFC6426GZAEP3KUK6KEJLACCWNMX", + "amount": "55.4433220" + }, + { + "_links": { + "self": { + "href": "https://horizon.stellar.org/operations/125387090556133377" + }, + "transaction": { + "href": "https://horizon.stellar.org/transactions/1eeb1cedf9b3b55f77a8bd92570c1216b4b4c88b6467ff17e62fed84df0060ee" + }, + "effects": { + "href": "https://horizon.stellar.org/operations/125387090556133377/effects" + }, + "succeeds": { + "href": "https://horizon.stellar.org/effects?order=desc\u0026cursor=125387090556133377" + }, + "precedes": { + "href": "https://horizon.stellar.org/effects?order=asc\u0026cursor=125387090556133377" + } + }, + "id": "125387090556133377", + "paging_token": "125387090556133377", + "transaction_successful": true, + "source_account": "GCWXXU6OABUNBTAAKCNSUJZN3URC72KYMYBNVGOIAIW35B5LH4AARIOL", + "type": "payment", + "type_i": 1, + "created_at": "2020-04-15T18:01:03Z", + "transaction_hash": "1eeb1cedf9b3b55f77a8bd92570c1216b4b4c88b6467ff17e62fed84df0060ee", + "asset_type": "native", + "from": "GCWXXU6OABUNBTAAKCNSUJZN3URC72KYMYBNVGOIAIW35B5LH4AARIOL", + "to": "GDKIJJIKXLOM2NRMPNQZUUYK24ZPVFC6426GZAEP3KUK6KEJLACCWNMX", + "amount": "0.1000000" + }, + { + "_links": { + "self": { + "href": "https://horizon.stellar.org/operations/118409941953355777" + }, + "transaction": { + "href": "https://horizon.stellar.org/transactions/2912d519b2c2174b0147a9e02208f3ed14820228913142f8c6a5cd360783c029" + }, + "effects": { + "href": "https://horizon.stellar.org/operations/118409941953355777/effects" + }, + "succeeds": { + "href": "https://horizon.stellar.org/effects?order=desc\u0026cursor=118409941953355777" + }, + "precedes": { + "href": "https://horizon.stellar.org/effects?order=asc\u0026cursor=118409941953355777" + } + }, + "id": "118409941953355777", + "paging_token": "118409941953355777", + "transaction_successful": true, + "source_account": "GDKIJJIKXLOM2NRMPNQZUUYK24ZPVFC6426GZAEP3KUK6KEJLACCWNMX", + "type": "payment", + "type_i": 1, + "created_at": "2020-01-03T00:26:37Z", + "transaction_hash": "2912d519b2c2174b0147a9e02208f3ed14820228913142f8c6a5cd360783c029", + "asset_type": "native", + "from": "GDKIJJIKXLOM2NRMPNQZUUYK24ZPVFC6426GZAEP3KUK6KEJLACCWNMX", + "to": "GDBX63ONLLI372D7FHJYEPKP3KOCH7HZPKJWZPYJMC5RN7L5HB4VFXLM", + "amount": "500000.0000000" + }, + { + "_links": { + "self": { + "href": "https://horizon.stellar.org/operations/117528387031003137" + }, + "transaction": { + "href": "https://horizon.stellar.org/transactions/23fa4d3c787f22a1755afa4275761ffba516ec4f2e039440ec02a5522b388f2c" + }, + "effects": { + "href": "https://horizon.stellar.org/operations/117528387031003137/effects" + }, + "succeeds": { + "href": "https://horizon.stellar.org/effects?order=desc\u0026cursor=117528387031003137" + }, + "precedes": { + "href": "https://horizon.stellar.org/effects?order=asc\u0026cursor=117528387031003137" + } + }, + "id": "117528387031003137", + "paging_token": "117528387031003137", + "transaction_successful": true, + "source_account": "GDKIJJIKXLOM2NRMPNQZUUYK24ZPVFC6426GZAEP3KUK6KEJLACCWNMX", + "type": "payment", + "type_i": 1, + "created_at": "2019-12-20T23:06:36Z", + "transaction_hash": "23fa4d3c787f22a1755afa4275761ffba516ec4f2e039440ec02a5522b388f2c", + "asset_type": "native", + "from": "GDKIJJIKXLOM2NRMPNQZUUYK24ZPVFC6426GZAEP3KUK6KEJLACCWNMX", + "to": "GCGVWRW5MHZW5OB2IR6RRFYBG5NV4BXUT5GYBRH2E3FD3TVYVINA72KM", + "amount": "3976053.0000000" + }, + { + "_links": { + "self": { + "href": "https://horizon.stellar.org/operations/117004160502652929" + }, + "transaction": { + "href": "https://horizon.stellar.org/transactions/a20c22cda7686d367b904ac895144be4370440f513945898881db2c2b4964718" + }, + "effects": { + "href": "https://horizon.stellar.org/operations/117004160502652929/effects" + }, + "succeeds": { + "href": "https://horizon.stellar.org/effects?order=desc\u0026cursor=117004160502652929" + }, + "precedes": { + "href": "https://horizon.stellar.org/effects?order=asc\u0026cursor=117004160502652929" + } + }, + "id": "117004160502652929", + "paging_token": "117004160502652929", + "transaction_successful": true, + "source_account": "GDKIJJIKXLOM2NRMPNQZUUYK24ZPVFC6426GZAEP3KUK6KEJLACCWNMX", + "type": "payment", + "type_i": 1, + "created_at": "2019-12-12T22:23:15Z", + "transaction_hash": "a20c22cda7686d367b904ac895144be4370440f513945898881db2c2b4964718", + "asset_type": "native", + "from": "GDKIJJIKXLOM2NRMPNQZUUYK24ZPVFC6426GZAEP3KUK6KEJLACCWNMX", + "to": "GCGVWRW5MHZW5OB2IR6RRFYBG5NV4BXUT5GYBRH2E3FD3TVYVINA72KM", + "amount": "8711596.0000000" + }, + { + "_links": { + "self": { + "href": "https://horizon.stellar.org/operations/116993702257340417" + }, + "transaction": { + "href": "https://horizon.stellar.org/transactions/f858cff80f985226509bc1521c141372f40bb7d3148adc62daae0dd644b51a71" + }, + "effects": { + "href": "https://horizon.stellar.org/operations/116993702257340417/effects" + }, + "succeeds": { + "href": "https://horizon.stellar.org/effects?order=desc\u0026cursor=116993702257340417" + }, + "precedes": { + "href": "https://horizon.stellar.org/effects?order=asc\u0026cursor=116993702257340417" + } + }, + "id": "116993702257340417", + "paging_token": "116993702257340417", + "transaction_successful": true, + "source_account": "GDKIJJIKXLOM2NRMPNQZUUYK24ZPVFC6426GZAEP3KUK6KEJLACCWNMX", + "type": "payment", + "type_i": 1, + "created_at": "2019-12-12T18:38:25Z", + "transaction_hash": "f858cff80f985226509bc1521c141372f40bb7d3148adc62daae0dd644b51a71", + "asset_type": "native", + "from": "GDKIJJIKXLOM2NRMPNQZUUYK24ZPVFC6426GZAEP3KUK6KEJLACCWNMX", + "to": "GBE3MDQFTXMCGMLUYQO2MKJ7IYEYZUWHF2O62EDYKS7SF5V4SOKDQZXQ", + "amount": "100000000.0000000" + }, + { + "_links": { + "self": { + "href": "https://horizon.stellar.org/operations/116590456367812609" + }, + "transaction": { + "href": "https://horizon.stellar.org/transactions/0c68ce53b184605a326a9f0dd94435fa49b68b3fa127d144b5db3bbba02baafe" + }, + "effects": { + "href": "https://horizon.stellar.org/operations/116590456367812609/effects" + }, + "succeeds": { + "href": "https://horizon.stellar.org/effects?order=desc\u0026cursor=116590456367812609" + }, + "precedes": { + "href": "https://horizon.stellar.org/effects?order=asc\u0026cursor=116590456367812609" + } + }, + "id": "116590456367812609", + "paging_token": "116590456367812609", + "transaction_successful": true, + "source_account": "GDKIJJIKXLOM2NRMPNQZUUYK24ZPVFC6426GZAEP3KUK6KEJLACCWNMX", + "type": "payment", + "type_i": 1, + "created_at": "2019-12-06T21:00:24Z", + "transaction_hash": "0c68ce53b184605a326a9f0dd94435fa49b68b3fa127d144b5db3bbba02baafe", + "asset_type": "native", + "from": "GDKIJJIKXLOM2NRMPNQZUUYK24ZPVFC6426GZAEP3KUK6KEJLACCWNMX", + "to": "GCGVWRW5MHZW5OB2IR6RRFYBG5NV4BXUT5GYBRH2E3FD3TVYVINA72KM", + "amount": "2000000.0000000" + }, + { + "_links": { + "self": { + "href": "https://horizon.stellar.org/operations/115003345692798977" + }, + "transaction": { + "href": "https://horizon.stellar.org/transactions/d4cbf471f393b51cf4f759b0ba9955dbbb146db18759f8a69eed5d6479850750" + }, + "effects": { + "href": "https://horizon.stellar.org/operations/115003345692798977/effects" + }, + "succeeds": { + "href": "https://horizon.stellar.org/effects?order=desc\u0026cursor=115003345692798977" + }, + "precedes": { + "href": "https://horizon.stellar.org/effects?order=asc\u0026cursor=115003345692798977" + } + }, + "id": "115003345692798977", + "paging_token": "115003345692798977", + "transaction_successful": true, + "source_account": "GDKIJJIKXLOM2NRMPNQZUUYK24ZPVFC6426GZAEP3KUK6KEJLACCWNMX", + "type": "payment", + "type_i": 1, + "created_at": "2019-11-13T17:19:32Z", + "transaction_hash": "d4cbf471f393b51cf4f759b0ba9955dbbb146db18759f8a69eed5d6479850750", + "asset_type": "native", + "from": "GDKIJJIKXLOM2NRMPNQZUUYK24ZPVFC6426GZAEP3KUK6KEJLACCWNMX", + "to": "GBE3MDQFTXMCGMLUYQO2MKJ7IYEYZUWHF2O62EDYKS7SF5V4SOKDQZXQ", + "amount": "100000000.0000000" + }, + { + "_links": { + "self": { + "href": "https://horizon.stellar.org/operations/114412018890498053" + }, + "transaction": { + "href": "https://horizon.stellar.org/transactions/fc66377172cfeb1c464ddf6f316feee565d4cb2e8c7b14e75adb301524b40e8b" + }, + "effects": { + "href": "https://horizon.stellar.org/operations/114412018890498053/effects" + }, + "succeeds": { + "href": "https://horizon.stellar.org/effects?order=desc\u0026cursor=114412018890498053" + }, + "precedes": { + "href": "https://horizon.stellar.org/effects?order=asc\u0026cursor=114412018890498053" + } + }, + "id": "114412018890498053", + "paging_token": "114412018890498053", + "transaction_successful": true, + "source_account": "GDKIJJIKXLOM2NRMPNQZUUYK24ZPVFC6426GZAEP3KUK6KEJLACCWNMX", + "type": "payment", + "type_i": 1, + "created_at": "2019-11-04T23:01:12Z", + "transaction_hash": "fc66377172cfeb1c464ddf6f316feee565d4cb2e8c7b14e75adb301524b40e8b", + "asset_type": "native", + "from": "GDKIJJIKXLOM2NRMPNQZUUYK24ZPVFC6426GZAEP3KUK6KEJLACCWNMX", + "to": "GBEVKAYIPWC5AQT6D4N7FC3XGKRRBMPCAMTO3QZWMHHACLHTMAHAM2TP", + "amount": "1999999990.0000000" + }, + { + "_links": { + "self": { + "href": "https://horizon.stellar.org/operations/114412018890498052" + }, + "transaction": { + "href": "https://horizon.stellar.org/transactions/fc66377172cfeb1c464ddf6f316feee565d4cb2e8c7b14e75adb301524b40e8b" + }, + "effects": { + "href": "https://horizon.stellar.org/operations/114412018890498052/effects" + }, + "succeeds": { + "href": "https://horizon.stellar.org/effects?order=desc\u0026cursor=114412018890498052" + }, + "precedes": { + "href": "https://horizon.stellar.org/effects?order=asc\u0026cursor=114412018890498052" + } + }, + "id": "114412018890498052", + "paging_token": "114412018890498052", + "transaction_successful": true, + "source_account": "GDKIJJIKXLOM2NRMPNQZUUYK24ZPVFC6426GZAEP3KUK6KEJLACCWNMX", + "type": "payment", + "type_i": 1, + "created_at": "2019-11-04T23:01:12Z", + "transaction_hash": "fc66377172cfeb1c464ddf6f316feee565d4cb2e8c7b14e75adb301524b40e8b", + "asset_type": "native", + "from": "GDKIJJIKXLOM2NRMPNQZUUYK24ZPVFC6426GZAEP3KUK6KEJLACCWNMX", + "to": "GALAXYVOIDAOPZTDLHILAJQKCVVFMD4IKLXLSZV5YHO7VY74IWZILUTO", + "amount": "37564933050.0000000" + }, + { + "_links": { + "self": { + "href": "https://horizon.stellar.org/operations/114388314965975041" + }, + "transaction": { + "href": "https://horizon.stellar.org/transactions/6eb38f3442543aa1aacbe8bea11d150c957507126c3198642ee5a4ed0ccea5c7" + }, + "effects": { + "href": "https://horizon.stellar.org/operations/114388314965975041/effects" + }, + "succeeds": { + "href": "https://horizon.stellar.org/effects?order=desc\u0026cursor=114388314965975041" + }, + "precedes": { + "href": "https://horizon.stellar.org/effects?order=asc\u0026cursor=114388314965975041" + } + }, + "id": "114388314965975041", + "paging_token": "114388314965975041", + "transaction_successful": true, + "source_account": "GB6D7BSIOPC7FTRLVMVRFPBQRFXWWDU3XXFU5YFSOPN4PQALNMQC7ANB", + "type": "payment", + "type_i": 1, + "created_at": "2019-11-04T14:39:10Z", + "transaction_hash": "6eb38f3442543aa1aacbe8bea11d150c957507126c3198642ee5a4ed0ccea5c7", + "asset_type": "native", + "from": "GB6D7BSIOPC7FTRLVMVRFPBQRFXWWDU3XXFU5YFSOPN4PQALNMQC7ANB", + "to": "GDKIJJIKXLOM2NRMPNQZUUYK24ZPVFC6426GZAEP3KUK6KEJLACCWNMX", + "amount": "100.0000000" + }, + { + "_links": { + "self": { + "href": "https://horizon.stellar.org/operations/110559733873651713" + }, + "transaction": { + "href": "https://horizon.stellar.org/transactions/cf0f5d6b2f5367335e7df7a6909d2fc18281b2d6c5b218419614a4f6acd5f86b" + }, + "effects": { + "href": "https://horizon.stellar.org/operations/110559733873651713/effects" + }, + "succeeds": { + "href": "https://horizon.stellar.org/effects?order=desc\u0026cursor=110559733873651713" + }, + "precedes": { + "href": "https://horizon.stellar.org/effects?order=asc\u0026cursor=110559733873651713" + } + }, + "id": "110559733873651713", + "paging_token": "110559733873651713", + "transaction_successful": true, + "source_account": "GA2JXLLIT66SWSGI4TFWMUXRXAJAHLHCISNMRUDRWFDKIVPDKZJ456T3", + "type": "payment", + "type_i": 1, + "created_at": "2019-09-09T14:02:31Z", + "transaction_hash": "cf0f5d6b2f5367335e7df7a6909d2fc18281b2d6c5b218419614a4f6acd5f86b", + "asset_type": "native", + "from": "GA2JXLLIT66SWSGI4TFWMUXRXAJAHLHCISNMRUDRWFDKIVPDKZJ456T3", + "to": "GDKIJJIKXLOM2NRMPNQZUUYK24ZPVFC6426GZAEP3KUK6KEJLACCWNMX", + "amount": "0.0010000" + }, + { + "_links": { + "self": { + "href": "https://horizon.stellar.org/operations/110372091047493633" + }, + "transaction": { + "href": "https://horizon.stellar.org/transactions/143c6d4b236818cda7613d9dec7489056a9ba28c459d0e92f3d429bfbdf38342" + }, + "effects": { + "href": "https://horizon.stellar.org/operations/110372091047493633/effects" + }, + "succeeds": { + "href": "https://horizon.stellar.org/effects?order=desc\u0026cursor=110372091047493633" + }, + "precedes": { + "href": "https://horizon.stellar.org/effects?order=asc\u0026cursor=110372091047493633" + } + }, + "id": "110372091047493633", + "paging_token": "110372091047493633", + "transaction_successful": true, + "source_account": "GDKIJJIKXLOM2NRMPNQZUUYK24ZPVFC6426GZAEP3KUK6KEJLACCWNMX", + "type": "payment", + "type_i": 1, + "created_at": "2019-09-06T20:09:26Z", + "transaction_hash": "143c6d4b236818cda7613d9dec7489056a9ba28c459d0e92f3d429bfbdf38342", + "asset_type": "native", + "from": "GDKIJJIKXLOM2NRMPNQZUUYK24ZPVFC6426GZAEP3KUK6KEJLACCWNMX", + "to": "GBE3MDQFTXMCGMLUYQO2MKJ7IYEYZUWHF2O62EDYKS7SF5V4SOKDQZXQ", + "amount": "100000000.0000000" + }, + { + "_links": { + "self": { + "href": "https://horizon.stellar.org/operations/108226441350512641" + }, + "transaction": { + "href": "https://horizon.stellar.org/transactions/6cd9ea51a4f0204a797f2ebe73867c5d7f9c426e1480549570b58d00db8a854e" + }, + "effects": { + "href": "https://horizon.stellar.org/operations/108226441350512641/effects" + }, + "succeeds": { + "href": "https://horizon.stellar.org/effects?order=desc\u0026cursor=108226441350512641" + }, + "precedes": { + "href": "https://horizon.stellar.org/effects?order=asc\u0026cursor=108226441350512641" + } + }, + "id": "108226441350512641", + "paging_token": "108226441350512641", + "transaction_successful": true, + "source_account": "GC7PA2EZIS6CMKKC4D5MA33XZQIEZKOOHK37XDTTXIH5ZCIMC3XSA7KC", + "type": "payment", + "type_i": 1, + "created_at": "2019-08-06T15:41:36Z", + "transaction_hash": "6cd9ea51a4f0204a797f2ebe73867c5d7f9c426e1480549570b58d00db8a854e", + "asset_type": "native", + "from": "GC7PA2EZIS6CMKKC4D5MA33XZQIEZKOOHK37XDTTXIH5ZCIMC3XSA7KC", + "to": "GDKIJJIKXLOM2NRMPNQZUUYK24ZPVFC6426GZAEP3KUK6KEJLACCWNMX", + "amount": "0.0010000" + }, + { + "_links": { + "self": { + "href": "https://horizon.stellar.org/operations/108225427738238977" + }, + "transaction": { + "href": "https://horizon.stellar.org/transactions/d20b732a936851897ba2971254e03f5923f2c462067c356ee76404f6cacead64" + }, + "effects": { + "href": "https://horizon.stellar.org/operations/108225427738238977/effects" + }, + "succeeds": { + "href": "https://horizon.stellar.org/effects?order=desc\u0026cursor=108225427738238977" + }, + "precedes": { + "href": "https://horizon.stellar.org/effects?order=asc\u0026cursor=108225427738238977" + } + }, + "id": "108225427738238977", + "paging_token": "108225427738238977", + "transaction_successful": true, + "source_account": "GA4RHS5KNMRV3AKBGACZNP2Y3VGSYSOVJANM5BFG447S2AC6PZ3YBMGC", + "type": "payment", + "type_i": 1, + "created_at": "2019-08-06T15:20:22Z", + "transaction_hash": "d20b732a936851897ba2971254e03f5923f2c462067c356ee76404f6cacead64", + "asset_type": "native", + "from": "GA4RHS5KNMRV3AKBGACZNP2Y3VGSYSOVJANM5BFG447S2AC6PZ3YBMGC", + "to": "GDKIJJIKXLOM2NRMPNQZUUYK24ZPVFC6426GZAEP3KUK6KEJLACCWNMX", + "amount": "1.0000000" + }, + { + "_links": { + "self": { + "href": "https://horizon.stellar.org/operations/105398746552012801" + }, + "transaction": { + "href": "https://horizon.stellar.org/transactions/e4aee643787b337f9afea878cf3ddd17c3c75de520214990b39489403ca20320" + }, + "effects": { + "href": "https://horizon.stellar.org/operations/105398746552012801/effects" + }, + "succeeds": { + "href": "https://horizon.stellar.org/effects?order=desc\u0026cursor=105398746552012801" + }, + "precedes": { + "href": "https://horizon.stellar.org/effects?order=asc\u0026cursor=105398746552012801" + } + }, + "id": "105398746552012801", + "paging_token": "105398746552012801", + "transaction_successful": true, + "source_account": "GDKIJJIKXLOM2NRMPNQZUUYK24ZPVFC6426GZAEP3KUK6KEJLACCWNMX", + "type": "payment", + "type_i": 1, + "created_at": "2019-06-26T19:02:17Z", + "transaction_hash": "e4aee643787b337f9afea878cf3ddd17c3c75de520214990b39489403ca20320", + "asset_type": "native", + "from": "GDKIJJIKXLOM2NRMPNQZUUYK24ZPVFC6426GZAEP3KUK6KEJLACCWNMX", + "to": "GAYOCVRRNXGQWREOZBDP4UEW475NKZKLA4EIEIBKBSJN2PQQWUQ5KGUH", + "amount": "3000000.0000000" + }, + { + "_links": { + "self": { + "href": "https://horizon.stellar.org/operations/100705086031818753" + }, + "transaction": { + "href": "https://horizon.stellar.org/transactions/9e30119a30a046f7f9dd264415c6158a19189f5335df1561b18b365b08470124" + }, + "effects": { + "href": "https://horizon.stellar.org/operations/100705086031818753/effects" + }, + "succeeds": { + "href": "https://horizon.stellar.org/effects?order=desc\u0026cursor=100705086031818753" + }, + "precedes": { + "href": "https://horizon.stellar.org/effects?order=asc\u0026cursor=100705086031818753" + } + }, + "id": "100705086031818753", + "paging_token": "100705086031818753", + "transaction_successful": true, + "source_account": "GCGKSRT5GYBRRBJYV3KCPWH2HSUBGLQQNDSIR2IFCMAXKNR4OKFU4CVE", + "type": "payment", + "type_i": 1, + "created_at": "2019-04-16T18:24:58Z", + "transaction_hash": "9e30119a30a046f7f9dd264415c6158a19189f5335df1561b18b365b08470124", + "asset_type": "native", + "from": "GCGKSRT5GYBRRBJYV3KCPWH2HSUBGLQQNDSIR2IFCMAXKNR4OKFU4CVE", + "to": "GDKIJJIKXLOM2NRMPNQZUUYK24ZPVFC6426GZAEP3KUK6KEJLACCWNMX", + "amount": "0.0000100" + }, + { + "_links": { + "self": { + "href": "https://horizon.stellar.org/operations/99566494496600065" + }, + "transaction": { + "href": "https://horizon.stellar.org/transactions/e33b85359d0f0644fb907e697d73525cb636bcb989576c0d2ff1c0d1b83f958a" + }, + "effects": { + "href": "https://horizon.stellar.org/operations/99566494496600065/effects" + }, + "succeeds": { + "href": "https://horizon.stellar.org/effects?order=desc\u0026cursor=99566494496600065" + }, + "precedes": { + "href": "https://horizon.stellar.org/effects?order=asc\u0026cursor=99566494496600065" + } + }, + "id": "99566494496600065", + "paging_token": "99566494496600065", + "transaction_successful": true, + "source_account": "GDTUSYPQNM2UGX36P2QBUQALHPXUHMAJXUR6UFZXUDPE2EQR5INQIF33", + "type": "payment", + "type_i": 1, + "created_at": "2019-03-30T18:32:03Z", + "transaction_hash": "e33b85359d0f0644fb907e697d73525cb636bcb989576c0d2ff1c0d1b83f958a", + "asset_type": "native", + "from": "GDTUSYPQNM2UGX36P2QBUQALHPXUHMAJXUR6UFZXUDPE2EQR5INQIF33", + "to": "GDKIJJIKXLOM2NRMPNQZUUYK24ZPVFC6426GZAEP3KUK6KEJLACCWNMX", + "amount": "0.0000001" + }, + { + "_links": { + "self": { + "href": "https://horizon.stellar.org/operations/99566434367078401" + }, + "transaction": { + "href": "https://horizon.stellar.org/transactions/58cb690dafc9d384409e66f066422c4d7e6893c50964c15856d38a59471749f7" + }, + "effects": { + "href": "https://horizon.stellar.org/operations/99566434367078401/effects" + }, + "succeeds": { + "href": "https://horizon.stellar.org/effects?order=desc\u0026cursor=99566434367078401" + }, + "precedes": { + "href": "https://horizon.stellar.org/effects?order=asc\u0026cursor=99566434367078401" + } + }, + "id": "99566434367078401", + "paging_token": "99566434367078401", + "transaction_successful": true, + "source_account": "GDTUSYPQNM2UGX36P2QBUQALHPXUHMAJXUR6UFZXUDPE2EQR5INQIF33", + "type": "payment", + "type_i": 1, + "created_at": "2019-03-30T18:30:49Z", + "transaction_hash": "58cb690dafc9d384409e66f066422c4d7e6893c50964c15856d38a59471749f7", + "asset_type": "native", + "from": "GDTUSYPQNM2UGX36P2QBUQALHPXUHMAJXUR6UFZXUDPE2EQR5INQIF33", + "to": "GDKIJJIKXLOM2NRMPNQZUUYK24ZPVFC6426GZAEP3KUK6KEJLACCWNMX", + "amount": "0.0000001" + } + ] + } +} \ No newline at end of file diff --git a/mock/ext-api-data/stellar-api_transactions_23fa4d3c787f22a1755afa4275761ffba516ec4f2e039440ec02a5522b388f2c.json b/mock/ext-api-data/stellar-api_transactions_23fa4d3c787f22a1755afa4275761ffba516ec4f2e039440ec02a5522b388f2c.json new file mode 100644 index 000000000..eebec9df0 --- /dev/null +++ b/mock/ext-api-data/stellar-api_transactions_23fa4d3c787f22a1755afa4275761ffba516ec4f2e039440ec02a5522b388f2c.json @@ -0,0 +1,52 @@ +{ + "_links": { + "self": { + "href": "https://horizon.stellar.org/transactions/23fa4d3c787f22a1755afa4275761ffba516ec4f2e039440ec02a5522b388f2c" + }, + "account": { + "href": "https://horizon.stellar.org/accounts/GDKIJJIKXLOM2NRMPNQZUUYK24ZPVFC6426GZAEP3KUK6KEJLACCWNMX" + }, + "ledger": { + "href": "https://horizon.stellar.org/ledgers/27364210" + }, + "operations": { + "href": "https://horizon.stellar.org/transactions/23fa4d3c787f22a1755afa4275761ffba516ec4f2e039440ec02a5522b388f2c/operations{?cursor,limit,order}", + "templated": true + }, + "effects": { + "href": "https://horizon.stellar.org/transactions/23fa4d3c787f22a1755afa4275761ffba516ec4f2e039440ec02a5522b388f2c/effects{?cursor,limit,order}", + "templated": true + }, + "precedes": { + "href": "https://horizon.stellar.org/transactions?order=asc\u0026cursor=117528387031003136" + }, + "succeeds": { + "href": "https://horizon.stellar.org/transactions?order=desc\u0026cursor=117528387031003136" + }, + "transaction": { + "href": "https://horizon.stellar.org/transactions/23fa4d3c787f22a1755afa4275761ffba516ec4f2e039440ec02a5522b388f2c" + } + }, + "id": "23fa4d3c787f22a1755afa4275761ffba516ec4f2e039440ec02a5522b388f2c", + "paging_token": "117528387031003136", + "successful": true, + "hash": "23fa4d3c787f22a1755afa4275761ffba516ec4f2e039440ec02a5522b388f2c", + "ledger": 27364210, + "created_at": "2019-12-20T23:06:36Z", + "source_account": "GDKIJJIKXLOM2NRMPNQZUUYK24ZPVFC6426GZAEP3KUK6KEJLACCWNMX", + "source_account_sequence": "25002129911447567", + "fee_account": "GDKIJJIKXLOM2NRMPNQZUUYK24ZPVFC6426GZAEP3KUK6KEJLACCWNMX", + "fee_charged": 100, + "max_fee": 100, + "operation_count": 1, + "envelope_xdr": "AAAAANSEpQq63M02LHthmlMK1zL6lF7mvGyAj9qoryiJWAQrAAAAZABY004AAAAPAAAAAAAAAAAAAAABAAAAAQAAAADUhKUKutzNNix7YZpTCtcy+pRe5rxsgI/aqK8oiVgEKwAAAAEAAAAAjVtG3WHzbrg6RH0YlwE3W14G9J9NgMT6Jso9zriqGg8AAAAAAAAkKXhESIAAAAAAAAAAA2b459kAAABA5EcZFubvZDa2IytO64bCB85UpjzLqHIS3FBWshoigfice819SwpBYkk7xa3kIWseL/kiQBCnrIAsU7ujYAR3AIlYBCsAAABA1oF6s5NMUEJas97SMRqHgeuXxCdKetSEPBtFGlgzSPTqG6mzAGPuwibKs3HaBjdmfbwh7ffTtjAAesLHIApdCRlL7xoAAABAkADolN0l8llCFxrkqMLbbU4NNKwPsQDrYDoxERo7uvuVJgg18zMBk4t1eqXqQfiYZVeIdAN/q9zcL2SGGYJaBg==", + "result_xdr": "AAAAAAAAAGQAAAAAAAAAAQAAAAAAAAABAAAAAAAAAAA=", + "result_meta_xdr": "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", + "fee_meta_xdr": "AAAAAgAAAAMBn66qAAAAAAAAAADUhKUKutzNNix7YZpTCtcy+pRe5rxsgI/aqK8oiVgEKwCFr9SbOOXqAFjTTgAAAA4AAAAEAAAAAQAAAADs3GnuWZXu1qpB+qhI/62WqM4dZ4A1pBgWqEOQJARFlAAAAAAAAAAFd29ybGQAAAABAwMDAAAABAAAAABYBYcJn4H9yxCzrVqI0n0el4b8AUafg9sxvcgJsRALiwAAAAEAAAAAc7yNUAU1YcAb84D5ufCOZyVNpEeCSNA5jaXDCRlL7xoAAAABAAAAALr2jV2dUnqsx1WUvs9TdYuzLargokVQGQ09R9I8gUuYAAAAAQAAAADVvMwB64q5vJdS6D9efKPUpiS/5xJS0JK8BzMjZvjn2QAAAAEAAAAAAAAAAAAAAAEBoYtyAAAAAAAAAADUhKUKutzNNix7YZpTCtcy+pRe5rxsgI/aqK8oiVgEKwCFr9SbOOWGAFjTTgAAAA4AAAAEAAAAAQAAAADs3GnuWZXu1qpB+qhI/62WqM4dZ4A1pBgWqEOQJARFlAAAAAAAAAAFd29ybGQAAAABAwMDAAAABAAAAABYBYcJn4H9yxCzrVqI0n0el4b8AUafg9sxvcgJsRALiwAAAAEAAAAAc7yNUAU1YcAb84D5ufCOZyVNpEeCSNA5jaXDCRlL7xoAAAABAAAAALr2jV2dUnqsx1WUvs9TdYuzLargokVQGQ09R9I8gUuYAAAAAQAAAADVvMwB64q5vJdS6D9efKPUpiS/5xJS0JK8BzMjZvjn2QAAAAEAAAAAAAAAAA==", + "memo_type": "none", + "signatures": [ + "5EcZFubvZDa2IytO64bCB85UpjzLqHIS3FBWshoigfice819SwpBYkk7xa3kIWseL/kiQBCnrIAsU7ujYAR3AA==", + "1oF6s5NMUEJas97SMRqHgeuXxCdKetSEPBtFGlgzSPTqG6mzAGPuwibKs3HaBjdmfbwh7ffTtjAAesLHIApdCQ==", + "kADolN0l8llCFxrkqMLbbU4NNKwPsQDrYDoxERo7uvuVJgg18zMBk4t1eqXqQfiYZVeIdAN/q9zcL2SGGYJaBg==" + ] +} \ No newline at end of file diff --git a/mock/ext-api-data/stellar-api_transactions_2912d519b2c2174b0147a9e02208f3ed14820228913142f8c6a5cd360783c029__.json b/mock/ext-api-data/stellar-api_transactions_2912d519b2c2174b0147a9e02208f3ed14820228913142f8c6a5cd360783c029__.json new file mode 100644 index 000000000..768d4589e --- /dev/null +++ b/mock/ext-api-data/stellar-api_transactions_2912d519b2c2174b0147a9e02208f3ed14820228913142f8c6a5cd360783c029__.json @@ -0,0 +1,52 @@ +{ + "_links": { + "self": { + "href": "https://horizon.stellar.org/transactions/2912d519b2c2174b0147a9e02208f3ed14820228913142f8c6a5cd360783c029" + }, + "account": { + "href": "https://horizon.stellar.org/accounts/GDKIJJIKXLOM2NRMPNQZUUYK24ZPVFC6426GZAEP3KUK6KEJLACCWNMX" + }, + "ledger": { + "href": "https://horizon.stellar.org/ledgers/27569463" + }, + "operations": { + "href": "https://horizon.stellar.org/transactions/2912d519b2c2174b0147a9e02208f3ed14820228913142f8c6a5cd360783c029/operations{?cursor,limit,order}", + "templated": true + }, + "effects": { + "href": "https://horizon.stellar.org/transactions/2912d519b2c2174b0147a9e02208f3ed14820228913142f8c6a5cd360783c029/effects{?cursor,limit,order}", + "templated": true + }, + "precedes": { + "href": "https://horizon.stellar.org/transactions?order=asc\u0026cursor=118409941953355776" + }, + "succeeds": { + "href": "https://horizon.stellar.org/transactions?order=desc\u0026cursor=118409941953355776" + }, + "transaction": { + "href": "https://horizon.stellar.org/transactions/2912d519b2c2174b0147a9e02208f3ed14820228913142f8c6a5cd360783c029" + } + }, + "id": "2912d519b2c2174b0147a9e02208f3ed14820228913142f8c6a5cd360783c029", + "paging_token": "118409941953355776", + "successful": true, + "hash": "2912d519b2c2174b0147a9e02208f3ed14820228913142f8c6a5cd360783c029", + "ledger": 27569463, + "created_at": "2020-01-03T00:26:37Z", + "source_account": "GDKIJJIKXLOM2NRMPNQZUUYK24ZPVFC6426GZAEP3KUK6KEJLACCWNMX", + "source_account_sequence": "25002129911447568", + "fee_account": "GDKIJJIKXLOM2NRMPNQZUUYK24ZPVFC6426GZAEP3KUK6KEJLACCWNMX", + "fee_charged": 100, + "max_fee": 100, + "operation_count": 1, + "envelope_xdr": "AAAAANSEpQq63M02LHthmlMK1zL6lF7mvGyAj9qoryiJWAQrAAAAZABY004AAAAQAAAAAAAAAAAAAAABAAAAAQAAAADUhKUKutzNNix7YZpTCtcy+pRe5rxsgI/aqK8oiVgEKwAAAAEAAAAAw39tzVrRv+h/KdOCPU/anCP8+XqTbL8JYLsW/X04eVIAAAAAAAAEjCc5UAAAAAAAAAAAA4lYBCsAAABAM4j0FWLKI8qMUcJMO3tP4rMAoIDZdbRlFjiFNACVoAd9dCtdgBBpbi6ZnXtimE370ar19q/qrbvOKBJrnYXjC2b459kAAABAtIedy2ER3ep90HE5rEPwh03iyQRp644Sm8/wK0c9sk6qPSTG2VEFEj85Jk0TrXLxDmxvnktEhPyec67ZcdxfDrEQC4sAAABAoabKlFbeUmDTtAiGVOHthzrCZHK8mpyFkKIS7QzjL4a6ASQ6RweWNUKedUBj4uuO5z1vHDr3I5EiLUhK8xceAQ==", + "result_xdr": "AAAAAAAAAGQAAAAAAAAAAQAAAAAAAAABAAAAAAAAAAA=", + "result_meta_xdr": "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", + "fee_meta_xdr": "AAAAAgAAAAMBoYtyAAAAAAAAAADUhKUKutzNNix7YZpTCtcy+pRe5rxsgI/aqK8oiVgEKwCFi6si9J0GAFjTTgAAAA8AAAAEAAAAAQAAAADs3GnuWZXu1qpB+qhI/62WqM4dZ4A1pBgWqEOQJARFlAAAAAAAAAAFd29ybGQAAAABAwMDAAAABAAAAABYBYcJn4H9yxCzrVqI0n0el4b8AUafg9sxvcgJsRALiwAAAAEAAAAAc7yNUAU1YcAb84D5ufCOZyVNpEeCSNA5jaXDCRlL7xoAAAABAAAAALr2jV2dUnqsx1WUvs9TdYuzLargokVQGQ09R9I8gUuYAAAAAQAAAADVvMwB64q5vJdS6D9efKPUpiS/5xJS0JK8BzMjZvjn2QAAAAEAAAAAAAAAAAAAAAEBpK03AAAAAAAAAADUhKUKutzNNix7YZpTCtcy+pRe5rxsgI/aqK8oiVgEKwCFi6si9JyiAFjTTgAAAA8AAAAEAAAAAQAAAADs3GnuWZXu1qpB+qhI/62WqM4dZ4A1pBgWqEOQJARFlAAAAAAAAAAFd29ybGQAAAABAwMDAAAABAAAAABYBYcJn4H9yxCzrVqI0n0el4b8AUafg9sxvcgJsRALiwAAAAEAAAAAc7yNUAU1YcAb84D5ufCOZyVNpEeCSNA5jaXDCRlL7xoAAAABAAAAALr2jV2dUnqsx1WUvs9TdYuzLargokVQGQ09R9I8gUuYAAAAAQAAAADVvMwB64q5vJdS6D9efKPUpiS/5xJS0JK8BzMjZvjn2QAAAAEAAAAAAAAAAA==", + "memo_type": "none", + "signatures": [ + "M4j0FWLKI8qMUcJMO3tP4rMAoIDZdbRlFjiFNACVoAd9dCtdgBBpbi6ZnXtimE370ar19q/qrbvOKBJrnYXjCw==", + "tIedy2ER3ep90HE5rEPwh03iyQRp644Sm8/wK0c9sk6qPSTG2VEFEj85Jk0TrXLxDmxvnktEhPyec67ZcdxfDg==", + "oabKlFbeUmDTtAiGVOHthzrCZHK8mpyFkKIS7QzjL4a6ASQ6RweWNUKedUBj4uuO5z1vHDr3I5EiLUhK8xceAQ==" + ] +} \ No newline at end of file diff --git a/mock/ext-api-data/tezos-api_account_tz1foWxaV3VQyWqFbWTERS6YDJjPT6C7jPp8_op__limit_25_order_desc_type_transaction_delegation.json b/mock/ext-api-data/tezos-api_account_tz1foWxaV3VQyWqFbWTERS6YDJjPT6C7jPp8_op__limit_25_order_desc_type_transaction_delegation.json new file mode 100644 index 000000000..1f71af453 --- /dev/null +++ b/mock/ext-api-data/tezos-api_account_tz1foWxaV3VQyWqFbWTERS6YDJjPT6C7jPp8_op__limit_25_order_desc_type_transaction_delegation.json @@ -0,0 +1,163 @@ +{ + "address": "tz1foWxaV3VQyWqFbWTERS6YDJjPT6C7jPp8", + "address_type": "ed25519", + "delegate": "", + "manager": "", + "pubkey": "edpkvKiFTVXxttCcDa2N6QfwgsnWHoEQdYRsVfUDBWPXJbhBPQpLVk", + "first_in": 797595, + "first_out": 797612, + "last_in": 797595, + "last_out": 797612, + "first_seen": 797595, + "last_seen": 797612, + "delegated_since": 0, + "delegate_since": 0, + "first_in_time": "2020-01-26T23:49:01Z", + "first_out_time": "2020-01-27T00:06:01Z", + "last_in_time": "2020-01-26T23:49:01Z", + "last_out_time": "2020-01-27T00:06:01Z", + "first_seen_time": "2020-01-26T23:49:01Z", + "last_seen_time": "2020-01-27T00:06:01Z", + "delegated_since_time": "0001-01-01T00:00:00Z", + "delegate_since_time": "0001-01-01T00:00:00Z", + "total_received": 0.01, + "total_sent": 0.007, + "total_burned": 0, + "total_fees_paid": 0.003, + "total_rewards_earned": 0, + "total_fees_earned": 0, + "total_lost": 0, + "frozen_deposits": 0, + "frozen_rewards": 0, + "frozen_fees": 0, + "unclaimed_balance": 0, + "spendable_balance": 0, + "total_balance": 0, + "delegated_balance": 0, + "total_delegations": 0, + "active_delegations": 0, + "is_funded": false, + "is_activated": false, + "is_vesting": false, + "is_spendable": true, + "is_delegatable": false, + "is_delegated": false, + "is_revealed": false, + "is_delegate": false, + "is_active_delegate": false, + "is_contract": false, + "blocks_baked": 0, + "blocks_missed": 0, + "blocks_stolen": 0, + "blocks_endorsed": 0, + "slots_endorsed": 0, + "slots_missed": 0, + "n_ops": 3, + "n_ops_failed": 0, + "n_tx": 2, + "n_delegation": 0, + "n_origination": 0, + "n_proposal": 0, + "n_ballot": 0, + "token_gen_min": 0, + "token_gen_max": 0, + "grace_period": 0, + "staking_balance": 0, + "rolls": 0, + "rich_rank": 0, + "traffic_rank": 0, + "flow_rank": 0, + "last_bake_height": 0, + "last_bake_block": "", + "last_bake_time": "0001-01-01T00:00:00Z", + "last_endorse_height": 0, + "last_endorse_block": "", + "last_endorse_time": "0001-01-01T00:00:00Z", + "next_bake_height": 0, + "next_bake_priority": 0, + "next_bake_time": "0001-01-01T00:00:00Z", + "next_endorse_height": 0, + "next_endorse_time": "0001-01-01T00:00:00Z", + "ops": [ + { + "row_id": 20862164, + "hash": "ooLrNAP233Qvoz3AGvjRjhk1fjG7z19UfyLEGBm1rwfHn4NSVhd", + "type": "transaction", + "block": "BMRy3L1EEkPrmv4UwTUsFNnD3Q25hVB36VyN5Tx5G96vUpfkiR1", + "time": "2020-01-27T00:06:01Z", + "height": 797612, + "cycle": 194, + "counter": 2946274, + "op_n": 50, + "op_l": 3, + "op_p": 2, + "op_c": 1, + "op_i": 0, + "status": "applied", + "is_success": true, + "is_contract": false, + "gas_limit": 10600, + "gas_used": 10209, + "gas_price": 0.14693, + "storage_limit": 257, + "storage_size": 0, + "storage_paid": 0, + "volume": 0.007, + "fee": 0.0015, + "reward": 0, + "deposit": 0, + "burned": 0, + "is_internal": false, + "has_data": false, + "days_destroyed": 0.000083, + "sender": "tz1foWxaV3VQyWqFbWTERS6YDJjPT6C7jPp8", + "receiver": "tz1KqtebPYZopqj65E6qPseW2GDGVgUs82wK", + "branch_id": 797612, + "branch_height": 797611, + "branch_depth": 1, + "branch": "BMEPJ9BA41LZKuS9ywVQAvdtV7SHqiKU6vmFsxPSEUzCLZ2pG5D", + "is_implicit": false, + "entrypoint_id": 0 + }, + { + "row_id": 20861661, + "hash": "op2f6FPSKhzKcN6o2uUNETUrgF4vX8pAEyRJb4k9uPnAFEoJjYq", + "type": "transaction", + "block": "BMJtDFTTaWABiv8ye1qALB5Jss2wQz3CFYjrMVhTX8yBWA8dttt", + "time": "2020-01-26T23:49:01Z", + "height": 797595, + "cycle": 194, + "counter": 2555733, + "op_n": 19, + "op_l": 3, + "op_p": 0, + "op_c": 0, + "op_i": 0, + "status": "applied", + "is_success": true, + "is_contract": false, + "gas_limit": 10307, + "gas_used": 10207, + "gas_price": 0.1258, + "storage_limit": 277, + "storage_size": 0, + "storage_paid": 0, + "volume": 0.01, + "fee": 0.001284, + "reward": 0, + "deposit": 0, + "burned": 0.257, + "is_internal": false, + "has_data": false, + "days_destroyed": 0.019403, + "sender": "tz1VwmmesDxud2BJEyDKUTV5T5VEP8tGBKGD", + "receiver": "tz1foWxaV3VQyWqFbWTERS6YDJjPT6C7jPp8", + "branch_id": 797595, + "branch_height": 797594, + "branch_depth": 1, + "branch": "BLcdWDBAN4N38tnsEGMT8vorsKeMgAbCN154AM93eZ348uhZGWy", + "is_implicit": false, + "entrypoint_id": 0 + } + ] +} diff --git a/mock/ext-api-data/theta-api_accounttx_0xac0eeb6ee3e32e2c74e14ac74155063e4f4f981f__isEqualType_true_limitNumber_100_pageNumber_1_type_2.json b/mock/ext-api-data/theta-api_accounttx_0xac0eeb6ee3e32e2c74e14ac74155063e4f4f981f__isEqualType_true_limitNumber_100_pageNumber_1_type_2.json new file mode 100644 index 000000000..ba75bbf7a --- /dev/null +++ b/mock/ext-api-data/theta-api_accounttx_0xac0eeb6ee3e32e2c74e14ac74155063e4f4f981f__isEqualType_true_limitNumber_100_pageNumber_1_type_2.json @@ -0,0 +1,2527 @@ +{ + "type": "account_tx_list", + "body": [ + { + "_id": "0x85aaf834470dd858dc2f60c7bd535ddf08c3fcfef9456f43676462950a355b78", + "block_height": "4160784", + "data": { + "fee": { + "thetawei": "0", + "tfuelwei": "2000000000000" + }, + "inputs": [ + { + "address": "0xac0eeb6ee3e32e2c74e14ac74155063e4f4f981f", + "coins": { + "thetawei": "1000000000000000", + "tfuelwei": "2000000000000" + }, + "sequence": "52", + "signature": "0x60ae320a7a0f7f6e72ed5080830d2156f145a191197092df9eb88e7b8c7637ad01894b128b81d33b67a6516e3a6c7dc064576eb40b9516b4dc127e9845ede8c300" + } + ], + "outputs": [ + { + "address": "0x082a2aef39b6473c55ba7e28c122ed3aea0de381", + "coins": { + "thetawei": "1000000000000000", + "tfuelwei": "0" + } + } + ] + }, + "hash": "0x85aaf834470dd858dc2f60c7bd535ddf08c3fcfef9456f43676462950a355b78", + "number": 31836666, + "status": "finalized", + "timestamp": "1579009947", + "type": 2 + }, + { + "_id": "0x43804bbc7ff254f5eb3ff0a9bc1feed5788cbbc3eb5b535c52de4c47c8963dfd", + "block_height": "4160736", + "data": { + "fee": { + "thetawei": "0", + "tfuelwei": "2000000000000" + }, + "inputs": [ + { + "address": "0xac0eeb6ee3e32e2c74e14ac74155063e4f4f981f", + "coins": { + "thetawei": "1000000000000000", + "tfuelwei": "2000000000000" + }, + "sequence": "51", + "signature": "0x23cd4f14859ef6a9cd0bd820591101cd53c74d3421e01b42ca0671501afdd6f73dcf2ec8e35ceba773319ba552c0b170daa3460bf6125992e846f9d0cf839a9700" + } + ], + "outputs": [ + { + "address": "0x082a2aef39b6473c55ba7e28c122ed3aea0de381", + "coins": { + "thetawei": "1000000000000000", + "tfuelwei": "0" + } + } + ] + }, + "hash": "0x43804bbc7ff254f5eb3ff0a9bc1feed5788cbbc3eb5b535c52de4c47c8963dfd", + "number": 31836430, + "status": "finalized", + "timestamp": "1579009642", + "type": 2 + }, + { + "_id": "0xf124f4a3aad047d677efda8d7f8ec7b14329d15fb1553b255e30a379cce72317", + "block_height": "4160649", + "data": { + "fee": { + "thetawei": "0", + "tfuelwei": "2000000000000" + }, + "inputs": [ + { + "address": "0xac0eeb6ee3e32e2c74e14ac74155063e4f4f981f", + "coins": { + "thetawei": "100000000000000", + "tfuelwei": "2000000000000" + }, + "sequence": "50", + "signature": "0xdef6415ba77901c5aaff46b3d82675c71f37805bf7ee64b708f8f46f6a30356a0b30d095052452591bc8b4550650b41d5820fe8ffb3164f163609012b6561c4c00" + } + ], + "outputs": [ + { + "address": "0x082a2aef39b6473c55ba7e28c122ed3aea0de381", + "coins": { + "thetawei": "100000000000000", + "tfuelwei": "0" + } + } + ] + }, + "hash": "0xf124f4a3aad047d677efda8d7f8ec7b14329d15fb1553b255e30a379cce72317", + "number": 31835847, + "status": "finalized", + "timestamp": "1579009091", + "type": 2 + }, + { + "_id": "0xdac984b7c4dcaa5b797469c886b83e632ccac090f5511b6c5af61ad8d399247a", + "block_height": "2431518", + "data": { + "fee": { + "thetawei": "0", + "tfuelwei": "2000000000000" + }, + "inputs": [ + { + "address": "0xac0eeb6ee3e32e2c74e14ac74155063e4f4f981f", + "coins": { + "thetawei": "0", + "tfuelwei": "15248860400000000" + }, + "sequence": "49", + "signature": "0x167c67f48664ef28d2d1a00f2ec572ce2651e523d3d51e0348b25311d8d680e4743ddb289fac786127e694179d4768a009a09ae53eaafef0df71c64534a8024900" + } + ], + "outputs": [ + { + "address": "0x0a7d7141e9abe5d1c760cffa1129c6eb94f35a2a", + "coins": { + "thetawei": "0", + "tfuelwei": "15246860400000000" + } + } + ] + }, + "hash": "0xdac984b7c4dcaa5b797469c886b83e632ccac090f5511b6c5af61ad8d399247a", + "number": 17613936, + "status": "finalized", + "timestamp": "1568046061", + "type": 2 + }, + { + "_id": "0x9c16b1fd23c9cc53ea369eaf54ee73a57c82c33c80c2a919ecea253324a1a32e", + "block_height": "2430944", + "data": { + "fee": { + "thetawei": "0", + "tfuelwei": "2000000000000" + }, + "inputs": [ + { + "address": "0xe9a02df5a59f9bd2b94adf0f8dc7f2311742a907", + "coins": { + "thetawei": "0", + "tfuelwei": "100000000000000000" + }, + "sequence": "1", + "signature": "0x4e34f9e1f9d541eb91b26f8814ad6c989378d528ac5b1ec41e9c7c23eeadfe7e2a58d522ba95fe6e2639011bfc3a49df44fbfd78338aac37f541e962da38b65100" + } + ], + "outputs": [ + { + "address": "0xac0eeb6ee3e32e2c74e14ac74155063e4f4f981f", + "coins": { + "thetawei": "0", + "tfuelwei": "99998000000000000" + } + } + ] + }, + "hash": "0x9c16b1fd23c9cc53ea369eaf54ee73a57c82c33c80c2a919ecea253324a1a32e", + "number": 17609546, + "status": "finalized", + "timestamp": "1568042434", + "type": 2 + }, + { + "_id": "0x0345f986a0401b124d437c819d424ed9673d3720a0cb18600a7f3f0adb172e63", + "block_height": "2430934", + "data": { + "fee": { + "thetawei": "0", + "tfuelwei": "2000000000000" + }, + "inputs": [ + { + "address": "0xac0eeb6ee3e32e2c74e14ac74155063e4f4f981f", + "coins": { + "thetawei": "0", + "tfuelwei": "100002000000000000" + }, + "sequence": "48", + "signature": "0x754582f5b22f94c73d9b88af6adcd4b802939c9e59959412d1417c93b37b8e57129c76a66f2abef675e4715cd7f855faae0cd2f95bb5d0f12bfbe819faf3802f01" + } + ], + "outputs": [ + { + "address": "0xe9a02df5a59f9bd2b94adf0f8dc7f2311742a907", + "coins": { + "thetawei": "0", + "tfuelwei": "100000000000000000" + } + } + ] + }, + "hash": "0x0345f986a0401b124d437c819d424ed9673d3720a0cb18600a7f3f0adb172e63", + "number": 17609465, + "status": "finalized", + "timestamp": "1568042371", + "type": 2 + }, + { + "_id": "0xa28493e76cc5f22a2b2f1514ad983162186dc1e46158f0abd7053c9c14b8d48e", + "block_height": "1574584", + "data": { + "fee": { + "thetawei": "0", + "tfuelwei": "2000000000000" + }, + "inputs": [ + { + "address": "0xac0eeb6ee3e32e2c74e14ac74155063e4f4f981f", + "coins": { + "thetawei": "10000000000000000000", + "tfuelwei": "2000000000000" + }, + "sequence": "47", + "signature": "0x8edf83cbd7ffb06c3580d17c95037e3f57e829390be80818e5644805a8a872ca385c705cc503488580ef5695882c8325ff55db6b91d3d98abb5f0d1ed4d5a98d01" + } + ], + "outputs": [ + { + "address": "0x082a2aef39b6473c55ba7e28c122ed3aea0de381", + "coins": { + "thetawei": "10000000000000000000", + "tfuelwei": "0" + } + } + ] + }, + "hash": "0xa28493e76cc5f22a2b2f1514ad983162186dc1e46158f0abd7053c9c14b8d48e", + "number": 12099631, + "status": "finalized", + "timestamp": "1562652647", + "type": 2 + }, + { + "_id": "0x37e130bdc7c189c02323191206b7d4d8083ee070704028aa6fd52c958cd782a6", + "block_height": "1564408", + "data": { + "fee": { + "thetawei": "0", + "tfuelwei": "2000000000000" + }, + "inputs": [ + { + "address": "0xac0eeb6ee3e32e2c74e14ac74155063e4f4f981f", + "coins": { + "thetawei": "1000000000000000000", + "tfuelwei": "2000000000000" + }, + "sequence": "46", + "signature": "0x838ea223d3572f7a3a390d54aa284e6f2d5ca61fb3b3d4b0902354b530a48cef22e3436da51b8537e045ea62d04cbdc2252a0f7f0059d424a5ceac3ed60db8a001" + } + ], + "outputs": [ + { + "address": "0x0a7d7141e9abe5d1c760cffa1129c6eb94f35a2a", + "coins": { + "thetawei": "1000000000000000000", + "tfuelwei": "0" + } + } + ] + }, + "hash": "0x37e130bdc7c189c02323191206b7d4d8083ee070704028aa6fd52c958cd782a6", + "number": 12056948, + "status": "finalized", + "timestamp": "1562589035", + "type": 2 + }, + { + "_id": "0x4f909d1e5ba2eba387e62dd235ceec9661db5e28138abd4bcb417f331a9461e2", + "block_height": "732538", + "data": { + "fee": { + "thetawei": "0", + "tfuelwei": "2000000000000" + }, + "inputs": [ + { + "address": "0xac0eeb6ee3e32e2c74e14ac74155063e4f4f981f", + "coins": { + "thetawei": "0", + "tfuelwei": "5301960000000000" + }, + "sequence": "45", + "signature": "0xcd14b396f60dd1c943cd23b28c0218f2d292c30c3a8080bf88c201bbb5a9012033248b990de4674e41f257bdf85d8d919580d1681f25a7833cbfe9049df9dc4300" + } + ], + "outputs": [ + { + "address": "0x0a7d7141e9abe5d1c760cffa1129c6eb94f35a2a", + "coins": { + "thetawei": "0", + "tfuelwei": "5299960000000000" + } + } + ] + }, + "hash": "0x4f909d1e5ba2eba387e62dd235ceec9661db5e28138abd4bcb417f331a9461e2", + "number": 7939449, + "status": "finalized", + "timestamp": "1557340224", + "type": 2 + }, + { + "_id": "0xdd10a6896132dd9873940dfba64c1bc450e9932ba7b09eeb002c687b7ff4f311", + "block_height": "729931", + "data": { + "fee": { + "thetawei": "0", + "tfuelwei": "2000000000000" + }, + "inputs": [ + { + "address": "0x0a7d7141e9abe5d1c760cffa1129c6eb94f35a2a", + "coins": { + "thetawei": "55000000000000000", + "tfuelwei": "2000000000000" + }, + "sequence": "13", + "signature": "0x5a952dda238650d59315b4ce317cd2829339a3413ce93ef24c80c6ea8dc467e342612cf5527e61dd6d0aa289cb01b73e7b4337a53f03c9b1f97789486216f78d01" + } + ], + "outputs": [ + { + "address": "0xac0eeb6ee3e32e2c74e14ac74155063e4f4f981f", + "coins": { + "thetawei": "55000000000000000", + "tfuelwei": "0" + } + } + ] + }, + "hash": "0xdd10a6896132dd9873940dfba64c1bc450e9932ba7b09eeb002c687b7ff4f311", + "number": 7925499, + "status": "finalized", + "timestamp": "1557323764", + "type": 2 + }, + { + "_id": "0x558cb5ec877119c2c84a677277efb5b3059adb830c6e74971b3dbe93221b7132", + "block_height": "700327", + "data": { + "fee": { + "thetawei": "0", + "tfuelwei": "2000000000000" + }, + "inputs": [ + { + "address": "0xac0eeb6ee3e32e2c74e14ac74155063e4f4f981f", + "coins": { + "thetawei": "0", + "tfuelwei": "44326000000000000" + }, + "sequence": "44", + "signature": "0x96722b9dabab76bacfb22ee4b15d6e30f7565e3f62f69635227dac860a2228dd753e1ce5bb14fba9d3760aa2a45053ff9f0c218a11dab2ef45a3dcc05d17bfa201" + } + ], + "outputs": [ + { + "address": "0x0a7d7141e9abe5d1c760cffa1129c6eb94f35a2a", + "coins": { + "thetawei": "0", + "tfuelwei": "44324000000000000" + } + } + ] + }, + "hash": "0x558cb5ec877119c2c84a677277efb5b3059adb830c6e74971b3dbe93221b7132", + "number": 7785266, + "status": "finalized", + "timestamp": "1557136821", + "type": 2 + }, + { + "_id": "0x413d8423fd1e6df99fc57f425dfd58c791c877657b364c62c15905ade5114a70", + "block_height": "700321", + "data": { + "fee": { + "thetawei": "0", + "tfuelwei": "2000000000000" + }, + "inputs": [ + { + "address": "0xac0eeb6ee3e32e2c74e14ac74155063e4f4f981f", + "coins": { + "thetawei": "4000000000000000000", + "tfuelwei": "2000000000000" + }, + "sequence": "43", + "signature": "0xb6b6c09b6942cbbb972b190e6f6dc3ade0e56953aca33718e6f7da9eac450029676104f21a111a0a5a11d09c3f4b828061e2fe3fad9616a4af036b2e4bd5f8fb01" + } + ], + "outputs": [ + { + "address": "0x0a7d7141e9abe5d1c760cffa1129c6eb94f35a2a", + "coins": { + "thetawei": "4000000000000000000", + "tfuelwei": "0" + } + } + ] + }, + "hash": "0x413d8423fd1e6df99fc57f425dfd58c791c877657b364c62c15905ade5114a70", + "number": 7785228, + "status": "finalized", + "timestamp": "1557136781", + "type": 2 + }, + { + "_id": "0xcd4072f7557bc943e17807b532deb4022b875d72a575da6d68d97f309a27e0aa", + "block_height": "700276", + "data": { + "fee": { + "thetawei": "0", + "tfuelwei": "2000000000000" + }, + "inputs": [ + { + "address": "0x0a7d7141e9abe5d1c760cffa1129c6eb94f35a2a", + "coins": { + "thetawei": "0", + "tfuelwei": "4236000000000000" + }, + "sequence": "12", + "signature": "0xed80cac7c8a7eab70ad64aa41536b2387890360e8bcc12996f478ad29670326168331ad4d92576ea7eac59963d169f804214117f155853f2b05f09d42983c4d800" + } + ], + "outputs": [ + { + "address": "0xac0eeb6ee3e32e2c74e14ac74155063e4f4f981f", + "coins": { + "thetawei": "0", + "tfuelwei": "4234000000000000" + } + } + ] + }, + "hash": "0xcd4072f7557bc943e17807b532deb4022b875d72a575da6d68d97f309a27e0aa", + "number": 7785052, + "status": "finalized", + "timestamp": "1557136496", + "type": 2 + }, + { + "_id": "0x97d9bd2d04691c8580216ef31f9934641fa1f20c41b2f6d31b94cb93a0c8dd02", + "block_height": "700266", + "data": { + "fee": { + "thetawei": "0", + "tfuelwei": "2000000000000" + }, + "inputs": [ + { + "address": "0x0a7d7141e9abe5d1c760cffa1129c6eb94f35a2a", + "coins": { + "thetawei": "514355440000000000", + "tfuelwei": "2000000000000" + }, + "sequence": "11", + "signature": "0xf93200a589c0bb9e5904a315d3ddeb01eb2ef7c6012b9d868731db2c83f8a103357c97576f35f9797952504aa3119bcda55eb8d9043696e310ed671e50536c4e00" + } + ], + "outputs": [ + { + "address": "0xac0eeb6ee3e32e2c74e14ac74155063e4f4f981f", + "coins": { + "thetawei": "514355440000000000", + "tfuelwei": "0" + } + } + ] + }, + "hash": "0x97d9bd2d04691c8580216ef31f9934641fa1f20c41b2f6d31b94cb93a0c8dd02", + "number": 7785014, + "status": "finalized", + "timestamp": "1557136431", + "type": 2 + }, + { + "_id": "0x48482084bb395439b8ce2c6fc28ab75f06793b8e54e79bf795aacc194d82e25e", + "block_height": "665871", + "data": { + "fee": { + "thetawei": "0", + "tfuelwei": "2000000000000" + }, + "inputs": [ + { + "address": "0xac0eeb6ee3e32e2c74e14ac74155063e4f4f981f", + "coins": { + "thetawei": "0", + "tfuelwei": "100002000000000000" + }, + "sequence": "42", + "signature": "0xca0ae518aa8999fe071fd199bef5be946a669563edda323e143b78cb4d7fc13673aae5d727de1c30577cf788b3fd19ade0057a553b445cc8184eb259990d291900" + } + ], + "outputs": [ + { + "address": "0x351e35bf70f2228a6e34ed27c664240043a02f94", + "coins": { + "thetawei": "0", + "tfuelwei": "100000000000000000" + } + } + ] + }, + "hash": "0x48482084bb395439b8ce2c6fc28ab75f06793b8e54e79bf795aacc194d82e25e", + "number": 7618201, + "status": "finalized", + "timestamp": "1556919195", + "type": 2 + }, + { + "_id": "0x2f356f071a2e71aab3024906cc1d88538694ddd1087ac16d52d340d6a21fd83e", + "block_height": "583831", + "data": { + "fee": { + "thetawei": "0", + "tfuelwei": "2000000000000" + }, + "inputs": [ + { + "address": "0xac0eeb6ee3e32e2c74e14ac74155063e4f4f981f", + "coins": { + "thetawei": "5500000000000000", + "tfuelwei": "2000000000000" + }, + "sequence": "41", + "signature": "0xfcdacd1d546f04cbb496eac3002bf8ce14b0d01fe6527bd0da72c9dd8d650a49696abe9ddf42edc1c934329e62aff5ff65f5a0dacea153bed0c6a3bd976f588901" + } + ], + "outputs": [ + { + "address": "0x0a7d7141e9abe5d1c760cffa1129c6eb94f35a2a", + "coins": { + "thetawei": "5500000000000000", + "tfuelwei": "0" + } + } + ] + }, + "hash": "0x2f356f071a2e71aab3024906cc1d88538694ddd1087ac16d52d340d6a21fd83e", + "number": 7224733, + "status": "finalized", + "timestamp": "1556401357", + "type": 2 + }, + { + "_id": "0x0ed264b12694f0d0279012167a523dfa378fd1573923134e47e000412c18d7bf", + "block_height": "556079", + "data": { + "fee": { + "thetawei": "0", + "tfuelwei": "2000000000000" + }, + "inputs": [ + { + "address": "0xac0eeb6ee3e32e2c74e14ac74155063e4f4f981f", + "coins": { + "thetawei": "0", + "tfuelwei": "502000000000000" + }, + "sequence": "40", + "signature": "0x754499d7b317867e434474221334eb105e6d60aaba96d7160a4c66c556f1906f7c04583c73137ce55fdd09d710e8c9cc4f05de15febdfeadbd48a89241d78bf400" + } + ], + "outputs": [ + { + "address": "0x0a7d7141e9abe5d1c760cffa1129c6eb94f35a2a", + "coins": { + "thetawei": "0", + "tfuelwei": "500000000000000" + } + } + ] + }, + "hash": "0x0ed264b12694f0d0279012167a523dfa378fd1573923134e47e000412c18d7bf", + "number": 7085187, + "status": "finalized", + "timestamp": "1556226228", + "type": 2 + }, + { + "_id": "0x43a7e20dcf5b1e29b545b4d0c4f3d510317cada73648665630a77d0b83d2b4e7", + "block_height": "541058", + "data": { + "fee": { + "thetawei": "0", + "tfuelwei": "2000000000000" + }, + "inputs": [ + { + "address": "0xac0eeb6ee3e32e2c74e14ac74155063e4f4f981f", + "coins": { + "thetawei": "0", + "tfuelwei": "202000000000000" + }, + "sequence": "39", + "signature": "0x4582a94ba36c6a56845f6863560d97d84fed9474b3b8182c4fa69cffa69c91ac3fb70fc92ccd7d441c035afc70b1e944b4aa6203c4444e7f1c483787ad16f5be00" + } + ], + "outputs": [ + { + "address": "0x0a7d7141e9abe5d1c760cffa1129c6eb94f35a2a", + "coins": { + "thetawei": "0", + "tfuelwei": "200000000000000" + } + } + ] + }, + "hash": "0x43a7e20dcf5b1e29b545b4d0c4f3d510317cada73648665630a77d0b83d2b4e7", + "number": 7007032, + "status": "finalized", + "timestamp": "1556131470", + "type": 2 + }, + { + "_id": "0x8238c514e998706067720c7cc4f91605da8e4d8e7c9d8eca1bc798ae0e30f416", + "block_height": "540383", + "data": { + "fee": { + "thetawei": "0", + "tfuelwei": "2000000000000" + }, + "inputs": [ + { + "address": "0xac0eeb6ee3e32e2c74e14ac74155063e4f4f981f", + "coins": { + "thetawei": "0", + "tfuelwei": "552000000000000" + }, + "sequence": "38", + "signature": "0xaedf23eb1f81d6d171c0442976f49eb22676226b04e9c8815f7a410f2307525a446026dc1c1084449cee19402a3e0d279b5dc77caecf31b1e9c1a83783abe77b01" + } + ], + "outputs": [ + { + "address": "0x2971e95728a971f92b79589567b00fa370a86a61", + "coins": { + "thetawei": "0", + "tfuelwei": "550000000000000" + } + } + ] + }, + "hash": "0x8238c514e998706067720c7cc4f91605da8e4d8e7c9d8eca1bc798ae0e30f416", + "number": 7002267, + "status": "finalized", + "timestamp": "1556127205", + "type": 2 + }, + { + "_id": "0xc9d604aa1e78f0ef08bfafd104b1806146315bc9c7737bbc7645742ea9456200", + "block_height": "540326", + "data": { + "fee": { + "thetawei": "0", + "tfuelwei": "2000000000000" + }, + "inputs": [ + { + "address": "0xac0eeb6ee3e32e2c74e14ac74155063e4f4f981f", + "coins": { + "thetawei": "0", + "tfuelwei": "150002000000000000" + }, + "sequence": "37", + "signature": "0xb0ffada03a9add0d826126a0e65d1ed5ca78adcaf2a2a201b40c09a0dd8d3100221a89c5654cc1d811fff2a374133cd3a7ba761e98da881c47697f8521a4cbdd00" + } + ], + "outputs": [ + { + "address": "0x2971e95728a971f92b79589567b00fa370a86a61", + "coins": { + "thetawei": "0", + "tfuelwei": "150000000000000000" + } + } + ] + }, + "hash": "0xc9d604aa1e78f0ef08bfafd104b1806146315bc9c7737bbc7645742ea9456200", + "number": 7001830, + "status": "finalized", + "timestamp": "1556126848", + "type": 2 + }, + { + "_id": "0x5d67e2fb6509fde58281b565ec4aa10f642bdfe4197b8cc4d203d29fb5171974", + "block_height": "539967", + "data": { + "fee": { + "thetawei": "0", + "tfuelwei": "2000000000000" + }, + "inputs": [ + { + "address": "0xac0eeb6ee3e32e2c74e14ac74155063e4f4f981f", + "coins": { + "thetawei": "8855440000000000", + "tfuelwei": "2000000000000" + }, + "sequence": "36", + "signature": "0xea42ebb3bee2f4636a07eeeb0a72ec8364203dffa111bc050f558c726c2fc1d643e0e93e8f92cf120c53e91e370e78e149b3c657b38221a4fb2d88f471f60fa200" + } + ], + "outputs": [ + { + "address": "0x0a7d7141e9abe5d1c760cffa1129c6eb94f35a2a", + "coins": { + "thetawei": "8855440000000000", + "tfuelwei": "0" + } + } + ] + }, + "hash": "0x5d67e2fb6509fde58281b565ec4aa10f642bdfe4197b8cc4d203d29fb5171974", + "number": 6999082, + "status": "finalized", + "timestamp": "1556124581", + "type": 2 + }, + { + "_id": "0xd77abaf300edc06c1fa54f92bfb0f27dff5e41008ca0ef1dbd747a56cb67916a", + "block_height": "539799", + "data": { + "fee": { + "thetawei": "0", + "tfuelwei": "2000000000000" + }, + "inputs": [ + { + "address": "0xac0eeb6ee3e32e2c74e14ac74155063e4f4f981f", + "coins": { + "thetawei": "500000000000000000", + "tfuelwei": "2000000000000" + }, + "sequence": "35", + "signature": "0xdf9a59ff6596ccf5dcb9c71447ea6a61a037dba407ef26ff467f7fbfa9c42fae534b537d3e8ee3be9408f483fc2198ddbe23f6bb9a4137ecc38d9c8e021ed14300" + } + ], + "outputs": [ + { + "address": "0x0a7d7141e9abe5d1c760cffa1129c6eb94f35a2a", + "coins": { + "thetawei": "500000000000000000", + "tfuelwei": "0" + } + } + ] + }, + "hash": "0xd77abaf300edc06c1fa54f92bfb0f27dff5e41008ca0ef1dbd747a56cb67916a", + "number": 6997917, + "status": "finalized", + "timestamp": "1556123520", + "type": 2 + }, + { + "_id": "0xa5584debb3f26fb087b573f01dc5fd1bfa2cca160eb8b95b77e9ba20e06d0f6b", + "block_height": "522707", + "data": { + "fee": { + "thetawei": "0", + "tfuelwei": "2000000000000" + }, + "inputs": [ + { + "address": "0x0a7d7141e9abe5d1c760cffa1129c6eb94f35a2a", + "coins": { + "thetawei": "44126500000000000000", + "tfuelwei": "2000000000000" + }, + "sequence": "10", + "signature": "0x235b125bcfb8015ce4b71b2fbbe75785e10acd6beda3b205e87a586ec3daf05461ac1e95ee41c07d56663ec1a3ac457cfc90b6807513178ba28dd7516a4509dc00" + } + ], + "outputs": [ + { + "address": "0xac0eeb6ee3e32e2c74e14ac74155063e4f4f981f", + "coins": { + "thetawei": "44126500000000000000", + "tfuelwei": "0" + } + } + ] + }, + "hash": "0xa5584debb3f26fb087b573f01dc5fd1bfa2cca160eb8b95b77e9ba20e06d0f6b", + "number": 6914377, + "status": "finalized", + "timestamp": "1556015687", + "type": 2 + }, + { + "_id": "0x85671ec5bad6e347e6e91e04f57d052678c7d60a67aac2ba6b77ed358ab6da80", + "block_height": "522700", + "data": { + "fee": { + "thetawei": "0", + "tfuelwei": "2000000000000" + }, + "inputs": [ + { + "address": "0xac0eeb6ee3e32e2c74e14ac74155063e4f4f981f", + "coins": { + "thetawei": "44126500000000000000", + "tfuelwei": "2000000000000" + }, + "sequence": "34", + "signature": "0x8e82cc09e462a23d61b17ca6e3c0d564119b3ddb2b43f5791fda02fb7c9b0bad17feb35ea6c9ffc95b2e6295ffb4df2a61e677b68176ef738d4023b4c81ade9e01" + } + ], + "outputs": [ + { + "address": "0x0a7d7141e9abe5d1c760cffa1129c6eb94f35a2a", + "coins": { + "thetawei": "44126500000000000000", + "tfuelwei": "0" + } + } + ] + }, + "hash": "0x85671ec5bad6e347e6e91e04f57d052678c7d60a67aac2ba6b77ed358ab6da80", + "number": 6914351, + "status": "finalized", + "timestamp": "1556015641", + "type": 2 + }, + { + "_id": "0xaa758472a734a6672b27cab5b0963286a36457f25df8734e2efa87d65b36f8e9", + "block_height": "522682", + "data": { + "fee": { + "thetawei": "0", + "tfuelwei": "2000000000000" + }, + "inputs": [ + { + "address": "0x0a7d7141e9abe5d1c760cffa1129c6eb94f35a2a", + "coins": { + "thetawei": "44126498000000000000", + "tfuelwei": "2000000000000" + }, + "sequence": "9", + "signature": "0x39efdd9f02dcbe6de02b04f399a0ca312948b158a69b6ff77cc6624bc62b7cb03e42c34e706d2c8cea5da95e038180c47083777ae81cc08bac1ceac18ba3187f00" + } + ], + "outputs": [ + { + "address": "0xac0eeb6ee3e32e2c74e14ac74155063e4f4f981f", + "coins": { + "thetawei": "44126498000000000000", + "tfuelwei": "0" + } + } + ] + }, + "hash": "0xaa758472a734a6672b27cab5b0963286a36457f25df8734e2efa87d65b36f8e9", + "number": 6914279, + "status": "finalized", + "timestamp": "1556015528", + "type": 2 + }, + { + "_id": "0xd0cde1d4d5882aa8500147ef5f8596f7065ef4802d2b404e14f7e11d88d0492d", + "block_height": "522657", + "data": { + "fee": { + "thetawei": "0", + "tfuelwei": "2000000000000" + }, + "inputs": [ + { + "address": "0xac0eeb6ee3e32e2c74e14ac74155063e4f4f981f", + "coins": { + "thetawei": "44126496000000000000", + "tfuelwei": "2000000000000" + }, + "sequence": "33", + "signature": "0xa7a1be3a61c5689020da1436defa0908f5e296a9b389e68786d7483d0beaa4cc47b94fd972861e5e46bd339d69d2ee1008ffc9cc27bb8b9b0d44e8fcac0b218601" + } + ], + "outputs": [ + { + "address": "0x0a7d7141e9abe5d1c760cffa1129c6eb94f35a2a", + "coins": { + "thetawei": "44126496000000000000", + "tfuelwei": "0" + } + } + ] + }, + "hash": "0xd0cde1d4d5882aa8500147ef5f8596f7065ef4802d2b404e14f7e11d88d0492d", + "number": 6914165, + "status": "finalized", + "timestamp": "1556015370", + "type": 2 + }, + { + "_id": "0x18a9a03057fd73d74af779dca017ab060f657e6cafd17caeed377593f87e78fc", + "block_height": "522632", + "data": { + "fee": { + "thetawei": "0", + "tfuelwei": "2000000000000" + }, + "inputs": [ + { + "address": "0x0a7d7141e9abe5d1c760cffa1129c6eb94f35a2a", + "coins": { + "thetawei": "4999998000000000000", + "tfuelwei": "2000000000000" + }, + "sequence": "8", + "signature": "0x7873a6aa0aff1b2df83127bd8c7848d7580c9525d8e006cf730ace22fa92e6eb7e2a9183bf1e6509946dbd8bfa96350d8bdbb0006b4604df630dc2d9213f419a00" + } + ], + "outputs": [ + { + "address": "0xac0eeb6ee3e32e2c74e14ac74155063e4f4f981f", + "coins": { + "thetawei": "4999998000000000000", + "tfuelwei": "0" + } + } + ] + }, + "hash": "0x18a9a03057fd73d74af779dca017ab060f657e6cafd17caeed377593f87e78fc", + "number": 6914059, + "status": "finalized", + "timestamp": "1556015211", + "type": 2 + }, + { + "_id": "0xa7dacd47efeb1b7ff3de61c6796db0140c89b4bc371ac5d6366f2c81dd53eeee", + "block_height": "522353", + "data": { + "fee": { + "thetawei": "0", + "tfuelwei": "2000000000000" + }, + "inputs": [ + { + "address": "0xac0eeb6ee3e32e2c74e14ac74155063e4f4f981f", + "coins": { + "thetawei": "5000000000000000000", + "tfuelwei": "2000000000000" + }, + "sequence": "32", + "signature": "0x7348da0a98909eb1e6dee672224ed8564b0363be55b2029a35e3b0ed4007caea556ab5f0b90f7a31da9d2ee4fb702491ceca8cc1ac5d2b7c57675ada137680d401" + } + ], + "outputs": [ + { + "address": "0x0a7d7141e9abe5d1c760cffa1129c6eb94f35a2a", + "coins": { + "thetawei": "5000000000000000000", + "tfuelwei": "0" + } + } + ] + }, + "hash": "0xa7dacd47efeb1b7ff3de61c6796db0140c89b4bc371ac5d6366f2c81dd53eeee", + "number": 6912886, + "status": "finalized", + "timestamp": "1556013450", + "type": 2 + }, + { + "_id": "0xdc2af10591897be486f29d29b3896dd42c516b2845959ce32fdb744fe0816377", + "block_height": "522338", + "data": { + "fee": { + "thetawei": "0", + "tfuelwei": "2000000000000" + }, + "inputs": [ + { + "address": "0x0a7d7141e9abe5d1c760cffa1129c6eb94f35a2a", + "coins": { + "thetawei": "44126500000000000000", + "tfuelwei": "2000000000000" + }, + "sequence": "7", + "signature": "0x90a6afdec766f3fc5276d7b026173a0175894398fb9f90fc31f3769d578628e7390676d07609bb7977eaa8cd9b624788f9cc9a738722d1e9cfa07aa44bd9d79b01" + } + ], + "outputs": [ + { + "address": "0xac0eeb6ee3e32e2c74e14ac74155063e4f4f981f", + "coins": { + "thetawei": "44126500000000000000", + "tfuelwei": "0" + } + } + ] + }, + "hash": "0xdc2af10591897be486f29d29b3896dd42c516b2845959ce32fdb744fe0816377", + "number": 6912829, + "status": "finalized", + "timestamp": "1556013355", + "type": 2 + }, + { + "_id": "0x319026f316a1d180dbf9bc304be7f8797cf311a57628c6498fa31b88a0d604a4", + "block_height": "522317", + "data": { + "fee": { + "thetawei": "0", + "tfuelwei": "2000000000000" + }, + "inputs": [ + { + "address": "0xac0eeb6ee3e32e2c74e14ac74155063e4f4f981f", + "coins": { + "thetawei": "2000000000000000000", + "tfuelwei": "2000000000000" + }, + "sequence": "31", + "signature": "0x64863e2f7f6ca1a6c2ef6011bb754df743ae87a8688f29daaa7acf19d833ff1853f8f9faafe9901078f88492450329357b68f2d7d9fab504db082b80b988e2ab00" + } + ], + "outputs": [ + { + "address": "0x0a7d7141e9abe5d1c760cffa1129c6eb94f35a2a", + "coins": { + "thetawei": "2000000000000000000", + "tfuelwei": "0" + } + } + ] + }, + "hash": "0x319026f316a1d180dbf9bc304be7f8797cf311a57628c6498fa31b88a0d604a4", + "number": 6912743, + "status": "finalized", + "timestamp": "1556013222", + "type": 2 + }, + { + "_id": "0x9957ae551fc4dd001c8d3f55fa4abe28416f2bd8d3050d36c1e3f37f15a63388", + "block_height": "520920", + "data": { + "fee": { + "thetawei": "0", + "tfuelwei": "2000000000000" + }, + "inputs": [ + { + "address": "0xefa0d997cfe96ff0b452e420b1434f05106c05b8", + "coins": { + "thetawei": "0", + "tfuelwei": "10002000000000000" + }, + "sequence": "3", + "signature": "0xa3fd8dd6a33d89a3fbb675de70372a476d37bac91df4f3e5fe38f80999f6297c62d02360ce883abd9c6a5e3f5094290bdfb2c3dfdd804152383f9a5db3c9c12b01" + } + ], + "outputs": [ + { + "address": "0xac0eeb6ee3e32e2c74e14ac74155063e4f4f981f", + "coins": { + "thetawei": "0", + "tfuelwei": "10000000000000000" + } + } + ] + }, + "hash": "0x9957ae551fc4dd001c8d3f55fa4abe28416f2bd8d3050d36c1e3f37f15a63388", + "number": 6907879, + "status": "finalized", + "timestamp": "1556004406", + "type": 2 + }, + { + "_id": "0x206b7926caea20ca6143ec5a53d08b1196c297fec4fef89e44172b7b2df77115", + "block_height": "520914", + "data": { + "fee": { + "thetawei": "0", + "tfuelwei": "2000000000000" + }, + "inputs": [ + { + "address": "0xefa0d997cfe96ff0b452e420b1434f05106c05b8", + "coins": { + "thetawei": "2000000000000000000", + "tfuelwei": "2000000000000" + }, + "sequence": "2", + "signature": "0xe6068f24b67e3a07035e761154f11e4322809f709522b39f846fca5fcc6c3b74761a82d3f3655b8147b24d5bcedfccf2387f2677e3afffe6e3ca660e8ec64a8d00" + } + ], + "outputs": [ + { + "address": "0xac0eeb6ee3e32e2c74e14ac74155063e4f4f981f", + "coins": { + "thetawei": "2000000000000000000", + "tfuelwei": "0" + } + } + ] + }, + "hash": "0x206b7926caea20ca6143ec5a53d08b1196c297fec4fef89e44172b7b2df77115", + "number": 6907855, + "status": "finalized", + "timestamp": "1556004366", + "type": 2 + }, + { + "_id": "0x1df714aa5f6be1dc512ee65f8c4b3f5244d52a6e4a15efdf30b8c33214ece297", + "block_height": "515163", + "data": { + "fee": { + "thetawei": "0", + "tfuelwei": "2000000000000" + }, + "inputs": [ + { + "address": "0xac0eeb6ee3e32e2c74e14ac74155063e4f4f981f", + "coins": { + "thetawei": "42126500000000000000", + "tfuelwei": "2000000000000" + }, + "sequence": "30", + "signature": "0xa2c8faab0a47009300f4723b01cbfd99dce795c64c2f01f7aeb17d75e6c45cd01e6d68a4e4adb1c2809f2c766615fa61a37ce2932b98c719a3ee83cd9d6ecaa600" + } + ], + "outputs": [ + { + "address": "0x0a7d7141e9abe5d1c760cffa1129c6eb94f35a2a", + "coins": { + "thetawei": "42126500000000000000", + "tfuelwei": "0" + } + } + ] + }, + "hash": "0x1df714aa5f6be1dc512ee65f8c4b3f5244d52a6e4a15efdf30b8c33214ece297", + "number": 6881884, + "status": "finalized", + "timestamp": "1555968080", + "type": 2 + }, + { + "_id": "0x75b3816505dc54b8d6a15013f735790778b20c122f23bc77819eb4cc159f76f0", + "block_height": "514809", + "data": { + "fee": { + "thetawei": "0", + "tfuelwei": "2000000000000" + }, + "inputs": [ + { + "address": "0x0a7d7141e9abe5d1c760cffa1129c6eb94f35a2a", + "coins": { + "thetawei": "36893488147419103232", + "tfuelwei": "2000000000000" + }, + "sequence": "6", + "signature": "0xc2cbf3a20950d517c8dd18110362acc92890a06b4ca14dbb26a5f7ba8c49ab470bba541871daf03c16fa16fe0c0cd1e1a3df9acc87270b129dc9c24633b3e98100" + } + ], + "outputs": [ + { + "address": "0xac0eeb6ee3e32e2c74e14ac74155063e4f4f981f", + "coins": { + "thetawei": "36893488147419103232", + "tfuelwei": "0" + } + } + ] + }, + "hash": "0x75b3816505dc54b8d6a15013f735790778b20c122f23bc77819eb4cc159f76f0", + "number": 6879883, + "status": "finalized", + "timestamp": "1555965845", + "type": 2 + }, + { + "_id": "0x6317fcae6997876a388f869ca4a3b8ba27d082a7685fddb0b343639e4216a1a3", + "block_height": "514753", + "data": { + "fee": { + "thetawei": "0", + "tfuelwei": "2000000000000" + }, + "inputs": [ + { + "address": "0x0a7d7141e9abe5d1c760cffa1129c6eb94f35a2a", + "coins": { + "thetawei": "0", + "tfuelwei": "2000000000000" + }, + "sequence": "5", + "signature": "0xa4b0c250c7d4e9cdddda8c0c1a8e29445b8efbfbca0c96216100eedceb8299db13e68898acc449e61138513b740c1043ee43a431eb07b651ea06a315177873a400" + } + ], + "outputs": [ + { + "address": "0xac0eeb6ee3e32e2c74e14ac74155063e4f4f981f", + "coins": { + "thetawei": "0", + "tfuelwei": "0" + } + } + ] + }, + "hash": "0x6317fcae6997876a388f869ca4a3b8ba27d082a7685fddb0b343639e4216a1a3", + "number": 6879560, + "status": "finalized", + "timestamp": "1555965492", + "type": 2 + }, + { + "_id": "0x5f19d4a8a83c7dc47f6040c14ef0121eed80b3d80b49742c20627da3b65c70a0", + "block_height": "514726", + "data": { + "fee": { + "thetawei": "0", + "tfuelwei": "2000000000000" + }, + "inputs": [ + { + "address": "0x0a7d7141e9abe5d1c760cffa1129c6eb94f35a2a", + "coins": { + "thetawei": "5233011852580896768", + "tfuelwei": "2000000000000" + }, + "sequence": "4", + "signature": "0x2f03352864a0798e1b918b67b688198abb01a89cc25a7c9b14242368a064902612e0954723df6ed8e595876d5a06a1a49d9f3e2ad8987e53534a5d93f69fd2d901" + } + ], + "outputs": [ + { + "address": "0xac0eeb6ee3e32e2c74e14ac74155063e4f4f981f", + "coins": { + "thetawei": "5233011852580896768", + "tfuelwei": "0" + } + } + ] + }, + "hash": "0x5f19d4a8a83c7dc47f6040c14ef0121eed80b3d80b49742c20627da3b65c70a0", + "number": 6879402, + "status": "finalized", + "timestamp": "1555965322", + "type": 2 + }, + { + "_id": "0xa5b18766f3fa9dee5b93da3bf6358098e88babe8504cad389b21db36e30a84bb", + "block_height": "514661", + "data": { + "fee": { + "thetawei": "0", + "tfuelwei": "2000000000000" + }, + "inputs": [ + { + "address": "0xac0eeb6ee3e32e2c74e14ac74155063e4f4f981f", + "coins": { + "thetawei": "5233011852580896768", + "tfuelwei": "2000000000000" + }, + "sequence": "29", + "signature": "0x56fd0256058bf74520a1a0cfacb242dc3a83d13c45531f276dcc596b8981a47f40fe1dab7c774f15fe70faf73687adb1c91af4831f73c2ce24f297cdb4dfc27900" + } + ], + "outputs": [ + { + "address": "0x0a7d7141e9abe5d1c760cffa1129c6eb94f35a2a", + "coins": { + "thetawei": "5233011852580896768", + "tfuelwei": "0" + } + } + ] + }, + "hash": "0xa5b18766f3fa9dee5b93da3bf6358098e88babe8504cad389b21db36e30a84bb", + "number": 6878999, + "status": "finalized", + "timestamp": "1555964914", + "type": 2 + }, + { + "_id": "0xa2abe6cf779790a37e1786bc71c7385e01ceba4843e59f5fd7530b6db9681f47", + "block_height": "514604", + "data": { + "fee": { + "thetawei": "0", + "tfuelwei": "2000000000000" + }, + "inputs": [ + { + "address": "0x0a7d7141e9abe5d1c760cffa1129c6eb94f35a2a", + "coins": { + "thetawei": "0", + "tfuelwei": "2000000000000" + }, + "sequence": "3", + "signature": "0x4a8694a8418fc2f3c94f0c40298824f52b5ba635c2b30bbdc651284ffcf741882ea0c3afed5cf581be6533a19c287816cd59318ea9147de36a29528cc7a6333a01" + } + ], + "outputs": [ + { + "address": "0xac0eeb6ee3e32e2c74e14ac74155063e4f4f981f", + "coins": { + "thetawei": "0", + "tfuelwei": "0" + } + } + ] + }, + "hash": "0xa2abe6cf779790a37e1786bc71c7385e01ceba4843e59f5fd7530b6db9681f47", + "number": 6878652, + "status": "finalized", + "timestamp": "1555964552", + "type": 2 + }, + { + "_id": "0x195590302d9050a447c7a5a3b312419aad3e032f70319af1dfd1d0ebfc812941", + "block_height": "514534", + "data": { + "fee": { + "thetawei": "0", + "tfuelwei": "2000000000000" + }, + "inputs": [ + { + "address": "0x0a7d7141e9abe5d1c760cffa1129c6eb94f35a2a", + "coins": { + "thetawei": "5233009852580896768", + "tfuelwei": "2000000000000" + }, + "sequence": "2", + "signature": "0x5b1ab0af7393a7225489b8a75845ab06ef18cbae52de2a247104a5dae05cb5e87221d9213b7c82c44a825d4f720f46235996f50e56f16d2f2e74686cb69e615e01" + } + ], + "outputs": [ + { + "address": "0xac0eeb6ee3e32e2c74e14ac74155063e4f4f981f", + "coins": { + "thetawei": "5233009852580896768", + "tfuelwei": "0" + } + } + ] + }, + "hash": "0x195590302d9050a447c7a5a3b312419aad3e032f70319af1dfd1d0ebfc812941", + "number": 6878196, + "status": "finalized", + "timestamp": "1555964111", + "type": 2 + }, + { + "_id": "0x5be9eb1c1d552837c7f91f72e95563b5d2b5fd18e8e5a81454ee59de30c15a1b", + "block_height": "514405", + "data": { + "fee": { + "thetawei": "0", + "tfuelwei": "2000000000000" + }, + "inputs": [ + { + "address": "0xac0eeb6ee3e32e2c74e14ac74155063e4f4f981f", + "coins": { + "thetawei": "36893486147419103232", + "tfuelwei": "2000000000000" + }, + "sequence": "28", + "signature": "0x4545703951750bc92c33fb085537f73e1949874c98dad687cacdff48fdebe4fc6ad22667da6908e21279e87be3aec3690469efac39ffd24f921769573fb9337201" + } + ], + "outputs": [ + { + "address": "0x0a7d7141e9abe5d1c760cffa1129c6eb94f35a2a", + "coins": { + "thetawei": "36893486147419103232", + "tfuelwei": "0" + } + } + ] + }, + "hash": "0x5be9eb1c1d552837c7f91f72e95563b5d2b5fd18e8e5a81454ee59de30c15a1b", + "number": 6877410, + "status": "finalized", + "timestamp": "1555963299", + "type": 2 + }, + { + "_id": "0x653626d2fb460cfee647e050b9a302df8c6ff453eafb6a59393b9072cf02245f", + "block_height": "514287", + "data": { + "fee": { + "thetawei": "0", + "tfuelwei": "2000000000000" + }, + "inputs": [ + { + "address": "0xac0eeb6ee3e32e2c74e14ac74155063e4f4f981f", + "coins": { + "thetawei": "5233011852580896768", + "tfuelwei": "2000000000000" + }, + "sequence": "27", + "signature": "0x45327c09b8b9a20e72104e61be207f61ea50f3c4f7519f455f1ddbca1771a811335591ac022bcb2b123a4563c2e08f1b07b7615d1e2dcce9639938d7bbdb50ee01" + } + ], + "outputs": [ + { + "address": "0x0a7d7141e9abe5d1c760cffa1129c6eb94f35a2a", + "coins": { + "thetawei": "5233011852580896768", + "tfuelwei": "0" + } + } + ] + }, + "hash": "0x653626d2fb460cfee647e050b9a302df8c6ff453eafb6a59393b9072cf02245f", + "number": 6876766, + "status": "finalized", + "timestamp": "1555962555", + "type": 2 + }, + { + "_id": "0x6e154a4bdcebbf3464f6aaa7e0cacc2a52ef41e7b82813f341fcccfb05f70a50", + "block_height": "480727", + "data": { + "fee": { + "thetawei": "0", + "tfuelwei": "2000000000000" + }, + "inputs": [ + { + "address": "0x0a7d7141e9abe5d1c760cffa1129c6eb94f35a2a", + "coins": { + "thetawei": "4568500000000000", + "tfuelwei": "2000000000000" + }, + "sequence": "1", + "signature": "0x23443c1b9b8542152d886bcc1552c92e6c34d5817b8d8039e37c53af250567377906d416963f31376a16303ed13b198b37134ab27d9a21e4de5e1837415e4a5700" + } + ], + "outputs": [ + { + "address": "0xac0eeb6ee3e32e2c74e14ac74155063e4f4f981f", + "coins": { + "thetawei": "4568500000000000", + "tfuelwei": "0" + } + } + ] + }, + "hash": "0x6e154a4bdcebbf3464f6aaa7e0cacc2a52ef41e7b82813f341fcccfb05f70a50", + "number": 6758583, + "status": "finalized", + "timestamp": "1555750809", + "type": 2 + }, + { + "_id": "0xc83a3315d61211df66faebf10442a90b28c4e0b1b44a43907c4b160472e3e2d4", + "block_height": "448487", + "data": { + "fee": { + "thetawei": "0", + "tfuelwei": "2000000000000" + }, + "inputs": [ + { + "address": "0xac0eeb6ee3e32e2c74e14ac74155063e4f4f981f", + "coins": { + "thetawei": "0", + "tfuelwei": "10002000000000000" + }, + "sequence": "26", + "signature": "0x42ced3509f6c3d5a1667d833e4405eb8c9fbc9787030adad9071432b78fc2d3a4a60f45bdb28c7c04d739715777637f28239c2ba41d9a01cf81a565d6777f6a000" + } + ], + "outputs": [ + { + "address": "0xd54d386b0590024ea00641ba0e9f4aaf52f9018e", + "coins": { + "thetawei": "0", + "tfuelwei": "10000000000000000" + } + } + ] + }, + "hash": "0xc83a3315d61211df66faebf10442a90b28c4e0b1b44a43907c4b160472e3e2d4", + "number": 6335899, + "status": "finalized", + "timestamp": "1555544770", + "type": 2 + }, + { + "_id": "0x311317eb46ca5e6a256ef87cfac85c3467ba8c850ff447575c6408e89e2a74dd", + "block_height": "448484", + "data": { + "fee": { + "thetawei": "0", + "tfuelwei": "2000000000000" + }, + "inputs": [ + { + "address": "0xac0eeb6ee3e32e2c74e14ac74155063e4f4f981f", + "coins": { + "thetawei": "25000000000000000000", + "tfuelwei": "2000000000000" + }, + "sequence": "25", + "signature": "0x888a3b81c57e8aafb3f10259e78c9b0d299fac0ded08f9cce89ae13dc0cb4e796defac90b538cd19cb9426da87491fcbcacdce45b7cdf07c83538e62bc6a106501" + } + ], + "outputs": [ + { + "address": "0xd54d386b0590024ea00641ba0e9f4aaf52f9018e", + "coins": { + "thetawei": "25000000000000000000", + "tfuelwei": "0" + } + } + ] + }, + "hash": "0x311317eb46ca5e6a256ef87cfac85c3467ba8c850ff447575c6408e89e2a74dd", + "number": 6335806, + "status": "finalized", + "timestamp": "1555544752", + "type": 2 + }, + { + "_id": "0x9a067fc508fa584271c8228778e205f95a8577f4ee692365c696636d51f2bc8f", + "block_height": "448415", + "data": { + "fee": { + "thetawei": "0", + "tfuelwei": "2000000000000" + }, + "inputs": [ + { + "address": "0xac0eeb6ee3e32e2c74e14ac74155063e4f4f981f", + "coins": { + "thetawei": "0", + "tfuelwei": "10002000000000000" + }, + "sequence": "24", + "signature": "0xdd42268f51c2db654708dc9c4d2a22a9a39701e8c60b0dec2c6bcc6e6c300c9231affe1e6e265984ba74f17d898ddfd7cb4e678d755ba94aab186fe18d63e2a901" + } + ], + "outputs": [ + { + "address": "0xc3e1fe158d3ba112d744f4cd7f298b9d18a4b049", + "coins": { + "thetawei": "0", + "tfuelwei": "10000000000000000" + } + } + ] + }, + "hash": "0x9a067fc508fa584271c8228778e205f95a8577f4ee692365c696636d51f2bc8f", + "number": 6334119, + "status": "finalized", + "timestamp": "1555544303", + "type": 2 + }, + { + "_id": "0x53718be0bac341fffedf123cca2f7def587a5626e754f11384f971bc3a00dd78", + "block_height": "448411", + "data": { + "fee": { + "thetawei": "0", + "tfuelwei": "2000000000000" + }, + "inputs": [ + { + "address": "0xac0eeb6ee3e32e2c74e14ac74155063e4f4f981f", + "coins": { + "thetawei": "0", + "tfuelwei": "10002000000000000" + }, + "sequence": "23", + "signature": "0x5c6038236849203233ff93da2b9600eb4948ef29fc5cd651e4fc53918ed9cb8037a10761cfa7e35f44685a020a7ba547394051db7c6ad52d4a180d375c265e5900" + } + ], + "outputs": [ + { + "address": "0xd74b376cfbf678249a438abe5b56fa697603008e", + "coins": { + "thetawei": "0", + "tfuelwei": "10000000000000000" + } + } + ] + }, + "hash": "0x53718be0bac341fffedf123cca2f7def587a5626e754f11384f971bc3a00dd78", + "number": 6334020, + "status": "finalized", + "timestamp": "1555544277", + "type": 2 + }, + { + "_id": "0x4b0bfdf2b4fafe0ebfe7a437dbbb156e58d674190869af4e09bfa48170a3a971", + "block_height": "448406", + "data": { + "fee": { + "thetawei": "0", + "tfuelwei": "2000000000000" + }, + "inputs": [ + { + "address": "0xac0eeb6ee3e32e2c74e14ac74155063e4f4f981f", + "coins": { + "thetawei": "0", + "tfuelwei": "10002000000000000" + }, + "sequence": "22", + "signature": "0x5fe69b2a3946880387dd5c2f18769e772ab446f587c8d01340fd7cc8449cf7f17fa50548f22c62e62d14d4bdcc656f7ba15072f77c7819012d349aa23f21c82101" + } + ], + "outputs": [ + { + "address": "0x07f9d0b8eb1e1b4ceeaade77467ed1b8267d2d81", + "coins": { + "thetawei": "0", + "tfuelwei": "10000000000000000" + } + } + ] + }, + "hash": "0x4b0bfdf2b4fafe0ebfe7a437dbbb156e58d674190869af4e09bfa48170a3a971", + "number": 6333904, + "status": "finalized", + "timestamp": "1555544245", + "type": 2 + }, + { + "_id": "0xd48940141a190497364960403e2c4bb2aeb16cfef1be4b6d8561415b927c7f09", + "block_height": "448403", + "data": { + "fee": { + "thetawei": "0", + "tfuelwei": "2000000000000" + }, + "inputs": [ + { + "address": "0xac0eeb6ee3e32e2c74e14ac74155063e4f4f981f", + "coins": { + "thetawei": "0", + "tfuelwei": "10002000000000000" + }, + "sequence": "21", + "signature": "0x37296db338f0d55b19989b9b1994d1020cc3ea4f22d196af4164a75fe4482c8f53f6397a9e61420ef2a6713104f954a4eecf8f3c73f9f8d49040afa1e9e6cdae01" + } + ], + "outputs": [ + { + "address": "0xe6b5af7812dd571904d0b1e313ed4ab0579308a1", + "coins": { + "thetawei": "0", + "tfuelwei": "10000000000000000" + } + } + ] + }, + "hash": "0xd48940141a190497364960403e2c4bb2aeb16cfef1be4b6d8561415b927c7f09", + "number": 6333824, + "status": "finalized", + "timestamp": "1555544226", + "type": 2 + }, + { + "_id": "0x27a005b40c064ff636939ed389f86ad79ac9b9ee60a1bff1a805a1c81058fd35", + "block_height": "448399", + "data": { + "fee": { + "thetawei": "0", + "tfuelwei": "2000000000000" + }, + "inputs": [ + { + "address": "0xac0eeb6ee3e32e2c74e14ac74155063e4f4f981f", + "coins": { + "thetawei": "0", + "tfuelwei": "10002000000000000" + }, + "sequence": "20", + "signature": "0x78c878d6c48ff64e4f82015a663ff94fbc5a65cf36ebb20aa5e31b0c13afc6be159b5d29e1c794bf5b281523e6c2d76466acca5e20859780c8093ce86b0c7f7701" + } + ], + "outputs": [ + { + "address": "0x07f9d0b8eb1e1b4ceeaade77467ed1b8267d2d81", + "coins": { + "thetawei": "0", + "tfuelwei": "10000000000000000" + } + } + ] + }, + "hash": "0x27a005b40c064ff636939ed389f86ad79ac9b9ee60a1bff1a805a1c81058fd35", + "number": 6333737, + "status": "finalized", + "timestamp": "1555544201", + "type": 2 + }, + { + "_id": "0xbe83e79914d187f568e471c9c986b4fe800a5c61ce684eb64ad675c868e1d0fd", + "block_height": "448389", + "data": { + "fee": { + "thetawei": "0", + "tfuelwei": "2000000000000" + }, + "inputs": [ + { + "address": "0xac0eeb6ee3e32e2c74e14ac74155063e4f4f981f", + "coins": { + "thetawei": "25000000000000000000", + "tfuelwei": "2000000000000" + }, + "sequence": "19", + "signature": "0x3ba6d4ad2f2a6d1556746fc3b1c7ee9f5ac4103c04a4de3f1b01dc84367b43762fb4a167ea8b946d1f2c84395df13ab0df101024c227382716970f99a838e7c800" + } + ], + "outputs": [ + { + "address": "0xc3e1fe158d3ba112d744f4cd7f298b9d18a4b049", + "coins": { + "thetawei": "25000000000000000000", + "tfuelwei": "0" + } + } + ] + }, + "hash": "0xbe83e79914d187f568e471c9c986b4fe800a5c61ce684eb64ad675c868e1d0fd", + "number": 6333571, + "status": "finalized", + "timestamp": "1555544135", + "type": 2 + }, + { + "_id": "0x77bf4a03f3504c9d111cf078d6b7e11773e9dc389b65cb21b79725ba45334278", + "block_height": "448330", + "data": { + "fee": { + "thetawei": "0", + "tfuelwei": "2000000000000" + }, + "inputs": [ + { + "address": "0xac0eeb6ee3e32e2c74e14ac74155063e4f4f981f", + "coins": { + "thetawei": "25000000000000000000", + "tfuelwei": "2000000000000" + }, + "sequence": "18", + "signature": "0xd4e72ef6a481202f02633f15f9bec1169c54baedbee2dba11224acfda2f3a79b4fd27de62e90f0118822485b8ed1dc5a07c6323682d6ccb378ae3f87f3ea2d2200" + } + ], + "outputs": [ + { + "address": "0xd74b376cfbf678249a438abe5b56fa697603008e", + "coins": { + "thetawei": "25000000000000000000", + "tfuelwei": "0" + } + } + ] + }, + "hash": "0x77bf4a03f3504c9d111cf078d6b7e11773e9dc389b65cb21b79725ba45334278", + "number": 6332075, + "status": "finalized", + "timestamp": "1555543751", + "type": 2 + }, + { + "_id": "0xbc3b3ac526e78e0e607a35047172cfae09c5441c03992d814943ae59165c7465", + "block_height": "448116", + "data": { + "fee": { + "thetawei": "0", + "tfuelwei": "2000000000000" + }, + "inputs": [ + { + "address": "0xac0eeb6ee3e32e2c74e14ac74155063e4f4f981f", + "coins": { + "thetawei": "25000000000000000000", + "tfuelwei": "2000000000000" + }, + "sequence": "17", + "signature": "0xf896284d9f6e2b941063c01000d63869b0d1b4c94b8d8266468a6f813a11dd8d44caf2cd8ec07eea28379b70f7a9a89816c23f0ebb15b3273755f5396ca9b8ac01" + } + ], + "outputs": [ + { + "address": "0x25c69e1d90677bb717ac506c2760670b346e35a6", + "coins": { + "thetawei": "25000000000000000000", + "tfuelwei": "0" + } + } + ] + }, + "hash": "0xbc3b3ac526e78e0e607a35047172cfae09c5441c03992d814943ae59165c7465", + "number": 6326704, + "status": "finalized", + "timestamp": "1555542360", + "type": 2 + }, + { + "_id": "0x76578714ca49fa9b94773a26da2bd1ade7c76c45d22112f5b7c92581e53db4ef", + "block_height": "448112", + "data": { + "fee": { + "thetawei": "0", + "tfuelwei": "2000000000000" + }, + "inputs": [ + { + "address": "0xac0eeb6ee3e32e2c74e14ac74155063e4f4f981f", + "coins": { + "thetawei": "25000000000000000000", + "tfuelwei": "2000000000000" + }, + "sequence": "16", + "signature": "0xc452595b91be0e5e515b48a00f7d35a1420318a304f89877b7f5cd5643bc3e3d784894f2605bb69efa59aa93d37a5260f4df19f73f41163e29063109c9ff08c100" + } + ], + "outputs": [ + { + "address": "0x07f9d0b8eb1e1b4ceeaade77467ed1b8267d2d81", + "coins": { + "thetawei": "25000000000000000000", + "tfuelwei": "0" + } + } + ] + }, + "hash": "0x76578714ca49fa9b94773a26da2bd1ade7c76c45d22112f5b7c92581e53db4ef", + "number": 6326620, + "status": "finalized", + "timestamp": "1555542334", + "type": 2 + }, + { + "_id": "0x9ab23428f133bbccefc7b020945c8853e7c016abaf452921aa5aa0d6600bb74b", + "block_height": "448108", + "data": { + "fee": { + "thetawei": "0", + "tfuelwei": "2000000000000" + }, + "inputs": [ + { + "address": "0xac0eeb6ee3e32e2c74e14ac74155063e4f4f981f", + "coins": { + "thetawei": "25000000000000000000", + "tfuelwei": "2000000000000" + }, + "sequence": "15", + "signature": "0xaa6d0f2cf748a27778232cf9424411baaee57d369eb884b6726c3a21f9f9207e28e1b5a06bb45a0403f8332114ae389e8338700d2e5ac16644c511630231b1d201" + } + ], + "outputs": [ + { + "address": "0xe6b5af7812dd571904d0b1e313ed4ab0579308a1", + "coins": { + "thetawei": "25000000000000000000", + "tfuelwei": "0" + } + } + ] + }, + "hash": "0x9ab23428f133bbccefc7b020945c8853e7c016abaf452921aa5aa0d6600bb74b", + "number": 6326545, + "status": "finalized", + "timestamp": "1555542309", + "type": 2 + }, + { + "_id": "0x007260fba1949eceefb83705254bcaa2cba46affbc8427c4b7ff165db5590f12", + "block_height": "424192", + "data": { + "fee": { + "thetawei": "0", + "tfuelwei": "2000000000000" + }, + "inputs": [ + { + "address": "0xac0eeb6ee3e32e2c74e14ac74155063e4f4f981f", + "coins": { + "thetawei": "2000000000000000000", + "tfuelwei": "2000000000000" + }, + "sequence": "14", + "signature": "0xfb5595bd6494f3109eefe42aec4fb06aa6bd56cbd726adc721233c4bcfcd8a6d4d1faa24db817eb2e9053b292a35a79e44962531038c0e58549393de9daffc0b01" + } + ], + "outputs": [ + { + "address": "0xefa0d997cfe96ff0b452e420b1434f05106c05b8", + "coins": { + "thetawei": "2000000000000000000", + "tfuelwei": "0" + } + } + ] + }, + "hash": "0x007260fba1949eceefb83705254bcaa2cba46affbc8427c4b7ff165db5590f12", + "number": 5902778, + "status": "finalized", + "timestamp": "1555388611", + "type": 2 + }, + { + "_id": "0x2fb3fc5769389efd178c9ba2a672e30f268744a1b9855241d70c6d55f1c8396b", + "block_height": "422336", + "data": { + "fee": { + "thetawei": "0", + "tfuelwei": "2000000000000" + }, + "inputs": [ + { + "address": "0xefa0d997cfe96ff0b452e420b1434f05106c05b8", + "coins": { + "thetawei": "2000000000000000000", + "tfuelwei": "2000000000000" + }, + "sequence": "1", + "signature": "0x5e2016a265986a1c4f7ee08ceca82ce581b38f04670b1df117645ec4cdafca562953229d87c6fb828818db5a8252d48cf6283d54e0405bbfdcbbf4af08b59ef201" + } + ], + "outputs": [ + { + "address": "0xac0eeb6ee3e32e2c74e14ac74155063e4f4f981f", + "coins": { + "thetawei": "2000000000000000000", + "tfuelwei": "0" + } + } + ] + }, + "hash": "0x2fb3fc5769389efd178c9ba2a672e30f268744a1b9855241d70c6d55f1c8396b", + "number": 5881181, + "status": "finalized", + "timestamp": "1555376786", + "type": 2 + }, + { + "_id": "0xd7bbf5c90d27d2795a38537c1a1540484da333157cb77e6310cd33f06536e3b1", + "block_height": "421709", + "data": { + "fee": { + "thetawei": "0", + "tfuelwei": "2000000000000" + }, + "inputs": [ + { + "address": "0xac0eeb6ee3e32e2c74e14ac74155063e4f4f981f", + "coins": { + "thetawei": "0", + "tfuelwei": "100002000000000000" + }, + "sequence": "13", + "signature": "0x0f6a1849ce86f85691644c2d312b67fa0289d92675c1ca5999e55d6ae2ccf7030d0f38e1a1161b4e4705af56ff45ffbdee95c0f544da88de2cfbbb5b8353b92300" + } + ], + "outputs": [ + { + "address": "0xefa0d997cfe96ff0b452e420b1434f05106c05b8", + "coins": { + "thetawei": "0", + "tfuelwei": "100000000000000000" + } + } + ] + }, + "hash": "0xd7bbf5c90d27d2795a38537c1a1540484da333157cb77e6310cd33f06536e3b1", + "number": 5870433, + "status": "finalized", + "timestamp": "1555372785", + "type": 2 + }, + { + "_id": "0xf3f4a2c5d74ec87bd7fb2dc090f126281ddcb6893657ea91758afa189772816c", + "block_height": "421698", + "data": { + "fee": { + "thetawei": "0", + "tfuelwei": "2000000000000" + }, + "inputs": [ + { + "address": "0xac0eeb6ee3e32e2c74e14ac74155063e4f4f981f", + "coins": { + "thetawei": "2000000000000000000", + "tfuelwei": "2000000000000" + }, + "sequence": "12", + "signature": "0x58443a838a55b85f10d50a0762fea8483bacaa8c844872d6f197447f31af3f51615f5a83502e38d501034a1e0332cfba6de1e4aa24aeab1e182d7769324b4e2401" + } + ], + "outputs": [ + { + "address": "0xefa0d997cfe96ff0b452e420b1434f05106c05b8", + "coins": { + "thetawei": "2000000000000000000", + "tfuelwei": "0" + } + } + ] + }, + "hash": "0xf3f4a2c5d74ec87bd7fb2dc090f126281ddcb6893657ea91758afa189772816c", + "number": 5870303, + "status": "finalized", + "timestamp": "1555372712", + "type": 2 + }, + { + "_id": "0x932226a93869194fece8ceb209c3512f92e019fb8716f02b9e2610036f06d91b", + "block_height": "417455", + "data": { + "fee": { + "thetawei": "0", + "tfuelwei": "2000000000000" + }, + "inputs": [ + { + "address": "0xac0eeb6ee3e32e2c74e14ac74155063e4f4f981f", + "coins": { + "thetawei": "850000000000000000", + "tfuelwei": "2000000000000" + }, + "sequence": "11", + "signature": "0x9bf3d6070e873597094d9f04e9709d6f3d7929c1da2a6ad1291d43eda26b7065183a3d161156ab01aea22c700211fe946d3d94759887c8650bfef90410879b1e01" + } + ], + "outputs": [ + { + "address": "0x2971e95728a971f92b79589567b00fa370a86a61", + "coins": { + "thetawei": "850000000000000000", + "tfuelwei": "0" + } + } + ] + }, + "hash": "0x932226a93869194fece8ceb209c3512f92e019fb8716f02b9e2610036f06d91b", + "number": 5798376, + "status": "finalized", + "timestamp": "1555345550", + "type": 2 + }, + { + "_id": "0xc35b1fd9655a745bcb8ad0da14519aed2ec45e5730b434aed9cb0d413e228056", + "block_height": "414933", + "data": { + "fee": { + "thetawei": "0", + "tfuelwei": "2000000000000" + }, + "inputs": [ + { + "address": "0xac0eeb6ee3e32e2c74e14ac74155063e4f4f981f", + "coins": { + "thetawei": "6000000000000000000", + "tfuelwei": "2000000000000" + }, + "sequence": "10", + "signature": "0x600362cb40761bd0a6ba9e02d60ef063d8b8723bc601511ffe8f4b0dfa251afd5463656241fd58bdc13d24066f215042a05a320b40644ccd1da28b5011d6ccae00" + } + ], + "outputs": [ + { + "address": "0x7cd0835befd95bd0527c8254f14e1202bf113505", + "coins": { + "thetawei": "6000000000000000000", + "tfuelwei": "0" + } + } + ] + }, + "hash": "0xc35b1fd9655a745bcb8ad0da14519aed2ec45e5730b434aed9cb0d413e228056", + "number": 5768149, + "status": "finalized", + "timestamp": "1555329559", + "type": 2 + }, + { + "_id": "0x6e87d7cd010543b28306c8c07063970c2631fb2183d4f19c84a85dcf35e3292b", + "block_height": "414927", + "data": { + "fee": { + "thetawei": "0", + "tfuelwei": "2000000000000" + }, + "inputs": [ + { + "address": "0xac0eeb6ee3e32e2c74e14ac74155063e4f4f981f", + "coins": { + "thetawei": "0", + "tfuelwei": "5002000000000000" + }, + "sequence": "9", + "signature": "0x0998593653b00b0e385e670521f5eac9573f1964daa9ddd58161bc826a2749d0087e859c57c058f95f010e6d7c9e1c43490d82fda44b1fd5dbb993455ad4bb0201" + } + ], + "outputs": [ + { + "address": "0x7cd0835befd95bd0527c8254f14e1202bf113505", + "coins": { + "thetawei": "0", + "tfuelwei": "5000000000000000" + } + } + ] + }, + "hash": "0x6e87d7cd010543b28306c8c07063970c2631fb2183d4f19c84a85dcf35e3292b", + "number": 5768087, + "status": "finalized", + "timestamp": "1555329523", + "type": 2 + }, + { + "_id": "0x9adb8681f2072f54b7dfef6d7c9a268e413e82cb6668030fb24cb10076221e9e", + "block_height": "406658", + "data": { + "fee": { + "thetawei": "0", + "tfuelwei": "1000000000000" + }, + "inputs": [ + { + "address": "0x5bd04178a7cac9c8f8f8d93d1c6c53ed2056d6fa", + "coins": { + "thetawei": "200000000000000000000", + "tfuelwei": "1000000000000" + }, + "sequence": "6", + "signature": "0xc2fda1322df918a2fdb39df4d8018ddba946c413c334b1db08bf9345f16b1c2f1507757e1fed5c58d58d71945e10c78ceadc33a6970a1b9bc75181881f2dfc7b00" + } + ], + "outputs": [ + { + "address": "0xac0eeb6ee3e32e2c74e14ac74155063e4f4f981f", + "coins": { + "thetawei": "200000000000000000000", + "tfuelwei": "0" + } + } + ] + }, + "hash": "0x9adb8681f2072f54b7dfef6d7c9a268e413e82cb6668030fb24cb10076221e9e", + "number": 5708614, + "status": "finalized", + "timestamp": "1555277309", + "type": 2 + }, + { + "_id": "0x882cd203ea70b926218ae27ed4e57b9cced20310eb85c0546c85b70bf3b4d979", + "block_height": "357738", + "data": { + "fee": { + "thetawei": "0", + "tfuelwei": "2000000000000" + }, + "inputs": [ + { + "address": "0xac0eeb6ee3e32e2c74e14ac74155063e4f4f981f", + "coins": { + "thetawei": "23300000000000000", + "tfuelwei": "2000000000000" + }, + "sequence": "8", + "signature": "0xd30437e7dd375f48998c236c13a9fb147d63b57e4cb1c5c59c914c1897fe991b44368151d21df7121f342bfcfd743f12ca584bec9412e4fe83d9d4b185b31dac00" + } + ], + "outputs": [ + { + "address": "0x4ddd0c6734a9bc4f49938ed0c8de257471c35755", + "coins": { + "thetawei": "23300000000000000", + "tfuelwei": "0" + } + } + ] + }, + "hash": "0x882cd203ea70b926218ae27ed4e57b9cced20310eb85c0546c85b70bf3b4d979", + "number": 5239549, + "status": "finalized", + "timestamp": "1554966610", + "type": 2 + }, + { + "_id": "0xa49d8b227a496f378552df5ede3fce41dd7f14c1d7dca69068602da32bfd1929", + "block_height": "357506", + "data": { + "fee": { + "thetawei": "0", + "tfuelwei": "2000000000000" + }, + "inputs": [ + { + "address": "0xac0eeb6ee3e32e2c74e14ac74155063e4f4f981f", + "coins": { + "thetawei": "0", + "tfuelwei": "10002000000000000" + }, + "sequence": "7", + "signature": "0xb782d4dcea8d4e4e39066938c1d8c36677eec8632f5f558d50ca50114d3a723a10929015bcfcaea9bfd9a04257fc8908934589a3b9a2fee1ec37275072a44f3601" + } + ], + "outputs": [ + { + "address": "0x4ddd0c6734a9bc4f49938ed0c8de257471c35755", + "coins": { + "thetawei": "0", + "tfuelwei": "10000000000000000" + } + } + ] + }, + "hash": "0xa49d8b227a496f378552df5ede3fce41dd7f14c1d7dca69068602da32bfd1929", + "number": 5237001, + "status": "finalized", + "timestamp": "1554965141", + "type": 2 + }, + { + "_id": "0x62ae2679d93f2787991837379349df927efb640e01a46189d3e76f6bf751498a", + "block_height": "357502", + "data": { + "fee": { + "thetawei": "0", + "tfuelwei": "2000000000000" + }, + "inputs": [ + { + "address": "0xac0eeb6ee3e32e2c74e14ac74155063e4f4f981f", + "coins": { + "thetawei": "0", + "tfuelwei": "10002000000000000" + }, + "sequence": "6", + "signature": "0xa5b8a62fee49ef84e349b81f522d4ad7e7a0834346af575e4cb1c6456f42dcca20b255755e0f71e5949ae73fe257a770e58457804e766d5f7a842217ce90e9cb01" + } + ], + "outputs": [ + { + "address": "0x4ddd0c6734a9bc4f49938ed0c8de257471c35755", + "coins": { + "thetawei": "0", + "tfuelwei": "10000000000000000" + } + } + ] + }, + "hash": "0x62ae2679d93f2787991837379349df927efb640e01a46189d3e76f6bf751498a", + "number": 5236954, + "status": "finalized", + "timestamp": "1554965115", + "type": 2 + }, + { + "_id": "0x9d82a263f3a1d93f0a40f877e966c5c6468094c96a228e08212686bb66228c02", + "block_height": "348734", + "data": { + "fee": { + "thetawei": "0", + "tfuelwei": "2000000000000" + }, + "inputs": [ + { + "address": "0xac0eeb6ee3e32e2c74e14ac74155063e4f4f981f", + "coins": { + "thetawei": "0", + "tfuelwei": "3560000000000000" + }, + "sequence": "5", + "signature": "0x1325ff2e00b4b5b817c84732b4195e5ded9032be751ff9078a32681a38ce2381030a0ef635ea01b65ffa122587c75725da0c4fa2d6dd5da80507c6b444262ec901" + } + ], + "outputs": [ + { + "address": "0x0a7d7141e9abe5d1c760cffa1129c6eb94f35a2a", + "coins": { + "thetawei": "0", + "tfuelwei": "3558000000000000" + } + } + ] + }, + "hash": "0x9d82a263f3a1d93f0a40f877e966c5c6468094c96a228e08212686bb66228c02", + "number": 5104041, + "status": "finalized", + "timestamp": "1554909040", + "type": 2 + }, + { + "_id": "0x5b549112550f013afe264886f9daab1e3c179146a0b755904979fbc2a9a57082", + "block_height": "348714", + "data": { + "fee": { + "thetawei": "0", + "tfuelwei": "2000000000000" + }, + "inputs": [ + { + "address": "0xac0eeb6ee3e32e2c74e14ac74155063e4f4f981f", + "coins": { + "thetawei": "4568500000000000", + "tfuelwei": "2000000000000" + }, + "sequence": "4", + "signature": "0x5956bf4b899e19bb12d3a1a4d0b2415921bb9e8fe73eb0580ae11c73fb8ea65b5da2df792fb650ddbf68e8f30029a3eb20d013350cfc44b1fba5d64a11b5f34d01" + } + ], + "outputs": [ + { + "address": "0x0a7d7141e9abe5d1c760cffa1129c6eb94f35a2a", + "coins": { + "thetawei": "4568500000000000", + "tfuelwei": "0" + } + } + ] + }, + "hash": "0x5b549112550f013afe264886f9daab1e3c179146a0b755904979fbc2a9a57082", + "number": 5103657, + "status": "finalized", + "timestamp": "1554908912", + "type": 2 + }, + { + "_id": "0xf0950f834cf61a523eabf2dcfb3ec138bdd44778e168107efaf0ed599fd713dd", + "block_height": "341414", + "data": { + "fee": { + "thetawei": "0", + "tfuelwei": "2000000000000" + }, + "inputs": [ + { + "address": "0xac0eeb6ee3e32e2c74e14ac74155063e4f4f981f", + "coins": { + "thetawei": "0", + "tfuelwei": "12000000000000" + }, + "sequence": "3", + "signature": "0x4687755a59c47942d32ba953003d7c3ae44f2ae17e6bdbf4c52d313cd8f70d895b2216e10bd1305262e0e91bdc2310323e77d174aff3c51a21386908e344fc5501" + } + ], + "outputs": [ + { + "address": "0xcbcef62ca7a2e367a9c93aba07ea4e63139da99d", + "coins": { + "thetawei": "0", + "tfuelwei": "10000000000000" + } + } + ] + }, + "hash": "0xf0950f834cf61a523eabf2dcfb3ec138bdd44778e168107efaf0ed599fd713dd", + "number": 5009444, + "status": "finalized", + "timestamp": "1554862473", + "type": 2 + }, + { + "_id": "0x75f7730a1bac757e54d362246d9f6f64c517e39f1d5e0f2305b7f621382f0a99", + "block_height": "341409", + "data": { + "fee": { + "thetawei": "0", + "tfuelwei": "2000000000000" + }, + "inputs": [ + { + "address": "0xac0eeb6ee3e32e2c74e14ac74155063e4f4f981f", + "coins": { + "thetawei": "100000000000000", + "tfuelwei": "2000000000000" + }, + "sequence": "2", + "signature": "0x6fe79d9a61cc1e71d4b7e0ac0a91ee3df99cda3671d04c9933b5d28bee9fc1c0075b034ae9319ecfadbdec12c025383e0aae2ea461a3f0c10e6a03614b7815d300" + } + ], + "outputs": [ + { + "address": "0xcbcef62ca7a2e367a9c93aba07ea4e63139da99d", + "coins": { + "thetawei": "100000000000000", + "tfuelwei": "0" + } + } + ] + }, + "hash": "0x75f7730a1bac757e54d362246d9f6f64c517e39f1d5e0f2305b7f621382f0a99", + "number": 5009436, + "status": "finalized", + "timestamp": "1554862440", + "type": 2 + }, + { + "_id": "0x2a9f6acbe86f2370a95d1cf41c274eb9b495244ffc24407c8502cffa8d6567de", + "block_height": "341096", + "data": { + "fee": { + "thetawei": "0", + "tfuelwei": "10000000000000" + }, + "inputs": [ + { + "address": "0xac0eeb6ee3e32e2c74e14ac74155063e4f4f981f", + "coins": { + "thetawei": "100000000000000", + "tfuelwei": "10000000000000" + }, + "sequence": "1", + "signature": "0x824f4ced1a5c8c858e20c6aef30b8e79d054da992dc546111a9405009cf31fda38a0221a8c665a4853beb2ed16e6659c93e5e8930f10f4a23b9a7baca6efe56500" + } + ], + "outputs": [ + { + "address": "0xcbcef62ca7a2e367a9c93aba07ea4e63139da99d", + "coins": { + "thetawei": "100000000000000", + "tfuelwei": "0" + } + } + ] + }, + "hash": "0x2a9f6acbe86f2370a95d1cf41c274eb9b495244ffc24407c8502cffa8d6567de", + "number": 5005700, + "status": "finalized", + "timestamp": "1554860438", + "type": 2 + }, + { + "_id": "0xaaae08793ca9cd550b85efa0bc02c9c2914f25286a345bcdc7aa5775263bfe04", + "block_height": "339188", + "data": { + "fee": { + "thetawei": "0", + "tfuelwei": "1000000000000" + }, + "inputs": [ + { + "address": "0xc959606724d40fff9b6c5e65c4150938a890d5b5", + "coins": { + "thetawei": "0", + "tfuelwei": "1000001000000000000" + }, + "sequence": "23", + "signature": "0xc0ee1d5d23d7ea848751e1c4996d11f2f46604e3420c66be9fa0890169b439a41090595f803b8a30b631d5d92d2c69510f0c2588ab5d1337603112f4f645202d00" + } + ], + "outputs": [ + { + "address": "0xac0eeb6ee3e32e2c74e14ac74155063e4f4f981f", + "coins": { + "thetawei": "0", + "tfuelwei": "1000000000000000000" + } + } + ] + }, + "hash": "0xaaae08793ca9cd550b85efa0bc02c9c2914f25286a345bcdc7aa5775263bfe04", + "number": 4984497, + "status": "finalized", + "timestamp": "1554848327", + "type": 2 + }, + { + "_id": "0xfc0da11d52b6d5b810ad8f2f157ac23d010f515120c90fa589d267b7ba60d68e", + "block_height": "339185", + "data": { + "fee": { + "thetawei": "0", + "tfuelwei": "1000000000000" + }, + "inputs": [ + { + "address": "0xc959606724d40fff9b6c5e65c4150938a890d5b5", + "coins": { + "thetawei": "1000000000000000000", + "tfuelwei": "1000000000000" + }, + "sequence": "22", + "signature": "0x42696f0ec72d2c9e566b5a2a1288b4a5b1f82361d85617ed042bd9172b15d24139ae3fd83682aaff0fd3863406eed92728b3dcfe2ee3f14e6bc662c51d247c5c01" + } + ], + "outputs": [ + { + "address": "0xac0eeb6ee3e32e2c74e14ac74155063e4f4f981f", + "coins": { + "thetawei": "1000000000000000000", + "tfuelwei": "0" + } + } + ] + }, + "hash": "0xfc0da11d52b6d5b810ad8f2f157ac23d010f515120c90fa589d267b7ba60d68e", + "number": 4984490, + "status": "finalized", + "timestamp": "1554848309", + "type": 2 + } + ], + "totalPageNumber": 1, + "currentPageNumber": 1 +} \ No newline at end of file diff --git a/mock/ext-api-data/thundertoken-api_tokens__address_0x0b230def08139f18a86536d9cfa150f04435414c.json b/mock/ext-api-data/thundertoken-api_tokens__address_0x0b230def08139f18a86536d9cfa150f04435414c.json new file mode 100644 index 000000000..4b4e394e0 --- /dev/null +++ b/mock/ext-api-data/thundertoken-api_tokens__address_0x0b230def08139f18a86536d9cfa150f04435414c.json @@ -0,0 +1 @@ +{"total":1,"docs":[{"address":"0x51BcA9300d034A7e6aB379399a317bDfA0D4835b","name":"The Third Identity","decimals":18,"symbol":"TTI"}]} \ No newline at end of file diff --git a/mock/ext-api-data/thundertoken-api_transactions__address_0x0b230def08139f18a86536d9cfa150f04435414c.json b/mock/ext-api-data/thundertoken-api_transactions__address_0x0b230def08139f18a86536d9cfa150f04435414c.json new file mode 100644 index 000000000..c84689686 --- /dev/null +++ b/mock/ext-api-data/thundertoken-api_transactions__address_0x0b230def08139f18a86536d9cfa150f04435414c.json @@ -0,0 +1 @@ +{"docs":[{"operations":[],"contract":null,"_id":"0xb644bbcdeedb68562c285ec962b4c15fc27578ad287282142e369112e6427603","blockNumber":37467849,"time":1588900192,"nonce":406,"from":"0x0B230dEf08139F18a86536d9CFa150f04435414c","to":"0x83Ed8e6135e079a49085CA2f2F5E502691ccC0B1","value":"0","gas":"4700000","gasPrice":"1000000000","gasUsed":"421569","input":"0xc78b6dea0000000000000000000000000000000000000000000000000000000000000800","error":"","id":"0xb644bbcdeedb68562c285ec962b4c15fc27578ad287282142e369112e6427603","timeStamp":"1588900192"},{"operations":[{"transactionId":"0xd4625f9637f11983df28dc343742a25149ee2c0b4151329ad6fad989dac5d1d5-0","contract":{"address":"0x51bca9300d034a7e6ab379399a317bdfa0d4835b","decimals":18,"name":"The Third Identity","symbol":"TTI","totalSupply":"10000000000000000000000000000","updatedAt":"2020-02-26T21:42:19.178Z"},"from":"0x3270b4e0916B4556BF236B6E5D4377282b3255e5","to":"0x0B230dEf08139F18a86536d9CFa150f04435414c","type":"token_transfer","value":"322102000000000000000","id":null}],"contract":null,"_id":"0xd4625f9637f11983df28dc343742a25149ee2c0b4151329ad6fad989dac5d1d5","blockNumber":37467805,"time":1588900148,"nonce":405,"from":"0x0B230dEf08139F18a86536d9CFa150f04435414c","to":"0x3270b4e0916B4556BF236B6E5D4377282b3255e5","value":"0","gas":"4700000","gasPrice":"1000000000","gasUsed":"1511414","input":"0x4008d2f3","error":"","id":"0xd4625f9637f11983df28dc343742a25149ee2c0b4151329ad6fad989dac5d1d5","timeStamp":"1588900148"},{"operations":[],"contract":null,"_id":"0x5d8c91495ceef7e46e209af540e77f7578764a754551a7808162c9f60fce2b6c","blockNumber":37391669,"time":1588823991,"nonce":404,"from":"0x0B230dEf08139F18a86536d9CFa150f04435414c","to":"0x83Ed8e6135e079a49085CA2f2F5E502691ccC0B1","value":"0","gas":"4700000","gasPrice":"1000000000","gasUsed":"421539","input":"0xc78b6dea0000000000000000000000000000000000000000000000000000000000000400","error":"","id":"0x5d8c91495ceef7e46e209af540e77f7578764a754551a7808162c9f60fce2b6c","timeStamp":"1588823991"},{"operations":[{"transactionId":"0xd4d51caebbd5e8eca4bf0e25ffba177c76a10f22cf4d93d79762649ad16d411a-0","contract":{"address":"0x51bca9300d034a7e6ab379399a317bdfa0d4835b","decimals":18,"name":"The Third Identity","symbol":"TTI","totalSupply":"10000000000000000000000000000","updatedAt":"2020-02-26T21:42:19.178Z"},"from":"0x3270b4e0916B4556BF236B6E5D4377282b3255e5","to":"0x0B230dEf08139F18a86536d9CFa150f04435414c","type":"token_transfer","value":"322102000000000000000","id":null}],"contract":null,"_id":"0xd4d51caebbd5e8eca4bf0e25ffba177c76a10f22cf4d93d79762649ad16d411a","blockNumber":37391647,"time":1588823969,"nonce":403,"from":"0x0B230dEf08139F18a86536d9CFa150f04435414c","to":"0x3270b4e0916B4556BF236B6E5D4377282b3255e5","value":"0","gas":"4700000","gasPrice":"1000000000","gasUsed":"1511414","input":"0x4008d2f3","error":"","id":"0xd4d51caebbd5e8eca4bf0e25ffba177c76a10f22cf4d93d79762649ad16d411a","timeStamp":"1588823969"},{"operations":[],"contract":null,"_id":"0x72e90fd0fd35b976d7ef7986556418ba85add4ed81b4174b7f31fb70329e15e2","blockNumber":37298689,"time":1588730986,"nonce":402,"from":"0x0B230dEf08139F18a86536d9CFa150f04435414c","to":"0x83Ed8e6135e079a49085CA2f2F5E502691ccC0B1","value":"0","gas":"4700000","gasPrice":"2000000000","gasUsed":"421569","input":"0xc78b6dea0000000000000000000000000000000000000000000000000000000000000800","error":"","id":"0x72e90fd0fd35b976d7ef7986556418ba85add4ed81b4174b7f31fb70329e15e2","timeStamp":"1588730986"},{"operations":[{"transactionId":"0x410849c83045527389f278c1e042f7e20fe46a95d66b4d0631067a2127896a42-0","contract":{"address":"0x51bca9300d034a7e6ab379399a317bdfa0d4835b","decimals":18,"name":"The Third Identity","symbol":"TTI","totalSupply":"10000000000000000000000000000","updatedAt":"2020-02-26T21:42:19.178Z"},"from":"0x3270b4e0916B4556BF236B6E5D4377282b3255e5","to":"0x0B230dEf08139F18a86536d9CFa150f04435414c","type":"token_transfer","value":"322102000000000000000","id":null}],"contract":null,"_id":"0x410849c83045527389f278c1e042f7e20fe46a95d66b4d0631067a2127896a42","blockNumber":37298664,"time":1588730961,"nonce":401,"from":"0x0B230dEf08139F18a86536d9CFa150f04435414c","to":"0x3270b4e0916B4556BF236B6E5D4377282b3255e5","value":"0","gas":"4700000","gasPrice":"2000000000","gasUsed":"1511414","input":"0x4008d2f3","error":"","id":"0x410849c83045527389f278c1e042f7e20fe46a95d66b4d0631067a2127896a42","timeStamp":"1588730961"},{"operations":[],"contract":null,"_id":"0xb94e7973a2a72f41723abe3c6213d81cca14aabd38bec4993429732bbc6c8cc5","blockNumber":37218845,"time":1588651119,"nonce":400,"from":"0x0B230dEf08139F18a86536d9CFa150f04435414c","to":"0x83Ed8e6135e079a49085CA2f2F5E502691ccC0B1","value":"0","gas":"4700000","gasPrice":"1000000000","gasUsed":"421569","input":"0xc78b6dea0000000000000000000000000000000000000000000000000000000000001000","error":"","id":"0xb94e7973a2a72f41723abe3c6213d81cca14aabd38bec4993429732bbc6c8cc5","timeStamp":"1588651119"},{"operations":[{"transactionId":"0x9fe8d2ffe9e9e85f5f37061f209505c5af4a738b21f441ab5d8b57329bfabb0f-0","contract":{"address":"0x51bca9300d034a7e6ab379399a317bdfa0d4835b","decimals":18,"name":"The Third Identity","symbol":"TTI","totalSupply":"10000000000000000000000000000","updatedAt":"2020-02-26T21:42:19.178Z"},"from":"0x3270b4e0916B4556BF236B6E5D4377282b3255e5","to":"0x0B230dEf08139F18a86536d9CFa150f04435414c","type":"token_transfer","value":"322102000000000000000","id":null}],"contract":null,"_id":"0x9fe8d2ffe9e9e85f5f37061f209505c5af4a738b21f441ab5d8b57329bfabb0f","blockNumber":37218820,"time":1588651094,"nonce":399,"from":"0x0B230dEf08139F18a86536d9CFa150f04435414c","to":"0x3270b4e0916B4556BF236B6E5D4377282b3255e5","value":"0","gas":"4700000","gasPrice":"1000000000","gasUsed":"1511414","input":"0x4008d2f3","error":"","id":"0x9fe8d2ffe9e9e85f5f37061f209505c5af4a738b21f441ab5d8b57329bfabb0f","timeStamp":"1588651094"},{"operations":[],"contract":null,"_id":"0x89f96a31725b8b0b5d7dc263e6df81a64501835c53f5b2c535d856cf06fb9c1c","blockNumber":37119075,"time":1588551300,"nonce":398,"from":"0x0B230dEf08139F18a86536d9CFa150f04435414c","to":"0x83Ed8e6135e079a49085CA2f2F5E502691ccC0B1","value":"0","gas":"4700000","gasPrice":"1000000000","gasUsed":"421569","input":"0xc78b6dea0000000000000000000000000000000000000000000000000000000000000800","error":"","id":"0x89f96a31725b8b0b5d7dc263e6df81a64501835c53f5b2c535d856cf06fb9c1c","timeStamp":"1588551300"},{"operations":[{"transactionId":"0x9cf4f5ccf25256fd7244dd68faa118a36f8a1de33e447365982e3f0b51b4f4c3-0","contract":{"address":"0x51bca9300d034a7e6ab379399a317bdfa0d4835b","decimals":18,"name":"The Third Identity","symbol":"TTI","totalSupply":"10000000000000000000000000000","updatedAt":"2020-02-26T21:42:19.178Z"},"from":"0x3270b4e0916B4556BF236B6E5D4377282b3255e5","to":"0x0B230dEf08139F18a86536d9CFa150f04435414c","type":"token_transfer","value":"322102000000000000000","id":null}],"contract":null,"_id":"0x9cf4f5ccf25256fd7244dd68faa118a36f8a1de33e447365982e3f0b51b4f4c3","blockNumber":37119058,"time":1588551283,"nonce":397,"from":"0x0B230dEf08139F18a86536d9CFa150f04435414c","to":"0x3270b4e0916B4556BF236B6E5D4377282b3255e5","value":"0","gas":"4700000","gasPrice":"1000000000","gasUsed":"1586414","input":"0x4008d2f3","error":"","id":"0x9cf4f5ccf25256fd7244dd68faa118a36f8a1de33e447365982e3f0b51b4f4c3","timeStamp":"1588551283"},{"operations":[],"contract":null,"_id":"0x2535a9542186fcfbd480434982bb34f9f3fb114627b01de69a18e40c5d893e9e","blockNumber":37033239,"time":1588465416,"nonce":396,"from":"0x0B230dEf08139F18a86536d9CFa150f04435414c","to":"0x83Ed8e6135e079a49085CA2f2F5E502691ccC0B1","value":"0","gas":"4700000","gasPrice":"2000000000","gasUsed":"421569","input":"0xc78b6dea0000000000000000000000000000000000000000000000000000000000000800","error":"","id":"0x2535a9542186fcfbd480434982bb34f9f3fb114627b01de69a18e40c5d893e9e","timeStamp":"1588465416"},{"operations":[{"transactionId":"0x9831b826a58313bff055718d5034170384ded72f7d8089b9be9e1ae62877c375-0","contract":{"address":"0x51bca9300d034a7e6ab379399a317bdfa0d4835b","decimals":18,"name":"The Third Identity","symbol":"TTI","totalSupply":"10000000000000000000000000000","updatedAt":"2020-02-26T21:42:19.178Z"},"from":"0x3270b4e0916B4556BF236B6E5D4377282b3255e5","to":"0x0B230dEf08139F18a86536d9CFa150f04435414c","type":"token_transfer","value":"322102000000000000000","id":null}],"contract":null,"_id":"0x9831b826a58313bff055718d5034170384ded72f7d8089b9be9e1ae62877c375","blockNumber":37033207,"time":1588465384,"nonce":395,"from":"0x0B230dEf08139F18a86536d9CFa150f04435414c","to":"0x3270b4e0916B4556BF236B6E5D4377282b3255e5","value":"0","gas":"4700000","gasPrice":"2000000000","gasUsed":"1556414","input":"0x4008d2f3","error":"","id":"0x9831b826a58313bff055718d5034170384ded72f7d8089b9be9e1ae62877c375","timeStamp":"1588465384"},{"operations":[],"contract":null,"_id":"0x0bd0b39760233ba693a280e8ee2fcb6afce866b4c80f82a742b4676c33626d74","blockNumber":36955282,"time":1588387435,"nonce":394,"from":"0x0B230dEf08139F18a86536d9CFa150f04435414c","to":"0x83Ed8e6135e079a49085CA2f2F5E502691ccC0B1","value":"0","gas":"4700000","gasPrice":"25000000000","gasUsed":"421569","input":"0xc78b6dea0000000000000000000000000000000000000000000000000000000000000800","error":"","id":"0x0bd0b39760233ba693a280e8ee2fcb6afce866b4c80f82a742b4676c33626d74","timeStamp":"1588387435"},{"operations":[{"transactionId":"0x043f306a06f3821cb19d6f7eb62a800c384889e429d1e26c837e67259efd73d8-0","contract":{"address":"0x51bca9300d034a7e6ab379399a317bdfa0d4835b","decimals":18,"name":"The Third Identity","symbol":"TTI","totalSupply":"10000000000000000000000000000","updatedAt":"2020-02-26T21:42:19.178Z"},"from":"0x3270b4e0916B4556BF236B6E5D4377282b3255e5","to":"0x0B230dEf08139F18a86536d9CFa150f04435414c","type":"token_transfer","value":"322102000000000000000","id":null}],"contract":null,"_id":"0x043f306a06f3821cb19d6f7eb62a800c384889e429d1e26c837e67259efd73d8","blockNumber":36955254,"time":1588387407,"nonce":393,"from":"0x0B230dEf08139F18a86536d9CFa150f04435414c","to":"0x3270b4e0916B4556BF236B6E5D4377282b3255e5","value":"0","gas":"4700000","gasPrice":"25000000000","gasUsed":"1511414","input":"0x4008d2f3","error":"","id":"0x043f306a06f3821cb19d6f7eb62a800c384889e429d1e26c837e67259efd73d8","timeStamp":"1588387407"},{"operations":[],"contract":null,"_id":"0x86394bbf49c7bc0e3fd02d5f875d160640e8d1f7a454bbd8dfedb922a0815f6a","blockNumber":36876439,"time":1588308515,"nonce":392,"from":"0x0B230dEf08139F18a86536d9CFa150f04435414c","to":"0x83Ed8e6135e079a49085CA2f2F5E502691ccC0B1","value":"0","gas":"4700000","gasPrice":"25000000000","gasUsed":"421569","input":"0xc78b6dea0000000000000000000000000000000000000000000000000000000000000800","error":"","id":"0x86394bbf49c7bc0e3fd02d5f875d160640e8d1f7a454bbd8dfedb922a0815f6a","timeStamp":"1588308515"},{"operations":[{"transactionId":"0x842d46a52e0fedc5911b62629f51bb0693dbc75e8d7a61b33247864f7ba4fa11-0","contract":{"address":"0x51bca9300d034a7e6ab379399a317bdfa0d4835b","decimals":18,"name":"The Third Identity","symbol":"TTI","totalSupply":"10000000000000000000000000000","updatedAt":"2020-02-26T21:42:19.178Z"},"from":"0x3270b4e0916B4556BF236B6E5D4377282b3255e5","to":"0x0B230dEf08139F18a86536d9CFa150f04435414c","type":"token_transfer","value":"322102000000000000000","id":null}],"contract":null,"_id":"0x842d46a52e0fedc5911b62629f51bb0693dbc75e8d7a61b33247864f7ba4fa11","blockNumber":36876421,"time":1588308497,"nonce":391,"from":"0x0B230dEf08139F18a86536d9CFa150f04435414c","to":"0x3270b4e0916B4556BF236B6E5D4377282b3255e5","value":"0","gas":"4700000","gasPrice":"25000000000","gasUsed":"1511414","input":"0x4008d2f3","error":"","id":"0x842d46a52e0fedc5911b62629f51bb0693dbc75e8d7a61b33247864f7ba4fa11","timeStamp":"1588308497"},{"operations":[],"contract":null,"_id":"0x01fc7ea6eaf9fe017ce6c4fa65e9a8b56abe9853947be17c5c73160f46757209","blockNumber":36776536,"time":1588208500,"nonce":390,"from":"0x0B230dEf08139F18a86536d9CFa150f04435414c","to":"0x83Ed8e6135e079a49085CA2f2F5E502691ccC0B1","value":"0","gas":"4700000","gasPrice":"7000000000","gasUsed":"421569","input":"0xc78b6dea0000000000000000000000000000000000000000000000000000000000000800","error":"","id":"0x01fc7ea6eaf9fe017ce6c4fa65e9a8b56abe9853947be17c5c73160f46757209","timeStamp":"1588208500"},{"operations":[{"transactionId":"0x54539cc7c6dd0abd8dfd7db288812e1bbe387ad8f9c7f57c149d9b9b7b01c113-0","contract":{"address":"0x51bca9300d034a7e6ab379399a317bdfa0d4835b","decimals":18,"name":"The Third Identity","symbol":"TTI","totalSupply":"10000000000000000000000000000","updatedAt":"2020-02-26T21:42:19.178Z"},"from":"0x3270b4e0916B4556BF236B6E5D4377282b3255e5","to":"0x0B230dEf08139F18a86536d9CFa150f04435414c","type":"token_transfer","value":"322102000000000000000","id":null}],"contract":null,"_id":"0x54539cc7c6dd0abd8dfd7db288812e1bbe387ad8f9c7f57c149d9b9b7b01c113","blockNumber":36776511,"time":1588208474,"nonce":389,"from":"0x0B230dEf08139F18a86536d9CFa150f04435414c","to":"0x3270b4e0916B4556BF236B6E5D4377282b3255e5","value":"0","gas":"4700000","gasPrice":"7000000000","gasUsed":"1586414","input":"0x4008d2f3","error":"","id":"0x54539cc7c6dd0abd8dfd7db288812e1bbe387ad8f9c7f57c149d9b9b7b01c113","timeStamp":"1588208474"},{"operations":[],"contract":null,"_id":"0x863bd927b9cfab490e61acc30d100c62e28180aac221f19921f8d2b7112d86a0","blockNumber":36709221,"time":1588141143,"nonce":388,"from":"0x0B230dEf08139F18a86536d9CFa150f04435414c","to":"0x83Ed8e6135e079a49085CA2f2F5E502691ccC0B1","value":"0","gas":"4700000","gasPrice":"5500000000","gasUsed":"421569","input":"0xc78b6dea0000000000000000000000000000000000000000000000000000000000000800","error":"","id":"0x863bd927b9cfab490e61acc30d100c62e28180aac221f19921f8d2b7112d86a0","timeStamp":"1588141143"},{"operations":[{"transactionId":"0xd9b8165580cf97970c40e32a121d64f67632f12268c70dc46dbc1705c3b16402-0","contract":{"address":"0x51bca9300d034a7e6ab379399a317bdfa0d4835b","decimals":18,"name":"The Third Identity","symbol":"TTI","totalSupply":"10000000000000000000000000000","updatedAt":"2020-02-26T21:42:19.178Z"},"from":"0x3270b4e0916B4556BF236B6E5D4377282b3255e5","to":"0x0B230dEf08139F18a86536d9CFa150f04435414c","type":"token_transfer","value":"322102000000000000000","id":null}],"contract":null,"_id":"0xd9b8165580cf97970c40e32a121d64f67632f12268c70dc46dbc1705c3b16402","blockNumber":36709202,"time":1588141124,"nonce":387,"from":"0x0B230dEf08139F18a86536d9CFa150f04435414c","to":"0x3270b4e0916B4556BF236B6E5D4377282b3255e5","value":"0","gas":"4700000","gasPrice":"5500000000","gasUsed":"1511414","input":"0x4008d2f3","error":"","id":"0xd9b8165580cf97970c40e32a121d64f67632f12268c70dc46dbc1705c3b16402","timeStamp":"1588141124"},{"operations":[],"contract":null,"_id":"0x42e15675c2ac878131a7901f229c203b1000703935000c13f90738fe13274a7c","blockNumber":36621273,"time":1588053151,"nonce":386,"from":"0x0B230dEf08139F18a86536d9CFa150f04435414c","to":"0x83Ed8e6135e079a49085CA2f2F5E502691ccC0B1","value":"0","gas":"4700000","gasPrice":"25000000000","gasUsed":"421569","input":"0xc78b6dea0000000000000000000000000000000000000000000000000000000000000800","error":"","id":"0x42e15675c2ac878131a7901f229c203b1000703935000c13f90738fe13274a7c","timeStamp":"1588053151"},{"operations":[{"transactionId":"0xfd329f552403b7befe724d63268e40a905d7da03bb0ac3dcb26e903607e4810f-0","contract":{"address":"0x51bca9300d034a7e6ab379399a317bdfa0d4835b","decimals":18,"name":"The Third Identity","symbol":"TTI","totalSupply":"10000000000000000000000000000","updatedAt":"2020-02-26T21:42:19.178Z"},"from":"0x3270b4e0916B4556BF236B6E5D4377282b3255e5","to":"0x0B230dEf08139F18a86536d9CFa150f04435414c","type":"token_transfer","value":"322102000000000000000","id":null}],"contract":null,"_id":"0xfd329f552403b7befe724d63268e40a905d7da03bb0ac3dcb26e903607e4810f","blockNumber":36621242,"time":1588053120,"nonce":385,"from":"0x0B230dEf08139F18a86536d9CFa150f04435414c","to":"0x3270b4e0916B4556BF236B6E5D4377282b3255e5","value":"0","gas":"4700000","gasPrice":"25000000000","gasUsed":"1511414","input":"0x4008d2f3","error":"","id":"0xfd329f552403b7befe724d63268e40a905d7da03bb0ac3dcb26e903607e4810f","timeStamp":"1588053120"},{"operations":[],"contract":null,"_id":"0xe668c4999be866cbe3d58dcfd8dd5deb05112a6f7ff508727c8f9673c7ab1a9f","blockNumber":36517634,"time":1587949433,"nonce":384,"from":"0x0B230dEf08139F18a86536d9CFa150f04435414c","to":"0x83Ed8e6135e079a49085CA2f2F5E502691ccC0B1","value":"0","gas":"4700000","gasPrice":"1000000000","gasUsed":"421569","input":"0xc78b6dea0000000000000000000000000000000000000000000000000000000000000800","error":"","id":"0xe668c4999be866cbe3d58dcfd8dd5deb05112a6f7ff508727c8f9673c7ab1a9f","timeStamp":"1587949433"},{"operations":[{"transactionId":"0xbefdf8b1b2e68f24ad8d1387b435a8ba9c250cd348c93b35cf306dab04886bb9-0","contract":{"address":"0x51bca9300d034a7e6ab379399a317bdfa0d4835b","decimals":18,"name":"The Third Identity","symbol":"TTI","totalSupply":"10000000000000000000000000000","updatedAt":"2020-02-26T21:42:19.178Z"},"from":"0x3270b4e0916B4556BF236B6E5D4377282b3255e5","to":"0x0B230dEf08139F18a86536d9CFa150f04435414c","type":"token_transfer","value":"322102000000000000000","id":null}],"contract":null,"_id":"0xbefdf8b1b2e68f24ad8d1387b435a8ba9c250cd348c93b35cf306dab04886bb9","blockNumber":36517608,"time":1587949407,"nonce":383,"from":"0x0B230dEf08139F18a86536d9CFa150f04435414c","to":"0x3270b4e0916B4556BF236B6E5D4377282b3255e5","value":"0","gas":"4700000","gasPrice":"1000000000","gasUsed":"1526414","input":"0x4008d2f3","error":"","id":"0xbefdf8b1b2e68f24ad8d1387b435a8ba9c250cd348c93b35cf306dab04886bb9","timeStamp":"1587949407"},{"operations":[],"contract":null,"_id":"0xdbc92db02a0dffb8d9aae8a3d1e0bde23ef46a2410c2d8d8cede2d08a25ee440","blockNumber":36439120,"time":1587870875,"nonce":382,"from":"0x0B230dEf08139F18a86536d9CFa150f04435414c","to":"0x83Ed8e6135e079a49085CA2f2F5E502691ccC0B1","value":"0","gas":"4700000","gasPrice":"1000000000","gasUsed":"421569","input":"0xc78b6dea0000000000000000000000000000000000000000000000000000000000000800","error":"","id":"0xdbc92db02a0dffb8d9aae8a3d1e0bde23ef46a2410c2d8d8cede2d08a25ee440","timeStamp":"1587870875"}],"total":25} \ No newline at end of file diff --git a/mock/ext-api-data/tomochain-api_tokens__address_0x8b353021189375591723e7384262f45709a3c3dc.json b/mock/ext-api-data/tomochain-api_tokens__address_0x8b353021189375591723e7384262f45709a3c3dc.json new file mode 100644 index 000000000..9fbc560d6 --- /dev/null +++ b/mock/ext-api-data/tomochain-api_tokens__address_0x8b353021189375591723e7384262f45709a3c3dc.json @@ -0,0 +1 @@ +{"total":2,"docs":[{"address":"0xaB7e4aE99D7bfff4de8322aB915e9066857227F0","name":"KONG","decimals":18,"symbol":"KONG"},{"address":"0xc7BdF5D257fF4EC078e12A3ABD34dFc329E55130","name":"AIS Token","decimals":18,"symbol":"AIS"}]} \ No newline at end of file diff --git a/mock/ext-api-data/tomochain-api_transactions__address_0x17e4c16605e32adead5fa371bf6117df34ca0200.json b/mock/ext-api-data/tomochain-api_transactions__address_0x17e4c16605e32adead5fa371bf6117df34ca0200.json new file mode 100644 index 000000000..3011d3795 --- /dev/null +++ b/mock/ext-api-data/tomochain-api_transactions__address_0x17e4c16605e32adead5fa371bf6117df34ca0200.json @@ -0,0 +1 @@ +{"docs":[{"operations":[],"contract":null,"_id":"0x55bc7e249fb9998eec372eb75b3df89cc593e5fd9a4fa388ea3af5efdd5207e3","blockNumber":20584562,"time":1589318003,"nonce":1042050,"from":"0x17e4C16605E32ADEaD5FA371BF6117Df34Ca0200","to":"0x0000000000000000000000000000000000000089","value":"0","gas":"200000","gasPrice":"0","gasUsed":"0","input":"0xe341eaa400000000000000000000000000000000000000000000000000000000013a18708c1582f5022b001fc8f5d3e4d78d78b92bd665f79f7dbd876970e489d89118b0","error":"","id":"0x55bc7e249fb9998eec372eb75b3df89cc593e5fd9a4fa388ea3af5efdd5207e3","timeStamp":"1589318003"},{"operations":[],"contract":null,"_id":"0xe917920d3121daf91c0888b0bb05947d5eea95a48d23f0d2a97c3469322369ed","blockNumber":20584547,"time":1589317973,"nonce":1042049,"from":"0x17e4C16605E32ADEaD5FA371BF6117Df34Ca0200","to":"0x0000000000000000000000000000000000000089","value":"0","gas":"200000","gasPrice":"0","gasUsed":"0","input":"0xe341eaa400000000000000000000000000000000000000000000000000000000013a186186b2d4d01b7c8305842aab96eee8f641be494ac6cf45b51ceab4eaa93d52f17a","error":"","id":"0xe917920d3121daf91c0888b0bb05947d5eea95a48d23f0d2a97c3469322369ed","timeStamp":"1589317973"},{"operations":[],"contract":null,"_id":"0x8b68e187f8160a9dcad4b5447465f2daf1f6d3cc465213b60b6cc5e74e36abfd","blockNumber":20584532,"time":1589317943,"nonce":1042048,"from":"0x17e4C16605E32ADEaD5FA371BF6117Df34Ca0200","to":"0x0000000000000000000000000000000000000089","value":"0","gas":"200000","gasPrice":"0","gasUsed":"0","input":"0xe341eaa400000000000000000000000000000000000000000000000000000000013a1852d733feca46a48d2b1605543c17a22c3641dbfe4582a66ead0e7428b051b528a9","error":"","id":"0x8b68e187f8160a9dcad4b5447465f2daf1f6d3cc465213b60b6cc5e74e36abfd","timeStamp":"1589317943"},{"operations":[],"contract":null,"_id":"0x61d9937d4b8a681455ddff82240f0f9313e0baa99d391c669ffebbc2bb40af7d","blockNumber":20584517,"time":1589317913,"nonce":1042047,"from":"0x17e4C16605E32ADEaD5FA371BF6117Df34Ca0200","to":"0x0000000000000000000000000000000000000089","value":"0","gas":"200000","gasPrice":"0","gasUsed":"0","input":"0xe341eaa400000000000000000000000000000000000000000000000000000000013a184306200bedd5181ed7a808f7e7b8f964e14c627434aab7018a6a4cb889f51e97e2","error":"","id":"0x61d9937d4b8a681455ddff82240f0f9313e0baa99d391c669ffebbc2bb40af7d","timeStamp":"1589317913"},{"operations":[],"contract":null,"_id":"0xd0d224a26821cc89137c3f7de55568c8d637f4d744bec5f8f7312b1f505cf61a","blockNumber":20584502,"time":1589317883,"nonce":1042046,"from":"0x17e4C16605E32ADEaD5FA371BF6117Df34Ca0200","to":"0x0000000000000000000000000000000000000089","value":"0","gas":"200000","gasPrice":"0","gasUsed":"0","input":"0xe341eaa400000000000000000000000000000000000000000000000000000000013a1834306752e7a66a502f1643a7a2193d87fd6ffa66f221e5ce3a3562c7fb869709aa","error":"","id":"0xd0d224a26821cc89137c3f7de55568c8d637f4d744bec5f8f7312b1f505cf61a","timeStamp":"1589317883"},{"operations":[],"contract":null,"_id":"0x7d71fa1fb6078546f176e4883ce31e874aa347948c1ff81785af0de73962f158","blockNumber":20584487,"time":1589317853,"nonce":1042045,"from":"0x17e4C16605E32ADEaD5FA371BF6117Df34Ca0200","to":"0x0000000000000000000000000000000000000089","value":"0","gas":"200000","gasPrice":"0","gasUsed":"0","input":"0xe341eaa400000000000000000000000000000000000000000000000000000000013a1825867b0ca6d301d91b1fa753e7fe6f0cf9dc8273733ec4753c16056d3a36b86d1a","error":"","id":"0x7d71fa1fb6078546f176e4883ce31e874aa347948c1ff81785af0de73962f158","timeStamp":"1589317853"},{"operations":[],"contract":null,"_id":"0x1e5f4c1008c67a0ac3d4c2dc884b77d6b68ece8b174f3845a3e8a2b7c121ed57","blockNumber":20584477,"time":1589317833,"nonce":1042045,"from":"0x17e4C16605E32ADEaD5FA371BF6117Df34Ca0200","to":"0x0000000000000000000000000000000000000092","value":"0","gas":"40000000","gasPrice":"0","gasUsed":"0","input":"0x437e44fa06a10d89c737e276e3ece67b2bd2c139e5d661bec8c168504bbf467556e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421","error":"","id":"0x1e5f4c1008c67a0ac3d4c2dc884b77d6b68ece8b174f3845a3e8a2b7c121ed57","timeStamp":"1589317833"},{"operations":[],"contract":null,"_id":"0xa44ee6f4518d1ba56af64a72bae4c82917c7ef7175c831c891a18dab8fc2e19e","blockNumber":20584472,"time":1589317823,"nonce":1042044,"from":"0x17e4C16605E32ADEaD5FA371BF6117Df34Ca0200","to":"0x0000000000000000000000000000000000000089","value":"0","gas":"200000","gasPrice":"0","gasUsed":"0","input":"0xe341eaa400000000000000000000000000000000000000000000000000000000013a181644530c838e677e10b2923f7858970ee987668e1fd52e8581c82c6c2117130162","error":"","id":"0xa44ee6f4518d1ba56af64a72bae4c82917c7ef7175c831c891a18dab8fc2e19e","timeStamp":"1589317823"},{"operations":[],"contract":null,"_id":"0xf1a03d857a1e347545185bae66e4bca392c23732a788c5964e90e8169e5f6696","blockNumber":20584457,"time":1589317793,"nonce":1042043,"from":"0x17e4C16605E32ADEaD5FA371BF6117Df34Ca0200","to":"0x0000000000000000000000000000000000000089","value":"0","gas":"200000","gasPrice":"0","gasUsed":"0","input":"0xe341eaa400000000000000000000000000000000000000000000000000000000013a180761ebf1a7b1c3ae7ed1b684064bb964e49ca7e1d93f921e1e0292c4bd1f1d12dc","error":"","id":"0xf1a03d857a1e347545185bae66e4bca392c23732a788c5964e90e8169e5f6696","timeStamp":"1589317793"},{"operations":[],"contract":null,"_id":"0x8c2fa072e5110f12cfb08620635ef9b4c172122cfcdd0ab140f896e47d6ca0d5","blockNumber":20584442,"time":1589317763,"nonce":1042042,"from":"0x17e4C16605E32ADEaD5FA371BF6117Df34Ca0200","to":"0x0000000000000000000000000000000000000089","value":"0","gas":"200000","gasPrice":"0","gasUsed":"0","input":"0xe341eaa400000000000000000000000000000000000000000000000000000000013a17f800249caa62eb771a9236565ee1dbf9d4cdeca4447713676da87f3ce5d930925c","error":"","id":"0x8c2fa072e5110f12cfb08620635ef9b4c172122cfcdd0ab140f896e47d6ca0d5","timeStamp":"1589317763"},{"operations":[],"contract":null,"_id":"0x86868a56c9bbc35d150927e2ee14e300261d4d328ea70248c731a985d649fdd3","blockNumber":20584427,"time":1589317733,"nonce":1042041,"from":"0x17e4C16605E32ADEaD5FA371BF6117Df34Ca0200","to":"0x0000000000000000000000000000000000000089","value":"0","gas":"200000","gasPrice":"0","gasUsed":"0","input":"0xe341eaa400000000000000000000000000000000000000000000000000000000013a17e9a3fa072992cdcbbcdd9893ef28f5b556d0d9a5d586356864c99c0c5030290bb8","error":"","id":"0x86868a56c9bbc35d150927e2ee14e300261d4d328ea70248c731a985d649fdd3","timeStamp":"1589317733"},{"operations":[],"contract":null,"_id":"0x5ae0338a127dacbbc27be5f1de92fb31b42fb137a305464f69cd1894bb40c52d","blockNumber":20584412,"time":1589317703,"nonce":1042040,"from":"0x17e4C16605E32ADEaD5FA371BF6117Df34Ca0200","to":"0x0000000000000000000000000000000000000089","value":"0","gas":"200000","gasPrice":"0","gasUsed":"0","input":"0xe341eaa400000000000000000000000000000000000000000000000000000000013a17dad36e561e88b3e43fa73eded00ae1085044cfe303e3a99405c9571a4732a5855b","error":"","id":"0x5ae0338a127dacbbc27be5f1de92fb31b42fb137a305464f69cd1894bb40c52d","timeStamp":"1589317703"},{"operations":[],"contract":null,"_id":"0xc34e735b240969b67338af2db87de8247b25f8162f9e409d200cb57ca69cab0e","blockNumber":20584397,"time":1589317673,"nonce":1042039,"from":"0x17e4C16605E32ADEaD5FA371BF6117Df34Ca0200","to":"0x0000000000000000000000000000000000000089","value":"0","gas":"200000","gasPrice":"0","gasUsed":"0","input":"0xe341eaa400000000000000000000000000000000000000000000000000000000013a17cb4bf64b5c4778a22a1cee73f5af4ec6d3e9dd473301a731e3b87a89430a1b69ad","error":"","id":"0xc34e735b240969b67338af2db87de8247b25f8162f9e409d200cb57ca69cab0e","timeStamp":"1589317673"},{"operations":[],"contract":null,"_id":"0xadeadb93356892184dff3ee6c9e17d6cefda998cd935731665c2523704bce17b","blockNumber":20584383,"time":1589317645,"nonce":1042038,"from":"0x17e4C16605E32ADEaD5FA371BF6117Df34Ca0200","to":"0x0000000000000000000000000000000000000089","value":"0","gas":"200000","gasPrice":"0","gasUsed":"0","input":"0xe341eaa400000000000000000000000000000000000000000000000000000000013a17bc5d97eb0b280bee9f22f09828013a2f8860097ddbfc8ab2b66231f26b3e28abf0","error":"","id":"0xadeadb93356892184dff3ee6c9e17d6cefda998cd935731665c2523704bce17b","timeStamp":"1589317645"},{"operations":[],"contract":null,"_id":"0x0436c34409f37d3434011751790f04a75c53834411d8d00aafe6e2e8146240ae","blockNumber":20584367,"time":1589317613,"nonce":1042037,"from":"0x17e4C16605E32ADEaD5FA371BF6117Df34Ca0200","to":"0x0000000000000000000000000000000000000089","value":"0","gas":"200000","gasPrice":"0","gasUsed":"0","input":"0xe341eaa400000000000000000000000000000000000000000000000000000000013a17ad8c43f40dde02e4589e8a78233f186b46ff813676e73e27b09b3247fc8fd97bef","error":"","id":"0x0436c34409f37d3434011751790f04a75c53834411d8d00aafe6e2e8146240ae","timeStamp":"1589317613"},{"operations":[],"contract":null,"_id":"0x9ea4323a24d3aa6d74a6538247c78153e39c7ae3516d229619cc220bd5e54d53","blockNumber":20584352,"time":1589317583,"nonce":1042036,"from":"0x17e4C16605E32ADEaD5FA371BF6117Df34Ca0200","to":"0x0000000000000000000000000000000000000089","value":"0","gas":"200000","gasPrice":"0","gasUsed":"0","input":"0xe341eaa400000000000000000000000000000000000000000000000000000000013a179ee4cdb871e9309a76b2d45767e8b7ac68c6d911fd1925b3c461eedf935105757e","error":"","id":"0x9ea4323a24d3aa6d74a6538247c78153e39c7ae3516d229619cc220bd5e54d53","timeStamp":"1589317583"},{"operations":[],"contract":null,"_id":"0x5f78ef43e98d3914a2c7f4d6f296e3bff25acb09d24beae912f93f3dd6bec640","blockNumber":20584340,"time":1589317559,"nonce":1042036,"from":"0x17e4C16605E32ADEaD5FA371BF6117Df34Ca0200","to":"0x0000000000000000000000000000000000000092","value":"0","gas":"40000000","gasPrice":"0","gasUsed":"0","input":"0x437e44fa06a10d89c737e276e3ece67b2bd2c139e5d661bec8c168504bbf467556e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421","error":"","id":"0x5f78ef43e98d3914a2c7f4d6f296e3bff25acb09d24beae912f93f3dd6bec640","timeStamp":"1589317559"},{"operations":[],"contract":null,"_id":"0x585fd5874cbc146123319ec736c3be06e57604f337880e8dea2d1a96dacfa588","blockNumber":20584337,"time":1589317553,"nonce":1042035,"from":"0x17e4C16605E32ADEaD5FA371BF6117Df34Ca0200","to":"0x0000000000000000000000000000000000000089","value":"0","gas":"200000","gasPrice":"0","gasUsed":"0","input":"0xe341eaa400000000000000000000000000000000000000000000000000000000013a178fd5a162ccc57e40da3fc18a5ac927760e356be6f09034743b9c181eb6b829ae42","error":"","id":"0x585fd5874cbc146123319ec736c3be06e57604f337880e8dea2d1a96dacfa588","timeStamp":"1589317553"},{"operations":[],"contract":null,"_id":"0x0022acedbeed21b8f608c6939e2b2d1015c9036d1f94d396a7fe5159edba5af1","blockNumber":20584323,"time":1589317525,"nonce":1042034,"from":"0x17e4C16605E32ADEaD5FA371BF6117Df34Ca0200","to":"0x0000000000000000000000000000000000000089","value":"0","gas":"200000","gasPrice":"0","gasUsed":"0","input":"0xe341eaa400000000000000000000000000000000000000000000000000000000013a1780892c51dc724a59a5099a0a181f86a43b01d7795fb81643306baa4459d1432e33","error":"","id":"0x0022acedbeed21b8f608c6939e2b2d1015c9036d1f94d396a7fe5159edba5af1","timeStamp":"1589317525"},{"operations":[],"contract":null,"_id":"0x66d90c80291875ca3ac395a137c45722d8d8a29ea31426284f5dc351a8e32723","blockNumber":20584307,"time":1589317493,"nonce":1042033,"from":"0x17e4C16605E32ADEaD5FA371BF6117Df34Ca0200","to":"0x0000000000000000000000000000000000000089","value":"0","gas":"200000","gasPrice":"0","gasUsed":"0","input":"0xe341eaa400000000000000000000000000000000000000000000000000000000013a177143a3ebb98872d4bcd17d313c6c21a39039d235ab114835524b29934e113ed289","error":"","id":"0x66d90c80291875ca3ac395a137c45722d8d8a29ea31426284f5dc351a8e32723","timeStamp":"1589317493"},{"operations":[],"contract":null,"_id":"0x5c5b676b626929664c1007988a3d280804ea635b04de438d38a664d158db5c15","blockNumber":20584292,"time":1589317463,"nonce":1042032,"from":"0x17e4C16605E32ADEaD5FA371BF6117Df34Ca0200","to":"0x0000000000000000000000000000000000000089","value":"0","gas":"200000","gasPrice":"0","gasUsed":"0","input":"0xe341eaa400000000000000000000000000000000000000000000000000000000013a1762170c3380b87bed310f585771de970929075bcd1a870d465fd7e18a6e922c562b","error":"","id":"0x5c5b676b626929664c1007988a3d280804ea635b04de438d38a664d158db5c15","timeStamp":"1589317463"},{"operations":[],"contract":null,"_id":"0x4d2d0e42b7410aa78e7ef9b9b333a003b7be36808eaf7d86adb4f35040901d4e","blockNumber":20584277,"time":1589317433,"nonce":1042031,"from":"0x17e4C16605E32ADEaD5FA371BF6117Df34Ca0200","to":"0x0000000000000000000000000000000000000089","value":"0","gas":"200000","gasPrice":"0","gasUsed":"0","input":"0xe341eaa400000000000000000000000000000000000000000000000000000000013a1753295206e9f985d4e72fed5bd857e6306272666308b31c26173fbc65f6ee476c6f","error":"","id":"0x4d2d0e42b7410aa78e7ef9b9b333a003b7be36808eaf7d86adb4f35040901d4e","timeStamp":"1589317433"},{"operations":[],"contract":null,"_id":"0x8be6c87f63110b5991e5c2602213a3936cc21f32d052de3aa157bd70246dd6cd","blockNumber":20584262,"time":1589317403,"nonce":1042030,"from":"0x17e4C16605E32ADEaD5FA371BF6117Df34Ca0200","to":"0x0000000000000000000000000000000000000089","value":"0","gas":"200000","gasPrice":"0","gasUsed":"0","input":"0xe341eaa400000000000000000000000000000000000000000000000000000000013a1744e506b96a9ccf6837e6efc8f90557a8763dfce5e359f6e4cd94369d97a75bf4e6","error":"","id":"0x8be6c87f63110b5991e5c2602213a3936cc21f32d052de3aa157bd70246dd6cd","timeStamp":"1589317403"},{"operations":[],"contract":null,"_id":"0x2f4dbe27e6a1150b1e72eaac7fc25936c6ad15a21e0f40479192995146da71ec","blockNumber":20584247,"time":1589317373,"nonce":1042029,"from":"0x17e4C16605E32ADEaD5FA371BF6117Df34Ca0200","to":"0x0000000000000000000000000000000000000089","value":"0","gas":"200000","gasPrice":"0","gasUsed":"0","input":"0xe341eaa400000000000000000000000000000000000000000000000000000000013a1735b1a5471be4f06c297f2e17a9cb9301587f688b7ca0cd42fe51544c6fd2775ecd","error":"","id":"0x2f4dbe27e6a1150b1e72eaac7fc25936c6ad15a21e0f40479192995146da71ec","timeStamp":"1589317373"},{"operations":[],"contract":null,"_id":"0xd28781523e7da1f9892fec4eb96cd23b1e39c7a11d67be5bf4c9dba76faca0a5","blockNumber":20584232,"time":1589317343,"nonce":1042028,"from":"0x17e4C16605E32ADEaD5FA371BF6117Df34Ca0200","to":"0x0000000000000000000000000000000000000089","value":"0","gas":"200000","gasPrice":"0","gasUsed":"0","input":"0xe341eaa400000000000000000000000000000000000000000000000000000000013a1726bcecf8b2be5d3fa70b978b6eef49071884f90bb56fa88029bbfe03c2b75126d9","error":"","id":"0xd28781523e7da1f9892fec4eb96cd23b1e39c7a11d67be5bf4c9dba76faca0a5","timeStamp":"1589317343"}],"total":25} \ No newline at end of file diff --git a/mock/ext-api-data/tron-api_v1_accounts_TFFriedwRtWdFuzerDDtkoQTZ29smDZ1MB.json b/mock/ext-api-data/tron-api_v1_accounts_TFFriedwRtWdFuzerDDtkoQTZ29smDZ1MB.json new file mode 100644 index 000000000..07b024fb9 --- /dev/null +++ b/mock/ext-api-data/tron-api_v1_accounts_TFFriedwRtWdFuzerDDtkoQTZ29smDZ1MB.json @@ -0,0 +1,77 @@ +{ + "success": true, + "meta": { + "at": 1589366680095, + "page_size": 1 + }, + "data": [ + { + "account_resource": {}, + "active_permission": [ + { + "id": 2, + "keys": [ + { + "address": "4139fec4d95bb59f45a727f9234020adaf2cec9e20", + "weight": 1 + } + ], + "operations": "7fff1fc0033e0000000000000000000000000000000000000000000000000000", + "permission_name": "active", + "threshold": 1, + "type": "Active" + } + ], + "address": "4139fec4d95bb59f45a727f9234020adaf2cec9e20", + "allowance": 848829, + "assetV2": [ + { + "key": "1002000", + "value": 10189204891 + }, + { + "key": "1002798", + "value": 10000000 + }, + { + "key": "1002814", + "value": 10000000 + } + ], + "balance": 278720000, + "create_time": 1553864037000, + "free_asset_net_usageV2": [ + { + "key": "1002000", + "value": 0 + }, + { + "key": "1002798", + "value": 0 + }, + { + "key": "1002814", + "value": 0 + } + ], + "latest_consume_free_time": 1575142326000, + "latest_consume_time": 1576767612000, + "latest_opration_time": 1576767612000, + "owner_permission": { + "keys": [ + { + "address": "4139fec4d95bb59f45a727f9234020adaf2cec9e20", + "weight": 1 + } + ], + "permission_name": "owner", + "threshold": 1 + }, + "trc20": [ + { + "TLa2f6VPqDgRE67v1736s7bJ8Ray5wYjU7": "53135738" + } + ] + } + ] +} \ No newline at end of file diff --git a/mock/ext-api-data/tron-api_v1_accounts_TFFriedwRtWdFuzerDDtkoQTZ29smDZ1MB_transactions__limit_25_order_by_block_timestamp_desc_token_id_.json b/mock/ext-api-data/tron-api_v1_accounts_TFFriedwRtWdFuzerDDtkoQTZ29smDZ1MB_transactions__limit_25_order_by_block_timestamp_desc_token_id_.json new file mode 100644 index 000000000..219d8a666 --- /dev/null +++ b/mock/ext-api-data/tron-api_v1_accounts_TFFriedwRtWdFuzerDDtkoQTZ29smDZ1MB_transactions__limit_25_order_by_block_timestamp_desc_token_id_.json @@ -0,0 +1,795 @@ +{ + "success": true, + "meta": { + "at": 1589366680021, + "page_size": 21 + }, + "data": [ + { + "blockNumber": 19634882, + "block_timestamp": 1589169090000, + "energy_fee": 0, + "energy_usage": 0, + "energy_usage_total": 0, + "internal_transactions": [], + "net_fee": 2820, + "net_usage": 0, + "raw_data": { + "contract": [ + { + "parameter": { + "type_url": "type.googleapis.com/protocol.TransferAssetContract", + "value": { + "amount": 2980411, + "asset_name": "1002000", + "owner_address": "41d0995a2071de293ff0c1fa25131c0f4bab3535ae", + "to_address": "4139fec4d95bb59f45a727f9234020adaf2cec9e20" + } + }, + "type": "TransferAssetContract" + } + ], + "expiration": 1589251721359, + "fee_limit": 0, + "ref_block_bytes": "95da", + "ref_block_hash": "0d56df8c2d4c1260", + "timestamp": 1589166646700 + }, + "raw_data_hex": "0a0295da22080d56df8c2d4c1260408f91a3b6a02e5a76080212720a32747970652e676f6f676c65617069732e636f6d2f70726f746f636f6c2e5472616e736665724173736574436f6e7472616374123c0a0731303032303030121541d0995a2071de293ff0c1fa25131c0f4bab3535ae1a154139fec4d95bb59f45a727f9234020adaf2cec9e2020bbf4b50170accbda8da02e", + "ret": [ + { + "code": "SUCESS", + "contractRet": "SUCCESS", + "fee": 2820 + } + ], + "signature": [ + "55bb94741af3976f215bb97021f85f71caf87a9b86f870bc74bbed4133a1adb748de51eaaea5c90e4cae9b33d586346f9da43154231b3f83b1dda9e0b9dc5cf501" + ], + "txID": "f6804d16ac87fa77357e8145fbfdafd459433f89f87019bc8ea2308260abb761" + }, + { + "blockNumber": 18770770, + "block_timestamp": 1586575584000, + "energy_fee": 0, + "energy_usage": 0, + "energy_usage_total": 0, + "internal_transactions": [], + "net_fee": 2820, + "net_usage": 0, + "raw_data": { + "contract": [ + { + "parameter": { + "type_url": "type.googleapis.com/protocol.TransferAssetContract", + "value": { + "amount": 2984422, + "asset_name": "1002000", + "owner_address": "4186048ac2ac8bb7985a1f68abb0077d4267e1c201", + "to_address": "4139fec4d95bb59f45a727f9234020adaf2cec9e20" + } + }, + "type": "TransferAssetContract" + } + ], + "expiration": 1586657356443, + "fee_limit": 0, + "ref_block_bytes": "6557", + "ref_block_hash": "59585d54bcb9da25", + "timestamp": 1586572629770 + }, + "raw_data_hex": "0a026557220859585d54bcb9da25409bd597e1962e5a76080212720a32747970652e676f6f676c65617069732e636f6d2f70726f746f636f6c2e5472616e736665724173736574436f6e7472616374123c0a073130303230303012154186048ac2ac8bb7985a1f68abb0077d4267e1c2011a154139fec4d95bb59f45a727f9234020adaf2cec9e2020e693b601708aaee4b8962e", + "ret": [ + { + "code": "SUCESS", + "contractRet": "SUCCESS", + "fee": 2820 + } + ], + "signature": [ + "2fa982f9e251780cc6f5c2354be8501d2b983ea099ed2e4f77ed0ab8f4842d240e206f9e5c068644e7c9c7a2b0f62a589216e576ea304423abf38664b3a1e78301" + ], + "txID": "b42ffe110198a5fa1351b41d23d5244b5fa69b92a6ecf30adcc582d65594c7f9" + }, + { + "block_timestamp": 1583897466000, + "internal_transactions": [], + "raw_data": { + "contract": [ + { + "parameter": { + "type_url": "type.googleapis.com/protocol.TransferAssetContract", + "value": { + "amount": 2988026, + "asset_name": "1002000", + "owner_address": "41934edccf923ee46daf057615d08f341f68078b41", + "to_address": "4139fec4d95bb59f45a727f9234020adaf2cec9e20" + } + }, + "type": "TransferAssetContract" + } + ], + "expiration": 1583980512649, + "fee_limit": 0, + "ref_block_bytes": "ca0c", + "ref_block_hash": "50875d785e719200", + "timestamp": 1583895463611 + }, + "raw_data_hex": "0a02ca0c220850875d785e71920040898be2e48c2e5a76080212720a32747970652e676f6f676c65617069732e636f6d2f70726f746f636f6c2e5472616e736665724173736574436f6e7472616374123c0a0731303032303030121541934edccf923ee46daf057615d08f341f68078b411a154139fec4d95bb59f45a727f9234020adaf2cec9e2020faafb60170bb8d9bbc8c2e", + "ret": [ + { + "code": "SUCESS", + "contractRet": "SUCCESS", + "fee": 2820 + } + ], + "signature": [ + "d28985d624a39eba13b4f694bfd3cd1fa7451b3a047014d55aa1230fbf5148d840fa9239e714ab1e0020dc7e236ae82299685f4a79255acadee11db70b91fca200" + ], + "txID": "745387b731b5b9a4cdee2c1fbaff88bcbc8ee603cd66bfe14cd0da2fe218173a" + }, + { + "block_timestamp": 1581392205000, + "internal_transactions": [], + "raw_data": { + "contract": [ + { + "parameter": { + "type_url": "type.googleapis.com/protocol.TransferAssetContract", + "value": { + "amount": 2761954, + "asset_name": "1002000", + "owner_address": "417751ef8410331a318d2eb94cdb15e8f2fd4eded0", + "to_address": "4139fec4d95bb59f45a727f9234020adaf2cec9e20" + } + }, + "type": "TransferAssetContract" + } + ], + "expiration": 1581475762919, + "fee_limit": 0, + "ref_block_bytes": "11cc", + "ref_block_hash": "60d8258a7feac870", + "timestamp": 1581390286202 + }, + "raw_data_hex": "0a0211cc220860d8258a7feac87040e7a5b4ba832e5a76080212720a32747970652e676f6f676c65617069732e636f6d2f70726f746f636f6c2e5472616e736665724173736574436f6e7472616374123c0a07313030323030301215417751ef8410331a318d2eb94cdb15e8f2fd4eded01a154139fec4d95bb59f45a727f9234020adaf2cec9e2020e2c9a80170fa9ad391832e", + "ret": [ + { + "code": "SUCESS", + "contractRet": "SUCCESS", + "fee": 0 + } + ], + "signature": [ + "c85bf358e1f0a6c0a84c82a02f0b47cc3e8c949a8b1c00117187c29ecb5e482c0e8dfa7b7e0c4963d036c5924d336d2ed636fa94601917acdebb8d10e24adb2000" + ], + "txID": "f478e08a3b79c0ede4d2869409792d303dba6591ac0dddf8c98dba6b54cd23dd" + }, + { + "block_timestamp": 1578712149000, + "internal_transactions": [], + "raw_data": { + "contract": [ + { + "parameter": { + "type_url": "type.googleapis.com/protocol.TransferAssetContract", + "value": { + "amount": 2766009, + "asset_name": "1002000", + "owner_address": "418c946a1b7974c653b5d6b8357c78e0feae15b066", + "to_address": "4139fec4d95bb59f45a727f9234020adaf2cec9e20" + } + }, + "type": "TransferAssetContract" + } + ], + "expiration": 1578795827650, + "fee_limit": 0, + "ref_block_bytes": "732d", + "ref_block_hash": "f6702c3b51ba7e60", + "timestamp": 1578710431666 + }, + "raw_data_hex": "0a02732d2208f6702c3b51ba7e6040c283c2bcf92d5a76080212720a32747970652e676f6f676c65617069732e636f6d2f70726f746f636f6c2e5472616e736665724173736574436f6e7472616374123c0a07313030323030301215418c946a1b7974c653b5d6b8357c78e0feae15b0661a154139fec4d95bb59f45a727f9234020adaf2cec9e2020b9e9a80170b2efe593f92d", + "ret": [ + { + "code": "SUCESS", + "contractRet": "SUCCESS", + "fee": 0 + } + ], + "signature": [ + "afdf9e1e4068b132c4327ae0c96cb5ea18d90a39f86aeb7a98c44688e171702f4b025740bbfaf1c7863b5002c8dd21d0ec36c9cfac9d1c43c7d3bb480a8eb31601" + ], + "txID": "ea5211cc65b5f6424fa1d744eb4c21ea9edd451d2171dc6ea102754271d45c45" + }, + { + "block_timestamp": 1576767630000, + "internal_transactions": [], + "raw_data": { + "contract": [ + { + "parameter": { + "type_url": "type.googleapis.com/protocol.TransferAssetContract", + "value": { + "amount": 10000000, + "asset_name": "1002814", + "owner_address": "419bd7449f9b84a1083622486c08573a7da0507154", + "to_address": "4139fec4d95bb59f45a727f9234020adaf2cec9e20" + } + }, + "type": "TransferAssetContract" + } + ], + "expiration": 1576767684000, + "fee_limit": 0, + "ref_block_bytes": "93f5", + "ref_block_hash": "da4f57515fbead80", + "timestamp": 1576767626457 + }, + "raw_data_hex": "0a0293f52208da4f57515fbead8040a0fbb5f5f12d5a76080212720a32747970652e676f6f676c65617069732e636f6d2f70726f746f636f6c2e5472616e736665724173736574436f6e7472616374123c0a07313030323831341215419bd7449f9b84a1083622486c08573a7da05071541a154139fec4d95bb59f45a727f9234020adaf2cec9e202080ade20470d9b9b2f5f12d", + "ret": [ + { + "code": "SUCESS", + "contractRet": "SUCCESS", + "fee": 0 + } + ], + "signature": [ + "a89953a4b6c17b83570bf0e03a5e3ef4e8a1d73f4e2c70d976863241edcacbf8564cc551ac2738863a0782d3c0475ad316ea28ec1b766b71bb14fcaf5de799c001" + ], + "txID": "cf097ddd585d9bd7634cd78f8d5c19f66be8610befc1036f6db0d29b6004f0a2" + }, + { + "block_timestamp": 1576767615000, + "internal_transactions": [], + "raw_data": { + "contract": [ + { + "parameter": { + "type_url": "type.googleapis.com/protocol.UnfreezeBalanceContract", + "value": { + "owner_address": "4139fec4d95bb59f45a727f9234020adaf2cec9e20", + "resource": 0, + "resource_type": "BANDWIDTH" + } + }, + "type": "UnfreezeBalanceContract" + } + ], + "expiration": 1576803608549, + "fee_limit": 0, + "ref_block_bytes": "9401", + "ref_block_hash": "f36c8589c1e80d4c", + "timestamp": 1576767608549 + }, + "raw_data_hex": "0a0294012208f36c8589c1e80d4c40e5cfc686f22d5a53080c124f0a34747970652e676f6f676c65617069732e636f6d2f70726f746f636f6c2e556e667265657a6542616c616e6365436f6e747261637412170a154139fec4d95bb59f45a727f9234020adaf2cec9e2070e5adb1f5f12d", + "ret": [ + { + "code": "SUCESS", + "contractRet": "SUCCESS", + "fee": 0 + } + ], + "signature": [ + "b873ad5cd7c00f370b8d395805775a12a3ace3e2025d5171b65d1679b115798400014ffa9a65535918b87022cce17441bf126f2f973d94a6b20f67b9d5d2e00600" + ], + "txID": "969e85b075fc94f8917c00461ed5e55f2e8e49e0ec26f529e7a52821b8ed65f9" + }, + { + "block_timestamp": 1576034517000, + "internal_transactions": [], + "raw_data": { + "contract": [ + { + "parameter": { + "type_url": "type.googleapis.com/protocol.TransferAssetContract", + "value": { + "amount": 2771361, + "asset_name": "1002000", + "owner_address": "413a094f1775afacfeedfd86a2f8f57f0230ee2723", + "to_address": "4139fec4d95bb59f45a727f9234020adaf2cec9e20" + } + }, + "type": "TransferAssetContract" + } + ], + "expiration": 1576118376059, + "fee_limit": 0, + "ref_block_bytes": "dc86", + "ref_block_hash": "2f66710df37485fe", + "timestamp": 1576032773155 + }, + "raw_data_hex": "0a02dc8622082f66710df37485fe40fbace7bfef2d5a76080212720a32747970652e676f6f676c65617069732e636f6d2f70726f746f636f6c2e5472616e736665724173736574436f6e7472616374123c0a07313030323030301215413a094f1775afacfeedfd86a2f8f57f0230ee27231a154139fec4d95bb59f45a727f9234020adaf2cec9e2020a193a90170a3c8fe96ef2d", + "ret": [ + { + "code": "SUCESS", + "contractRet": "SUCCESS", + "fee": 0 + } + ], + "signature": [ + "203bf41538ad46bb8477413cb25c61dba24055228ac79935369b84e16114f3873a22a1e78c4c89caf2580e1f48df8ec08b207747794300d4e583102b6f25196901" + ], + "txID": "97d2b6262d685aaa22ea5840bb6793049b908b524d0c5014af1291470f3d6be2" + }, + { + "block_timestamp": 1575142365000, + "raw_data": { + "contract": [ + { + "parameter": { + "type_url": "type.googleapis.com/protocol.TransferAssetContract", + "value": { + "amount": 10000000, + "asset_name": "1002798", + "owner_address": "41aa5e59e84334df05368ae6e720b5167700b42e18", + "to_address": "4139fec4d95bb59f45a727f9234020adaf2cec9e20" + } + }, + "type": "TransferAssetContract" + } + ], + "expiration": 1575142419000, + "fee_limit": 0, + "ref_block_bytes": "57b2", + "ref_block_hash": "b2ee022babe71218", + "timestamp": 1575142361463 + }, + "raw_data_hex": "0a0257b22208b2ee022babe7121840b8d4b7eeeb2d5a76080212720a32747970652e676f6f676c65617069732e636f6d2f70726f746f636f6c2e5472616e736665724173736574436f6e7472616374123c0a0731303032373938121541aa5e59e84334df05368ae6e720b5167700b42e181a154139fec4d95bb59f45a727f9234020adaf2cec9e202080ade20470f792b4eeeb2d", + "ret": [ + { + "code": "SUCESS", + "contractRet": "SUCCESS", + "fee": 0 + } + ], + "signature": [ + "65bbe799908d92fa9b4c06fa4eaacc537c80a9c32833795197b6d2a88c88f7f45999ba22a930761d61874cc20887210959747a9c9014450a4fe0713cef2c9bc301" + ], + "txID": "af2c820fc24eebbd811da03e4053c0e99638d8220f1a704b5d813ef6f1f2a949" + }, + { + "block_timestamp": 1575142338000, + "raw_data": { + "contract": [ + { + "parameter": { + "type_url": "type.googleapis.com/protocol.VoteWitnessContract", + "value": { + "owner_address": "4139fec4d95bb59f45a727f9234020adaf2cec9e20", + "votes": [ + { + "vote_address": "4178c842ee63b253f8f0d2955bbc582c661a078c9d", + "vote_count": 278 + } + ] + } + }, + "type": "VoteWitnessContract" + } + ], + "expiration": 1575178334333, + "fee_limit": 0, + "ref_block_bytes": "57bb", + "ref_block_hash": "4b3d554e9eed24bf", + "timestamp": 1575142334333 + }, + "raw_data_hex": "0a0257bb22084b3d554e9eed24bf40fde0c7ffeb2d5a6b080412670a30747970652e676f6f676c65617069732e636f6d2f70726f746f636f6c2e566f74655769746e657373436f6e747261637412330a154139fec4d95bb59f45a727f9234020adaf2cec9e20121a0a154178c842ee63b253f8f0d2955bbc582c661a078c9d10960270fdbeb2eeeb2d", + "ret": [ + { + "code": "SUCESS", + "contractRet": "SUCCESS", + "fee": 0 + } + ], + "signature": [ + "426e9fe96b384552a6cdf06dbd6c644e2ba86d71b7b81d4944df9cf6f7f978f43ff59786927b59592fa7552c460352797b2dddab32700c5ea108e36d6bbc845d00" + ], + "txID": "01700b76279521d69c7b0b0e3ca929fde1630cead2f5f6912df4852e966136e4" + }, + { + "block_timestamp": 1575142329000, + "raw_data": { + "contract": [ + { + "parameter": { + "type_url": "type.googleapis.com/protocol.FreezeBalanceContract", + "value": { + "frozen_balance": 278000000, + "frozen_duration": 3, + "owner_address": "4139fec4d95bb59f45a727f9234020adaf2cec9e20", + "resource": 0, + "resource_type": "BANDWIDTH", + "resource_value": 0 + } + }, + "type": "FreezeBalanceContract" + } + ], + "expiration": 1575178323797, + "fee_limit": 0, + "ref_block_bytes": "57b8", + "ref_block_hash": "af6ffa6819c1f720", + "timestamp": 1575142323797 + }, + "raw_data_hex": "0a0257b82208af6ffa6819c1f72040d58ec7ffeb2d5a59080b12550a32747970652e676f6f676c65617069732e636f6d2f70726f746f636f6c2e467265657a6542616c616e6365436f6e7472616374121f0a154139fec4d95bb59f45a727f9234020adaf2cec9e201080e3c78401180370d5ecb1eeeb2d", + "ret": [ + { + "code": "SUCESS", + "contractRet": "SUCCESS", + "fee": 0 + } + ], + "signature": [ + "c6f428b1c3666a5becd409ffe0a8c6535c997466c4ae741de20100f1689157c234ffa0b1f75bf48b0e54a5074bab95e4ad2a119d21819399c99fd9cd1cc8e87100" + ], + "txID": "b56bd0f2bdff2806da052b013a183014b44b3b39797f5c30427695e94c92640d" + }, + { + "block_timestamp": 1573442805000, + "raw_data": { + "contract": [ + { + "parameter": { + "type_url": "type.googleapis.com/protocol.TransferAssetContract", + "value": { + "amount": 2773215, + "asset_name": "1002000", + "owner_address": "41eb054d59928ef6600fb86c5a158861d1faaba48e", + "to_address": "4139fec4d95bb59f45a727f9234020adaf2cec9e20" + } + }, + "type": "TransferAssetContract" + } + ], + "expiration": 1573526182557, + "fee_limit": 0, + "ref_block_bytes": "afb3", + "ref_block_hash": "3c845aa598e806e7", + "timestamp": 1573441188048 + }, + "raw_data_hex": "0a02afb322083c845aa598e806e7409db5e0ebe52d5a76080212720a32747970652e676f6f676c65617069732e636f6d2f70726f746f636f6c2e5472616e736665724173736574436f6e7472616374123c0a0731303032303030121541eb054d59928ef6600fb86c5a158861d1faaba48e1a154139fec4d95bb59f45a727f9234020adaf2cec9e2020dfa1a90170d0e19cc3e52d", + "ret": [ + { + "code": "SUCESS", + "contractRet": "SUCCESS", + "fee": 0 + } + ], + "signature": [ + "b0b30bad88d0625ce88be0d0dfd4dee1dadce8321b09e98287c20f4c4c82da5b60f4d59f5e9edb0bfea841ef7f4053a242d52a657bf4de925935cfa317e42ba500" + ], + "txID": "d9486e03cdb6720e2995f7140dad80c06aeee1bc118392f166b8031142922c2f" + }, + { + "block_timestamp": 1570766748000, + "raw_data": { + "contract": [ + { + "parameter": { + "type_url": "type.googleapis.com/protocol.TransferAssetContract", + "value": { + "amount": 2774263, + "asset_name": "1002000", + "owner_address": "41d629aa1a501663918e9973381a65fa0239f77757", + "to_address": "4139fec4d95bb59f45a727f9234020adaf2cec9e20" + } + }, + "type": "TransferAssetContract" + } + ], + "expiration": 1570847328110, + "fee_limit": 0, + "ref_block_bytes": "1249", + "ref_block_hash": "f6d9b560f362e182", + "timestamp": 1570763940319 + }, + "raw_data_hex": "0a0212492208f6d9b560f362e18240ee8eb0eedb2d5a76080212720a32747970652e676f6f676c65617069732e636f6d2f70726f746f636f6c2e5472616e736665724173736574436f6e7472616374123c0a0731303032303030121541d629aa1a501663918e9973381a65fa0239f777571a154139fec4d95bb59f45a727f9234020adaf2cec9e2020f7a9a90170dfc3cec6db2d", + "ret": [ + { + "code": "SUCESS", + "contractRet": "SUCCESS", + "fee": 0 + } + ], + "signature": [ + "4c648c6f50cca283dbdcf33bf0f94996ee5596a84d2834a24d8b26d384edfeb30d217fc5df789fb970788db957e373f33a6233631d365ab482a1b2b1064a458901" + ], + "txID": "75e74b1cc3fca10b234193e3ea2314ad6158ee0ad90f115edd6d8d56e85df8fe" + }, + { + "block_timestamp": 1568172852000, + "raw_data": { + "contract": [ + { + "parameter": { + "type_url": "type.googleapis.com/protocol.TransferAssetContract", + "value": { + "amount": 2775304, + "asset_name": "1002000", + "owner_address": "41535565ae98247cee9b590983be8d09896f38e318", + "to_address": "4139fec4d95bb59f45a727f9234020adaf2cec9e20" + } + }, + "type": "TransferAssetContract" + } + ], + "expiration": 1568255474558, + "fee_limit": 0, + "ref_block_bytes": "e6e2", + "ref_block_hash": "46c69a30e7c32b37", + "timestamp": 1568170813057 + }, + "raw_data_hex": "0a02e6e2220846c69a30e7c32b3740fef6bd9ad22d5a76080212720a32747970652e676f6f676c65617069732e636f6d2f70726f746f636f6c2e5472616e736665724173736574436f6e7472616374123c0a0731303032303030121541535565ae98247cee9b590983be8d09896f38e3181a154139fec4d95bb59f45a727f9234020adaf2cec9e202088b2a9017081cd8ef2d12d", + "ret": [ + { + "code": "SUCESS", + "contractRet": "SUCCESS", + "fee": 0 + } + ], + "signature": [ + "34ba1adc145857be9f77ccb09e9894d9beeb8b1f5d7bfe955ca6b3140113faf511a84388be0636ee2d4bdac3fa60c32337df56a3524a14a46a12566f8df45e0b00" + ], + "txID": "14a51866eebf58440789e617f63dca0f15bbdaf174f80af7c0b1e04b5887d94b" + }, + { + "block_timestamp": 1565486163000, + "raw_data": { + "contract": [ + { + "parameter": { + "type_url": "type.googleapis.com/protocol.TransferAssetContract", + "value": { + "amount": 2776267, + "asset_name": "1002000", + "owner_address": "4186da818766179e1fc4c7830ac345936ef3d04e8e", + "to_address": "4139fec4d95bb59f45a727f9234020adaf2cec9e20" + } + }, + "type": "TransferAssetContract" + } + ], + "expiration": 1565569061084, + "fee_limit": 0, + "ref_block_bytes": "463d", + "ref_block_hash": "4dad9960c2c6d089", + "timestamp": 1565483669805 + }, + "raw_data_hex": "0a02463d22084dad9960c2c6d08940dca1c099c82d5a76080212720a32747970652e676f6f676c65617069732e636f6d2f70726f746f636f6c2e5472616e736665724173736574436f6e7472616374123c0a073130303230303012154186da818766179e1fc4c7830ac345936ef3d04e8e1a154139fec4d95bb59f45a727f9234020adaf2cec9e2020cbb9a90170adb2e4f0c72d", + "ret": [ + { + "code": "SUCESS", + "contractRet": "SUCCESS", + "fee": 0 + } + ], + "signature": [ + "f4aa7ffefd93421bc5113626c69f509da11746d0c0861990b6272d2290e31b0c2e2572f49469e15a979c514786fbda76b095dd0190f51a38987aaa255f2ccca000" + ], + "txID": "488e57c033a3d6ff193c0bda6f2b0ea224f82ad294b9ba705faaec2bcb02155a" + }, + { + "block_timestamp": 1562826081000, + "raw_data": { + "contract": [ + { + "parameter": { + "type_url": "type.googleapis.com/protocol.TransferAssetContract", + "value": { + "amount": 2776887, + "asset_name": "1002000", + "owner_address": "41313dbb31dd9eeb90c535edc7d2048182d3d5740a", + "to_address": "4139fec4d95bb59f45a727f9234020adaf2cec9e20" + } + }, + "type": "TransferAssetContract" + } + ], + "expiration": 1562910473588, + "fee_limit": 0, + "ref_block_bytes": "ec00", + "ref_block_hash": "3f1eb9822744575d", + "timestamp": 1562824848491 + }, + "raw_data_hex": "0a02ec0022083f1eb9822744575d40f4fae4a5be2d5a76080212720a32747970652e676f6f676c65617069732e636f6d2f70726f746f636f6c2e5472616e736665724173736574436f6e7472616374123c0a0731303032303030121541313dbb31dd9eeb90c535edc7d2048182d3d5740a1a154139fec4d95bb59f45a727f9234020adaf2cec9e2020b7bea90170ebe8fafcbd2d", + "ret": [ + { + "code": "SUCESS", + "contractRet": "SUCCESS", + "fee": 0 + } + ], + "signature": [ + "e2a28a242ac2d028a1771a8900d4b0678bb8a14c6e8b90ea4fdc916f71ed4c9c4f74ff16e0b2041e25936e1a84ed851510b209401e89fe116f2476619bf0f32900" + ], + "txID": "932473d894155439c55efc641c7eac203f9b9cc75aeddff9c4787fb29fc3799f" + }, + { + "block_timestamp": 1560214770000, + "raw_data": { + "contract": [ + { + "parameter": { + "type_url": "type.googleapis.com/protocol.TransferAssetContract", + "value": { + "amount": 2777963, + "asset_name": "1002000", + "owner_address": "41535df354e6e25707e2e566426fa9fbe26f2a00b4", + "to_address": "4139fec4d95bb59f45a727f9234020adaf2cec9e20" + } + }, + "type": "TransferAssetContract" + } + ], + "expiration": 1560298462780, + "fee_limit": 0, + "ref_block_bytes": "b65e", + "ref_block_hash": "eb0ec24fdbaf4166", + "timestamp": 1560213325513 + }, + "raw_data_hex": "0a02b65e2208eb0ec24fdbaf416640bcbca4c8b42d5a76080212720a32747970652e676f6f676c65617069732e636f6d2f70726f746f636f6c2e5472616e736665724173736574436f6e7472616374123c0a0731303032303030121541535df354e6e25707e2e566426fa9fbe26f2a00b41a154139fec4d95bb59f45a727f9234020adaf2cec9e2020ebc6a90170c98dd89fb42d", + "ret": [ + { + "code": "SUCESS", + "contractRet": "SUCCESS", + "fee": 0 + } + ], + "signature": [ + "876c48d579b68af052bdbbce7e5338950466be7f72c44df177f1bfe619ae83957fb1a1425626c27fa488426f1c33b87cce4887505465864fcb51bc399eb6276901" + ], + "txID": "e0c51b1c38f35f13c45b5b10a8aa6ea03eaba85402a4f99d8b68c795d08fae69" + }, + { + "blockNumber": 9125059, + "block_timestamp": 1557536844000, + "energy_fee": 0, + "energy_usage": 0, + "energy_usage_total": 0, + "internal_transactions": [], + "net_fee": 2820, + "net_usage": 0, + "raw_data": { + "contract": [ + { + "parameter": { + "type_url": "type.googleapis.com/protocol.TransferAssetContract", + "value": { + "amount": 2778999, + "asset_name": "1002000", + "owner_address": "41f0121e7fb828baaf6016c30a38df2852cc91bf63", + "to_address": "4139fec4d95bb59f45a727f9234020adaf2cec9e20" + } + }, + "type": "TransferAssetContract" + } + ], + "expiration": 1557620299006, + "fee_limit": 0, + "ref_block_bytes": "3950", + "ref_block_hash": "0fa563518d313adc", + "timestamp": 1557535303504 + }, + "raw_data_hex": "0a02395022080fa563518d313adc40fea99ecbaa2d5a76080212720a32747970652e676f6f676c65617069732e636f6d2f70726f746f636f6c2e5472616e736665724173736574436f6e7472616374123c0a0731303032303030121541f0121e7fb828baaf6016c30a38df2852cc91bf631a154139fec4d95bb59f45a727f9234020adaf2cec9e2020f7cea90170d0cedaa2aa2d", + "ret": [ + { + "code": "SUCESS", + "contractRet": "SUCCESS", + "fee": 2820 + } + ], + "signature": [ + "a84d6291474b6a4403628a0f56ec9af02ae7002e4cec7fb1a222d4e532038852137163131d43e80a9fb304cf448620c009d0fb50d51bbd9409ae28765e81336d01" + ], + "txID": "e557b1e03142d68fce5a82db36f0c404e7db0609c4fd2d14395bab2616eb00ec" + }, + { + "block_timestamp": 1554947670000, + "raw_data": { + "contract": [ + { + "parameter": { + "type_url": "type.googleapis.com/protocol.TransferAssetContract", + "value": { + "amount": 2779810, + "asset_name": "1002000", + "owner_address": "4173760159ffe7116385d5d64890d87f1254be65db", + "to_address": "4139fec4d95bb59f45a727f9234020adaf2cec9e20" + } + }, + "type": "TransferAssetContract" + } + ], + "expiration": 1555030923157, + "fee_limit": 0, + "ref_block_bytes": "2502", + "ref_block_hash": "074004b3532d4b12", + "timestamp": 1554945513705 + }, + "raw_data_hex": "0a0225022208074004b3532d4b124095afc3f8a02d5a76080212720a32747970652e676f6f676c65617069732e636f6d2f70726f746f636f6c2e5472616e736665724173736574436f6e7472616374123c0a073130303230303012154173760159ffe7116385d5d64890d87f1254be65db1a154139fec4d95bb59f45a727f9234020adaf2cec9e2020a2d5a90170e9b1e6cfa02d", + "ret": [ + { + "code": "SUCESS", + "contractRet": "SUCCESS", + "fee": 0 + } + ], + "signature": [ + "c76cf4def7d0a38a5d04045183dc15b6512b576d2e49c110f733a5c7d591f6ee3a09ad6cd417590676aeffa2abcb47be22a19ebddcc2e09f12cd68a9ef6bf13400" + ], + "txID": "fd17c87acc8226989592d93e4e530ef3fe19a1c486259af23ad5ac1a68793d33" + }, + { + "block_timestamp": 1553870898000, + "raw_data": { + "contract": [ + { + "parameter": { + "type_url": "type.googleapis.com/protocol.TransferAssetContract", + "value": { + "amount": 10149740000, + "asset_name": "1002000", + "owner_address": "410583a68a3bcd86c25ab1bee482bac04a216b0261", + "to_address": "4139fec4d95bb59f45a727f9234020adaf2cec9e20" + } + }, + "type": "TransferAssetContract" + } + ], + "expiration": 1553870955000, + "fee_limit": 0, + "ref_block_bytes": "b560", + "ref_block_hash": "2d9026ee979db6b6", + "timestamp": 1553870897024 + }, + "raw_data_hex": "0a02b56022082d9026ee979db6b640f8c3b4cf9c2d5a77080212730a32747970652e676f6f676c65617069732e636f6d2f70726f746f636f6c2e5472616e736665724173736574436f6e7472616374123d0a07313030323030301215410583a68a3bcd86c25ab1bee482bac04a216b02611a154139fec4d95bb59f45a727f9234020adaf2cec9e2020e0fbe2e7257080ffb0cf9c2d", + "ret": [ + { + "code": "SUCESS", + "contractRet": "SUCCESS", + "fee": 0 + } + ], + "signature": [ + "10c57bda2346f4cc7e287a2b696fcd8dcbec273d84df8b8d41fcf49d13e02fdf1ca539d1b631feabd58e3f0a8c501c8d74595774fd149cfba16770eb8a4bd18100" + ], + "txID": "d9206168ee601935bb19de30a613f735972f1ab59178ba05d078ff1ae19c0602" + }, + { + "block_timestamp": 1553864040000, + "raw_data": { + "contract": [ + { + "parameter": { + "type_url": "type.googleapis.com/protocol.TransferContract", + "value": { + "amount": 278720000, + "owner_address": "410583a68a3bcd86c25ab1bee482bac04a216b0261", + "to_address": "4139fec4d95bb59f45a727f9234020adaf2cec9e20" + } + }, + "type": "TransferContract" + } + ], + "expiration": 1553864097000, + "fee_limit": 0, + "ref_block_bytes": "ac7f", + "ref_block_hash": "648c4cb65453b4de", + "timestamp": 1553864038710 + }, + "raw_data_hex": "0a02ac7f2208648c4cb65453b4de40e8f991cc9c2d5a69080112650a2d747970652e676f6f676c65617069732e636f6d2f70726f746f636f6c2e5472616e73666572436f6e747261637412340a15410583a68a3bcd86c25ab1bee482bac04a216b026112154139fec4d95bb59f45a727f9234020adaf2cec9e201880dcf3840170b6b28ecc9c2d", + "ret": [ + { + "code": "SUCESS", + "contractRet": "SUCCESS", + "fee": 0 + } + ], + "signature": [ + "25052c3c653de8c06dc2294f9078a621179102282799f14f4a6950b805e66ea17c1a894a34922d92b7b14aad27cc07aeb129cb31570d55e9f21a0e3f5dd11ce701" + ], + "txID": "3ef5e225ce5bdd01333286e4ab4413ae3da8b80c24b26c5811ae78962940a8ca" + } + ] +} \ No newline at end of file diff --git a/mock/ext-api-data/tron-api_v1_assets_1002000.json b/mock/ext-api-data/tron-api_v1_assets_1002000.json new file mode 100644 index 000000000..ea4261a3b --- /dev/null +++ b/mock/ext-api-data/tron-api_v1_assets_1002000.json @@ -0,0 +1,23 @@ +{ + "success": true, + "meta": { + "at": 1589387413939, + "page_size": 1 + }, + "data": [ + { + "id": "1002000", + "abbr": "BTT", + "description": "Official Token of BitTorrent Protocol", + "name": "BitTorrent", + "num": 1, + "precision": 6, + "total_supply": "990000000000000000", + "trx_num": 1, + "url": "www.bittorrent.com", + "owner_address": "4137fa1a56eb8c503624701d776d95f6dae1d9f0d6", + "start_time": 1548000000000, + "end_time": 1548000001000 + } + ] +} \ No newline at end of file diff --git a/mock/ext-api-data/tron-api_v1_assets_1002798.json b/mock/ext-api-data/tron-api_v1_assets_1002798.json new file mode 100644 index 000000000..b5c850fad --- /dev/null +++ b/mock/ext-api-data/tron-api_v1_assets_1002798.json @@ -0,0 +1,24 @@ +{ + "success": true, + "meta": { + "at": 1589366702515, + "page_size": 1 + }, + "data": [ + { + "id": "1002798", + "abbr": "EPICAL", + "description": "The token of the game Builder III", + "name": "EPICAL", + "num": 1000000000, + "precision": 6, + "total_supply": "10000000000000000", + "trx_num": 1000000000, + "url": "https://builder3.fun", + "vote_score": 0, + "owner_address": "41133b084f5225a9112f4e8527db26b381a32babd0", + "start_time": 1574966426578, + "end_time": 1574966486578 + } + ] +} \ No newline at end of file diff --git a/mock/ext-api-data/tron-api_v1_assets_1002814.json b/mock/ext-api-data/tron-api_v1_assets_1002814.json new file mode 100644 index 000000000..8af11521d --- /dev/null +++ b/mock/ext-api-data/tron-api_v1_assets_1002814.json @@ -0,0 +1,24 @@ +{ + "success": true, + "meta": { + "at": 1589387440079, + "page_size": 1 + }, + "data": [ + { + "id": "1002814", + "abbr": "AX", + "description": "The token of the game TrainX", + "name": "AX", + "num": 1000000000, + "precision": 6, + "total_supply": "10000000000000000", + "trx_num": 1000000000, + "url": "https://trainx.fun", + "vote_score": 0, + "owner_address": "418e267ead411aaaf671be100a7afe587d4eab0d71", + "start_time": 1576483805985, + "end_time": 1576483865985 + } + ] +} \ No newline at end of file diff --git a/mock/ext-api-data/tron-api_wallet_getaccount.json b/mock/ext-api-data/tron-api_wallet_getaccount.json new file mode 100644 index 000000000..0967ef424 --- /dev/null +++ b/mock/ext-api-data/tron-api_wallet_getaccount.json @@ -0,0 +1 @@ +{} diff --git a/mock/ext-api-data/tron-api_wallet_getaccount.request_json b/mock/ext-api-data/tron-api_wallet_getaccount.request_json new file mode 100644 index 000000000..bd1460390 --- /dev/null +++ b/mock/ext-api-data/tron-api_wallet_getaccount.request_json @@ -0,0 +1 @@ +{"address":"TFFriedwRtWdFuzerDDtkoQTZ29smDZ1MB","visible":true} diff --git a/mock/ext-api-data/tron-api_wallet_listwitnesses.json b/mock/ext-api-data/tron-api_wallet_listwitnesses.json new file mode 100644 index 000000000..ac7a02b97 --- /dev/null +++ b/mock/ext-api-data/tron-api_wallet_listwitnesses.json @@ -0,0 +1,1617 @@ +{ + "witnesses": [ + { + "address": "417bdd2efb4401c50b6ad255e6428ba688e0b83f81", + "voteCount": 298493753, + "url": "https://minergate.com", + "totalProduced": 409483, + "totalMissed": 801, + "latestBlockNum": 19700720, + "latestSlotNum": 529788893, + "isJobs": true + }, + { + "address": "41d376d829440505ea13c9d1c455317d51b62e4ab6", + "voteCount": 317269760, + "url": "http://blockchain.org", + "totalProduced": 482712, + "totalMissed": 2654, + "latestBlockNum": 19700712, + "latestSlotNum": 529788885, + "isJobs": true + }, + { + "address": "4138e3e3a163163db1f6cfceca1d1c64594dd1f0ca", + "voteCount": 312761034, + "url": "https://twitter.com/justinsuntron", + "totalProduced": 678403, + "totalMissed": 1714, + "latestBlockNum": 19700713, + "latestSlotNum": 529788886, + "isJobs": true + }, + { + "address": "41037e18c9ca44b2ba35f0bb7d0c075f252a191294", + "voteCount": 299572403, + "url": "https://trxultra.org", + "totalProduced": 414497, + "totalMissed": 1608, + "latestBlockNum": 19700719, + "latestSlotNum": 529788892, + "isJobs": true + }, + { + "address": "4114f2c09d3de3fe82a71960da65d4935a30b24e1f", + "voteCount": 304155685, + "url": "https://staked.us", + "totalProduced": 11668, + "latestBlockNum": 19700717, + "latestSlotNum": 529788890, + "isJobs": true + }, + { + "address": "41c05142fd1ca1e03688a43585096866ae658f2cb2", + "voteCount": 312143320, + "url": "http://tronalliance.org", + "totalProduced": 475137, + "totalMissed": 1236, + "latestBlockNum": 19700714, + "latestSlotNum": 529788887, + "isJobs": true + }, + { + "address": "41f29f57614a6b201729473c837e1d2879e9f90b8e", + "voteCount": 330655577, + "url": "https://www.utorrent.com/", + "totalProduced": 695385, + "totalMissed": 1972, + "latestBlockNum": 19700710, + "latestSlotNum": 529788883, + "isJobs": true + }, + { + "address": "4118e2e1c6cdf4b74b7c1eb84682e503213a174955", + "voteCount": 307176451, + "url": "https://tronscan.org", + "totalProduced": 419985, + "totalMissed": 436, + "latestBlockNum": 19700716, + "latestSlotNum": 529788889, + "isJobs": true + }, + { + "address": "41a9d4b388c009b7ee36819114b8558d078103ad0b", + "voteCount": 300055396, + "url": "https://hitbtc.com", + "totalProduced": 402664, + "totalMissed": 4553, + "latestBlockNum": 19700718, + "latestSlotNum": 529788891, + "isJobs": true + }, + { + "address": "414d1ef8673f916debb7e2515a8f3ecaf2611034aa", + "voteCount": 364140926, + "url": "https://www.sesameseed.org", + "totalProduced": 711187, + "totalMissed": 5755, + "latestBlockNum": 19700704, + "latestSlotNum": 529788877, + "isJobs": true + }, + { + "address": "4192c5d96c3b847268f4cb3e33b87ecfc67b5ce3de", + "voteCount": 330908358, + "url": "https://infstones.io/", + "totalProduced": 572555, + "totalMissed": 2232, + "latestBlockNum": 19700709, + "latestSlotNum": 529788882, + "isJobs": true + }, + { + "address": "4178c842ee63b253f8f0d2955bbc582c661a078c9d", + "voteCount": 311816791, + "url": "https://www.binance.com/en/staking", + "totalProduced": 241472, + "totalMissed": 73, + "latestBlockNum": 19700715, + "latestSlotNum": 529788888, + "isJobs": true + }, + { + "address": "415863f6091b8e71766da808b1dd3159790f61de7d", + "voteCount": 341400688, + "url": "https://www.huobipool.com", + "totalProduced": 662003, + "totalMissed": 7871, + "latestBlockNum": 19700706, + "latestSlotNum": 529788879, + "isJobs": true + }, + { + "address": "41e40302d6b5e889bfbd395ed884638d7f03ee3f87", + "voteCount": 344070018, + "url": "https://tronlink.org", + "totalProduced": 413730, + "totalMissed": 331, + "latestBlockNum": 19700705, + "latestSlotNum": 529788878, + "isJobs": true + }, + { + "address": "41beab998551416b02f6721129bb01b51fceceba08", + "voteCount": 330974623, + "url": "https://tronspark.com", + "totalProduced": 671456, + "totalMissed": 3504, + "latestBlockNum": 19700708, + "latestSlotNum": 529788881, + "isJobs": true + }, + { + "address": "41c189fa6fc9ed7a3580c3fe291915d5c6a6259be7", + "voteCount": 327673142, + "url": "https://www.cryptoguyinza.co.za/", + "totalProduced": 703648, + "totalMissed": 2328, + "latestBlockNum": 19700711, + "latestSlotNum": 529788884, + "isJobs": true + }, + { + "address": "41c81107148e5fa4b4a2edf3d5354db6c6be5b5549", + "voteCount": 367283865, + "url": "https://www.trongrid.io", + "totalProduced": 338991, + "totalMissed": 95, + "latestBlockNum": 19700703, + "latestSlotNum": 529788876, + "isJobs": true + }, + { + "address": "4167e39013be3cdd3814bed152d7439fb5b6791409", + "voteCount": 334317801, + "url": "http://cryptochain.network", + "totalProduced": 695157, + "totalMissed": 2269, + "latestBlockNum": 19700707, + "latestSlotNum": 529788880, + "isJobs": true + }, + { + "address": "4100e9fdbd1d24ab56996bd37d76fb7b16dcf62ff1", + "voteCount": 288043, + "url": "https://www.tronmacau.com" + }, + { + "address": "41012f81bd368f632fb22b9ddfeb284155f1f04198", + "voteCount": 213, + "url": "https://firekraken.media" + }, + { + "address": "4101c17562ee5a1ecb60f9ea6e49ef94ec0de99580", + "voteCount": 113369, + "url": "https://tronpad.com" + }, + { + "address": "4102a0ed82a9609e7ea9155f00137dc3fce818033f", + "voteCount": 1834997, + "url": "XREGlobal.com" + }, + { + "address": "4102f95b2185f52ac539128b28033998ab01466986", + "voteCount": 114, + "url": "http://imcash.io" + }, + { + "address": "4103ca8124bfa7c06b20b2e3d2278f67d5d1cb6a66", + "voteCount": 151702, + "url": "https://twitter.com/mr_oceanview" + }, + { + "address": "41061e3f4e108d8aaf5cd75b499f811ae30ed04b77", + "voteCount": 87612, + "url": "https://dexnode.net" + }, + { + "address": "410694981b116304ed21e05896fb16a6bc2e91c92c", + "voteCount": 1501, + "url": "http://TronGr21.com", + "totalProduced": 28449, + "latestBlockNum": 1614751, + "latestSlotNum": 511581581 + }, + { + "address": "41080126628c7a8c7edfddf6a027e458f0001d2e09", + "voteCount": 248, + "url": "https://rinzler.eu" + }, + { + "address": "4108b55b2611ec829d308a62b3339fba9dd5c27151", + "voteCount": 203, + "url": "http://TronGr5.com", + "totalProduced": 36710, + "latestBlockNum": 1226106, + "latestSlotNum": 511192800 + }, + { + "address": "410b05a97454cc7aac6e736b4390ee751665941568", + "voteCount": 778744, + "url": "http://test.com" + }, + { + "address": "410c6747caa68213bd0d1f3ed891ee93b090fbf223", + "voteCount": 3408489, + "url": "https://bixin.com" + }, + { + "address": "4110dc5d4731b5463c372a5615d47fc4ad470c3c6b", + "voteCount": 1037, + "url": "http://www.ocoins.cc/" + }, + { + "address": "411103d62d8299e90fa011b4ce7fc6ba151e5f1a23", + "voteCount": 106693397, + "url": "https://www.tronvietnam.com/", + "totalProduced": 594831, + "totalMissed": 9060, + "latestBlockNum": 17299301, + "latestSlotNum": 527385598 + }, + { + "address": "411155d10415fac16a8f4cb2f382ce0e0f0a7e64cc", + "voteCount": 1029, + "url": "http://TronGr22.com", + "totalProduced": 21773, + "latestBlockNum": 1593157, + "latestSlotNum": 511559981 + }, + { + "address": "41137c94812b79641515e92c5a567bd3a79d1f9f7b", + "voteCount": 29003, + "url": "http://tronjapan.io" + }, + { + "address": "4116329c4b64920408342e66221a1d52a974901984", + "voteCount": 7678, + "url": "https://trx.bitcoingod.org" + }, + { + "address": "4116440834509c59de4ee6ba4933678626f451befe", + "voteCount": 801768, + "url": "https://WINTokenGames.com", + "totalProduced": 104760, + "totalMissed": 819, + "latestBlockNum": 4144662, + "latestSlotNum": 514129269 + }, + { + "address": "411661f25387370c9cd3a9a5d97e60ca90f4844e7e", + "voteCount": 611, + "url": "http://TronGr8.com", + "totalProduced": 47910, + "totalMissed": 1, + "latestBlockNum": 1650122, + "latestSlotNum": 511617599 + }, + { + "address": "41167647e8720a4ac305c1c0fa3c71e8a7be3d7d39", + "voteCount": 15001, + "url": "NULL.DAT" + }, + { + "address": "4116aaab3741fc65dc875585ee7eae622daaf425ca", + "voteCount": 20, + "url": "http://blog.naver.com/coolkim01" + }, + { + "address": "4119bec4e96e417f936d40bd4fe3876d1a516a064d", + "voteCount": 340228, + "url": "digitalgeotreasure.com/" + }, + { + "address": "411d7aba13ea199a63d1647e58e39c16a9bb9da689", + "voteCount": 29410, + "url": "http://TronGr20.com", + "totalProduced": 56172, + "latestBlockNum": 1549970, + "latestSlotNum": 511516780 + }, + { + "address": "411e65f18ba80f132fa645727f4dd05cd7eb72e3b1", + "voteCount": 251, + "url": "https://theseusx.net" + }, + { + "address": "411ec54599d42f1e2e699cd1c24dcd79644d8b3e19", + "voteCount": 196, + "url": "https://twitter.com/KaanKOZANn" + }, + { + "address": "41207ab1585b9cc6c4c1232f67e4a10e19a442fe68", + "voteCount": 501, + "url": "http://TronGr10.com", + "totalProduced": 26298, + "latestBlockNum": 1076255, + "latestSlotNum": 511041581 + }, + { + "address": "4121eca596da7e2465b390df2e8bd297881ab3dc57", + "voteCount": 139058, + "url": "https://tronsecure.io" + }, + { + "address": "4123d6947ca8b9b3748f1d1aac88a0867d415d4ac9", + "voteCount": 601, + "url": "http://www.trongalaxy.io" + }, + { + "address": "41241d998b00b3431e3b2d1cce714566659ccaef5c", + "voteCount": 584, + "url": "https://www.museprotocol.com" + }, + { + "address": "41243accc5241d97ce79272b06952ee88a34d8e1f9", + "voteCount": 6490100, + "url": "https://www.tronics.io/", + "totalProduced": 134119, + "totalMissed": 96, + "latestBlockNum": 4203064, + "latestSlotNum": 514187999 + }, + { + "address": "4124443254e2d1f3e1f55521d518bd875138f4173c", + "voteCount": 6594518, + "url": "http://www.communitynode.org/" + }, + { + "address": "41247c3c989c2d31e454ba06e6d9d421908d7a0fd8", + "voteCount": 67132, + "url": "https://tronlottery.io" + }, + { + "address": "41267e38504037133a20a79d38dfbb2cf0988942e6", + "voteCount": 61, + "url": "https://reyna2.com" + }, + { + "address": "4127a6419bbe59f4e64a064d710787e578a150d6a7", + "voteCount": 2732, + "url": "http://TronGr4.com", + "totalProduced": 53772, + "latestBlockNum": 1513990, + "latestSlotNum": 511480789 + }, + { + "address": "4127bf0d1a57f335c11bc5d002dd82e9e0727cb967", + "voteCount": 1214, + "url": "http://TronGr26.com", + "totalProduced": 24711, + "latestBlockNum": 1104788, + "latestSlotNum": 511070388 + }, + { + "address": "4128283cfbbffe9e267fb32bfef1e0533042ad3756", + "voteCount": 61611, + "url": "https://www.tronboston.com" + }, + { + "address": "412929e0e1d5d0ba3b68d8e3a376ef884ab23dd8e0", + "voteCount": 300, + "url": "http://hqn.vn" + }, + { + "address": "4129f3dd5bb0941bde8dc4538332c14fca595a7fe0", + "voteCount": 604, + "url": "http://www.tron.school/" + }, + { + "address": "412a5308a747e62dda5fd06cf516b31bf746ce2b3d", + "voteCount": 600, + "url": "http://www.linkvc.com/" + }, + { + "address": "412c31119d41ba850dd666b6d7d5c52ec85da9e4ef", + "voteCount": 120, + "url": "http://cryptochain.network" + }, + { + "address": "412d62975bc329b501368110f435cd8d277a1115e9", + "voteCount": 79535, + "url": "https://sites.google.com/view/proudbtc1nvest/startsida" + }, + { + "address": "412d7bdb9846499a2e5e6c5a7e6fb05731c83107c7", + "voteCount": 407990435, + "url": "https://www.tronwallet.me/", + "totalProduced": 588418, + "totalMissed": 1230, + "latestBlockNum": 19700702, + "latestSlotNum": 529788875, + "isJobs": true + }, + { + "address": "412edce151c81d9b4aae17f974f7f646242eff989d", + "voteCount": 1839, + "url": "http://TronGr14.com", + "totalProduced": 27117, + "latestBlockNum": 760520, + "latestSlotNum": 510724788 + }, + { + "address": "412fb5abdf8a1670f533c219e7251fe30b89849359", + "voteCount": 6061915, + "url": "http://www.lianjinshu.com", + "totalProduced": 405906, + "totalMissed": 6512, + "latestBlockNum": 11497746, + "latestSlotNum": 521575194 + }, + { + "address": "412ff2cc08e2b4ae41adae991b20c582f42c958efa", + "url": "http://the-crazy-once.de" + }, + { + "address": "41318b2b6b4c7fcaa4b62f25a282329e1952a3c0d1", + "voteCount": 1525, + "url": "http://TronGr23.com", + "totalProduced": 19115, + "latestBlockNum": 1557177, + "latestSlotNum": 511523990 + }, + { + "address": "4131b0bbc3ec749ed0666e4ea6db0a58d464daf007", + "voteCount": 17, + "url": "https://darano.network/" + }, + { + "address": "4132c014adb6ff15038d5b67d97046c2556d9a9dc3", + "voteCount": 711, + "url": "https://www.robocoinexchange.com" + }, + { + "address": "41333bf31c095163a07e14a75c1f717f99f7934a8c", + "voteCount": 17712832, + "url": "\thttps://www.cashierest.com" + }, + { + "address": "4135c07ff4c26880a9c758a8b15e6fa1ad6d7e18a2", + "voteCount": 905197, + "url": "https://noraigi.com/en/home" + }, + { + "address": "4135c3c756c094d7b7f4f733f5b61bafc36b52510b", + "voteCount": 52, + "url": "https://inrtoken.io/" + }, + { + "address": "4135d7a72c7431d36f076d2c078a149a9037bb244b", + "voteCount": 27, + "url": "http://t.me/TheL1Crew" + }, + { + "address": "41362519bf874a901e7488fba6a0e06bc6ba781489", + "voteCount": 2239, + "url": "http://www.meg4tron.com/" + }, + { + "address": "4139801ec34decc39c8c206b46c79cd2c46f48e08a", + "voteCount": 408495, + "url": "." + }, + { + "address": "413ba13182b026a6e8ec8af2302ad86d221682000d", + "voteCount": 2138794, + "url": "https://www.coinnest.co.kr" + }, + { + "address": "413d2e1a011533da0da6f5b4d07384945b45e0cd0e", + "voteCount": 4415, + "url": "https://helloworldteam.org" + }, + { + "address": "413dd6a14c95be5d43d1d1e51f94205ffbfc63b8fb", + "voteCount": 93766, + "url": "https://tronbet.com", + "totalProduced": 13060, + "totalMissed": 1, + "latestBlockNum": 4259295, + "latestSlotNum": 514245587 + }, + { + "address": "413f5f20247069fe5b674ed21c693f7d382db0b8e0", + "voteCount": 54, + "url": "https://atticlab.net" + }, + { + "address": "414061ef90a87bf861cb5dddb7897f60ffd1f36372", + "voteCount": 82007323, + "url": "https://www.nodeasy.com" + }, + { + "address": "4140c59d6ae1923d3a67bc49b40981c1569b8a2475", + "voteCount": 1621, + "url": "https://tronkh.org" + }, + { + "address": "41410e468919155aa847d83b0c206148511b6dc848", + "voteCount": 5501, + "url": "http://TronGr11.com", + "totalProduced": 30041, + "totalMissed": 5, + "latestBlockNum": 1463589, + "latestSlotNum": 511430374 + }, + { + "address": "41411d7f31ae1a4840458667c52ac1e4d25843e009", + "voteCount": 1083, + "url": "https://globalricetoken.wixsite.com/grttoken" + }, + { + "address": "4141b285495e0dba4a39fe79dba38b068506b2f841", + "voteCount": 31, + "url": "http://tronman.io/" + }, + { + "address": "4142e95c76430e62dfe5182d58f46a482101648304", + "voteCount": 782704, + "url": "https://member.alleexchange.com", + "totalProduced": 37122, + "totalMissed": 1002, + "latestBlockNum": 5116518, + "latestSlotNum": 515131163 + }, + { + "address": "41432bd4093f1c8ef0ffe38f5e2f75f52c884c1986", + "voteCount": 645, + "url": "http://jdi.group" + }, + { + "address": "414431bf75a2acb6e36802a371447ffe559f3cf642", + "voteCount": 30086, + "url": "https://www.tron.buzz" + }, + { + "address": "414593d27b70d21454b39ab60bf13291dae8dc0326", + "voteCount": 4236, + "url": "http://TronGr16.com", + "totalProduced": 54023, + "totalMissed": 559, + "latestBlockNum": 1542790, + "latestSlotNum": 511509598 + }, + { + "address": "4145955a72c20b65ce9bae07830ce240bff3108389", + "voteCount": 521, + "url": "https://trongameglobal.network" + }, + { + "address": "41460b49a0ec5ce6340ff40020704f21b1d4e4f7ff", + "voteCount": 6, + "url": "http://www.nextgenius.com.au" + }, + { + "address": "4147e83677cf459b0bdc976ae6fe27b91c0d49329d", + "voteCount": 827, + "url": "http://VeganIS.ME/" + }, + { + "address": "414853b6a81a6ea7be929758c6adafda1f4f4faea2", + "voteCount": 600, + "url": "https://DoNotVote-Not-Active-SR" + }, + { + "address": "41496e85711fa3b7ba5a093af635269a67230ac2c1", + "voteCount": 21774463, + "url": "https://www.beatzcoin.io/", + "totalProduced": 221974, + "totalMissed": 3004, + "latestBlockNum": 14077587, + "latestSlotNum": 524159989 + }, + { + "address": "4149939465083f75a8769087f89aaf68032b575ceb", + "voteCount": 2963, + "url": "https://t.me/joinchat/F5QrYU9C8y-nAN2w0M327Q" + }, + { + "address": "4149f34cc0e7eecf4ad4515b7f5a5c333469f76ca5", + "voteCount": 15957, + "url": "https://twitter.com/1000WONG" + }, + { + "address": "414a193c92cd631c1911b99ca964da8fd342f4cddd", + "voteCount": 462393856, + "url": "http://www.skypeople.co.kr", + "totalProduced": 726373, + "totalMissed": 4883, + "latestBlockNum": 19700700, + "latestSlotNum": 529788873, + "isJobs": true + }, + { + "address": "414ac0706a3d08c0416ad361878b05d6fc8d36863e", + "voteCount": 207208, + "url": "https://cobo.com" + }, + { + "address": "414b4778beebb48abe0bc1df42e92e0fe64d0c8685", + "voteCount": 701, + "url": "http://TronGr7.com", + "totalProduced": 35113, + "latestBlockNum": 1571562, + "latestSlotNum": 511538379 + }, + { + "address": "414c121deddd140d5969dbbd8ac3aa611421251ecf", + "voteCount": 128, + "url": "http://he.capital/" + }, + { + "address": "414dd6d662582d5b6ff6c5b824a2b194f41e361631", + "voteCount": 5004, + "url": "https://tron.34rth.com/" + }, + { + "address": "414e785037af0091f269d1d47506be94336b317e86", + "voteCount": 12400, + "url": "https://gotno.life" + }, + { + "address": "415095d4f4d26ebc672ca12fc0e3a48d6ce3b169d2", + "voteCount": 5782, + "url": "http://TronGr1.com", + "totalProduced": 58297, + "latestBlockNum": 1621714, + "latestSlotNum": 511588788 + }, + { + "address": "4150eae1569968dbb87bbd786e6cfbf60c47464644", + "voteCount": 142499, + "url": "https://CharityCompassionCoin.com" + }, + { + "address": "4152a5962248ce05bcd114f976304eb2d052b6f034", + "voteCount": 12734, + "url": "https://www.neoply.com" + }, + { + "address": "4152bb0b293d6441ef44a36b92a290f0a9b952ffa0", + "voteCount": 2, + "url": "VoteTronicStorm" + }, + { + "address": "4152cca32a23b5a78b26237cb3ef587a0f20d113e1", + "voteCount": 20658, + "url": "https://www.thz.net" + }, + { + "address": "41530f931037de0c369968a5cf622003d240ef96e2", + "voteCount": 459657456, + "url": "https://www.beekuaibao.com", + "totalProduced": 213438, + "totalMissed": 475, + "latestBlockNum": 19700701, + "latestSlotNum": 529788874, + "isJobs": true + }, + { + "address": "41561bfd00769866b44282b773f2ed8bba00907dd9", + "voteCount": 35, + "url": "https://www.rightbtc.com" + }, + { + "address": "4157c381611f36ee7da21e6ab0bdc825774045de83", + "voteCount": 196, + "url": "https://www.livenodes.network/" + }, + { + "address": "415a8f7b00624fbcc0ec022d91a04000f573356cb9", + "voteCount": 408, + "url": "Https://www.numeriuno.eu" + }, + { + "address": "415baad9ab1e821a81ad4d512d71037326e3b04126", + "voteCount": 1260157, + "url": "http://troncoin.nl" + }, + { + "address": "415c6202be8f2a984c8f73f4d9fd841c0bfca8e3be", + "voteCount": 299011, + "url": "https://tronhope.org/" + }, + { + "address": "415c7f4890ed927ad276401851f38575fe42ff2eb3", + "voteCount": 12270, + "url": "https://www.cityuptake.com" + }, + { + "address": "415dc72ddad8966b1e22dfc94980243fce1c75ef9b", + "voteCount": 86686, + "url": "https://www.tron-mining.com" + }, + { + "address": "415f9d90205868184e240937140ab44b30f8012dbf", + "voteCount": 2033040, + "url": "www" + }, + { + "address": "416202093e031985b877eb60d508f583f45b50ae16", + "voteCount": 502, + "url": "http://www.apexinformatics.com" + }, + { + "address": "4162398d516b555ac64af24416e05c199c01823048", + "voteCount": 901559198, + "url": "https://poloniex.com/", + "totalProduced": 89458, + "totalMissed": 5, + "latestBlockNum": 19700698, + "latestSlotNum": 529788871, + "isJobs": true + }, + { + "address": "4162e1a76d28c0bee6eb56a53e864c810514c7fa08", + "voteCount": 1322, + "url": "www.tronixglobal.com" + }, + { + "address": "4163233b6d495606ded800a4e2d7b2a5eafbf4e53b", + "voteCount": 207, + "url": "https://molotovlab.com" + }, + { + "address": "4163ca1146abdf34944b5b84d62deac68b56fdc0f9", + "voteCount": 1837235, + "url": "https://activ8coin.com" + }, + { + "address": "416419765bacf1dc441f722cabc8b661140558bb5d", + "voteCount": 3257, + "url": "http://TronGr6.com", + "totalProduced": 55640, + "totalMissed": 1, + "latestBlockNum": 1513988, + "latestSlotNum": 511480787 + }, + { + "address": "4164bba21b3e2d1635fdf3eea556fe1e98763eb8a6", + "voteCount": 339976, + "url": "https://tran.systems/tronhub/" + }, + { + "address": "4165ad45cfb233daa0816f5df5444c5c5f4a189f20", + "voteCount": 501, + "url": "http://d2fapp.com" + }, + { + "address": "41685ef5321f2d94080d6bdcd1d4cbdded428cecb6", + "voteCount": 3529011, + "url": "http://tronkorea.io", + "totalProduced": 238, + "totalMissed": 28, + "latestBlockNum": 300029, + "latestSlotNum": 510263985 + }, + { + "address": "4168e2922f40b2971311b5e57b7573c526399860d0", + "voteCount": 158723, + "url": "https://promo.network/" + }, + { + "address": "4169051b001c6169201970f5a6a4f9ababfd916ae3", + "voteCount": 690238, + "url": "https://WinTokenGames.com", + "totalProduced": 23273, + "totalMissed": 187, + "latestBlockNum": 4791405, + "latestSlotNum": 514782404 + }, + { + "address": "416f849a033d62d854b6daad9052f6d9686c60c1c6", + "voteCount": 88, + "url": "https://cobo.com" + }, + { + "address": "417040583133e831953ea4f65a8196fcffcfbf0d80", + "voteCount": 330, + "url": "http://TronGr13.com", + "totalProduced": 24448, + "latestBlockNum": 1571564, + "latestSlotNum": 511538381 + }, + { + "address": "41704833c02883b3261f7baf62f8cb19b4b0c2e64e", + "voteCount": 6167, + "url": "https://game.com" + }, + { + "address": "4170b1be516ef67e1ca019d78b2112ccc8a3e8bd1b", + "voteCount": 7038, + "url": "https://tronvip.io" + }, + { + "address": "4172fd5dfb8ab36eb28df8e4aee97966a60ebf9efe", + "voteCount": 315, + "url": "http://TronGr27.com", + "totalProduced": 30838, + "latestBlockNum": 1513987, + "latestSlotNum": 511480786 + }, + { + "address": "417312080619a24d38a2029b724ff5c84d8f2e4483", + "voteCount": 9672, + "url": "https://weibo.com/bitdog666", + "totalProduced": 27199, + "totalMissed": 1, + "latestBlockNum": 3226491, + "latestSlotNum": 513208790 + }, + { + "address": "41746e6af4ac9db3473c0c955f1fca11d4013f32ed", + "voteCount": 7831, + "url": "http://TronGr17.com", + "totalProduced": 49765, + "totalMissed": 8, + "latestBlockNum": 1650121, + "latestSlotNum": 511617598 + }, + { + "address": "4175f1045e92680e52d072c1f92dec0874a8cbe2cc", + "voteCount": 35, + "url": "https://gconnect.io/" + }, + { + "address": "41770407d686a8a57c035a9615f25e4a7748a67739", + "voteCount": 416861, + "url": "http://tronshares.com" + }, + { + "address": "41788cd87d1525c0163240cd8832863845605fddc8", + "voteCount": 303500, + "url": "https://kryptowaluty.org.pl" + }, + { + "address": "4178af3274df44866a5bb63671d648583fce7ab08e", + "voteCount": 519, + "url": "https://c773.com/" + }, + { + "address": "4179497d5a29cbade8fac1394148379037e5618aed", + "voteCount": 4052, + "url": "http://tron-man.com/" + }, + { + "address": "417ad0ee1300d0366e901fa613a929137dde1d2224", + "voteCount": 221419, + "url": "https://mlgblockchain.com", + "totalProduced": 16896, + "totalMissed": 963, + "latestBlockNum": 1370030, + "latestSlotNum": 511336789 + }, + { + "address": "417b88db9da8aacae0a7e967d24c0fc00129e815f6", + "voteCount": 1498089, + "url": "www.Tron-Europe.com", + "totalProduced": 122888, + "totalMissed": 5326, + "latestBlockNum": 5101331, + "latestSlotNum": 515111693 + }, + { + "address": "417d0fa745bc8ee7137544ef93230089a34846892b", + "voteCount": 167, + "url": "https://cobo.com" + }, + { + "address": "417ec8dc8ceebf5e8b37875a3ab2769e93454465b9", + "voteCount": 2465, + "url": "Change Your Vote From This SR Position, To Our New SR Position: \"DEXExchange-DEXCOIN\"" + }, + { + "address": "417ecf3ba1ea90bce91a3b82c0774811d886bd85f6", + "voteCount": 240486, + "url": " https://www.phituasesor.com/smart-2/" + }, + { + "address": "4181d3b51217f51831d1600dc1903c7b7a3bbd5444", + "voteCount": 247, + "url": "https://twitter.com/@brianjun09" + }, + { + "address": "418276c0d4adc3f99daf592d90369f64ee16d1fb94", + "voteCount": 57667, + "url": "https://twitter.com/black0din" + }, + { + "address": "418343eae219414f585c21cd0c6610c0b0de19dedf", + "voteCount": 979612, + "url": "http://tronsiqveland.co.uk/" + }, + { + "address": "4183bbde499a4e7792dbf69033115180a36630cb8d", + "voteCount": 10, + "url": "https://www.wunderchain.com" + }, + { + "address": "41841201843fc3b0ee68a36ada464f606e82a53b05", + "voteCount": 5540, + "url": "https://gravelproject.io/" + }, + { + "address": "4184399fc6a98edc11a6efb146e86a3e153d0a0933", + "voteCount": 295142167, + "url": "https://www.tron-europe.org", + "totalProduced": 468341, + "totalMissed": 1894, + "latestBlockNum": 19700696, + "latestSlotNum": 529788869, + "isJobs": true + }, + { + "address": "418440ffd578f7a5abf3537b5f46a6980d382db581", + "voteCount": 17708684, + "url": "https://www.huobiwallet.com/" + }, + { + "address": "418565229cdbc48f6155c9863abedff8c8f3f61fcf", + "voteCount": 1616254, + "url": "https://twitter.com/TronsRocknRoll" + }, + { + "address": "41856eef3d964e450b52def7c0d49bb5719d2d22d3", + "voteCount": 11560, + "url": "tronsr", + "totalProduced": 1065, + "latestBlockNum": 3908714, + "latestSlotNum": 513892774 + }, + { + "address": "4185a503b5341d9628618d92b97d506788b92d0a12", + "voteCount": 32042, + "url": "http://www.tron-france.com" + }, + { + "address": "41869648f6368ec64afa4a68e00bd6864ee1b13583", + "voteCount": 4824, + "url": "https://www.gameoftron.net/" + }, + { + "address": "4186f5793eb678c65d9673d5498c550439d762c1cc", + "voteCount": 3370, + "url": "http://TronGr12.com", + "totalProduced": 46832, + "latestBlockNum": 1492394, + "latestSlotNum": 511459187 + }, + { + "address": "4187269d327159dcf579f267aa8d44631c49c7d8d6", + "voteCount": 3678, + "url": "https://www.google.com/" + }, + { + "address": "4187de03394f21e3d7b2e630296e4ea1ea994bb6d3", + "voteCount": 98664314, + "url": "https://tron.newdex.one" + }, + { + "address": "418891e5cd756727a61f2332bbaef99722a4e6d8b7", + "voteCount": 505, + "url": "http://www.tronium.net" + }, + { + "address": "418a445facc2aa94d72292ebbcb2a611e9fd8a6c6e", + "voteCount": 295494001, + "url": "http://zempty.peiwo.cn/", + "totalProduced": 559467, + "totalMissed": 1861, + "latestBlockNum": 19700695, + "latestSlotNum": 529788868, + "isJobs": true + }, + { + "address": "418a470d3a9614f93f43b332ba49b8848c26598352", + "voteCount": 800, + "url": "https://tronix.international/" + }, + { + "address": "418ac86d2381c71c405bd0703a944d428ac49a01a8", + "voteCount": 25, + "url": "www.upvote.world TBD" + }, + { + "address": "418ae580dfed3ce5c55232fb506c768463d68cf0db", + "voteCount": 376058, + "url": "https://www.baggi.co/" + }, + { + "address": "418b50e0f2952edcd43391aede597b85408f7eb4a2", + "voteCount": 250, + "url": "www.dtroynx.com" + }, + { + "address": "418bbd49f14ddd5d1ff996ccbbcde9ed0416c5a216", + "voteCount": 1000, + "url": "ffgtrgh" + }, + { + "address": "418c2e9bbc8c6fff0f947f264fae318b53815b4af7", + "voteCount": 103954, + "url": "https://healthport.io/" + }, + { + "address": "418c66e4883782b793fcf2dcb92b23eece57769499", + "voteCount": 290038614, + "url": "http://www.thelast.me", + "totalProduced": 215545, + "totalMissed": 3326, + "latestBlockNum": 18946553, + "latestSlotNum": 529034381 + }, + { + "address": "4193a8bc2e7d6bb1bd75fb2d74107ffbda81af439d", + "voteCount": 1839063, + "url": "http://www.cryptodiva.io/", + "totalProduced": 503055, + "totalMissed": 4892, + "latestBlockNum": 14005616, + "latestSlotNum": 524087980 + }, + { + "address": "41944d972a983881fd86c5b2cd49e18bdbaff116d0", + "voteCount": 174, + "url": "https://www.facebook.com/sevo.nikolov" + }, + { + "address": "4196ff32cfa51692dd6987ae161e3cf8b36143d827", + "voteCount": 35005157, + "url": "http://bz.com/" + }, + { + "address": "419837a9e5e14ce4921a2c6bd33cdba00e2f2688c5", + "voteCount": 518, + "url": "https://t.me/ONGISTRON_NewsChannel" + }, + { + "address": "4198787f5ebebb0a8fe26f148d81de0fdd88c28329", + "voteCount": 239, + "url": "http://www.contactnetwork.fr/" + }, + { + "address": "4198bf627cb3d9b3ac11cb9fbbb10aeed74615936d", + "voteCount": 562, + "url": "https://tronblock.co" + }, + { + "address": "4199fe7d33b4d7fc111fb1c5ef2c751676e1fb250b", + "voteCount": 76890, + "url": "https://TRONS.WORLD" + }, + { + "address": "419a856a04df38a4d9ce74d046af96872741ded747", + "voteCount": 1116, + "url": "https://trontx.com" + }, + { + "address": "419bae807d803192c5cc09a1f6c98c43a9141c32cf", + "voteCount": 83, + "url": "https://mobile.twitter.com/busyblaze" + }, + { + "address": "419deb263b16e25063fd47208fac89b01a32003ce7", + "voteCount": 500, + "url": "https://TRXGUARDIAN.ORG" + }, + { + "address": "419e46cd3c3b4a5543798962bd5f14d017cf6a124c", + "voteCount": 5131, + "url": "https://www.bitcoinworld.com/" + }, + { + "address": "41a300b290201cb337fe62794afbe9ed5cb183db55", + "voteCount": 103, + "url": "https://www.trxkings.com" + }, + { + "address": "41a4475dbd14feb2221f303fc33dc8d0a08f25f445", + "voteCount": 30583389, + "url": "https://tron-society.com", + "totalProduced": 168733, + "totalMissed": 2433, + "latestBlockNum": 8208429, + "latestSlotNum": 518255974 + }, + { + "address": "41a47e8b12d006a2c2a3f044453e2745bfb9321939", + "voteCount": 6859, + "url": "http://tronpro.io", + "totalProduced": 15194, + "totalMissed": 1, + "latestBlockNum": 1305260, + "latestSlotNum": 511271991 + }, + { + "address": "41a6c467ef40aa712fa239153309c0225300fbfa88", + "voteCount": 159, + "url": "https://www.vena.network" + }, + { + "address": "41a75a876ef0e8715aa2cd34597154382502b8d646", + "voteCount": 1523, + "url": " ", + "totalProduced": 102241, + "totalMissed": 426, + "latestBlockNum": 13998453, + "latestSlotNum": 524080797 + }, + { + "address": "41a857362c1b77cb04e8f2b51b6e970f24fa5c1e5b", + "voteCount": 6007, + "url": "http://TronGr24.com", + "totalProduced": 21248, + "latestBlockNum": 1614750, + "latestSlotNum": 511581580 + }, + { + "address": "41a89e743413e30d5462c95ac8ff0abcc13e7cf38f", + "voteCount": 2001, + "url": "https://mdt.co" + }, + { + "address": "41a8bb7680d85f9821b3d82505edc4663f6fbd8fde", + "voteCount": 1626, + "url": "http://TronGr25.com", + "totalProduced": 18571, + "totalMissed": 11, + "latestBlockNum": 1542791, + "latestSlotNum": 511509599 + }, + { + "address": "41a9b6a087c7f622548e338884f1a4c69972d691ab", + "voteCount": 6690, + "url": "https://www.troncanada.com/" + }, + { + "address": "41aa97642e4137cf828a971de448756958b844d72f", + "voteCount": 2830146, + "url": "https://github.com/trondex/", + "totalProduced": 25313, + "latestBlockNum": 1154111, + "latestSlotNum": 511120783 + }, + { + "address": "41ad85b8b51c9651f911da795e4d481db419c00c6b", + "voteCount": 497, + "url": "https://youtu.be/pWhw_NjVV68" + }, + { + "address": "41b096b3251f131f8a16f4b1beb7126d3ee071bc59", + "voteCount": 13457, + "url": "https://teamhelios.org/" + }, + { + "address": "41b25bd7ef93130ca2bf6eb05f1bdb9ee0f055c60a", + "voteCount": 80, + "url": "https://zhizhu.top/" + }, + { + "address": "41b3eec71481e8864f0fc1f601b836b74c40548287", + "voteCount": 293541325, + "url": "https://www.bittorrent.com/", + "totalProduced": 687487, + "totalMissed": 3836, + "latestBlockNum": 19479108, + "latestSlotNum": 529567199 + }, + { + "address": "41b438be21f9652e7f41b1d34a5a999f75ffeb2375", + "voteCount": 140, + "url": " " + }, + { + "address": "41b487cdc02de90f15ac89a68c82f44cbfe3d915ea", + "voteCount": 104879, + "url": "http://dapps.house", + "totalProduced": 250389, + "totalMissed": 2342, + "latestBlockNum": 8387532, + "latestSlotNum": 518435979 + }, + { + "address": "41b668d4991cd636b694989ebf3fa1a84613d7899e", + "voteCount": 5760439, + "url": "https://www.iggalaxy.com", + "totalProduced": 154409, + "totalMissed": 1550, + "latestBlockNum": 8416221, + "latestSlotNum": 518464799 + }, + { + "address": "41b6e726360eccfbeeb3bd52ae89aff8aeb2b23e14", + "voteCount": 1013, + "url": "https://tronswap.io" + }, + { + "address": "41b6eed928f86c2b80a85b83572a87311e7da7682c", + "voteCount": 206, + "url": "https://a4oo.ml" + }, + { + "address": "41b813e99b6a9fc38fb279d51a0d217fccece3280a", + "voteCount": 1567, + "url": "https://antpool.com" + }, + { + "address": "41ba7cc2711b5b3dcdedfd5ae493197d5bae597202", + "voteCount": 136738, + "url": "xreglobal.com" + }, + { + "address": "41bac7378c4265ad2739772337682183b8864f517a", + "voteCount": 295548591, + "url": "http://trx.market", + "totalProduced": 662356, + "totalMissed": 4092, + "latestBlockNum": 19700694, + "latestSlotNum": 529788867, + "isJobs": true + }, + { + "address": "41bd0e945de2c2397b24aafd0ab02422705f6dbc87", + "voteCount": 70946, + "url": "https://www.tronvietnam.org" + }, + { + "address": "41bd2fee2df4a2ba73f29d58b777c4c1113b74e5db", + "voteCount": 200, + "url": "https://www.teamx.com", + "totalProduced": 17850, + "totalMissed": 2, + "latestBlockNum": 3966296, + "latestSlotNum": 513950399 + }, + { + "address": "41bd58a790f43b052cd39418d2ffaefb316b846578", + "voteCount": 220791, + "url": "https://bankroll.network" + }, + { + "address": "41bfd6af35f4cbf8846b8ecd5d8d24a444d47e4aaf", + "voteCount": 984, + "url": "www.tbd.com" + }, + { + "address": "41c299c307d6dc655520f7e77438c57a002d0c3810", + "voteCount": 31, + "url": "Can" + }, + { + "address": "41c2de79fc11be35c35e5148bd2e45d0633f641ac8", + "voteCount": 2527121420, + "url": "https://www.neoply.com", + "totalProduced": 46832, + "totalMissed": 44, + "latestBlockNum": 19700697, + "latestSlotNum": 529788870, + "isJobs": true + }, + { + "address": "41c4bc4d7f64df4fd3670ce38e1a60080a50da85cf", + "voteCount": 72431, + "url": "http://raybo.com", + "totalProduced": 267142, + "totalMissed": 2326, + "latestBlockNum": 8523378, + "latestSlotNum": 518572799 + }, + { + "address": "41c56268480d3d9f8943eccd9a63caf19dd6fe4950", + "voteCount": 24871, + "url": "https://global.bittrex.com/" + }, + { + "address": "41c57a3e8c229b611fc81ba9adadd758ee47e58457", + "voteCount": 974, + "url": "http://tronbitcoin.io" + }, + { + "address": "41c6a0f6bdc5380d47d4d96a9ae5d283f9b520f8f3", + "voteCount": 32, + "url": "https://gsc.social" + }, + { + "address": "41c6ab8f6fa5717f49b5c19c5b527d34c885d507b3", + "voteCount": 3322, + "url": "https://dexexchange.us" + }, + { + "address": "41c8f401931724be02deed70cb7e8349a1a13af896", + "voteCount": 22531, + "url": "https://huxlium.org" + }, + { + "address": "41c912b348e87b518aacc270642e115b5cda59e409", + "voteCount": 10301, + "url": "http://StakeWithMe.io" + }, + { + "address": "41cc49d79ad451bcf4b35f785d84d169cda2913626", + "voteCount": 6021, + "url": "https://www.hashfin.com" + }, + { + "address": "41ced3494c81de8d5ff4da950c7137120a2bbf8e1e", + "voteCount": 6821, + "url": "https://trip4web.com" + }, + { + "address": "41d1dbde8b8f71b48655bec4f6bb532a0142b88bc0", + "voteCount": 5232636, + "url": "Tronstronics", + "totalProduced": 195873, + "totalMissed": 1952, + "latestBlockNum": 5971325, + "latestSlotNum": 516002399 + }, + { + "address": "41d25855804e4e65de904faf3ac74b0bdfc53fac76", + "voteCount": 691735170, + "url": "https://www.bitguild.com", + "totalProduced": 637652, + "totalMissed": 2606, + "latestBlockNum": 19700699, + "latestSlotNum": 529788872, + "isJobs": true + }, + { + "address": "41d32b3fa8ca0b4896257fdf1821ac8d116da84c45", + "voteCount": 3050, + "url": "http://TronGr2.com", + "totalProduced": 53764, + "totalMissed": 2, + "latestBlockNum": 1549967, + "latestSlotNum": 511516777 + }, + { + "address": "41d3b1e86db62d5a870d605ae39fb1ad7ee2ddca12", + "voteCount": 2017932, + "url": "HTTPS://AOCOIN.IO" + }, + { + "address": "41d492cf18007c62026f66742446d19368773fb8bc", + "voteCount": 206, + "url": "https://dootron.com/en/home" + }, + { + "address": "41d49bf5202b3dba65d46a5be73396b6b66d3555aa", + "voteCount": 2280286, + "url": "https://www.cryptogirls.ro/", + "totalProduced": 127145, + "totalMissed": 305, + "latestBlockNum": 4052661, + "latestSlotNum": 514036796 + }, + { + "address": "41d51fb9ae063610ddd8f04ecedb2a36f97fbb9a53", + "voteCount": 1015, + "url": "https://www.tronbet.io", + "totalProduced": 800, + "latestBlockNum": 17306496, + "latestSlotNum": 527392798 + }, + { + "address": "41d599cb8c1b609722e81741667ba3c8fb441fba41", + "voteCount": 120683597, + "url": "www.tronspirit.com", + "totalProduced": 214599, + "totalMissed": 4863, + "latestBlockNum": 17284888, + "latestSlotNum": 527371181 + }, + { + "address": "41d70365508e5a6fe846ad433af9302779fd5fdb1b", + "voteCount": 214157644, + "url": "http://krypto-knight.us/", + "totalProduced": 484381, + "totalMissed": 1288, + "latestBlockNum": 18550761, + "latestSlotNum": 528638395 + }, + { + "address": "41da5cf6279279a93572362b9edc7cdd86644b6214", + "voteCount": 1377, + "url": "https://coinhe.io" + }, + { + "address": "41dca1955f9edbfb7b25a3fe2998793a4b22746eb9", + "voteCount": 110011856, + "url": "https://www.tronace.com", + "totalProduced": 800, + "latestBlockNum": 17306495, + "latestSlotNum": 527392797 + }, + { + "address": "41de4c45a96857dc02fe1b9ba8d534dabc46245164", + "voteCount": 1558561, + "url": "https://www.millioncoinx.com/pl" + }, + { + "address": "41de9c3c2276abe2da70a7cdb34a205ecf7750d063", + "voteCount": 4010755, + "url": "https://www.tron-family.de" + }, + { + "address": "41df3bd4e0463534cb7f1f3ffc2ec14ac4693dc3b2", + "voteCount": 702, + "url": "http://TronGr3.com", + "totalProduced": 25247, + "latestBlockNum": 681353, + "latestSlotNum": 510645598 + }, + { + "address": "41e0a6cd1f1465a48195d93980b33e2658706203f6", + "voteCount": 346, + "url": " " + }, + { + "address": "41e27744d39af1e582cba7d80d65f413b5a3e80a70", + "voteCount": 1697784, + "url": "https://www.whaleex.com" + }, + { + "address": "41e2d3e56c42a2d304167b8abf5394ac2552f7f007", + "voteCount": 5002, + "url": "http://www.nodecap.com/" + }, + { + "address": "41e3b821e76830fef394a570c57c3c8aa2c1079348", + "voteCount": 4324, + "url": "https://tronvote.club" + }, + { + "address": "41e40de6895c142ade8b86194063bcdbaa6c9360b6", + "voteCount": 2452, + "url": "http://TronGr9.com", + "totalProduced": 47904, + "latestBlockNum": 1362829, + "latestSlotNum": 511329585 + }, + { + "address": "41e425fe49e76e7573b7aa746ac92fbf795b6b660e", + "voteCount": 5561, + "url": "http://bt.co" + }, + { + "address": "41e60b9bdd083676b2d58d179764edbe773e7f7fe6", + "voteCount": 5495, + "url": "https://www.troninvestgroup.org" + }, + { + "address": "41e72d833e0c46837c0802864acc5f119a0a904d05", + "voteCount": 8758, + "url": "http://TronGr18.com", + "totalProduced": 34565, + "latestBlockNum": 1492396, + "latestSlotNum": 511459189 + }, + { + "address": "41e7a7be105be761a13d3c821c1b02d0283e64669b", + "voteCount": 218503, + "url": "https://www.musiccasper.com/" + }, + { + "address": "41e85b204342401ab30a4e84f9b2356e05fb2c017f", + "voteCount": 659, + "url": "http://www.troncenter.com" + }, + { + "address": "41eb8d54ea7886df726114ac5089f253c13902c039", + "voteCount": 500, + "url": "https://t.me/TronParty" + }, + { + "address": "41ebf50b9054cd1c9f05cba54a9c335140cab81ca5", + "voteCount": 27507, + "url": "https://pyro.network" + }, + { + "address": "41ee98edeedd68ddce222f5f6ccfd07cea8735282f", + "voteCount": 247, + "url": "www" + }, + { + "address": "41ef5c9152d74a044cc0cd9156b1335345eea8aa25", + "voteCount": 136567, + "url": "https://TRON-Want" + }, + { + "address": "41f439093df1758a8b6b4b1279a702ef9939fef3ee", + "voteCount": 652, + "url": "http://www.dagbvi.com" + }, + { + "address": "41f5c3ccb9d2d776e20e892188d983dbcc590d3408", + "voteCount": 5012, + "url": "http://newgenesiscap.com/" + }, + { + "address": "41f6862099bff15eade076c3a8f1b5abd7712b46d4", + "voteCount": 1392, + "url": "http://www.tronfans.info", + "totalProduced": 5328, + "latestBlockNum": 2480734, + "latestSlotNum": 512452775 + }, + { + "address": "41f6af07517ab62b3af95017b440efb3e8454376b4", + "voteCount": 132843, + "url": "https://www.tronlabs.ro" + }, + { + "address": "41f70386347e689e6308e4172ed7319c49c0f66e0b", + "voteCount": 39457396, + "url": "http://tronone.com", + "totalProduced": 518353, + "totalMissed": 5124, + "latestBlockNum": 15149942, + "latestSlotNum": 525232781 + }, + { + "address": "41f8c7acc4c08cf36ca08fc2a61b1f5a7c8dea7bec", + "voteCount": 10, + "url": "http://TronGr19.com", + "totalProduced": 26567, + "latestBlockNum": 1621715, + "latestSlotNum": 511588789 + }, + { + "address": "41f90484ea93e94f2b92479d3d8b8dbadda6ddef3e", + "voteCount": 177799, + "url": "https://reyna.exchange/" + }, + { + "address": "41faec1ff18daaec28f080c54ba9bf8168c2cfadf8", + "voteCount": 46887, + "url": "https://www.gm-informatics.com" + }, + { + "address": "41fc45da0e51966bd1af2cb1e0f66633f160603a8b", + "voteCount": 3198, + "url": "http://www.etherpoker.cc", + "totalProduced": 69878, + "totalMissed": 249, + "latestBlockNum": 3548904, + "latestSlotNum": 513532790 + }, + { + "address": "41fcbc93454e116c2213f794d931c03b0943df2633", + "voteCount": 2103780, + "url": "https://metronix.imba-exchange.co" + }, + { + "address": "41fcf485751e99f5da9501b31733a2ae0c5c657ce2", + "voteCount": 667, + "url": "http://bit.ly/libertytron" + }, + { + "address": "41fe069c89ef4d59e7566ca7d794797a45feeb7a89", + "voteCount": 46979, + "url": "https://t.me/tron_my" + }, + { + "address": "41fe8d87ba51f89b6e29948dc86b69600d253632ec", + "voteCount": 205, + "url": "https://cryptotalkers.com" + }, + { + "address": "41ffd564656556a8b6b79311a932e3d216f4fc030b", + "voteCount": 125, + "url": "http://TronGr15.com", + "totalProduced": 25516, + "latestBlockNum": 1549971, + "latestSlotNum": 511516781 + } + ] +} diff --git a/mock/ext-api-data/unstoppabledomains_api_v1__dpantani.crypto.json b/mock/ext-api-data/unstoppabledomains_api_v1__dpantani.crypto.json new file mode 100644 index 000000000..3b6d9cb0f --- /dev/null +++ b/mock/ext-api-data/unstoppabledomains_api_v1__dpantani.crypto.json @@ -0,0 +1,23 @@ +{ + "addresses": { + "BCH": "qzpjlfnzudeu83krv0yk0r2kys67qptj6ys6eg6dms", + "BNB": "bnb1h4vyuuytu4rm86ust29wwlevt95du52383cctm", + "BTC": "bc1qd7eystu9xl53hkyxm4kyg7h5yk4p436sqx6f27", + "ETH": "0x5574Cd97432cEd0D7Caf58ac3c4fEDB2061C98fB", + "LTC": "ltc1qz6nd472gx5gl3urfeldkrhg3h83c8tp2m7m6sd", + "XRP": "rUvXBttEXhdwaKjEM2MxbtswHU6AMhUTgJ", + "ZIL": "zil1vdntvlk47j9kh9a85klqcd9rvgze06ruhmna64", + "DOGE": "DP9VmQyDMyB1TWwgXkyRpBa7rTfPYgMvjy" + }, + "whois": {}, + "ipfs": { + "html": "QmUG2riiUkALEGB3AzgsJtN5KbgFcVb3p8qvc96gcsfzHo", + "redirect_domain": "https://abbfe6z95qov3d40hf6j30g7auo7afhp.mypinata.cloud/ipfs/QmUG2riiUkALEGB3AzgsJtN5KbgFcVb3p8qvc96gcsfzHo" + }, + "gundb": {}, + "meta": { + "owner": "0x5574cd97432ced0d7caf58ac3c4fedb2061c98fb", + "type": "CNS", + "ttl": 0 + } +} \ No newline at end of file diff --git a/mock/ext-api-data/unstoppabledomains_api_v1__dpantani.zil.json b/mock/ext-api-data/unstoppabledomains_api_v1__dpantani.zil.json new file mode 100644 index 000000000..d26241439 --- /dev/null +++ b/mock/ext-api-data/unstoppabledomains_api_v1__dpantani.zil.json @@ -0,0 +1,23 @@ +{ + "addresses": { + "BCH": "qzpjlfnzudeu83krv0yk0r2kys67qptj6ys6eg6dms", + "BNB": "bnb1h4vyuuytu4rm86ust29wwlevt95du52383cctm", + "BTC": "bc1qd7eystu9xl53hkyxm4kyg7h5yk4p436sqx6f27", + "ETH": "0x5574Cd97432cEd0D7Caf58ac3c4fEDB2061C98fB", + "LTC": "ltc1qz6nd472gx5gl3urfeldkrhg3h83c8tp2m7m6sd", + "XRP": "rUvXBttEXhdwaKjEM2MxbtswHU6AMhUTgJ", + "ZIL": "zil1vdntvlk47j9kh9a85klqcd9rvgze06ruhmna64", + "DOGE": "DP9VmQyDMyB1TWwgXkyRpBa7rTfPYgMvjy" + }, + "whois": {}, + "ipfs": { + "html": "QmUG2riiUkALEGB3AzgsJtN5KbgFcVb3p8qvc96gcsfzHo", + "redirect_domain": "https://abbfe6z95qov3d40hf6j30g7auo7afhp.mypinata.cloud/ipfs/QmUG2riiUkALEGB3AzgsJtN5KbgFcVb3p8qvc96gcsfzHo" + }, + "gundb": {}, + "meta": { + "owner": "0xe4da405976f315ab91ff9a43a51972cc94739aa8", + "type": "ZNS", + "ttl": 0 + } +} \ No newline at end of file diff --git a/mock/ext-api-data/vechain-api_blocks_best.json b/mock/ext-api-data/vechain-api_blocks_best.json new file mode 100644 index 000000000..916fe6589 --- /dev/null +++ b/mock/ext-api-data/vechain-api_blocks_best.json @@ -0,0 +1,20 @@ +{ + "number": 5887932, + "id": "0x0059d7bc873407f863b77f731f8e3c9335dc16aae1c53c0f18e780773d42a7f0", + "size": 542, + "parentID": "0x0059d7bb2f7ba5a8482d0b9937788f212f9b6b1de08818466985f943dbc8b4c6", + "timestamp": 1589366680, + "gasLimit": 38953771, + "beneficiary": "0xeb0c565f69557481c6c7fa347cae273128a0996e", + "gasUsed": 66003, + "totalScore": 566756408, + "txsRoot": "0xc4b8844cdc5dcd6b48627205ef30d7e09041d0e7ba013057690778e33e881127", + "txsFeatures": 1, + "stateRoot": "0xf572f33e7d55a193c7ef31f6cda0a0d51b339085e2296b6e05a81b593aa66e6e", + "receiptsRoot": "0x65bf45677f275349a9a9eeebdfdcb1ffd8760c98cd273fb909453b444265d081", + "signer": "0x8eaefdf7d25c001e7e59363c33d7f5ad47970086", + "isTrunk": true, + "transactions": [ + "0x36720eaff4ac46835d3300bab1c2a6e9f45907c3151ff36c247dd7c287ba8125" + ] +} \ No newline at end of file diff --git a/mock/ext-api-data/vechain-api_logs_transfer.json b/mock/ext-api-data/vechain-api_logs_transfer.json new file mode 100644 index 000000000..cdd48e25e --- /dev/null +++ b/mock/ext-api-data/vechain-api_logs_transfer.json @@ -0,0 +1,197 @@ +[ + { + "sender": "0xb5e883349e68ab59307d1604555ac890fac47128", + "recipient": "0x2c7a8d5cce0d5e6a8a31233b7dc3dae9aae4b405", + "amount": "0x12b1815d00738000", + "meta": { + "blockID": "0x004313a4bd4286e821b684cc1749deb3df12fa2a8114435fbd35baa155e82016", + "blockNumber": 4395940, + "blockTimestamp": 1574410670, + "txID": "0x702edd54bd4e13e0012798cc8b2dfa52f7150173945103d203fae26b8e3d2ed7", + "txOrigin": "0xb5e883349e68ab59307d1604555ac890fac47128", + "clauseIndex": 0 + } + }, + { + "sender": "0xb5e883349e68ab59307d1604555ac890fac47128", + "recipient": "0x00bae5ed35736e4ef17af1be0c6f50e0fb73d685", + "amount": "0x38f6ea18e810b6f00", + "meta": { + "blockID": "0x0042249bee56223e0ed7a9c7fcfffe8e61b9fd95d29d24843c558ff2c46ea094", + "blockNumber": 4334747, + "blockTimestamp": 1573795570, + "txID": "0x004aa0448e458105b098aea2a764a1d54ab95451bee488869f417b351857c3c5", + "txOrigin": "0xb5e883349e68ab59307d1604555ac890fac47128", + "clauseIndex": 0 + } + }, + { + "sender": "0xb5e883349e68ab59307d1604555ac890fac47128", + "recipient": "0xb5e883349e68ab59307d1604555ac890fac47128", + "amount": "0x4563918244f40000", + "meta": { + "blockID": "0x003f8fcf4019eee33a337104e1ccc58cfdcc436fdff009d5fdc3c4a303ff0de2", + "blockNumber": 4165583, + "blockTimestamp": 1572095480, + "txID": "0x12914b9ea2f0b141b02666bd4b526e62b6a95c061c01bf8ed955e38ec3024d05", + "txOrigin": "0xb5e883349e68ab59307d1604555ac890fac47128", + "clauseIndex": 0 + } + }, + { + "sender": "0xb5e883349e68ab59307d1604555ac890fac47128", + "recipient": "0xb5e883349e68ab59307d1604555ac890fac47128", + "amount": "0xde0b6b3a7640000", + "meta": { + "blockID": "0x003f7652b21c1c9bf22507a37277d6cfa1db4e319dd3a689c94a0d67ef2fbffa", + "blockNumber": 4159058, + "blockTimestamp": 1572030170, + "txID": "0x7d700869cbefe144639518db2b9ac5a695f62c62cea402d31dc6648d3ca27f00", + "txOrigin": "0xb5e883349e68ab59307d1604555ac890fac47128", + "clauseIndex": 0 + } + }, + { + "sender": "0xb5e883349e68ab59307d1604555ac890fac47128", + "recipient": "0xb5e883349e68ab59307d1604555ac890fac47128", + "amount": "0xde0b6b3a7640000", + "meta": { + "blockID": "0x003f67aa05143d785f7ef7fdd7dd4def76e228c240cd3dcd980e6865f7e9add4", + "blockNumber": 4155306, + "blockTimestamp": 1571992620, + "txID": "0x9f14450a964396f24cacf144c6c674c81a034448e9de3c2a05c1e95480e58fc3", + "txOrigin": "0xb5e883349e68ab59307d1604555ac890fac47128", + "clauseIndex": 0 + } + }, + { + "sender": "0xb5e883349e68ab59307d1604555ac890fac47128", + "recipient": "0xb5e883349e68ab59307d1604555ac890fac47128", + "amount": "0xde0b6b3a7640000", + "meta": { + "blockID": "0x003f2fe2ff00f12a5282d1dda4a5f1c968fd1c47c43c88fe3db50cfa789b98fb", + "blockNumber": 4141026, + "blockTimestamp": 1571848760, + "txID": "0x19c264236b5863300d93175997acd7d6a06856b3bc2fea083c1e14cf809f726f", + "txOrigin": "0xb5e883349e68ab59307d1604555ac890fac47128", + "clauseIndex": 0 + } + }, + { + "sender": "0xb5e883349e68ab59307d1604555ac890fac47128", + "recipient": "0xb5e883349e68ab59307d1604555ac890fac47128", + "amount": "0x1322116c8720b18000", + "meta": { + "blockID": "0x003f04e8527d796d578a6b5688a6762c564f31fdaa6adc0f0492b783a269c2d1", + "blockNumber": 4130024, + "blockTimestamp": 1571738290, + "txID": "0x3d3ee661e3ac9e27540a9e292882ad56b52c1a4e5a7bc1d604e66f73e6d425b9", + "txOrigin": "0xb5e883349e68ab59307d1604555ac890fac47128", + "clauseIndex": 0 + } + }, + { + "sender": "0xb5e883349e68ab59307d1604555ac890fac47128", + "recipient": "0x8c7d176caa85c716a895026f32df2fd34a5f9146", + "amount": "0xde0b6b3a7640000", + "meta": { + "blockID": "0x003f04e55bba0d119d3d3eb6de02d0e30f79a4a00390c574023f45ecf4adf08e", + "blockNumber": 4130021, + "blockTimestamp": 1571738260, + "txID": "0x561108d7be73258eb4f052dc4cb00326b007da003a199a7017d0e5b0b94f1e24", + "txOrigin": "0xb5e883349e68ab59307d1604555ac890fac47128", + "clauseIndex": 0 + } + }, + { + "sender": "0xb5e883349e68ab59307d1604555ac890fac47128", + "recipient": "0xb5e883349e68ab59307d1604555ac890fac47128", + "amount": "0xde0b6b3a7640000", + "meta": { + "blockID": "0x003f04b84f961b775b344385459ce6be8af88d20a7e89ae05002d3a0372194d3", + "blockNumber": 4129976, + "blockTimestamp": 1571737810, + "txID": "0x1c647668741691fd82724cf50798ced8e0c980f88b0c1546e3435ad512c8e7e1", + "txOrigin": "0xb5e883349e68ab59307d1604555ac890fac47128", + "clauseIndex": 0 + } + }, + { + "sender": "0xb5e883349e68ab59307d1604555ac890fac47128", + "recipient": "0xb5e883349e68ab59307d1604555ac890fac47128", + "amount": "0xde0b6b3a7640000", + "meta": { + "blockID": "0x003f047f4430df38a6a07166ea0a389867f6f49c10f745826cbfdbb37820fd6f", + "blockNumber": 4129919, + "blockTimestamp": 1571737220, + "txID": "0xc61f713a23462c9eb44b1695d855e21d21815340b4861ffaefa0b78a2cc463bf", + "txOrigin": "0xb5e883349e68ab59307d1604555ac890fac47128", + "clauseIndex": 0 + } + }, + { + "sender": "0xb5e883349e68ab59307d1604555ac890fac47128", + "recipient": "0xb5e883349e68ab59307d1604555ac890fac47128", + "amount": "0xde0b6b3a7640000", + "meta": { + "blockID": "0x003f044fc421c9d57bdddf31f9122c1306a5417690cef59c0b589c522ae5d2b7", + "blockNumber": 4129871, + "blockTimestamp": 1571736740, + "txID": "0xbf666ca63607088267c3b769545585066bfc9239700e635ff9b60345ebc324cd", + "txOrigin": "0xb5e883349e68ab59307d1604555ac890fac47128", + "clauseIndex": 0 + } + }, + { + "sender": "0xb5e883349e68ab59307d1604555ac890fac47128", + "recipient": "0xb5e883349e68ab59307d1604555ac890fac47128", + "amount": "0xde0b6b3a7640000", + "meta": { + "blockID": "0x003ef3d9151b500600c0a545cdcf31a322a3534123439fc42883b6d5145fd12e", + "blockNumber": 4125657, + "blockTimestamp": 1571694230, + "txID": "0xbc054c6e31fde87be89c863059f591247ad7fc72585d23c2e738a42d3c7ac1c6", + "txOrigin": "0xb5e883349e68ab59307d1604555ac890fac47128", + "clauseIndex": 0 + } + }, + { + "sender": "0xb5e883349e68ab59307d1604555ac890fac47128", + "recipient": "0xb5e883349e68ab59307d1604555ac890fac47128", + "amount": "0xde0b6b3a7640000", + "meta": { + "blockID": "0x003ef3c8db0338c63459e85117da9e4085dd6eb9a2d3e075c07803611baeecfd", + "blockNumber": 4125640, + "blockTimestamp": 1571694060, + "txID": "0x645d86bac876a982dd273332b7ae4d6e64d1a96998ec9b663e5e3d0b40f6bb45", + "txOrigin": "0xb5e883349e68ab59307d1604555ac890fac47128", + "clauseIndex": 0 + } + }, + { + "sender": "0xb5e883349e68ab59307d1604555ac890fac47128", + "recipient": "0xb5e883349e68ab59307d1604555ac890fac47128", + "amount": "0xde0b6b3a7640000", + "meta": { + "blockID": "0x003ef3953aecad21806c07bed0b225a070cffe5e6aa63cee293c21ecf471d7aa", + "blockNumber": 4125589, + "blockTimestamp": 1571693550, + "txID": "0xeb65e55d6fd6c6b40b663b8f06df8865a7ee3cfff6fa4a0a8a63eb35f565b5c8", + "txOrigin": "0xb5e883349e68ab59307d1604555ac890fac47128", + "clauseIndex": 0 + } + }, + { + "sender": "0xb5e883349e68ab59307d1604555ac890fac47128", + "recipient": "0xb5e883349e68ab59307d1604555ac890fac47128", + "amount": "0xde0b6b3a7640000", + "meta": { + "blockID": "0x003ef3473d0ff2ab212fe729a57e27dbd28dfcb59dc24421d7815bba971a32fc", + "blockNumber": 4125511, + "blockTimestamp": 1571692770, + "txID": "0x80c404f93e5a915398d43ae90ed7c000f2b8ac37dcd2234d3ead3bfdaa726d92", + "txOrigin": "0xb5e883349e68ab59307d1604555ac890fac47128", + "clauseIndex": 0 + } + } +] \ No newline at end of file diff --git a/mock/ext-api-data/vechain-api_logs_transfer.request_json b/mock/ext-api-data/vechain-api_logs_transfer.request_json new file mode 100644 index 000000000..4d5973b67 --- /dev/null +++ b/mock/ext-api-data/vechain-api_logs_transfer.request_json @@ -0,0 +1,20 @@ +{ + "options": { + "offset": 0, + "limit": 15 + }, + "criteriaSet": [ + { + "sender": "0xB5e883349e68aB59307d1604555AC890fAC47128" + }, + { + "recipient": "0xB5e883349e68aB59307d1604555AC890fAC47128" + } + ], + "range": { + "unit": "block", + "from": 0, + "to": 5466405 + }, + "order": "desc" +} \ No newline at end of file diff --git a/mock/ext-api-data/vechain-api_transactions_0x004aa0448e458105b098aea2a764a1d54ab95451bee488869f417b351857c3c5.json b/mock/ext-api-data/vechain-api_transactions_0x004aa0448e458105b098aea2a764a1d54ab95451bee488869f417b351857c3c5.json new file mode 100644 index 000000000..e58892998 --- /dev/null +++ b/mock/ext-api-data/vechain-api_transactions_0x004aa0448e458105b098aea2a764a1d54ab95451bee488869f417b351857c3c5.json @@ -0,0 +1,25 @@ +{ + "id": "0x004aa0448e458105b098aea2a764a1d54ab95451bee488869f417b351857c3c5", + "chainTag": 74, + "blockRef": "0x0042249a647f63e7", + "expiration": 720, + "clauses": [ + { + "to": "0x00bae5ed35736e4ef17af1be0c6f50e0fb73d685", + "value": "0x38f6ea18e810b6f00", + "data": "0x" + } + ], + "gasPriceCoef": 0, + "gas": 21000, + "origin": "0xb5e883349e68ab59307d1604555ac890fac47128", + "delegator": null, + "nonce": "0x6fa76caac4c18bd", + "dependsOn": null, + "size": 130, + "meta": { + "blockID": "0x0042249bee56223e0ed7a9c7fcfffe8e61b9fd95d29d24843c558ff2c46ea094", + "blockNumber": 4334747, + "blockTimestamp": 1573795570 + } +} \ No newline at end of file diff --git a/mock/ext-api-data/vechain-api_transactions_0x702edd54bd4e13e0012798cc8b2dfa52f7150173945103d203fae26b8e3d2ed7.json b/mock/ext-api-data/vechain-api_transactions_0x702edd54bd4e13e0012798cc8b2dfa52f7150173945103d203fae26b8e3d2ed7.json new file mode 100644 index 000000000..4e2823cf5 --- /dev/null +++ b/mock/ext-api-data/vechain-api_transactions_0x702edd54bd4e13e0012798cc8b2dfa52f7150173945103d203fae26b8e3d2ed7.json @@ -0,0 +1,25 @@ +{ + "id": "0x702edd54bd4e13e0012798cc8b2dfa52f7150173945103d203fae26b8e3d2ed7", + "chainTag": 74, + "blockRef": "0x004313a393a18efb", + "expiration": 720, + "clauses": [ + { + "to": "0x2c7a8d5cce0d5e6a8a31233b7dc3dae9aae4b405", + "value": "0x12b1815d00738000", + "data": "0x" + } + ], + "gasPriceCoef": 0, + "gas": 21000, + "origin": "0xb5e883349e68ab59307d1604555ac890fac47128", + "delegator": null, + "nonce": "0x8cff29df64a414f8", + "dependsOn": null, + "size": 129, + "meta": { + "blockID": "0x004313a4bd4286e821b684cc1749deb3df12fa2a8114435fbd35baa155e82016", + "blockNumber": 4395940, + "blockTimestamp": 1574410670 + } +} \ No newline at end of file diff --git a/mock/ext-api-data/viacoin-api_v2_address_VdMPvn7vUTSzbYjiMDs1jku9wAh1Ri2Y1A__details_txs.json b/mock/ext-api-data/viacoin-api_v2_address_VdMPvn7vUTSzbYjiMDs1jku9wAh1Ri2Y1A__details_txs.json new file mode 100644 index 000000000..08139f499 --- /dev/null +++ b/mock/ext-api-data/viacoin-api_v2_address_VdMPvn7vUTSzbYjiMDs1jku9wAh1Ri2Y1A__details_txs.json @@ -0,0 +1 @@ +{"page":1,"totalPages":160338,"itemsOnPage":10,"address":"VdMPvn7vUTSzbYjiMDs1jku9wAh1Ri2Y1A","balance":"151181530522","totalReceived":"18401865678328","totalSent":"18250684147806","unconfirmedBalance":"0","unconfirmedTxs":0,"txs":1603379,"transactions":[{"txid":"fb71dae00a0ef3044c8085077e0def3147e0fc24e3a7d5e9fe67867e54a1a1d5","version":1,"vin":[{"sequence":4294967295,"n":0,"coinbase":"03afa774045ec68b8f"}],"vout":[{"value":"976562","n":0,"hex":"76a91424cc424c1e5e977175d2b20012554d39024bd68f88ac","addresses":["VdMPvn7vUTSzbYjiMDs1jku9wAh1Ri2Y1A"]}],"blockHash":"2a9e6773dd0ace56fb7807423e4bf1615a96e246fba6f07ca3de06ca5fbb0c68","blockHeight":7645103,"confirmations":1,"blockTime":1590070159,"value":"976562","valueIn":"0","fees":"0","hex":"01000000010000000000000000000000000000000000000000000000000000000000000000ffffffff0903afa774045ec68b8fffffffff01b2e60e00000000001976a91424cc424c1e5e977175d2b20012554d39024bd68f88ac00000000"},{"txid":"95bdfa9064b2e3089897c22fd21cf8eeb05e07d1a21c70b88e3ccce02c6b35e9","version":1,"vin":[{"sequence":4294967295,"n":0,"coinbase":"03ada774045ec68b72"}],"vout":[{"value":"976562","n":0,"hex":"76a91424cc424c1e5e977175d2b20012554d39024bd68f88ac","addresses":["VdMPvn7vUTSzbYjiMDs1jku9wAh1Ri2Y1A"]}],"blockHash":"18c911c768a87370dcd1f4dd618893047fbe48a05f969cdc1b239754a4cc0ca3","blockHeight":7645101,"confirmations":3,"blockTime":1590070130,"value":"976562","valueIn":"0","fees":"0","hex":"01000000010000000000000000000000000000000000000000000000000000000000000000ffffffff0903ada774045ec68b72ffffffff01b2e60e00000000001976a91424cc424c1e5e977175d2b20012554d39024bd68f88ac00000000"},{"txid":"9941602545e489e1370df8025a9ed100571f5056d5b36b5e0b90ede817bdb3c6","version":1,"vin":[{"sequence":4294967295,"n":0,"coinbase":"03a6a774045ec68a7e"}],"vout":[{"value":"976562","n":0,"hex":"76a91424cc424c1e5e977175d2b20012554d39024bd68f88ac","addresses":["VdMPvn7vUTSzbYjiMDs1jku9wAh1Ri2Y1A"]},{"value":"0","n":1,"hex":"6a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf9","addresses":["OP_RETURN aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf9"]}],"blockHash":"c7b4ae0bcda9c6d70b1879eb761458a34a5411f6464f92e0fd6e09e45907db55","blockHeight":7645094,"confirmations":10,"blockTime":1590069886,"value":"976562","valueIn":"0","fees":"0","hex":"010000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff0903a6a774045ec68a7effffffff02b2e60e00000000001976a91424cc424c1e5e977175d2b20012554d39024bd68f88ac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000"},{"txid":"d0f20c3cdb80d0467318a4168f24f57ba9eb5b5c398a889bd836a779d253a370","version":1,"vin":[{"sequence":4294967295,"n":0,"coinbase":"039fa774045ec68938"}],"vout":[{"value":"976562","n":0,"hex":"76a91424cc424c1e5e977175d2b20012554d39024bd68f88ac","addresses":["VdMPvn7vUTSzbYjiMDs1jku9wAh1Ri2Y1A"]}],"blockHash":"bb55efe10eb7e6a54f96a4cba73be191f58add358de83a68760ecdfe0e727ce5","blockHeight":7645087,"confirmations":17,"blockTime":1590069560,"value":"976562","valueIn":"0","fees":"0","hex":"01000000010000000000000000000000000000000000000000000000000000000000000000ffffffff09039fa774045ec68938ffffffff01b2e60e00000000001976a91424cc424c1e5e977175d2b20012554d39024bd68f88ac00000000"},{"txid":"7ff3b66c68baf22efa6767abede6e07cc42dbe7854ad9550230239b6bd5f9baa","version":1,"vin":[{"sequence":4294967295,"n":0,"coinbase":"039ea774045ec68915"}],"vout":[{"value":"976562","n":0,"hex":"76a91424cc424c1e5e977175d2b20012554d39024bd68f88ac","addresses":["VdMPvn7vUTSzbYjiMDs1jku9wAh1Ri2Y1A"]}],"blockHash":"723a275a090400a275bba97d26ee5053b79e0cab4b9d4cae3d07d84a9148cb16","blockHeight":7645086,"confirmations":18,"blockTime":1590069525,"value":"976562","valueIn":"0","fees":"0","hex":"01000000010000000000000000000000000000000000000000000000000000000000000000ffffffff09039ea774045ec68915ffffffff01b2e60e00000000001976a91424cc424c1e5e977175d2b20012554d39024bd68f88ac00000000"},{"txid":"d77862a099db4d33207ff7b98a534f618a00d73855186e9b7039edc490c0d4c4","version":1,"vin":[{"sequence":4294967295,"n":0,"coinbase":"039da774045ec68900"}],"vout":[{"value":"976562","n":0,"hex":"76a91424cc424c1e5e977175d2b20012554d39024bd68f88ac","addresses":["VdMPvn7vUTSzbYjiMDs1jku9wAh1Ri2Y1A"]},{"value":"0","n":1,"hex":"6a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf9","addresses":["OP_RETURN aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf9"]}],"blockHash":"1cf47ce738f299f7f99dfb09f1a6a97095340f38957a4726777ebb213c4d2521","blockHeight":7645085,"confirmations":19,"blockTime":1590069504,"value":"976562","valueIn":"0","fees":"0","hex":"010000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff09039da774045ec68900ffffffff02b2e60e00000000001976a91424cc424c1e5e977175d2b20012554d39024bd68f88ac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000"},{"txid":"f7dbeeea3ab0c44642c7647e0a6da4723d27cc6b01f18df03efee8377461cd52","version":1,"vin":[{"sequence":4294967295,"n":0,"coinbase":"0398a774045ec6888f"}],"vout":[{"value":"976562","n":0,"hex":"76a91424cc424c1e5e977175d2b20012554d39024bd68f88ac","addresses":["VdMPvn7vUTSzbYjiMDs1jku9wAh1Ri2Y1A"]}],"blockHash":"6c1df3751861f94df019ad0f5c2cfe78de848a1140c99c99d9b51755873395e0","blockHeight":7645080,"confirmations":24,"blockTime":1590069391,"value":"976562","valueIn":"0","fees":"0","hex":"01000000010000000000000000000000000000000000000000000000000000000000000000ffffffff090398a774045ec6888fffffffff01b2e60e00000000001976a91424cc424c1e5e977175d2b20012554d39024bd68f88ac00000000"},{"txid":"d00072dd6416f65a55b7178aa951b486fad6f71423d4fa0b8872cd3795282b63","version":1,"vin":[{"sequence":4294967295,"n":0,"coinbase":"0394a774045ec68821"}],"vout":[{"value":"976562","n":0,"hex":"76a91424cc424c1e5e977175d2b20012554d39024bd68f88ac","addresses":["VdMPvn7vUTSzbYjiMDs1jku9wAh1Ri2Y1A"]},{"value":"0","n":1,"hex":"6a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf9","addresses":["OP_RETURN aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf9"]}],"blockHash":"8324bb579b7e429723a10711ddc5338354ce1640632c1097bebac952bf0e39b0","blockHeight":7645076,"confirmations":28,"blockTime":1590069281,"value":"976562","valueIn":"0","fees":"0","hex":"010000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff090394a774045ec68821ffffffff02b2e60e00000000001976a91424cc424c1e5e977175d2b20012554d39024bd68f88ac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000"},{"txid":"bd408661283a213ec48b5e46314b687161914795b841bb2d1c3ccc0fc0e91360","version":1,"vin":[{"sequence":4294967295,"n":0,"coinbase":"0391a774045ec68802"}],"vout":[{"value":"976562","n":0,"hex":"76a91424cc424c1e5e977175d2b20012554d39024bd68f88ac","addresses":["VdMPvn7vUTSzbYjiMDs1jku9wAh1Ri2Y1A"]}],"blockHash":"9146e301cda547092e2d563db4e0437caa327fffcbbe4b16fe23b7704fe85b7f","blockHeight":7645073,"confirmations":31,"blockTime":1590069250,"value":"976562","valueIn":"0","fees":"0","hex":"01000000010000000000000000000000000000000000000000000000000000000000000000ffffffff090391a774045ec68802ffffffff01b2e60e00000000001976a91424cc424c1e5e977175d2b20012554d39024bd68f88ac00000000"},{"txid":"8aefbd2b6c32a6d70cb905d1c6303e5940fe26b242d40da8c34173252b41648c","version":1,"vin":[{"sequence":4294967295,"n":0,"coinbase":"038ea774045ec687cf"}],"vout":[{"value":"976562","n":0,"hex":"76a91424cc424c1e5e977175d2b20012554d39024bd68f88ac","addresses":["VdMPvn7vUTSzbYjiMDs1jku9wAh1Ri2Y1A"]}],"blockHash":"4627ee53a7487b762627dc42efe57c9f2e700d445c53740958bae483014070bb","blockHeight":7645070,"confirmations":34,"blockTime":1590069199,"value":"976562","valueIn":"0","fees":"0","hex":"01000000010000000000000000000000000000000000000000000000000000000000000000ffffffff09038ea774045ec687cfffffffff01b2e60e00000000001976a91424cc424c1e5e977175d2b20012554d39024bd68f88ac00000000"}]} diff --git a/mock/ext-api-data/viacoin-api_v2_xpub_zpub6qVn6ubhK9tfepuABqy8wBXXn3qUZTbpqyNBqLyqakqTrZZD9rXZ3L5MZ945g8Mu7vmMSbC7vfLtLatTgxAnVJ8ECCtwmKqCo6TJm2ZsFJK__details_txs.json b/mock/ext-api-data/viacoin-api_v2_xpub_zpub6qVn6ubhK9tfepuABqy8wBXXn3qUZTbpqyNBqLyqakqTrZZD9rXZ3L5MZ945g8Mu7vmMSbC7vfLtLatTgxAnVJ8ECCtwmKqCo6TJm2ZsFJK__details_txs.json new file mode 100644 index 000000000..ea82e7a48 --- /dev/null +++ b/mock/ext-api-data/viacoin-api_v2_xpub_zpub6qVn6ubhK9tfepuABqy8wBXXn3qUZTbpqyNBqLyqakqTrZZD9rXZ3L5MZ945g8Mu7vmMSbC7vfLtLatTgxAnVJ8ECCtwmKqCo6TJm2ZsFJK__details_txs.json @@ -0,0 +1,1814 @@ +{ + "page": 1, + "totalPages": 1, + "itemsOnPage": 1000, + "address": "zpub6qVn6ubhK9tfepuABqy8wBXXn3qUZTbpqyNBqLyqakqTrZZD9rXZ3L5MZ945g8Mu7vmMSbC7vfLtLatTgxAnVJ8ECCtwmKqCo6TJm2ZsFJK", + "balance": "740523040", + "totalReceived": "57315523588", + "totalSent": "56575000548", + "unconfirmedBalance": "0", + "unconfirmedTxs": 0, + "txs": 40, + "transactions": [ + { + "txid": "dc45eec5b0660eac0a5e291839aef5f5c5d7ff5ac71d056afbb17780c9da53e8", + "version": 1, + "vin": [ + { + "txid": "bdff404da14940abd84f7cb741fe8f77ad5de5aefbb74254caee683fe2a9b540", + "sequence": 4294967293, + "n": 0, + "addresses": [ + "via1qxdul6szs3mppq8s3cdge5vtpthnw0dnn06m5qp" + ], + "value": "100000000" + } + ], + "vout": [ + { + "value": "1000000", + "n": 0, + "hex": "00147689515a58655155c0b8cc73f94ae82b32045cb5", + "addresses": [ + "via1qw6y4zkjcv4g4ts9ce3eljjhg9veqgh94akn7j4" + ] + }, + { + "value": "98774000", + "n": 1, + "hex": "00143379fd40508ec2101e11c3519a31615de6e7b673", + "addresses": [ + "via1qxdul6szs3mppq8s3cdge5vtpthnw0dnn06m5qp" + ] + } + ], + "blockHash": "3ce7592c15b2987085e69e085888249e01819f306a84ced9180a0f7c53a65156", + "blockHeight": 7590296, + "confirmations": 25553, + "blockTime": 1588752167, + "value": "99774000", + "valueIn": "100000000", + "fees": "226000", + "hex": "0100000000010140b5a9e23f68eeca5442b7fbaee55dad778ffe41b77c4fd8ab4049a14d40ffbd0000000000fdffffff0240420f00000000001600147689515a58655155c0b8cc73f94ae82b32045cb5f02be305000000001600143379fd40508ec2101e11c3519a31615de6e7b67302483045022100e90168f0b832bb59cac87582e82c31a4cef5ead0f8075f1e65e880538c4f156002201628b227519f50c4346d6e9623a19ea9bafe86f4839f7ecc8784dbd7547afd82012102b5e09e1dbb76a0eeebea67bf80069ce41c26c81d0f06d1dd42e712ebf55de4bc00000000" + }, + { + "txid": "bdff404da14940abd84f7cb741fe8f77ad5de5aefbb74254caee683fe2a9b540", + "version": 1, + "vin": [ + { + "txid": "32790f42de714507b6a1e6001a4a334600ac316937a98489c19821bba0d5c74f", + "vout": 1, + "n": 0, + "addresses": [ + "via1qxdul6szs3mppq8s3cdge5vtpthnw0dnn06m5qp" + ], + "value": "741862718" + } + ], + "vout": [ + { + "value": "100000000", + "n": 0, + "spent": true, + "hex": "00143379fd40508ec2101e11c3519a31615de6e7b673", + "addresses": [ + "via1qxdul6szs3mppq8s3cdge5vtpthnw0dnn06m5qp" + ] + }, + { + "value": "641749040", + "n": 1, + "hex": "00143379fd40508ec2101e11c3519a31615de6e7b673", + "addresses": [ + "via1qxdul6szs3mppq8s3cdge5vtpthnw0dnn06m5qp" + ] + } + ], + "blockHash": "0853179f0baef807426b977e4a9ae260ba1a3a3726dbb7513ff4150991f5827a", + "blockHeight": 7305935, + "confirmations": 309914, + "blockTime": 1581914336, + "value": "741749040", + "valueIn": "741862718", + "fees": "113678", + "hex": "010000000001014fc7d5a0bb2198c18984a9376931ac0046334a1a00e6a1b6074571de420f79320100000000000000000200e1f505000000001600143379fd40508ec2101e11c3519a31615de6e7b67330504026000000001600143379fd40508ec2101e11c3519a31615de6e7b67302473044022049b1d030bd9ec88ec343a52971d354b470d1357413675e985161bf2d5f8ca8ba02205d393b4d5232ae983faba4237e0c8feace5483493bf4da35313ce62459c87c66012102b5e09e1dbb76a0eeebea67bf80069ce41c26c81d0f06d1dd42e712ebf55de4bc00000000" + }, + { + "txid": "32790f42de714507b6a1e6001a4a334600ac316937a98489c19821bba0d5c74f", + "version": 1, + "vin": [ + { + "txid": "442f51ea9ee10919f0af8f8d586926f700a5f0b04712e97e6565a19a6c5b739a", + "n": 0, + "addresses": [ + "via1qxdul6szs3mppq8s3cdge5vtpthnw0dnn06m5qp" + ], + "value": "7741976396" + } + ], + "vout": [ + { + "value": "7000000000", + "n": 0, + "spent": true, + "hex": "76a9148c9ce0d33ef042c65356ed5b5d278d846e21c16a88ac", + "addresses": [ + "VnpKSf3qe4sJXNbj7PmMyiHZqpdzWVX84X" + ] + }, + { + "value": "741862718", + "n": 1, + "spent": true, + "hex": "00143379fd40508ec2101e11c3519a31615de6e7b673", + "addresses": [ + "via1qxdul6szs3mppq8s3cdge5vtpthnw0dnn06m5qp" + ] + } + ], + "blockHash": "325170b9481c815eee11755417ef4501551bf8a17c8ab318ade52709ed0de27d", + "blockHeight": 7273671, + "confirmations": 342178, + "blockTime": 1581138785, + "value": "7741862718", + "valueIn": "7741976396", + "fees": "113678", + "hex": "010000000001019a735b6c9aa165657ee91247b0f0a500f72669588d8faff01909e19eea512f440000000000000000000200863ba1010000001976a9148c9ce0d33ef042c65356ed5b5d278d846e21c16a88ac3eed372c000000001600143379fd40508ec2101e11c3519a31615de6e7b67302483045022100ba65ef64f992996ed7b1aa12c90ad9b71cfe12be556b454ceacaa7efec3ae42802203abe6719dae22105a9827f3a4d0836c67649d20539ce8cb1945e7a1801a58907012102b5e09e1dbb76a0eeebea67bf80069ce41c26c81d0f06d1dd42e712ebf55de4bc00000000" + }, + { + "txid": "442f51ea9ee10919f0af8f8d586926f700a5f0b04712e97e6565a19a6c5b739a", + "version": 1, + "vin": [ + { + "txid": "1f73b6896a2266a4410bd8ca059feaed6c41d2b0b330d5d35609c702c35f18cf", + "n": 0, + "addresses": [ + "via1qjzfzfshvkkfvke52mvr7rmlexdynkcvsqzvu8l" + ], + "value": "100000" + }, + { + "txid": "6d5151cb8df2eb819c9ea008a07e2e889edae7c70f187a578bbfbc226394d1ac", + "n": 1, + "addresses": [ + "via1qnjwjefwqm49uavy0w2n50gfwq722hn4ua6ka7h" + ], + "value": "10000000" + }, + { + "txid": "f70fa075aff2fd73c125975978d600b0b2f1bca878bc41209b1c6ae0aba3a459", + "n": 2, + "addresses": [ + "via1q8gyufeuhxkt428cgjn8wp6leydwwky0x30wvue" + ], + "value": "499890124" + }, + { + "txid": "6d5151cb8df2eb819c9ea008a07e2e889edae7c70f187a578bbfbc226394d1ac", + "vout": 1, + "n": 3, + "addresses": [ + "via1qc0c6g7pzce4dtseatgt9ltxvyap64efquhlu27" + ], + "value": "7232306180" + } + ], + "vout": [ + { + "value": "7741976396", + "n": 0, + "spent": true, + "hex": "00143379fd40508ec2101e11c3519a31615de6e7b673", + "addresses": [ + "via1qxdul6szs3mppq8s3cdge5vtpthnw0dnn06m5qp" + ] + } + ], + "blockHash": "4e98a8fad4bb02dcb799725d7ede5f545596688466d85a1091b2ba563d85a062", + "blockHeight": 7255611, + "confirmations": 360238, + "blockTime": 1580704540, + "value": "7741976396", + "valueIn": "7742296304", + "fees": "319908", + "hex": "01000000000104cf185fc302c70956d3d530b3b0d2416cedea9f05cad80b41a466226a89b6731f000000000000000000acd1946322bcbf8b577a180fc7e7da9e882e7ea008a09e9c81ebf28dcb51516d00000000000000000059a4a3abe06a1c9b2041bc78a8bcf1b2b000d678599725c173fdf2af75a00ff7000000000000000000acd1946322bcbf8b577a180fc7e7da9e882e7ea008a09e9c81ebf28dcb51516d010000000000000000014c2f75cd010000001600143379fd40508ec2101e11c3519a31615de6e7b6730247304402200f7e4b4573de54f1967e2f94daefb869ab99ee5fc9d00807d41d749cb8f4e74402205aa4ea6f7d0cf9742e7bbd46f47a2923cc586afd8699d143ccd02c36ee25f53b012102a56256f78e4dd22ec54125f908892a6d42b47e8638707245235a4ed03611b34102483045022100bef33dc381dd372513c8385a1c2e51f298fe992c71aa1ab4301c001c216f306402200dbc2a4736655cde7e4d6a3fffc507d2c67f2022438dc80065ca624ae6f50939012102252dd7efb799c8766b2ae1568a302b361bc3dfba811d29cea714be9c06916033024830450221008b80cad80219f536288d4a691bcc1f6b4520038da1e92161d201b2b9c8a106c30220255f17b669c3cc2ea1fb930e64ad5222751b2ef9c8a6eee478d62247273f5807012103f321418135881669dc1de73dec8f0c59af758be9b75b5b627efa9cb955a35e6102483045022100ff9ae1423ed28f7728c184d8df4ab158b66e756de1ecfa0bcb8e3d5b0164d71f0220343028022a63c3a327bf1ed242f2dc839a138784d1a7399ed26e5fdffa831fbb01210258cd0af468ed450ebbbaae8aed0e7ec7122856491a2fb84ea56a1f91f28e04cb00000000" + }, + { + "txid": "f70fa075aff2fd73c125975978d600b0b2f1bca878bc41209b1c6ae0aba3a459", + "version": 1, + "vin": [ + { + "txid": "e05387d8a470d7a144c19588c7f0613f5b8b3013ac34c34c561f124a71d81e4a", + "n": 0, + "addresses": [ + "via1qe2g00nkzhflfuq8ee65fyr92gq9240umdy902z" + ], + "value": "499986700" + } + ], + "vout": [ + { + "value": "499890124", + "n": 0, + "spent": true, + "hex": "00143a09c4e7973597551f0894cee0ebf9235ceb11e6", + "addresses": [ + "via1q8gyufeuhxkt428cgjn8wp6leydwwky0x30wvue" + ] + } + ], + "blockHash": "6670e848b2ad5123b9e01fa5e20722e2b127cc37f5f05c5d0a7f7262571f8038", + "blockHeight": 7130119, + "confirmations": 485730, + "blockTime": 1577687140, + "value": "499890124", + "valueIn": "499986700", + "fees": "96576", + "hex": "010000000001014a1ed8714a121f564cc334ac13308b5b3f61f0c78895c144a1d770a4d88753e000000000000000000001ccb7cb1d000000001600143a09c4e7973597551f0894cee0ebf9235ceb11e602483045022100d2ae492c00749ada65c3f214c4d639efc65439cc0516cf8d1b3904cb06ad201502203b97312193284a8429c6c2242c3ce023083f7f9446d473563d4b5047175244fd0121032e83d8ee4adcaf863a262c54aadc46cc3ace851e147ceac0b61dbd1f6910e3e400000000" + }, + { + "txid": "6d5151cb8df2eb819c9ea008a07e2e889edae7c70f187a578bbfbc226394d1ac", + "version": 1, + "vin": [ + { + "txid": "d483ff03f4ed67e3e34a8ac886fb975e25359c3d355ce729f3b935c44a4a74c8", + "sequence": 4294967294, + "n": 0, + "addresses": [ + "via1q8yau03cmeg8meaw3jt5ducsjmm8mq7tyaynkqh" + ], + "value": "7242532180" + } + ], + "vout": [ + { + "value": "10000000", + "n": 0, + "spent": true, + "hex": "00149c9d2ca5c0dd4bceb08f72a747a12e0794abcebc", + "addresses": [ + "via1qnjwjefwqm49uavy0w2n50gfwq722hn4ua6ka7h" + ] + }, + { + "value": "7232306180", + "n": 1, + "spent": true, + "hex": "0014c3f1a47822c66ad5c33d5a165faccc2743aae520", + "addresses": [ + "via1qc0c6g7pzce4dtseatgt9ltxvyap64efquhlu27" + ] + } + ], + "blockHash": "89f0e6e76d6024265570f05992d1b90fd40d5c8d9d4f0eae1983765f04273928", + "blockHeight": 7013403, + "confirmations": 602446, + "blockTime": 1574881934, + "value": "7242306180", + "valueIn": "7242532180", + "fees": "226000", + "hex": "01000000000101c8744a4ac435b9f329e75c353d9c35255e97fb86c88a4ae3e367edf403ff83d40000000000feffffff0280969800000000001600149c9d2ca5c0dd4bceb08f72a747a12e0794abcebc043c14af01000000160014c3f1a47822c66ad5c33d5a165faccc2743aae52002483045022100f6634aa4e8c532c2e13bf9c7f5426d642f3252a1dc2366801f7483237a97efec02207f1f74164ca966249e6e80668eb92e26b332aff23428c31f9697eb1a0dd7036901210330d36cece866b930e14d48e4a115b15aacc621a87c1f1c56e55dd3583239529300000000" + }, + { + "txid": "d483ff03f4ed67e3e34a8ac886fb975e25359c3d355ce729f3b935c44a4a74c8", + "version": 1, + "vin": [ + { + "txid": "c0e61eaebf96f6a9a193ef721327ca5924ad7562f1909b7b53ca291a5bf53d85", + "n": 0, + "addresses": [ + "via1qql3y6vknyd7d5dyzjdsw35lj8s5ntpkgul48xs" + ], + "value": "7242628756" + } + ], + "vout": [ + { + "value": "7242532180", + "n": 0, + "spent": true, + "hex": "0014393bc7c71bca0fbcf5d192e8de6212decfb07964", + "addresses": [ + "via1q8yau03cmeg8meaw3jt5ducsjmm8mq7tyaynkqh" + ] + } + ], + "blockHash": "892a289c68c3400c0984841d99e9e7f6ef4849c178cd06c7174068da60679b85", + "blockHeight": 6982859, + "confirmations": 632990, + "blockTime": 1574147784, + "value": "7242532180", + "valueIn": "7242628756", + "fees": "96576", + "hex": "01000000000101853df55b1a29ca537b9b90f16275ad2459ca271372ef93a1a9f696bfae1ee6c0000000000000000000015445b0af01000000160014393bc7c71bca0fbcf5d192e8de6212decfb079640247304402202b3f0bcfbb04fda92566defbd5307d86fac4dfb3bef74242f5b65e0f89e6f7b802202606741aeba63cc552d50551ce4a815d58a412901b7788b357d39ba6b745a83e0121024d07f866d7de139ebc87173745e1a17315d0c44d64063b23eb64c039c220667b00000000" + }, + { + "txid": "c0e61eaebf96f6a9a193ef721327ca5924ad7562f1909b7b53ca291a5bf53d85", + "version": 1, + "vin": [ + { + "txid": "d98a521e1f42848aa70889080954ce47e0a4dfa8a523e1a7ba6d786148be1998", + "sequence": 4294967294, + "n": 0, + "addresses": [ + "via1qvh6wxn9ryr0pmp8xeeg29hgj4pwmaws4r78vq9" + ], + "value": "7242854756" + } + ], + "vout": [ + { + "value": "7242628756", + "n": 0, + "spent": true, + "hex": "001407e24d32d3237cda34829360e8d3f23c293586c8", + "addresses": [ + "via1qql3y6vknyd7d5dyzjdsw35lj8s5ntpkgul48xs" + ] + } + ], + "blockHash": "02bc047ccc595eede2828907af1e49915f3c90593e4529c1a1f0a978ad6d3672", + "blockHeight": 6982851, + "confirmations": 632998, + "blockTime": 1574147586, + "value": "7242628756", + "valueIn": "7242854756", + "fees": "226000", + "hex": "010000000001019819be4861786dbaa7e123a5a8dfa4e047ce5409088908a78a84421f1e528ad90000000000feffffff0194beb1af0100000016001407e24d32d3237cda34829360e8d3f23c293586c802473044022047726b9a153f1151e837092632bb35ce2bbc1a976864eaa4161b11879547738b0220028efd224a642aa05d11607df71319e77a67b8fa8a56050bb2cc3c33f904032401210292b315d9e4d889bcd69098e838b06ca697ac0eab6fcebf538a0f50c5322ea94600000000" + }, + { + "txid": "d98a521e1f42848aa70889080954ce47e0a4dfa8a523e1a7ba6d786148be1998", + "version": 1, + "vin": [ + { + "txid": "07dde2c136ffdeffebd630d4578c02aec2f62f2f7d7b1b53d7524c7382660acf", + "n": 0, + "addresses": [ + "via1q88qhrx05ukgx9py4uu7gz9l6fg7gsjx38u6v2x" + ], + "value": "7242951332" + } + ], + "vout": [ + { + "value": "7242854756", + "n": 0, + "spent": true, + "hex": "001465f4e34ca320de1d84e6ce50a2dd12a85dbeba15", + "addresses": [ + "via1qvh6wxn9ryr0pmp8xeeg29hgj4pwmaws4r78vq9" + ] + } + ], + "blockHash": "a9cd25d3fbaf1b469e09df2785f9da177e540533bcc92d22ce0409ea447b1405", + "blockHeight": 6982834, + "confirmations": 633015, + "blockTime": 1574147247, + "value": "7242854756", + "valueIn": "7242951332", + "fees": "96576", + "hex": "01000000000101cf0a6682734c52d7531b7b7d2f2ff6c2ae028c57d430d6ebffdeff36c1e2dd07000000000000000000016431b5af0100000016001465f4e34ca320de1d84e6ce50a2dd12a85dbeba1502473044022065495e4611f9aa444f52755ab7ed1af483a6114fd813e8cab82cbf0ba88220a4022018542a21f5ba5dc772ddc2f8ad36b102ff66dab484940f2ccc126c2387136bc1012103d8b633e95b597e0c204b9840daf65ea4130a49a4f253d0bd44dad6e8100626db00000000" + }, + { + "txid": "07dde2c136ffdeffebd630d4578c02aec2f62f2f7d7b1b53d7524c7382660acf", + "version": 1, + "vin": [ + { + "txid": "1f73b6896a2266a4410bd8ca059feaed6c41d2b0b330d5d35609c702c35f18cf", + "vout": 1, + "sequence": 4294967293, + "n": 0, + "addresses": [ + "via1qhh33kdegs4057ttyx3w4wqx8qucvj7yehc9t5e" + ], + "value": "674000" + }, + { + "txid": "5c52e68bb5c098edb2113d0a05f3e56acc421cb4733a98b831c2933c1f765578", + "sequence": 4294967294, + "n": 1, + "addresses": [ + "via1q78tmuzvnyffz9lc3yd3xx26qem3p80v6rz6lue" + ], + "value": "1000000" + }, + { + "txid": "7925e744dfa33513745962bba4d87e90f3264cb9131bb49461004865c587de1f", + "sequence": 4294967289, + "n": 2, + "addresses": [ + "via1q0kvzuak82rdaqmgtx0lzrus5c6ct9lx55t7seq" + ], + "value": "1000000" + }, + { + "txid": "639124722d1348e9fdce56feb2617d716abd5875a5d17adf95d32d9e0c02f70f", + "sequence": 4294967285, + "n": 3, + "addresses": [ + "via1q8lc7tuy04z9ssxmz3lndzpk3ul9favy7f70qme" + ], + "value": "1000000" + }, + { + "txid": "2171fc3bb981ea69eb5631b4ab3b48e06cfc273669f925d73511df360c23ead2", + "sequence": 4294967288, + "n": 4, + "addresses": [ + "via1qx72z9rxy3fmqvr47ak99uxam3fwgugvu60d6ws" + ], + "value": "1000000" + }, + { + "txid": "639124722d1348e9fdce56feb2617d716abd5875a5d17adf95d32d9e0c02f70f", + "vout": 1, + "sequence": 4294967284, + "n": 5, + "addresses": [ + "via1q9xpat8z29v8xv5265l53ee8gf0jn3fy8cu3j8e" + ], + "value": "8774000" + }, + { + "txid": "d51ee57fc297072a635b4bba5457511719a6b57b4b108f65e68ebcdb6690098b", + "sequence": 4294967283, + "n": 6, + "addresses": [ + "via1qxdul6szs3mppq8s3cdge5vtpthnw0dnn06m5qp" + ], + "value": "10000000" + }, + { + "txid": "d51ee57fc297072a635b4bba5457511719a6b57b4b108f65e68ebcdb6690098b", + "vout": 1, + "sequence": 4294967282, + "n": 7, + "addresses": [ + "via1qgz6hyva6qcq4gpr030d4lamyuxamf4naawe0e5" + ], + "value": "23087332" + }, + { + "txid": "093904f8f08f3a651711efb2d338df6544252acbaf492aa266cd68239d76f9f8", + "vout": 1, + "sequence": 4294967290, + "n": 8, + "addresses": [ + "via1qtdu5et77ctlsydqwrfkxr5u63j26ng7lkwt0z7" + ], + "value": "46750366" + }, + { + "txid": "b1a53149702bcab970c8603f9844afc1d2543ebec3fcd1c219ea130468a967a2", + "vout": 1, + "sequence": 4294967291, + "n": 9, + "addresses": [ + "via1q760gw3alk4f2jn7wa8faldvrnh3ak3t7avjcwz" + ], + "value": "52119634" + }, + { + "txid": "b1a53149702bcab970c8603f9844afc1d2543ebec3fcd1c219ea130468a967a2", + "sequence": 4294967292, + "n": 10, + "addresses": [ + "via1q62j6pz8t0reg54vnmd4drqpm7ktq02kqcvkdpf" + ], + "value": "100000000" + }, + { + "txid": "8e1fde5beb90db4fe2664040bced2a906dec01d39b5e25f011b9ace488b01051", + "sequence": 4294967287, + "n": 11, + "addresses": [ + "via1qwn0emd9l0qj98xcuw707jxwytxuh36lempkfre" + ], + "value": "145731332" + }, + { + "txid": "8e1fde5beb90db4fe2664040bced2a906dec01d39b5e25f011b9ace488b01051", + "vout": 1, + "sequence": 4294967286, + "n": 12, + "addresses": [ + "via1q8cp08dqnhdwulv748chh8htzakwz2lfjksugtm" + ], + "value": "6853816668" + } + ], + "vout": [ + { + "value": "7242951332", + "n": 0, + "spent": true, + "hex": "001439c17199f4e590628495e73c8117fa4a3c8848d1", + "addresses": [ + "via1q88qhrx05ukgx9py4uu7gz9l6fg7gsjx38u6v2x" + ] + } + ], + "blockHash": "2bfee63a6cd5572890cc6d877a04b7ec0bfb621654ad97a80f09ed15a780beae", + "blockHeight": 6982823, + "confirmations": 633026, + "blockTime": 1574147048, + "value": "7242951332", + "valueIn": "7244953332", + "fees": "2002000", + "hex": "0100000000010dcf185fc302c70956d3d530b3b0d2416cedea9f05cad80b41a466226a89b6731f0100000000fdffffff7855761f3c93c231b8983a73b41c42cc6ae5f3050a3d11b2ed98c0b58be6525c0000000000feffffff1fde87c56548006194b41b13b94c26f3907ed8a4bb6259741335a3df44e725790000000000f9ffffff0ff7020c9e2dd395df7ad1a57558bd6a717d61b2fe56cefde948132d722491630000000000f5ffffffd2ea230c36df1135d725f9693627fc6ce0483babb43156eb69ea81b93bfc71210000000000f8ffffff0ff7020c9e2dd395df7ad1a57558bd6a717d61b2fe56cefde948132d722491630100000000f4ffffff8b099066dbbc8ee6658f104b7bb5a61917515754ba4b5b632a0797c27fe51ed50000000000f3ffffff8b099066dbbc8ee6658f104b7bb5a61917515754ba4b5b632a0797c27fe51ed50100000000f2fffffff8f9769d2368cd66a22a49afcb2a254465df38d3b2ef1117653a8ff0f80439090100000000faffffffa267a9680413ea19c2d1fcc3be3e54d2c1af44983f60c870b9ca2b704931a5b10100000000fbffffffa267a9680413ea19c2d1fcc3be3e54d2c1af44983f60c870b9ca2b704931a5b10000000000fcffffff5110b088e4acb911f0255e9bd301ec6d902aedbc404066e24fdb90eb5bde1f8e0000000000f7ffffff5110b088e4acb911f0255e9bd301ec6d902aedbc404066e24fdb90eb5bde1f8e0100000000f6ffffff01a4aab6af0100000016001439c17199f4e590628495e73c8117fa4a3c8848d1024730440220321ddeb00045126259c92d7a3528705730738bff24a88efbbf4d33ae44b34da5022019046eca1abcbe925f8ee71fdeafd70d697255579e63b7ea7200228e8bd97be60121039187e3d84bb3970d1d22429b3a484d6baaa00050e3b94b83f14abe4749c8470502473044022012e8d4bd47cc722d034d6924af284693a13fb5033478cd963a69a968f3cfbce40220294fdbe29d0998c77939ce6df339c68af6fbfbbbfa638e45e155ae73e52433c8012102ea92b54038005bca8e4d4249019be1b0b5d889208aaa14406d8387644797dd6c02473044022003e8a14b868fb30c43da60b4b909145c5315044ee557aee34ea4cef565fe459802203d9872afd539128ce4013392b912ef197490280f56f3610676d5de6fe8d4c0eb01210212bacd3361e85a16a16dc197d7fcbb9496fbf61e1a70e41ecc81da9d80dca8de02483045022100a064613164d6aedf724326e02621dc985683aa3f89643f57a892d28302e8e4df022052374f12980dab9d91d16ea678c4a7d12a1e68469d88633aa12ddbc6fc31c8ed012102213bcc708dbdf5fab6d3ac1499966dfce37510c6e09b2a58027c0ebe787141ad0247304402202752ec3d2f64b13bc1e64d11a072fe5212cb73fe903109eaf830d334898ed890022013e0973bc3e56b78948d0ea2309fb5bf2002c7ce73ac4193502ff6363589476601210270c78f1d49370f4f03c420ccd8fa35e9e40ee61405b30e4f1171054d3e9248bf02483045022100a730cf6a17580e170bfbbcec139cc2141b2a2091492ac80ad053a653eb04fe1702203efddff0ef666658109669ab2c84597b8f890a95d3fa776da51643825fa2e1570121021acd7a35a34f3e997d7289128f502b08a6e940130619ef7327f8047dc194d08d02483045022100db9a2c03b0750653a7cc3ec5370ebe0da19253e80e4fd0daa889aac942ad398a02202563b1d72248f0e60cd2e2e2143e51b6da8a940f07a684c8bee54afe6c76c184012102b5e09e1dbb76a0eeebea67bf80069ce41c26c81d0f06d1dd42e712ebf55de4bc02483045022100bb23d31e49852b2b5b85292c3cd8a9d6dc8c7487d01def5c74eb646a929e20e7022049b0c8a62cb4420ee1e558c410cd65d0fea44ba652b4d2a435610712ff6d4f700121020f082e2cc3561ea664c82d91deb6b87d99ac7dea173933e8f6529af73be0837d02483045022100d97b09fc661e97faba573d0e9484f6cb2bf08086852b150c15a3044efc0edbcf02200eea145be44dbe90b1bc8dcf26e8d6b1d7fa55f9db30586c688f32c14aef52560121034db1e84ae0636c1b0324e85a7efdcd03b0ca3ecabddb2bcb9ae87e7cf2bcb31102483045022100a4d13d895464e0575c028c2a917039fd33e2e513295d7b3136afb54ace4568e0022037c7ba83445de0aef3fc4659b5a0a1ae9dfc651cfedcaa74e719e47625d4b35f012103f00f6d89e6acd56ac44b0bb42bd30aede6d5180917e35197329108a1ef90fbb3024730440220080ce7571a2db052c45ad3273629a2cbedc787e73bf7cf6687b38b85521bd997022021dc670e9073fcf512640523460eb10d7d9be3e1c6b14392d451c3a1f681f28201210269306517d1eb1aa53bc236e3a62d68ccd24f43d7ad4180b08b4390908139fa24024730440220582ce53d504508435be22101e5d9950423cded2832b136cd02c11ade3e4e6aba022018ccd415785d615d429406eabb8d5aedf2ed8c578fdb028b60040ceaf910b466012102cd0cfcb09d4651c5f320567d61056cdbc9d402c38e6e8b94574aa9902959549602473044022003b362e0408039ac335ced057ece89425e8ea1050f9eddd9f1ae84c2a6ed6867022003f53f8ce13f6001e463c8941b64590cd36a28a24351219342a98519225a9101012103c03e2f55a1abe37ed1a7839ad66f27516a49711cab8c9e6390996ff9ea05455600000000" + }, + { + "txid": "d51ee57fc297072a635b4bba5457511719a6b57b4b108f65e68ebcdb6690098b", + "version": 1, + "vin": [ + { + "txid": "5a5bba52860dff14e1cd3975da180910eac9c1ce4b05df7e4bc287f283fd07b8", + "vout": 1, + "sequence": 4294967287, + "n": 0, + "addresses": [ + "via1qqv3wq50x9y4sdae4eqzpqwgrwtel5p7qdrc5cq" + ], + "value": "33313332" + } + ], + "vout": [ + { + "value": "10000000", + "n": 0, + "spent": true, + "hex": "00143379fd40508ec2101e11c3519a31615de6e7b673", + "addresses": [ + "via1qxdul6szs3mppq8s3cdge5vtpthnw0dnn06m5qp" + ] + }, + { + "value": "23087332", + "n": 1, + "spent": true, + "hex": "001440b57233ba060154046f8bdb5ff764e1bbb4d67d", + "addresses": [ + "via1qgz6hyva6qcq4gpr030d4lamyuxamf4naawe0e5" + ] + } + ], + "blockHash": "8f2106b41d4988a3b4650d59a9d3fd7a4aa8e5ed3785d014783f90fcbdceac99", + "blockHeight": 6963630, + "confirmations": 652219, + "blockTime": 1573685639, + "value": "33087332", + "valueIn": "33313332", + "fees": "226000", + "hex": "01000000000101b807fd83f287c24b7edf054bcec1c9ea100918da7539cde114ff0d8652ba5b5a0100000000f7ffffff0280969800000000001600143379fd40508ec2101e11c3519a31615de6e7b673e44860010000000016001440b57233ba060154046f8bdb5ff764e1bbb4d67d0247304402200252d54e1ffa31b1be50cfe715f390d33617642686430416be24325fae853c82022073cd4c84df229af3645cf5795caf8081636cab3fb8a25a9c844aa318c0db96840121032b3a6da896cafe03264effa44dd349cb47bda0d86d5fc51224233828f045867100000000" + }, + { + "txid": "639124722d1348e9fdce56feb2617d716abd5875a5d17adf95d32d9e0c02f70f", + "version": 1, + "vin": [ + { + "txid": "5a5bba52860dff14e1cd3975da180910eac9c1ce4b05df7e4bc287f283fd07b8", + "sequence": 4294967287, + "n": 0, + "addresses": [ + "via1qvd32vttv9j55qdj0qwqltkrh29yxvv9f5wecsx" + ], + "value": "10000000" + } + ], + "vout": [ + { + "value": "1000000", + "n": 0, + "spent": true, + "hex": "00143ff1e5f08fa88b081b628fe6d106d1e7ca9eb09e", + "addresses": [ + "via1q8lc7tuy04z9ssxmz3lndzpk3ul9favy7f70qme" + ] + }, + { + "value": "8774000", + "n": 1, + "spent": true, + "hex": "00142983d59c4a2b0e66515aa7e91ce4e84be538a487", + "addresses": [ + "via1q9xpat8z29v8xv5265l53ee8gf0jn3fy8cu3j8e" + ] + } + ], + "blockHash": "e792457c686024e8007938c432e6fafc78cc9ff24ea6d5ccb3ee0211f6c490d8", + "blockHeight": 6937938, + "confirmations": 677911, + "blockTime": 1573068178, + "value": "9774000", + "valueIn": "10000000", + "fees": "226000", + "hex": "01000000000101b807fd83f287c24b7edf054bcec1c9ea100918da7539cde114ff0d8652ba5b5a0000000000f7ffffff0240420f00000000001600143ff1e5f08fa88b081b628fe6d106d1e7ca9eb09e70e18500000000001600142983d59c4a2b0e66515aa7e91ce4e84be538a48702483045022100f28293b7857151eccad4a0c6b50e0d729981ce62c1c30149778a6f6c6b66517e022075bd4432991498a9e65a5d9dbda7d30f0bdf64f956bab2909e00e43bf4a3165701210266c2b86dd04e846725f7c826879a8e4e281ec08ebc665b65c329e8b00ec7516400000000" + }, + { + "txid": "8e1fde5beb90db4fe2664040bced2a906dec01d39b5e25f011b9ace488b01051", + "version": 1, + "vin": [ + { + "txid": "7d8fc63757811fe4d273e3b42b494d13545cf0710cd821f7465572a7584c8642", + "vout": 1, + "sequence": 4294967294, + "n": 0, + "addresses": [ + "via1qhrqrcvj9djwrpyss5mk87gyz2k2t0r8feacgpj" + ], + "value": "6999774000" + } + ], + "vout": [ + { + "value": "145731332", + "n": 0, + "spent": true, + "hex": "001474df9db4bf7824539b1c779fe919c459b978ebf9", + "addresses": [ + "via1qwn0emd9l0qj98xcuw707jxwytxuh36lempkfre" + ] + }, + { + "value": "6853816668", + "n": 1, + "spent": true, + "hex": "00143e02f3b413bb5dcfb3d53e2f73dd62ed9c257d32", + "addresses": [ + "via1q8cp08dqnhdwulv748chh8htzakwz2lfjksugtm" + ] + } + ], + "blockHash": "aed49601b577434ba4b33e18e244119fb94d1c0cf5ff3126aba3520f3cd9f4df", + "blockHeight": 6915541, + "confirmations": 700308, + "blockTime": 1572529818, + "value": "6999548000", + "valueIn": "6999774000", + "fees": "226000", + "hex": "0100000000010142864c58a7725546f721d80c71f05c54134d492bb4e373d2e41f815737c68f7d0100000000feffffff0204afaf080000000016001474df9db4bf7824539b1c779fe919c459b978ebf95cf18498010000001600143e02f3b413bb5dcfb3d53e2f73dd62ed9c257d3202483045022100b839ad22d00b6bac9f4aba109d38a76a1724aa9d47d94d1d03b2fdd68bed5d9b0220595944e4b1c6170d8995fc9b506584d8a3c4d1ac0e110ace79f06d8e47b8c976012103a7ca8479fe2d2284eb91cd26d02c821a1cfe57eb5a660a06c02b72b1e2ed30dd00000000" + }, + { + "txid": "5a5bba52860dff14e1cd3975da180910eac9c1ce4b05df7e4bc287f283fd07b8", + "version": 1, + "vin": [ + { + "txid": "2171fc3bb981ea69eb5631b4ab3b48e06cfc273669f925d73511df360c23ead2", + "vout": 1, + "n": 0, + "addresses": [ + "via1qlm2s4wgh5n64kukpnjkq0kea3fg6lcw4l2ptrw" + ], + "value": "43427010" + } + ], + "vout": [ + { + "value": "10000000", + "n": 0, + "spent": true, + "hex": "00146362a62d6c2ca940364f0381f5d87751486630a9", + "addresses": [ + "via1qvd32vttv9j55qdj0qwqltkrh29yxvv9f5wecsx" + ] + }, + { + "value": "33313332", + "n": 1, + "spent": true, + "hex": "00140322e051e6292b06f735c80410390372f3fa07c0", + "addresses": [ + "via1qqv3wq50x9y4sdae4eqzpqwgrwtel5p7qdrc5cq" + ] + } + ], + "blockHash": "754e01ca904e90b88da23b50237969099ea7a07ea71f5cb7842601559a852384", + "blockHeight": 6892052, + "confirmations": 723797, + "blockTime": 1571965158, + "value": "43313332", + "valueIn": "43427010", + "fees": "113678", + "hex": "01000000000101d2ea230c36df1135d725f9693627fc6ce0483babb43156eb69ea81b93bfc71210100000000000000000280969800000000001600146362a62d6c2ca940364f0381f5d87751486630a93452fc01000000001600140322e051e6292b06f735c80410390372f3fa07c00247304402203670013811d6b055f214dd0882b065b93850f842c5ff45d1c47618c7515a4c2802201ff4a11df094a857e8c1bbfa4cd4aec16593583c07596d2cd4ddf9276a9d8aea01210284942b015a484563494f37559e8f12958ef842439b95657c84fefa60b0c0116800000000" + }, + { + "txid": "2171fc3bb981ea69eb5631b4ab3b48e06cfc273669f925d73511df360c23ead2", + "version": 1, + "vin": [ + { + "txid": "7925e744dfa33513745962bba4d87e90f3264cb9131bb49461004865c587de1f", + "vout": 1, + "n": 0, + "addresses": [ + "via1qnuxuwrrscmdezm6xdl053hcedzmrl27ylnd5gw" + ], + "value": "44540688" + } + ], + "vout": [ + { + "value": "1000000", + "n": 0, + "spent": true, + "hex": "00143794228cc48a76060ebeed8a5e1bbb8a5c8e219c", + "addresses": [ + "via1qx72z9rxy3fmqvr47ak99uxam3fwgugvu60d6ws" + ] + }, + { + "value": "43427010", + "n": 1, + "spent": true, + "hex": "0014fed50ab917a4f55b72c19cac07db3d8a51afe1d5", + "addresses": [ + "via1qlm2s4wgh5n64kukpnjkq0kea3fg6lcw4l2ptrw" + ] + } + ], + "blockHash": "cef1a23a742f6dd54d47604e7f4f84d0b1f88654ef7828279f28ee98272fbcfa", + "blockHeight": 6857056, + "confirmations": 758793, + "blockTime": 1571123779, + "value": "44427010", + "valueIn": "44540688", + "fees": "113678", + "hex": "010000000001011fde87c56548006194b41b13b94c26f3907ed8a4bb6259741335a3df44e725790100000000000000000240420f00000000001600143794228cc48a76060ebeed8a5e1bbb8a5c8e219cc2a4960200000000160014fed50ab917a4f55b72c19cac07db3d8a51afe1d502483045022100a23745485206718356760dd4ed48f48d034abfba0c45c172dc88df88e89d2a1b022024ad2aafb0fdace395b28fe01c9df8814afacb24740839384e82e99db8936b59012103e628b30b3fd01b370fba114c15c2233fcb37cb5450461b8428b08dda7466e12900000000" + }, + { + "txid": "7925e744dfa33513745962bba4d87e90f3264cb9131bb49461004865c587de1f", + "version": 1, + "vin": [ + { + "txid": "f89d999261e691ee65cc4d0dd8b516c7fbbb0f2a35f03ed449fa29388d0414c2", + "vout": 1, + "n": 0, + "addresses": [ + "via1qe43a7w7us8vyaa4mmdwjppr6gh8j9j9pwpxpyh" + ], + "value": "45654366" + } + ], + "vout": [ + { + "value": "1000000", + "n": 0, + "spent": true, + "hex": "00147d982e76c750dbd06d0b33fe21f214c6b0b2fcd4", + "addresses": [ + "via1q0kvzuak82rdaqmgtx0lzrus5c6ct9lx55t7seq" + ] + }, + { + "value": "44540688", + "n": 1, + "spent": true, + "hex": "00149f0dc70c70c6db916f466fdf48df1968b63fabc4", + "addresses": [ + "via1qnuxuwrrscmdezm6xdl053hcedzmrl27ylnd5gw" + ] + } + ], + "blockHash": "d4e68ba9688ea2cd0523a9ce086b830cc90921780d86061a8294dc446a35f69e", + "blockHeight": 6856608, + "confirmations": 759241, + "blockTime": 1571113111, + "value": "45540688", + "valueIn": "45654366", + "fees": "113678", + "hex": "01000000000101c214048d3829fa49d43ef0352a0fbbfbc716b5d80d4dcc65ee91e66192999df80100000000000000000240420f00000000001600147d982e76c750dbd06d0b33fe21f214c6b0b2fcd410a3a702000000001600149f0dc70c70c6db916f466fdf48df1968b63fabc402483045022100b842ca78affb900ec901e48cf0b4df311d833cf8ac3fa168948f97099cd50f320220404d4c85ee2039371b5a9c14e2a74678b0888e8b60647a6152871e0a4480055d012102a14c53b1f112c58eabc9e58b07c7be3b81fb6ad4a7e5260952a66882d88d34cf00000000" + }, + { + "txid": "093904f8f08f3a651711efb2d338df6544252acbaf492aa266cd68239d76f9f8", + "version": 1, + "vin": [ + { + "txid": "8888df5bd0444723eabd8d3034ad042cf58f8aa2ffa9b18b8e7d3d3e0ed1763f", + "sequence": 4294967291, + "n": 0, + "addresses": [ + "via1qy6fkhfza4kj7f83lnkjkqyz73zuffyaq2ttxx6" + ], + "value": "146976366" + } + ], + "vout": [ + { + "value": "100000000", + "n": 0, + "hex": "001453e45e03d888aaef8c94fc144859448ddd4ed36d", + "addresses": [ + "via1q20j9uq7c3z4wlry5ls2ysk2y3hw5a5mdv709m8" + ] + }, + { + "value": "46750366", + "n": 1, + "spent": true, + "hex": "00145b794cafdec2ff02340e1a6c61d39a8c95a9a3df", + "addresses": [ + "via1qtdu5et77ctlsydqwrfkxr5u63j26ng7lkwt0z7" + ] + } + ], + "blockHash": "adb73826ff107abc11452d72d974980c1b9147dc505b3a1e6932178a7fffb26e", + "blockHeight": 6812515, + "confirmations": 803334, + "blockTime": 1570053434, + "value": "146750366", + "valueIn": "146976366", + "fees": "226000", + "hex": "010000000001013f76d10e3e3d7d8e8bb1a9ffa28a8ff52c04ad34308dbdea234744d05bdf88880000000000fbffffff0200e1f5050000000016001453e45e03d888aaef8c94fc144859448ddd4ed36d9e5ac902000000001600145b794cafdec2ff02340e1a6c61d39a8c95a9a3df02483045022100906f19bc71c18053459941d737a0efe321c3e6193e8f67e969ff2f1fea16ca0c0220711da1af0613e970bb04a3eb70373c91345cf39747d8fa5187bf4bac62a0546e012102f3236f9caf206ac54900f17d113ec9c298017f3a78179cfc738e06b364938a1100000000" + }, + { + "txid": "b1a53149702bcab970c8603f9844afc1d2543ebec3fcd1c219ea130468a967a2", + "version": 1, + "vin": [ + { + "txid": "8888df5bd0444723eabd8d3034ad042cf58f8aa2ffa9b18b8e7d3d3e0ed1763f", + "vout": 1, + "sequence": 4294967290, + "n": 0, + "addresses": [ + "via1qnjmu3ce5veyn4wd2wrjdvtz9amz0l2kw7x6hp4" + ], + "value": "152345634" + } + ], + "vout": [ + { + "value": "100000000", + "n": 0, + "spent": true, + "hex": "0014d2a5a088eb78f28a5593db6ad1803bf59607aac0", + "addresses": [ + "via1q62j6pz8t0reg54vnmd4drqpm7ktq02kqcvkdpf" + ] + }, + { + "value": "52119634", + "n": 1, + "spent": true, + "hex": "0014f69e8747bfb552a94fcee9d3dfb5839de3db457e", + "addresses": [ + "via1q760gw3alk4f2jn7wa8faldvrnh3ak3t7avjcwz" + ] + } + ], + "blockHash": "831d5243d513772135fb5a8d8f4499db3ba6b513009afde1c01af14a2881883a", + "blockHeight": 6800220, + "confirmations": 815629, + "blockTime": 1569757759, + "value": "152119634", + "valueIn": "152345634", + "fees": "226000", + "hex": "010000000001013f76d10e3e3d7d8e8bb1a9ffa28a8ff52c04ad34308dbdea234744d05bdf88880100000000faffffff0200e1f50500000000160014d2a5a088eb78f28a5593db6ad1803bf59607aac052481b0300000000160014f69e8747bfb552a94fcee9d3dfb5839de3db457e024830450221008c8568f209b728145e3292d1480b5e1d8bff4c84c4f283d5a0ca2cc391bd0bfc0220465f0cf504ec5eb83055efd89bb50d26e04ce0b510ecd2f307cad22b37e2730d012102b73beb45f31938085a4e44a66c8d16c4f430d5cc203bf5861d20158d7260680a00000000" + }, + { + "txid": "1f73b6896a2266a4410bd8ca059feaed6c41d2b0b330d5d35609c702c35f18cf", + "version": 1, + "vin": [ + { + "txid": "c3ad35b33ba3d9c2b11335e6b2f63b3f60ee6a89e8f0f63f1c4a7867ac471410", + "sequence": 4294967292, + "n": 0, + "addresses": [ + "via1q78tmuzvnyffz9lc3yd3xx26qem3p80v6rz6lue" + ], + "value": "1000000" + } + ], + "vout": [ + { + "value": "100000", + "n": 0, + "spent": true, + "hex": "0014909224c2ecb592cb668adb07e1eff933493b6190", + "addresses": [ + "via1qjzfzfshvkkfvke52mvr7rmlexdynkcvsqzvu8l" + ] + }, + { + "value": "674000", + "n": 1, + "spent": true, + "hex": "0014bde31b3728855f4f2d64345d5700c70730c97899", + "addresses": [ + "via1qhh33kdegs4057ttyx3w4wqx8qucvj7yehc9t5e" + ] + } + ], + "blockHash": "ed79788499fcd324e8c3cc0dde623187d1f822c322b87c5ad2c5207bf5707845", + "blockHeight": 6795818, + "confirmations": 820031, + "blockTime": 1569652139, + "value": "774000", + "valueIn": "1000000", + "fees": "226000", + "hex": "01000000000101101447ac67784a1c3ff6f0e8896aee603f3bf6b2e63513b1c2d9a33bb335adc30000000000fcffffff02a086010000000000160014909224c2ecb592cb668adb07e1eff933493b6190d0480a0000000000160014bde31b3728855f4f2d64345d5700c70730c9789902483045022100b77fed5e8393b5da21303d9ca8f2166d1217a14937fd08dd13deda5ecb9d9c030220773124466fff61400df36eeb170cccff26a7d969c57cbff45d3e4c745d799819012102ea92b54038005bca8e4d4249019be1b0b5d889208aaa14406d8387644797dd6c00000000" + }, + { + "txid": "8888df5bd0444723eabd8d3034ad042cf58f8aa2ffa9b18b8e7d3d3e0ed1763f", + "version": 1, + "vin": [ + { + "txid": "67f57fffb949986e8e3a7ffb162246826f6a4c7868249f0ca01841c84ed849b5", + "vout": 1, + "sequence": 4294967293, + "n": 0, + "addresses": [ + "via1qc777z0fxa5zys4uqydcz2q8k9a9k38plskv9uj" + ], + "value": "299548000" + } + ], + "vout": [ + { + "value": "146976366", + "n": 0, + "spent": true, + "hex": "001426936ba45dada5e49e3f9da560105e88b89493a0", + "addresses": [ + "via1qy6fkhfza4kj7f83lnkjkqyz73zuffyaq2ttxx6" + ] + }, + { + "value": "152345634", + "n": 1, + "spent": true, + "hex": "00149cb7c8e33466493ab9aa70e4d62c45eec4ffaace", + "addresses": [ + "via1qnjmu3ce5veyn4wd2wrjdvtz9amz0l2kw7x6hp4" + ] + } + ], + "blockHash": "cd681ca3d28a391b0a5b8fd2e2b3f1f3fbf52a812766616ac785651b67b29424", + "blockHeight": 6784116, + "confirmations": 831733, + "blockTime": 1569370788, + "value": "299322000", + "valueIn": "299548000", + "fees": "226000", + "hex": "01000000000101b549d84ec84118a00c9f2468784c6a6f82462216fb7f3a8e6e9849b9ff7ff5670100000000fdffffff026eaec2080000000016001426936ba45dada5e49e3f9da560105e88b89493a0229c1409000000001600149cb7c8e33466493ab9aa70e4d62c45eec4ffaace0247304402200e4f5a4adf75abcd3f1ba0318d15f1723dddf0d3eec9ab1130e9987aad238ae10220195c0d0bc690f512272dbdaf8b84adff47779715917a583e02202872c753756e0121020fbccca36fb54cf3848401e73b9a5828006bcbafdc5456881d46253d7c72ec9500000000" + }, + { + "txid": "f89d999261e691ee65cc4d0dd8b516c7fbbb0f2a35f03ed449fa29388d0414c2", + "version": 1, + "vin": [ + { + "txid": "5c52e68bb5c098edb2113d0a05f3e56acc421cb4733a98b831c2933c1f765578", + "vout": 1, + "n": 0, + "addresses": [ + "via1qvunq979fdt26qt0ez7ftth8tlw6zrlpl832ddu" + ], + "value": "46768044" + } + ], + "vout": [ + { + "value": "1000000", + "n": 0, + "hex": "0014dc7aa2089196a3bc06b4a055419f4c81209a6748", + "addresses": [ + "via1qm3a2yzy3j63mcp455p25r86vsysf5e6gfvylv8" + ] + }, + { + "value": "45654366", + "n": 1, + "spent": true, + "hex": "0014cd63df3bdc81d84ef6bbdb5d20847a45cf22c8a1", + "addresses": [ + "via1qe43a7w7us8vyaa4mmdwjppr6gh8j9j9pwpxpyh" + ] + } + ], + "blockHash": "e7abb937d43aad42ba863751a358f0734c365a9aa64a06d9b35da09a5a41f0cc", + "blockHeight": 6780184, + "confirmations": 835665, + "blockTime": 1569276054, + "value": "46654366", + "valueIn": "46768044", + "fees": "113678", + "hex": "010000000001017855761f3c93c231b8983a73b41c42cc6ae5f3050a3d11b2ed98c0b58be6525c0100000000000000000240420f0000000000160014dc7aa2089196a3bc06b4a055419f4c81209a67485ea1b80200000000160014cd63df3bdc81d84ef6bbdb5d20847a45cf22c8a1024730440220477773a615d0b4ec4320e329a349c561c9e03af152d52f22a5713123b67d2daf02207d8b22fb6fef4b22add99dd2f0d7622ef85633a75ecdc1a890aa1b0899ffea2e0121033068f399551ff7b26ba4e0a9e77d775a2de00f72c75dd696e9d4bb990507b73800000000" + }, + { + "txid": "c3ad35b33ba3d9c2b11335e6b2f63b3f60ee6a89e8f0f63f1c4a7867ac471410", + "version": 1, + "vin": [ + { + "txid": "7c05afb2da19d6802ba6149e1830ad0461ce335b8f90a8edc0cd1766dc024cca", + "vout": 1, + "n": 0, + "addresses": [ + "via1qfc4y3lwjfpgvjlsu3y3cvekvmdrlp96ckeawxe" + ], + "value": "48995400" + } + ], + "vout": [ + { + "value": "1000000", + "n": 0, + "spent": true, + "hex": "0014f1d7be0993225222ff112362632b40cee213bd9a", + "addresses": [ + "via1q78tmuzvnyffz9lc3yd3xx26qem3p80v6rz6lue" + ] + }, + { + "value": "47881722", + "n": 1, + "spent": true, + "hex": "0014672602f8a96ad5a02df91792b5dcebfbb421fc3f", + "addresses": [ + "via1qvunq979fdt26qt0ez7ftth8tlw6zrlpl832ddu" + ] + } + ], + "blockHash": "43f683cab4827c11326a51dedb7d4eb2736b93702bc7e569377a581087e4f3d7", + "blockHeight": 6780089, + "confirmations": 835760, + "blockTime": 1569273836, + "value": "48881722", + "valueIn": "48995400", + "fees": "113678", + "hex": "01000000000101ca4c02dc6617cdc0eda8908f5b33ce6104ad30189e14a62b80d619dab2af057c0100000000000000000240420f0000000000160014f1d7be0993225222ff112362632b40cee213bd9afa9dda0200000000160014672602f8a96ad5a02df91792b5dcebfbb421fc3f02473044022022c5c99e2dbaa1c699d4449a846aa0d7b2b2ad9a547712a93d9ade6592fd23cf022056b19faf1a0f7702137b7da2c8f131b1a1d509092634241b61a29d9b3474f47f0121037b45b9e2a32072e7546971aa5b39c90558bcd4784817946976ccf93ead81d71a00000000" + }, + { + "txid": "5c52e68bb5c098edb2113d0a05f3e56acc421cb4733a98b831c2933c1f765578", + "version": 1, + "vin": [ + { + "txid": "c3ad35b33ba3d9c2b11335e6b2f63b3f60ee6a89e8f0f63f1c4a7867ac471410", + "vout": 1, + "n": 0, + "addresses": [ + "via1qvunq979fdt26qt0ez7ftth8tlw6zrlpl832ddu" + ], + "value": "47881722" + } + ], + "vout": [ + { + "value": "1000000", + "n": 0, + "spent": true, + "hex": "0014f1d7be0993225222ff112362632b40cee213bd9a", + "addresses": [ + "via1q78tmuzvnyffz9lc3yd3xx26qem3p80v6rz6lue" + ] + }, + { + "value": "46768044", + "n": 1, + "spent": true, + "hex": "0014672602f8a96ad5a02df91792b5dcebfbb421fc3f", + "addresses": [ + "via1qvunq979fdt26qt0ez7ftth8tlw6zrlpl832ddu" + ] + } + ], + "blockHash": "43f683cab4827c11326a51dedb7d4eb2736b93702bc7e569377a581087e4f3d7", + "blockHeight": 6780089, + "confirmations": 835760, + "blockTime": 1569273836, + "value": "47768044", + "valueIn": "47881722", + "fees": "113678", + "hex": "01000000000101101447ac67784a1c3ff6f0e8896aee603f3bf6b2e63513b1c2d9a33bb335adc30100000000000000000240420f0000000000160014f1d7be0993225222ff112362632b40cee213bd9aac9fc90200000000160014672602f8a96ad5a02df91792b5dcebfbb421fc3f024730440220169b26ddcb926c6c1660b8c36ec33ea3759d1309f45591a965b4cb22ab3317e60220531485fe11cb14f6207c70312cf1145d7d101782e6650d6e16ba77133159944c0121033068f399551ff7b26ba4e0a9e77d775a2de00f72c75dd696e9d4bb990507b73800000000" + }, + { + "txid": "67f57fffb949986e8e3a7ffb162246826f6a4c7868249f0ca01841c84ed849b5", + "version": 1, + "vin": [ + { + "txid": "2ae361d18204115b70ff6a4c9732731e17f7cbb74bba81e8da00ed59ccff341a", + "vout": 1, + "n": 0, + "addresses": [ + "via1q89sm5qp46gsz6v2fru3s9xts4l3zry4gh7t6ma" + ], + "value": "399774000" + } + ], + "vout": [ + { + "value": "100000000", + "n": 0, + "hex": "0014318c521111bce0532476791cd1ba35f141630758", + "addresses": [ + "via1qxxx9yyg3hns9xfrk0ywdrw3479qkxp6czjy88m" + ] + }, + { + "value": "299548000", + "n": 1, + "spent": true, + "hex": "0014c7bde13d26ed0448578023702500f62f4b689c3f", + "addresses": [ + "via1qc777z0fxa5zys4uqydcz2q8k9a9k38plskv9uj" + ] + } + ], + "blockHash": "18498d8579c63b3d8686bf8cac77cc45a2576252fad3bcbbd2c30eb82bee46ec", + "blockHeight": 6779825, + "confirmations": 836024, + "blockTime": 1569267386, + "value": "399548000", + "valueIn": "399774000", + "fees": "226000", + "hex": "010000000001011a34ffcc59ed00dae881ba4bb7cbf7171e7332974c6aff705b110482d161e32a0100000000000000000200e1f50500000000160014318c521111bce0532476791cd1ba35f14163075860bdda1100000000160014c7bde13d26ed0448578023702500f62f4b689c3f0247304402201d568d8335a7d33c44a61415c20b6c0806a1691a44469237587fd43e585037970220335d2bab70e5aa1b794b719ac49d904481bae8b0f9dfb586179285d1e44aece60121021d1d0eb5e3175a527826672498a86c3ccd64b73bb8c0659b601a1ceaf4e4521700000000" + }, + { + "txid": "7c05afb2da19d6802ba6149e1830ad0461ce335b8f90a8edc0cd1766dc024cca", + "version": 1, + "vin": [ + { + "txid": "4de1e3038e96ec2a5fcb6794d5929eeb29b1ef0c594310877260ab2ba28178ab", + "vout": 1, + "n": 0, + "addresses": [ + "via1qqffjd0qc7vxfrc3rp9phwvajlchg20e6lt3dmx" + ], + "value": "99221400" + } + ], + "vout": [ + { + "value": "50000000", + "n": 0, + "hex": "00148577f1eb6875c3999d4c5c758eb1de786225bdbf", + "addresses": [ + "via1qs4mlr6mgwhpen82vt36cavw70p3zt0dljekypn" + ] + }, + { + "value": "48995400", + "n": 1, + "spent": true, + "hex": "00144e2a48fdd24850c97e1c89238666ccdb47f09758", + "addresses": [ + "via1qfc4y3lwjfpgvjlsu3y3cvekvmdrlp96ckeawxe" + ] + } + ], + "blockHash": "d99d2b3fd6b0a12ba753976030fc58512c761701d4d6017a6dc0d733c2b116da", + "blockHeight": 6779783, + "confirmations": 836066, + "blockTime": 1569266470, + "value": "98995400", + "valueIn": "99221400", + "fees": "226000", + "hex": "01000000000101ab7881a22bab6072871043590cefb129eb9e92d59467cb5f2aec968e03e3e14d0100000000000000000280f0fa02000000001600148577f1eb6875c3999d4c5c758eb1de786225bdbf489ceb02000000001600144e2a48fdd24850c97e1c89238666ccdb47f09758024730440220162685e7ede00a699387514a18712e83688507bc3ffd5e4e1ebe004415dad2d602205793613e6fe1affff1218c2617c6be539e4dcd53ade1e32fab6d08927f0f4bd5012103a505d41830eadcdf44daefe4ac1ba38b68b331645ba13d5048d5d817b228374a00000000" + }, + { + "txid": "2ae361d18204115b70ff6a4c9732731e17f7cbb74bba81e8da00ed59ccff341a", + "version": 1, + "vin": [ + { + "txid": "dc42ddd940b64e9ff5f9e09e631b3796713ddb32bba866bcd6fdf37d646f34e9", + "sequence": 4294967294, + "n": 0, + "addresses": [ + "via1q72a3hy7xpcyc2leda6qkct6xfwej8s4v9r3az8" + ], + "value": "500000000" + } + ], + "vout": [ + { + "value": "100000000", + "n": 0, + "hex": "001423b4e2d36ba4da7f817acac1b7007dc9312ecda4", + "addresses": [ + "via1qyw6w95mt5nd8lqt6etqmwqraeycjandyl330rv" + ] + }, + { + "value": "399774000", + "n": 1, + "spent": true, + "hex": "00143961ba0035d2202d31491f23029970afe22192a8", + "addresses": [ + "via1q89sm5qp46gsz6v2fru3s9xts4l3zry4gh7t6ma" + ] + } + ], + "blockHash": "289b8b2d4b4941918154906dd27eb74a81079a1e7760f0f842d0e56c1ede179b", + "blockHeight": 6779738, + "confirmations": 836111, + "blockTime": 1569265554, + "value": "499774000", + "valueIn": "500000000", + "fees": "226000", + "hex": "01000000000101e9346f647df3fdd6bc66a8bb32db3d7196371b639ee0f9f59f4eb640d9dd42dc0000000000feffffff0200e1f5050000000016001423b4e2d36ba4da7f817acac1b7007dc9312ecda43011d417000000001600143961ba0035d2202d31491f23029970afe22192a802483045022100ef67ba5a6f7d520489e442593c28efd4caf6603a2c9d28a8e81114db140a1bb1022008fb9a91f39a1bb2a0dd34235a18974c2f61038f57f2acc7a267d849df21c80001210378804c3bc03d59f9d42990d300b9a0a6b2617bb4d212fbc876c8b52a5cc1aaed00000000" + }, + { + "txid": "7d8fc63757811fe4d273e3b42b494d13545cf0710cd821f7465572a7584c8642", + "version": 1, + "vin": [ + { + "txid": "01260aa2c76f779bcaffe5b8ffa2c94679f04f5b56bb37c219d7a1e8709681ba", + "vout": 1, + "n": 0, + "addresses": [ + "via1qs0q96xq7sewylsn6ymnvav8wgmzmdmvmjyxgnj" + ], + "value": "8000000000" + } + ], + "vout": [ + { + "value": "1000000000", + "n": 0, + "hex": "001492ab39fd32ac57ba3a7addbd877edd26a478c8d7", + "addresses": [ + "via1qj24nnlfj43tm5wn6mk7cwlkay6j83jxhj9wnqj" + ] + }, + { + "value": "6999774000", + "n": 1, + "spent": true, + "hex": "0014b8c03c32456c9c309210a6ec7f20825594b78ce9", + "addresses": [ + "via1qhrqrcvj9djwrpyss5mk87gyz2k2t0r8feacgpj" + ] + } + ], + "blockHash": "b0c22a4281142db8bfcbd4b93cc2b487aab7dd70bb503d429b981eb4bcee3631", + "blockHeight": 6646858, + "confirmations": 968991, + "blockTime": 1566071686, + "value": "7999774000", + "valueIn": "8000000000", + "fees": "226000", + "hex": "01000000000101ba819670e8a1d719c237bb565b4ff07946c9a2ffb8e5ffca9b776fc7a20a26010100000000000000000200ca9a3b0000000016001492ab39fd32ac57ba3a7addbd877edd26a478c8d7301338a101000000160014b8c03c32456c9c309210a6ec7f20825594b78ce902473044022022068961df34895c5a49390d9697f940d9bd8655b1638ff3ea8f39a83bd1107d022071a0a89d18670d7300f95b4400783960dbdfbf31e92e9fbfc60e4d815dbc1fd4012103d6f34e01ca999f901846a299cbd1f20c3b249b10a3f84f960973126abbc42cdb00000000" + }, + { + "txid": "4de1e3038e96ec2a5fcb6794d5929eeb29b1ef0c594310877260ab2ba28178ab", + "version": 1, + "vin": [ + { + "txid": "63c1ca0539d77934114fef011b4bf63ba69509eafcdc4b1a398e5668a69fe80a", + "vout": 1, + "sequence": 4294967292, + "n": 0, + "addresses": [ + "via1qupymhaypcepp2jhsgnxch5amgnf860jwqp3u6h" + ], + "value": "184447400" + } + ], + "vout": [ + { + "value": "85000000", + "n": 0, + "hex": "001453e45e03d888aaef8c94fc144859448ddd4ed36d", + "addresses": [ + "via1q20j9uq7c3z4wlry5ls2ysk2y3hw5a5mdv709m8" + ] + }, + { + "value": "99221400", + "n": 1, + "spent": true, + "hex": "0014025326bc18f30c91e22309437733b2fe2e853f3a", + "addresses": [ + "via1qqffjd0qc7vxfrc3rp9phwvajlchg20e6lt3dmx" + ] + } + ], + "blockHash": "51a8c267d36372c67b0c10cf1c5e95ae3f57a1d0a4ca2011bf3b2a240c797ceb", + "blockHeight": 6609941, + "confirmations": 1005908, + "blockTime": 1565184213, + "value": "184221400", + "valueIn": "184447400", + "fees": "226000", + "hex": "010000000001010ae89fa668568e391a4bdcfcea0995a63bf64b1b01ef4f113479d73905cac1630100000000fcffffff0240ff10050000000016001453e45e03d888aaef8c94fc144859448ddd4ed36d98ffe90500000000160014025326bc18f30c91e22309437733b2fe2e853f3a0247304402207b4c49cc91b7352e74082d75dc03a73b12ce69c2ba04b5036803313e540fc5a302207c0a5dc7af53d02e3a4d4ace4a8177d304c199bcfebec300064a637c08f65e8c012102bf4cb51b466fcce619d09e4b94c2989cb43a562e90f1cc2dfb83583226e6924200000000" + }, + { + "txid": "63c1ca0539d77934114fef011b4bf63ba69509eafcdc4b1a398e5668a69fe80a", + "version": 1, + "vin": [ + { + "txid": "053f581b81e25e470986d39b65684c7980f2ebcc9a024bd48ae3b8f9610910d3", + "vout": 1, + "sequence": 4294967294, + "n": 0, + "addresses": [ + "via1q9f0fhxl8sgrxegldfczed5lftf4wxy3c085ch2" + ], + "value": "191173400" + } + ], + "vout": [ + { + "value": "6500000", + "n": 0, + "hex": "001453e45e03d888aaef8c94fc144859448ddd4ed36d", + "addresses": [ + "via1q20j9uq7c3z4wlry5ls2ysk2y3hw5a5mdv709m8" + ] + }, + { + "value": "184447400", + "n": 1, + "spent": true, + "hex": "0014e049bbf481c642154af044cd8bd3bb44d27d3e4e", + "addresses": [ + "via1qupymhaypcepp2jhsgnxch5amgnf860jwqp3u6h" + ] + } + ], + "blockHash": "c8ec9dd52527c65404741e980d0cd36f5b56f30f3c9678fc30e6824485d75a06", + "blockHeight": 6609932, + "confirmations": 1005917, + "blockTime": 1565184011, + "value": "190947400", + "valueIn": "191173400", + "fees": "226000", + "hex": "01000000000101d3100961f9b8e38ad44b029accebf280794c68659bd38609475ee2811b583f050100000000feffffff02a02e63000000000016001453e45e03d888aaef8c94fc144859448ddd4ed36da871fe0a00000000160014e049bbf481c642154af044cd8bd3bb44d27d3e4e0247304402202768c6220d3e9b5640baffdf56b1196863d0a31b8efe88d656d504dc7eb02e720220359acab7fccf4ec647e3640256a92a46dbb542186ae0f9ebd3aadf9065eecab3012103a5ce3a1e5945c517b3e0b8843dccaa4fecb14ef243d536abe24480a2fd8c96c400000000" + }, + { + "txid": "01260aa2c76f779bcaffe5b8ffa2c94679f04f5b56bb37c219d7a1e8709681ba", + "version": 2, + "lockTime": 6301784, + "vin": [ + { + "txid": "773eb0c88439f8f97dc6f85537846d8afe536852fb4c08dbda69b6c89187b639", + "sequence": 4294967293, + "n": 0, + "addresses": [ + "EJ7xexKUB43nuGpZUvyVXreboogRAj2F6q" + ], + "value": "9300000000", + "hex": "16001423eb40fc587abc864be5996b6e38c974d01dd2a4" + } + ], + "vout": [ + { + "value": "1299967200", + "n": 0, + "hex": "0014c488f81733eac2080d4939e5b6fd70f18a493231", + "addresses": [ + "via1qcjy0s9enatpqsr2f88jmdlts7x9yjv33z5aj7x" + ] + }, + { + "value": "8000000000", + "n": 1, + "spent": true, + "hex": "001483c05d181e865c4fc27a26e6ceb0ee46c5b6ed9b", + "addresses": [ + "via1qs0q96xq7sewylsn6ymnvav8wgmzmdmvmjyxgnj" + ] + } + ], + "blockHash": "a2f204b450f1a1ae551fbc0355ae3b31e6f7080f04765761dcb2ff9af0beb29b", + "blockHeight": 6301790, + "confirmations": 1314059, + "blockTime": 1557777925, + "value": "9299967200", + "valueIn": "9300000000", + "fees": "32800", + "hex": "0200000000010139b68791c8b669dadb084cfb526853fe8a6d843755f8c67df9f83984c8b03e77000000001716001423eb40fc587abc864be5996b6e38c974d01dd2a4fdffffff02e0ec7b4d00000000160014c488f81733eac2080d4939e5b6fd70f18a4932310050d6dc0100000016001483c05d181e865c4fc27a26e6ceb0ee46c5b6ed9b02483045022100f86c406aca19b3df2429b612d23b3d1f0ede81969a7809b6979782aa1e886d2b022074c8186b06704bf8ffa0821241cf624e53be699be78c8a2243b7f58c8a38a3ad012102381b81cc88fbbe7c6dba6df6119d594232fe88e48e8f77201dd46ce4ae5120c158286000" + }, + { + "txid": "dc42ddd940b64e9ff5f9e09e631b3796713ddb32bba866bcd6fdf37d646f34e9", + "version": 1, + "vin": [ + { + "txid": "08fb8ccb9fd84b77618ac517246823482d483f1e8071e781dcfc750fc6a9062a", + "sequence": 4294967295, + "n": 0, + "addresses": [ + "via1q9elq2d3w7fy0t9e4dlq97ke5wwvl8c0lnp39lv" + ], + "value": "45647600" + }, + { + "txid": "93fb0d8004081b534040a98918b5459b05f6cdffca8c1380da6ba9eadb9a95a3", + "vout": 1, + "sequence": 4294967295, + "n": 1, + "addresses": [ + "EYqWehbaMwECMmGNqrQJnCgBmYiM4Xyzq8" + ], + "value": "2000000000", + "hex": "160014c5c8806f9b4121da84c2e71d84aaa493b6483780" + } + ], + "vout": [ + { + "value": "500000000", + "n": 0, + "spent": true, + "hex": "0014f2bb1b93c60e09857f2dee816c2f464bb323c2ac", + "addresses": [ + "via1q72a3hy7xpcyc2leda6qkct6xfwej8s4v9r3az8" + ] + }, + { + "value": "1545624400", + "n": 1, + "spent": true, + "hex": "0014e3830780b3479eb68be6514ac99142e845546434", + "addresses": [ + "via1quwps0q9ng70tdzlx299vny2zapz4gep5uqhcza" + ] + } + ], + "blockHash": "4d40765a8809d91e63c0a1ed388b8e401a2e4842bef7eb072ba264c47b0841ba", + "blockHeight": 6301606, + "confirmations": 1314243, + "blockTime": 1557773592, + "value": "2045624400", + "valueIn": "2045647600", + "fees": "23200", + "hex": "010000000001022a06a9c60f75fcdc81e771801e3f482d4823682417c58a61774bd89fcb8cfb080000000000ffffffffa3959adbeaa96bda80138ccaffcdf6059b45b51889a94040531b0804800dfb930100000017160014c5c8806f9b4121da84c2e71d84aaa493b6483780ffffffff020065cd1d00000000160014f2bb1b93c60e09857f2dee816c2f464bb323c2ac505b205c00000000160014e3830780b3479eb68be6514ac99142e845546434024830450221008a830b1ee71835ad2a4c31001b49dc4e0fed6fb64968de90c94d2a046c7ca07902201a63bafb30b4492a344bea0ef820118e64503bbf4e9fa4a4b41e6697cc461367012103126b31ef1559c206cb2e44071e944cc06075bc6291c9c9461bf5ea2045758f55024830450221008bd85781519ebd1cdaa8266ffb3fc658e2c2c426a0836299419c5b0b75cdaa4602200f626b4f67a6f513584a7d3eb30443de417acc6b12996db08653596ad82e9658012103b547c68a31e3b76b35d9146b535294930a5171646a915a213d1bfe2ee16c5a3800000000" + }, + { + "txid": "053f581b81e25e470986d39b65684c7980f2ebcc9a024bd48ae3b8f9610910d3", + "version": 1, + "vin": [ + { + "txid": "d52996ebc9fb16d7fca7cf1525d15e905418e5be8ea65bff0ddc356bdece7ae3", + "sequence": 4294967294, + "n": 0, + "addresses": [ + "via1qfw0fqy69hquwcss23vfzehtwaxmyygr0qs5hhl" + ], + "value": "196440000" + } + ], + "vout": [ + { + "value": "5244000", + "n": 0, + "hex": "001453e45e03d888aaef8c94fc144859448ddd4ed36d", + "addresses": [ + "via1q20j9uq7c3z4wlry5ls2ysk2y3hw5a5mdv709m8" + ] + }, + { + "value": "191173400", + "n": 1, + "spent": true, + "hex": "00142a5e9b9be782066ca3ed4e0596d3e95a6ae31238", + "addresses": [ + "via1q9f0fhxl8sgrxegldfczed5lftf4wxy3c085ch2" + ] + } + ], + "blockHash": "7149d870281bdba85945809863e34ce554a5d8c4d1f87bca8ef309430662a0a1", + "blockHeight": 6294326, + "confirmations": 1321523, + "blockTime": 1557598695, + "value": "196417400", + "valueIn": "196440000", + "fees": "22600", + "hex": "01000000000101e37acede6b35dc0dff5ba68ebee51854905ed12515cfa7fcd716fbc9eb9629d50000000000feffffff02600450000000000016001453e45e03d888aaef8c94fc144859448ddd4ed36d1813650b000000001600142a5e9b9be782066ca3ed4e0596d3e95a6ae312380247304402202626ce59799ce75e290cd16bb496a2e17a2a5c1670ef98e831cbcfe2ceb52cb502204237d5d75f759a74f81a8c575fcc1c9475059f578207a092ea2693c147c49b5a012102b9a28dacc8e9fae53c21becae0584357fab36731c90b295a819d859e4b7f6b7f00000000" + }, + { + "txid": "d52996ebc9fb16d7fca7cf1525d15e905418e5be8ea65bff0ddc356bdece7ae3", + "version": 1, + "vin": [ + { + "txid": "a0a853771d179d8470088256c619a84a931731979249c820d7c885213f499ec3", + "sequence": 4294967290, + "n": 0, + "addresses": [ + "via1q20j9uq7c3z4wlry5ls2ysk2y3hw5a5mdv709m8" + ], + "value": "200355200" + } + ], + "vout": [ + { + "value": "196440000", + "n": 0, + "spent": true, + "hex": "00144b9e901345b838ec420a8b122cdd6ee9b642206f", + "addresses": [ + "via1qfw0fqy69hquwcss23vfzehtwaxmyygr0qs5hhl" + ] + }, + { + "value": "3892600", + "n": 1, + "hex": "001427b6fa8e73f50a22d04072e591a2e7d541360469", + "addresses": [ + "via1qy7m04rnn759z95zqwtjergh864qnvprf7v7xcy" + ] + } + ], + "blockHash": "68ff8a072d6ddec6561194b33cd3a341cdc1a569fe161f5f69ed0703e78fd38a", + "blockHeight": 6294078, + "confirmations": 1321771, + "blockTime": 1557592523, + "value": "200332600", + "valueIn": "200355200", + "fees": "22600", + "hex": "01000000000101c39e493f2185c8d720c84992973117934aa819c656820870849d171d7753a8a00000000000faffffff02c06fb50b000000001600144b9e901345b838ec420a8b122cdd6ee9b642206f78653b000000000016001427b6fa8e73f50a22d04072e591a2e7d54136046902473044022045b9d5abbcfbff0c172908971fbd1fc96739e7013b68f964613627324103cb03022012c0b2dafc71660111e5edd34e37e394ad7a6634f1bdbeb62646e6bafd4dcb9401210315e1885595004e10a3be41030ca0ae3ad11bad0d290840a8a417e71f46b16d5000000000" + }, + { + "txid": "a0a853771d179d8470088256c619a84a931731979249c820d7c885213f499ec3", + "version": 1, + "vin": [ + { + "txid": "a807cc96408d93ba5537de360f68860a3c17329173501c33f6ae5f24ed390cf9", + "vout": 1, + "sequence": 4294967294, + "n": 0, + "addresses": [ + "via1qfw0fqy69hquwcss23vfzehtwaxmyygr0qs5hhl" + ], + "value": "200377800" + } + ], + "vout": [ + { + "value": "200355200", + "n": 0, + "spent": true, + "hex": "001453e45e03d888aaef8c94fc144859448ddd4ed36d", + "addresses": [ + "via1q20j9uq7c3z4wlry5ls2ysk2y3hw5a5mdv709m8" + ] + } + ], + "blockHash": "483c4a4ecccfe5bd940f3ad22c78ee6462709642cbc2cc82b9bcfd682361b8e4", + "blockHeight": 6294075, + "confirmations": 1321774, + "blockTime": 1557592449, + "value": "200355200", + "valueIn": "200377800", + "fees": "22600", + "hex": "01000000000101f90c39ed245faef6331c50739132173c0a86680f36de3755ba938d4096cc07a80100000000feffffff01802df10b0000000016001453e45e03d888aaef8c94fc144859448ddd4ed36d0247304402202e641fbe3f03aab0fa2e2abddd284e038b7e81f5ac496bdf437eeb8893f6c92b02200c1d34a9a96af0baeff4fbb845ce9f0eae0f53503e63cf72b058913efb430620012102b9a28dacc8e9fae53c21becae0584357fab36731c90b295a819d859e4b7f6b7f00000000" + }, + { + "txid": "a807cc96408d93ba5537de360f68860a3c17329173501c33f6ae5f24ed390cf9", + "version": 1, + "vin": [ + { + "txid": "d51ef863702bf5152900e1ea78f9d27df22904cab7aa004f7033966deccbbd06", + "vout": 1, + "sequence": 4294967294, + "n": 0, + "addresses": [ + "via1q7hnlgt3g8x8h2zyqjp557l0g24ryxkl9w0yvge" + ], + "value": "203988900" + } + ], + "vout": [ + { + "value": "3588500", + "n": 0, + "spent": true, + "hex": "00142677d00e44348ed8723c01fb8e12ced5db27e7f8", + "addresses": [ + "via1qyemaqrjyxj8dsu3uq8acuykw6hdj0elcueevju" + ] + }, + { + "value": "200377800", + "n": 1, + "spent": true, + "hex": "00144b9e901345b838ec420a8b122cdd6ee9b642206f", + "addresses": [ + "via1qfw0fqy69hquwcss23vfzehtwaxmyygr0qs5hhl" + ] + } + ], + "blockHash": "262dd8b5bd9006cac101676b69aaa5686626e98c782c2bb3daed97a3b8730ff1", + "blockHeight": 6289948, + "confirmations": 1325901, + "blockTime": 1557493487, + "value": "203966300", + "valueIn": "203988900", + "fees": "22600", + "hex": "0100000000010106bdcbec6d9633704f00aab7ca0429f27dd2f978eae1002915f52b7063f81ed50100000000feffffff0294c13600000000001600142677d00e44348ed8723c01fb8e12ced5db27e7f8c885f10b000000001600144b9e901345b838ec420a8b122cdd6ee9b642206f02483045022100e58997e0530db0a1947e9b939bccde4a9d7dc92ed5b67c2145064efcf795749a02200741b399a19366267b6738255794b19c668d3b4f094a968e45c9d08f485672c401210244dd18297b477142e681bc4cf5b5c9dde1e8bd22b0c246d56573cdef649a993000000000" + }, + { + "txid": "d51ef863702bf5152900e1ea78f9d27df22904cab7aa004f7033966deccbbd06", + "version": 1, + "vin": [ + { + "txid": "adac9e71a907cca1761ef2169130c1eae9dd67b5396ea4c7cdbfa9f47c789e05", + "sequence": 4294967294, + "n": 0, + "addresses": [ + "via1qwyddvzw5rak3v4qp7sxn703lnvevr976jg8lc7" + ], + "value": "205000000" + } + ], + "vout": [ + { + "value": "988500", + "n": 0, + "hex": "001453e45e03d888aaef8c94fc144859448ddd4ed36d", + "addresses": [ + "via1q20j9uq7c3z4wlry5ls2ysk2y3hw5a5mdv709m8" + ] + }, + { + "value": "203988900", + "n": 1, + "spent": true, + "hex": "0014f5e7f42e28398f75088090694f7de85546435be5", + "addresses": [ + "via1q7hnlgt3g8x8h2zyqjp557l0g24ryxkl9w0yvge" + ] + } + ], + "blockHash": "603ebc256ee81f518d3ce3405408f79036956f0e0daf68184c4ad752848fec71", + "blockHeight": 6289936, + "confirmations": 1325913, + "blockTime": 1557493227, + "value": "204977400", + "valueIn": "205000000", + "fees": "22600", + "hex": "01000000000101059e787cf4a9bfcdc7a46e39b567dde9eac1309116f21e76a1cc07a9719eacad0000000000feffffff0254150f000000000016001453e45e03d888aaef8c94fc144859448ddd4ed36da49f280c00000000160014f5e7f42e28398f75088090694f7de85546435be502473044022059795753c9a3997c60fd6dfd1ee8ef58a404e8e193c4b3404d2003d5c8783cc102205ebbb9b615e39c99c74a2858b90ab1e206d31cfb3754bd3b80d095811770c11c01210344786208c833b70374d4dd49d151d9ff3454b401e6577757e2cf72b256a1979400000000" + }, + { + "txid": "adac9e71a907cca1761ef2169130c1eae9dd67b5396ea4c7cdbfa9f47c789e05", + "version": 1, + "vin": [ + { + "txid": "f5bc1231dc7337d7cdb9eb59d0496fab61378cb2b78563e372edb97f7a3581e5", + "sequence": 4294967293, + "n": 0, + "addresses": [ + "via1q20j9uq7c3z4wlry5ls2ysk2y3hw5a5mdv709m8" + ], + "value": "207854800" + } + ], + "vout": [ + { + "value": "205000000", + "n": 0, + "spent": true, + "hex": "0014711ad609d41f6d165401f40d3f3e3f9b32c197da", + "addresses": [ + "via1qwyddvzw5rak3v4qp7sxn703lnvevr976jg8lc7" + ] + }, + { + "value": "2832200", + "n": 1, + "hex": "001419f6fdd1a3bab54d58fe697d1a4f36c7393a2f0a", + "addresses": [ + "via1qr8m0m5drh2656k87d9735nekcuun5tc239kzyv" + ] + } + ], + "blockHash": "40ed688764298e87b7ee5cb47c163aa1f9883b6329b4e68e69043fe67b480cc2", + "blockHeight": 6289612, + "confirmations": 1326237, + "blockTime": 1557485360, + "value": "207832200", + "valueIn": "207854800", + "fees": "22600", + "hex": "01000000000101e581357a7fb9ed72e36385b7b28c3761ab6f49d059ebb9cdd73773dc3112bcf50000000000fdffffff02400d380c00000000160014711ad609d41f6d165401f40d3f3e3f9b32c197da48372b000000000016001419f6fdd1a3bab54d58fe697d1a4f36c7393a2f0a02473044022068803fbd0b8c77dd05cc075e51ebdab96c30d68cabbc29fd5ed78298e61559480220078686b023c0d3d684c1ed1fd7f5bbc0f92fb48288b591346cdbd6baef5ef9c001210315e1885595004e10a3be41030ca0ae3ad11bad0d290840a8a417e71f46b16d5000000000" + }, + { + "txid": "f5bc1231dc7337d7cdb9eb59d0496fab61378cb2b78563e372edb97f7a3581e5", + "version": 1, + "vin": [ + { + "txid": "28595f9ffe04d875043a88fd6fc4b7a48a27a3e2cb82834d610b40677a686466", + "vout": 1, + "sequence": 4294967294, + "n": 0, + "addresses": [ + "via1qzx37ahs0ua840ulkrdgh3mt4euzme25zu5j42k" + ], + "value": "207877400" + } + ], + "vout": [ + { + "value": "207854800", + "n": 0, + "spent": true, + "hex": "001453e45e03d888aaef8c94fc144859448ddd4ed36d", + "addresses": [ + "via1q20j9uq7c3z4wlry5ls2ysk2y3hw5a5mdv709m8" + ] + } + ], + "blockHash": "a6fe317eda080d0b3f9a8c21f277b3b83ff6b8ec11742bd6de1dd5c1a9adbaa9", + "blockHeight": 6289598, + "confirmations": 1326251, + "blockTime": 1557485034, + "value": "207854800", + "valueIn": "207877400", + "fees": "22600", + "hex": "010000000001016664687a67400b614d8382cbe2a3278aa4b7c46ffd883a0475d804fe9f5f59280100000000feffffff01d09c630c0000000016001453e45e03d888aaef8c94fc144859448ddd4ed36d02483045022100cf778eb2fe629653d565e3238dc8da5f0172b6320dadfce30808d43370aad44d02203b36044c1051aded9631edc737043aad28b6c8ce2991e62ffe2492dfb39dea6001210392e7c7848932c0c8d7c726fdf955c40148f9ec6166d1fff3bbee835c6448fe2400000000" + }, + { + "txid": "28595f9ffe04d875043a88fd6fc4b7a48a27a3e2cb82834d610b40677a686466", + "version": 1, + "vin": [ + { + "txid": "34bc3cc597340945e4cae362684605f211a062c47d092db3bd7b9cb0a3365871", + "sequence": 4294967294, + "n": 0, + "addresses": [ + "via1qxdul6szs3mppq8s3cdge5vtpthnw0dnn06m5qp" + ], + "value": "210000000" + } + ], + "vout": [ + { + "value": "2100000", + "n": 0, + "hex": "001453e45e03d888aaef8c94fc144859448ddd4ed36d", + "addresses": [ + "via1q20j9uq7c3z4wlry5ls2ysk2y3hw5a5mdv709m8" + ] + }, + { + "value": "207877400", + "n": 1, + "spent": true, + "hex": "001411a3eede0fe74f57f3f61b5178ed75cf05bcaa82", + "addresses": [ + "via1qzx37ahs0ua840ulkrdgh3mt4euzme25zu5j42k" + ] + } + ], + "blockHash": "bc4ce65e505e62a2924fcbcd475c28f52fdf32fc92c76385277ce970ed51c52d", + "blockHeight": 6289161, + "confirmations": 1326688, + "blockTime": 1557474602, + "value": "209977400", + "valueIn": "210000000", + "fees": "22600", + "hex": "01000000000101715836a3b09c7bbdb32d097dc462a011f205466862e3cae445093497c53cbc340000000000feffffff02200b20000000000016001453e45e03d888aaef8c94fc144859448ddd4ed36d18f5630c0000000016001411a3eede0fe74f57f3f61b5178ed75cf05bcaa8202483045022100e2e680715b7df28e351786e05bcebe480fbb140a571374f47fece1a75cdfc47a02207830a798ed4cf273444305c9bffb9d4437322c3af170a0788cdc5a73310ee8fe012102b5e09e1dbb76a0eeebea67bf80069ce41c26c81d0f06d1dd42e712ebf55de4bc00000000" + }, + { + "txid": "34bc3cc597340945e4cae362684605f211a062c47d092db3bd7b9cb0a3365871", + "version": 1, + "vin": [ + { + "txid": "08fb8ccb9fd84b77618ac517246823482d483f1e8071e781dcfc750fc6a9062a", + "vout": 1, + "n": 0, + "addresses": [ + "via1qtphs73pytedrd6dxs2h695d0f5jtjxns95zykv" + ], + "value": "500000000" + } + ], + "vout": [ + { + "value": "210000000", + "n": 0, + "spent": true, + "hex": "00143379fd40508ec2101e11c3519a31615de6e7b673", + "addresses": [ + "via1qxdul6szs3mppq8s3cdge5vtpthnw0dnn06m5qp" + ] + }, + { + "value": "289977400", + "n": 1, + "spent": true, + "hex": "0014dd01ab573b2f4ca9aac3f89d101263be78896af4", + "addresses": [ + "via1qm5q6k4em9ax2n2krlzw3qynrheugj6h5vffra6" + ] + } + ], + "blockHash": "78dd08436d7baf989cafd3ef81905f5ca202ad0b971ec3040c93445b52ae626b", + "blockHeight": 6274638, + "confirmations": 1341211, + "blockTime": 1557125330, + "value": "499977400", + "valueIn": "500000000", + "fees": "22600", + "hex": "010000000001012a06a9c60f75fcdc81e771801e3f482d4823682417c58a61774bd89fcb8cfb08010000000000000000028058840c000000001600143379fd40508ec2101e11c3519a31615de6e7b67338b4481100000000160014dd01ab573b2f4ca9aac3f89d101263be78896af402473044022004607ace08c398815bb7218d514facd12444d0e740576b135d201d50c857b1ad0220010f726c44099352693a90c25939ef046006ef157763f0133a4b79b81d1010bd012103a8cfde9f4308008b74eb5649a5660c5f3657a892e4e971efbe5a6b9894a118e900000000" + } + ], + "usedTokens": 40, + "tokens": [ + { + "type": "XPUBAddress", + "name": "via1qxdul6szs3mppq8s3cdge5vtpthnw0dnn06m5qp", + "path": "m/84'/14'/0'/0/0", + "transfers": 8, + "decimals": 8, + "balance": "740523040", + "totalReceived": "9544362154", + "totalSent": "8803839114" + } + ] +} diff --git a/mock/ext-api-data/waves-api_transactions_address_3PJ4q4sqriJs2y7Z45wmbLrbmV9MDecbPxD_limit_25.json b/mock/ext-api-data/waves-api_transactions_address_3PJ4q4sqriJs2y7Z45wmbLrbmV9MDecbPxD_limit_25.json new file mode 100644 index 000000000..a1e4d98ca --- /dev/null +++ b/mock/ext-api-data/waves-api_transactions_address_3PJ4q4sqriJs2y7Z45wmbLrbmV9MDecbPxD_limit_25.json @@ -0,0 +1,183 @@ +[ + [ + { + "senderPublicKey": "2UstBx1nMYQ2mPeaJi6tv9oUFCUHLvU1G7nS8Leazsbw", + "amount": 369133368000, + "signature": "5Hw5SW7C1EK8hE2YKawFCAWcJoB1Z5NSZFkA65bS3PcDY9w2fi7etPCJDamK2WNb14RWa3BykdT5yFd64SxodjeQ", + "fee": 100000, + "type": 4, + "version": 1, + "attachment": "", + "sender": "3PJ4q4sqriJs2y7Z45wmbLrbmV9MDecbPxD", + "feeAssetId": null, + "proofs": [ + "5Hw5SW7C1EK8hE2YKawFCAWcJoB1Z5NSZFkA65bS3PcDY9w2fi7etPCJDamK2WNb14RWa3BykdT5yFd64SxodjeQ" + ], + "assetId": null, + "recipient": "3PLrCnhKyX5iFbGDxbqqMvea5VAqxMcinPW", + "feeAsset": null, + "id": "23JGFzBh65fzZArK6KSeRqjjBG5WnQshJJkUv53hCE1E", + "timestamp": 1582527770493, + "height": 1943922 + }, + { + "senderPublicKey": "3uT3a9ceebFf6vEa5DmedD5pK6xa1GY7PnvhWPMVyqxC", + "amount": 369133468000, + "signature": "3Nrz47KpD3U39Nf7Los23MDoukqXCrCJun1BqnUgjpy9iZLfXc163dTrz4wVvURC2yiULsNYDYA2pxTPGWpBotc5", + "fee": 100000, + "type": 4, + "version": 1, + "attachment": "Paribu", + "sender": "3PHYYqBA6ZfBsoGsrXP8r7ZptLXYdGDt1Cm", + "feeAssetId": null, + "proofs": [ + "3Nrz47KpD3U39Nf7Los23MDoukqXCrCJun1BqnUgjpy9iZLfXc163dTrz4wVvURC2yiULsNYDYA2pxTPGWpBotc5" + ], + "assetId": null, + "recipient": "3PJ4q4sqriJs2y7Z45wmbLrbmV9MDecbPxD", + "feeAsset": null, + "id": "1456haw7zSTKDmVSbY1njrYdskX7xKbv241c5WJjWhCu", + "timestamp": 1582527244669, + "height": 1943911 + }, + { + "senderPublicKey": "2UstBx1nMYQ2mPeaJi6tv9oUFCUHLvU1G7nS8Leazsbw", + "amount": 698850000, + "signature": "3NzepUFYyrCPaK6GgVZW47hxQpMTaA3ETvYYA2QVGvbGaQWhxhuWW6nmED9SdmwNqq1tksWt2BVJM8B4NAGtPUiy", + "fee": 100000, + "type": 4, + "version": 1, + "attachment": "", + "sender": "3PJ4q4sqriJs2y7Z45wmbLrbmV9MDecbPxD", + "feeAssetId": null, + "proofs": [ + "3NzepUFYyrCPaK6GgVZW47hxQpMTaA3ETvYYA2QVGvbGaQWhxhuWW6nmED9SdmwNqq1tksWt2BVJM8B4NAGtPUiy" + ], + "assetId": null, + "recipient": "3PLrCnhKyX5iFbGDxbqqMvea5VAqxMcinPW", + "feeAsset": null, + "id": "E9iL8JuspsUvf1umcWSir62wU9jsmUUU1ENbLPHJBu8z", + "timestamp": 1582257653562, + "height": 1939356 + }, + { + "senderPublicKey": "3uT3a9ceebFf6vEa5DmedD5pK6xa1GY7PnvhWPMVyqxC", + "amount": 698950000, + "signature": "5bW75Bk5oVzr9jNWa5sPCGJn5jC7zA4Z66kLGVgHznAXa54217HHMdto6yNEQfq7Qy3jh1oBE9EbnSzKP7sSCGNd", + "fee": 100000, + "type": 4, + "version": 1, + "attachment": "Paribu", + "sender": "3PHYYqBA6ZfBsoGsrXP8r7ZptLXYdGDt1Cm", + "feeAssetId": null, + "proofs": [ + "5bW75Bk5oVzr9jNWa5sPCGJn5jC7zA4Z66kLGVgHznAXa54217HHMdto6yNEQfq7Qy3jh1oBE9EbnSzKP7sSCGNd" + ], + "assetId": null, + "recipient": "3PJ4q4sqriJs2y7Z45wmbLrbmV9MDecbPxD", + "feeAsset": null, + "id": "AAkVWcPTPPAUxE86sK1Buvb4CzurLr8x3FLFR5U85cQz", + "timestamp": 1582256644982, + "height": 1939340 + }, + { + "senderPublicKey": "2UstBx1nMYQ2mPeaJi6tv9oUFCUHLvU1G7nS8Leazsbw", + "amount": 38291930000, + "signature": "4whJCn9BsVQfEsETHhAu9brPoPRCwHXnVz7mA7vA6fAY7Lth26brP6QmZdgsxHcw7Vr9n7WeRooBE2PBGbh2EduK", + "fee": 100000, + "type": 4, + "version": 1, + "attachment": "", + "sender": "3PJ4q4sqriJs2y7Z45wmbLrbmV9MDecbPxD", + "feeAssetId": null, + "proofs": [ + "4whJCn9BsVQfEsETHhAu9brPoPRCwHXnVz7mA7vA6fAY7Lth26brP6QmZdgsxHcw7Vr9n7WeRooBE2PBGbh2EduK" + ], + "assetId": null, + "recipient": "3PLrCnhKyX5iFbGDxbqqMvea5VAqxMcinPW", + "feeAsset": null, + "id": "ALSHobQKkMkeeUySE1yK9s5FMLXmLYgSJ7b3jSCtGctr", + "timestamp": 1579504858670, + "height": 1892719 + }, + { + "senderPublicKey": "2otUJmrNBWHahdA9jUeBTLnW7g43hVfVKNyws9f1LFtR", + "amount": 38292030000, + "signature": "2oMvzrnMZzWX7Ne2McY8Zi3QZAHFMeomz4DiWGZLSRbMGC5W6h3aqDpo65TRrutLQ6p6UyWznxA67fPg3u2C8mo8", + "fee": 100000, + "type": 4, + "version": 1, + "attachment": "Paribu", + "sender": "3PEDjPSkKrMtaaJJLGfL849Fg39TSZ7WGzY", + "feeAssetId": null, + "proofs": [ + "2oMvzrnMZzWX7Ne2McY8Zi3QZAHFMeomz4DiWGZLSRbMGC5W6h3aqDpo65TRrutLQ6p6UyWznxA67fPg3u2C8mo8" + ], + "assetId": null, + "recipient": "3PJ4q4sqriJs2y7Z45wmbLrbmV9MDecbPxD", + "feeAsset": null, + "id": "EvTk5zX9vQTDD9qKPuGGHjAUzcbkeRjemWMqioubUNUV", + "timestamp": 1579503724349, + "height": 1892702 + }, + { + "senderPublicKey": "5LNhM4E1AkNcB4j5cYPVi4dcu6puMU9v83iKDt8w8V54", + "amount": 550000000, + "fee": 100000, + "type": 4, + "version": 2, + "attachment": "3cdoipiKbLBweYBgvay72xUe8WjA24XCcyyfxPmJimVgtvSUfecpFhFe2GdotgUwNhHKT6dqAHcp8FeESFpqPv3RoxcSR62Bv3LG", + "sender": "3PPqRC9iYTcgz16RLjpMJhevxStDJGcmgFr", + "feeAssetId": null, + "proofs": [ + "2r52JRLPFmrAnLnrYfdmCit6cmquDrW7GpRDVXnSqk8gYwKwuGrWdj2r9kS9MNHXnTVpvPFqCKDFmJjTuaqEubM6" + ], + "assetId": "8Yw4QmskrQauQeNjgh2fTQ4swmkNm85GTQzdHEf6QdUU", + "recipient": "3PJ4q4sqriJs2y7Z45wmbLrbmV9MDecbPxD", + "feeAsset": null, + "id": "FTTrC3xr3YAk8MeehkS4LbGLnzsYcmaJMfLdyezAhWte", + "timestamp": 1579189633267, + "height": 1887377 + }, + { + "senderPublicKey": "2UstBx1nMYQ2mPeaJi6tv9oUFCUHLvU1G7nS8Leazsbw", + "amount": 55628399500, + "signature": "5gsoW82BqH83gUWqTGUCL6cAdGeNnycVBvSKVJRGopaLbnHXVTBUdYQgL2zwjudHQ7DnYUyrAauDTLBFa91Pj97U", + "fee": 100000, + "type": 4, + "version": 1, + "attachment": "", + "sender": "3PJ4q4sqriJs2y7Z45wmbLrbmV9MDecbPxD", + "feeAssetId": null, + "proofs": [ + "5gsoW82BqH83gUWqTGUCL6cAdGeNnycVBvSKVJRGopaLbnHXVTBUdYQgL2zwjudHQ7DnYUyrAauDTLBFa91Pj97U" + ], + "assetId": null, + "recipient": "3PLrCnhKyX5iFbGDxbqqMvea5VAqxMcinPW", + "feeAsset": null, + "id": "8CKBhfKiJQENKyjbySzaTshgcHd6tNccHu6oxQKXihBc", + "timestamp": 1579171201233, + "height": 1887049 + }, + { + "senderPublicKey": "2otUJmrNBWHahdA9jUeBTLnW7g43hVfVKNyws9f1LFtR", + "amount": 55628499500, + "signature": "QiDKpBkSECdxmRaBknCthgrjU3NXgWXWxNmHzv3bKLHCTFxg3hTe2Bnpv1UJFk1F9b9FJLXZzGm35C5fdXTXvxM", + "fee": 100000, + "type": 4, + "version": 1, + "attachment": "Paribu", + "sender": "3PEDjPSkKrMtaaJJLGfL849Fg39TSZ7WGzY", + "feeAssetId": null, + "proofs": [ + "QiDKpBkSECdxmRaBknCthgrjU3NXgWXWxNmHzv3bKLHCTFxg3hTe2Bnpv1UJFk1F9b9FJLXZzGm35C5fdXTXvxM" + ], + "assetId": null, + "recipient": "3PJ4q4sqriJs2y7Z45wmbLrbmV9MDecbPxD", + "feeAsset": null, + "id": "BNDCzVPK2j65Aunq7SavSNMWbn1N8iNxCwi4Hib1C2qt", + "timestamp": 1579063084088, + "height": 1885216 + } + ] +] \ No newline at end of file diff --git a/mock/ext-api-data/zcash-api_v2_address_t1LwLWo1Mo3s4RPtUpeyUD1eYd47inL3bwX__details_txs.json b/mock/ext-api-data/zcash-api_v2_address_t1LwLWo1Mo3s4RPtUpeyUD1eYd47inL3bwX__details_txs.json new file mode 100644 index 000000000..7a19d4c21 --- /dev/null +++ b/mock/ext-api-data/zcash-api_v2_address_t1LwLWo1Mo3s4RPtUpeyUD1eYd47inL3bwX__details_txs.json @@ -0,0 +1 @@ +{"page":1,"totalPages":206,"itemsOnPage":10,"address":"t1LwLWo1Mo3s4RPtUpeyUD1eYd47inL3bwX","balance":"12344656","totalReceived":"109663825939","totalSent":"109651481283","unconfirmedBalance":"0","unconfirmedTxs":0,"txs":2058,"transactions":[{"txid":"a81cae38d27445ad22dad26b60e10753e7b03aa6a0f58578d554f7702bf7f440","version":4,"vin":[{"sequence":4294967295,"n":0,"isAddress":false,"coinbase":"032bcb0c0044656661756c7420732d6e6f6d7020706f6f6c2068747470733a2f2f6769746875622e636f6d2f732d6e6f6d702f732d6e6f6d702f77696b692f496e73696768742d706f6f6c2d6c696e6b"}],"vout":[{"value":"0","n":0,"hex":"76a914219d1bea95fc9c401d4073a20f840c71fc1a920288ac","addresses":["t1LwLWo1Mo3s4RPtUpeyUD1eYd47inL3bwX"],"isAddress":true},{"value":"125000000","n":1,"hex":"a914accba16ec3b9fa60ca3143419c81e9fc4217d05a87","addresses":["t3aKH6NiWN1ofGd8c19rZiqgYpkJ3n679ME"],"isAddress":true},{"value":"6250000","n":2,"spent":true,"hex":"76a914f82c1c9f44630fe1a9ab4cb1b5023c91ee4ddae688ac","addresses":["t1gVpRrLdr8R2M2RaGisWZRspEF8EZvLZHv"],"isAddress":true},{"value":"493750000","n":3,"spent":true,"hex":"76a914521d713a3660b86d03ab6c68358433c30389ea1f88ac","addresses":["t1RMngkaWf2F8EDrpzQ1fhLBhfi89L14tN2"],"isAddress":true}],"blockHash":"000000000194e6f92ba9ee20ed1ca0396858aca572898742e8920fa0ab0ae17e","blockHeight":838443,"confirmations":510,"blockTime":1590031334,"value":"625000000","valueIn":"0","fees":"0","hex":"0400008085202f89010000000000000000000000000000000000000000000000000000000000000000ffffffff50032bcb0c0044656661756c7420732d6e6f6d7020706f6f6c2068747470733a2f2f6769746875622e636f6d2f732d6e6f6d702f732d6e6f6d702f77696b692f496e73696768742d706f6f6c2d6c696e6bffffffff0400000000000000001976a914219d1bea95fc9c401d4073a20f840c71fc1a920288ac405973070000000017a914accba16ec3b9fa60ca3143419c81e9fc4217d05a87105e5f00000000001976a914f82c1c9f44630fe1a9ab4cb1b5023c91ee4ddae688acf0066e1d000000001976a914521d713a3660b86d03ab6c68358433c30389ea1f88ac00000000000000000000000000000000000000"},{"txid":"5af8584d87cbe7bf286def0325b23b42b6ebc380d4ebb4691e0c9e4b12ab13c2","version":4,"vin":[{"sequence":4294967295,"n":0,"isAddress":false,"coinbase":"031acb0c0044656661756c7420732d6e6f6d7020706f6f6c2068747470733a2f2f6769746875622e636f6d2f732d6e6f6d702f732d6e6f6d702f77696b692f496e73696768742d706f6f6c2d6c696e6b"}],"vout":[{"value":"0","n":0,"hex":"76a914219d1bea95fc9c401d4073a20f840c71fc1a920288ac","addresses":["t1LwLWo1Mo3s4RPtUpeyUD1eYd47inL3bwX"],"isAddress":true},{"value":"125000000","n":1,"hex":"a914accba16ec3b9fa60ca3143419c81e9fc4217d05a87","addresses":["t3aKH6NiWN1ofGd8c19rZiqgYpkJ3n679ME"],"isAddress":true},{"value":"6250000","n":2,"spent":true,"hex":"76a914f82c1c9f44630fe1a9ab4cb1b5023c91ee4ddae688ac","addresses":["t1gVpRrLdr8R2M2RaGisWZRspEF8EZvLZHv"],"isAddress":true},{"value":"493750000","n":3,"spent":true,"hex":"76a914521d713a3660b86d03ab6c68358433c30389ea1f88ac","addresses":["t1RMngkaWf2F8EDrpzQ1fhLBhfi89L14tN2"],"isAddress":true}],"blockHash":"0000000000d49a802d7ee6dd713cd8eddbf8fb308eda8ec96deec7b0d1140cc5","blockHeight":838426,"confirmations":527,"blockTime":1590030285,"value":"625000000","valueIn":"0","fees":"0","hex":"0400008085202f89010000000000000000000000000000000000000000000000000000000000000000ffffffff50031acb0c0044656661756c7420732d6e6f6d7020706f6f6c2068747470733a2f2f6769746875622e636f6d2f732d6e6f6d702f732d6e6f6d702f77696b692f496e73696768742d706f6f6c2d6c696e6bffffffff0400000000000000001976a914219d1bea95fc9c401d4073a20f840c71fc1a920288ac405973070000000017a914accba16ec3b9fa60ca3143419c81e9fc4217d05a87105e5f00000000001976a914f82c1c9f44630fe1a9ab4cb1b5023c91ee4ddae688acf0066e1d000000001976a914521d713a3660b86d03ab6c68358433c30389ea1f88ac00000000000000000000000000000000000000"},{"txid":"e81a55bf227c8589bf22452ee0c958b491865917a09c56afb614d12db77c0697","version":4,"vin":[{"sequence":4294967295,"n":0,"isAddress":false,"coinbase":"03d7ca0c0044656661756c7420732d6e6f6d7020706f6f6c2068747470733a2f2f6769746875622e636f6d2f732d6e6f6d702f732d6e6f6d702f77696b692f496e73696768742d706f6f6c2d6c696e6b"}],"vout":[{"value":"0","n":0,"hex":"76a914219d1bea95fc9c401d4073a20f840c71fc1a920288ac","addresses":["t1LwLWo1Mo3s4RPtUpeyUD1eYd47inL3bwX"],"isAddress":true},{"value":"125000000","n":1,"hex":"a914accba16ec3b9fa60ca3143419c81e9fc4217d05a87","addresses":["t3aKH6NiWN1ofGd8c19rZiqgYpkJ3n679ME"],"isAddress":true},{"value":"6250000","n":2,"spent":true,"hex":"76a914f82c1c9f44630fe1a9ab4cb1b5023c91ee4ddae688ac","addresses":["t1gVpRrLdr8R2M2RaGisWZRspEF8EZvLZHv"],"isAddress":true},{"value":"493750000","n":3,"spent":true,"hex":"76a914521d713a3660b86d03ab6c68358433c30389ea1f88ac","addresses":["t1RMngkaWf2F8EDrpzQ1fhLBhfi89L14tN2"],"isAddress":true}],"blockHash":"00000000021580cfb80cc7ddfa6d3b8e585a8612eb11d60d66cd6d6be43832f2","blockHeight":838359,"confirmations":594,"blockTime":1590024601,"value":"625000000","valueIn":"0","fees":"0","hex":"0400008085202f89010000000000000000000000000000000000000000000000000000000000000000ffffffff5003d7ca0c0044656661756c7420732d6e6f6d7020706f6f6c2068747470733a2f2f6769746875622e636f6d2f732d6e6f6d702f732d6e6f6d702f77696b692f496e73696768742d706f6f6c2d6c696e6bffffffff0400000000000000001976a914219d1bea95fc9c401d4073a20f840c71fc1a920288ac405973070000000017a914accba16ec3b9fa60ca3143419c81e9fc4217d05a87105e5f00000000001976a914f82c1c9f44630fe1a9ab4cb1b5023c91ee4ddae688acf0066e1d000000001976a914521d713a3660b86d03ab6c68358433c30389ea1f88ac00000000000000000000000000000000000000"},{"txid":"4ec0d7d0a12c5eb7eaeb13907c0e059d07f6800115344df3ad9c6be3fe16f773","version":4,"vin":[{"sequence":4294967295,"n":0,"isAddress":false,"coinbase":"03cdc90c0044656661756c7420732d6e6f6d7020706f6f6c2068747470733a2f2f6769746875622e636f6d2f732d6e6f6d702f732d6e6f6d702f77696b692f496e73696768742d706f6f6c2d6c696e6b"}],"vout":[{"value":"0","n":0,"hex":"76a914219d1bea95fc9c401d4073a20f840c71fc1a920288ac","addresses":["t1LwLWo1Mo3s4RPtUpeyUD1eYd47inL3bwX"],"isAddress":true},{"value":"125000000","n":1,"hex":"a914accba16ec3b9fa60ca3143419c81e9fc4217d05a87","addresses":["t3aKH6NiWN1ofGd8c19rZiqgYpkJ3n679ME"],"isAddress":true},{"value":"6250000","n":2,"spent":true,"hex":"76a914f82c1c9f44630fe1a9ab4cb1b5023c91ee4ddae688ac","addresses":["t1gVpRrLdr8R2M2RaGisWZRspEF8EZvLZHv"],"isAddress":true},{"value":"493750000","n":3,"spent":true,"hex":"76a914521d713a3660b86d03ab6c68358433c30389ea1f88ac","addresses":["t1RMngkaWf2F8EDrpzQ1fhLBhfi89L14tN2"],"isAddress":true}],"blockHash":"0000000000cc015ff69beb89862035a623cb63c83a5b037066157067829fc077","blockHeight":838093,"confirmations":860,"blockTime":1590004400,"value":"625000000","valueIn":"0","fees":"0","hex":"0400008085202f89010000000000000000000000000000000000000000000000000000000000000000ffffffff5003cdc90c0044656661756c7420732d6e6f6d7020706f6f6c2068747470733a2f2f6769746875622e636f6d2f732d6e6f6d702f732d6e6f6d702f77696b692f496e73696768742d706f6f6c2d6c696e6bffffffff0400000000000000001976a914219d1bea95fc9c401d4073a20f840c71fc1a920288ac405973070000000017a914accba16ec3b9fa60ca3143419c81e9fc4217d05a87105e5f00000000001976a914f82c1c9f44630fe1a9ab4cb1b5023c91ee4ddae688acf0066e1d000000001976a914521d713a3660b86d03ab6c68358433c30389ea1f88ac00000000000000000000000000000000000000"},{"txid":"1fcd9251ec885b1ca028f702317ddd651b101a43d8516025f450518b0a388a8c","version":4,"vin":[{"sequence":4294967295,"n":0,"isAddress":false,"coinbase":"03acc90c0044656661756c7420732d6e6f6d7020706f6f6c2068747470733a2f2f6769746875622e636f6d2f732d6e6f6d702f732d6e6f6d702f77696b692f496e73696768742d706f6f6c2d6c696e6b"}],"vout":[{"value":"0","n":0,"hex":"76a914219d1bea95fc9c401d4073a20f840c71fc1a920288ac","addresses":["t1LwLWo1Mo3s4RPtUpeyUD1eYd47inL3bwX"],"isAddress":true},{"value":"125000000","n":1,"hex":"a914accba16ec3b9fa60ca3143419c81e9fc4217d05a87","addresses":["t3aKH6NiWN1ofGd8c19rZiqgYpkJ3n679ME"],"isAddress":true},{"value":"6250000","n":2,"spent":true,"hex":"76a914f82c1c9f44630fe1a9ab4cb1b5023c91ee4ddae688ac","addresses":["t1gVpRrLdr8R2M2RaGisWZRspEF8EZvLZHv"],"isAddress":true},{"value":"493750000","n":3,"spent":true,"hex":"76a914521d713a3660b86d03ab6c68358433c30389ea1f88ac","addresses":["t1RMngkaWf2F8EDrpzQ1fhLBhfi89L14tN2"],"isAddress":true}],"blockHash":"000000000285693849986f6d070445fe86ca3b2ac60644e7d7921b8ec35408f9","blockHeight":838060,"confirmations":893,"blockTime":1590001994,"value":"625000000","valueIn":"0","fees":"0","hex":"0400008085202f89010000000000000000000000000000000000000000000000000000000000000000ffffffff5003acc90c0044656661756c7420732d6e6f6d7020706f6f6c2068747470733a2f2f6769746875622e636f6d2f732d6e6f6d702f732d6e6f6d702f77696b692f496e73696768742d706f6f6c2d6c696e6bffffffff0400000000000000001976a914219d1bea95fc9c401d4073a20f840c71fc1a920288ac405973070000000017a914accba16ec3b9fa60ca3143419c81e9fc4217d05a87105e5f00000000001976a914f82c1c9f44630fe1a9ab4cb1b5023c91ee4ddae688acf0066e1d000000001976a914521d713a3660b86d03ab6c68358433c30389ea1f88ac00000000000000000000000000000000000000"},{"txid":"4f5990dfd9ab8776c2e3bed233914e5cae004ca5ecaca0c257ea41446e55f598","version":4,"vin":[{"sequence":4294967295,"n":0,"isAddress":false,"coinbase":"03aac90c0044656661756c7420732d6e6f6d7020706f6f6c2068747470733a2f2f6769746875622e636f6d2f732d6e6f6d702f732d6e6f6d702f77696b692f496e73696768742d706f6f6c2d6c696e6b"}],"vout":[{"value":"0","n":0,"hex":"76a914219d1bea95fc9c401d4073a20f840c71fc1a920288ac","addresses":["t1LwLWo1Mo3s4RPtUpeyUD1eYd47inL3bwX"],"isAddress":true},{"value":"125000000","n":1,"hex":"a914accba16ec3b9fa60ca3143419c81e9fc4217d05a87","addresses":["t3aKH6NiWN1ofGd8c19rZiqgYpkJ3n679ME"],"isAddress":true},{"value":"6250000","n":2,"spent":true,"hex":"76a914f82c1c9f44630fe1a9ab4cb1b5023c91ee4ddae688ac","addresses":["t1gVpRrLdr8R2M2RaGisWZRspEF8EZvLZHv"],"isAddress":true},{"value":"493750000","n":3,"spent":true,"hex":"76a914521d713a3660b86d03ab6c68358433c30389ea1f88ac","addresses":["t1RMngkaWf2F8EDrpzQ1fhLBhfi89L14tN2"],"isAddress":true}],"blockHash":"0000000002549398c6f738b370072dd776c5ecc68bb61b901ead2be118d08594","blockHeight":838058,"confirmations":895,"blockTime":1590001966,"value":"625000000","valueIn":"0","fees":"0","hex":"0400008085202f89010000000000000000000000000000000000000000000000000000000000000000ffffffff5003aac90c0044656661756c7420732d6e6f6d7020706f6f6c2068747470733a2f2f6769746875622e636f6d2f732d6e6f6d702f732d6e6f6d702f77696b692f496e73696768742d706f6f6c2d6c696e6bffffffff0400000000000000001976a914219d1bea95fc9c401d4073a20f840c71fc1a920288ac405973070000000017a914accba16ec3b9fa60ca3143419c81e9fc4217d05a87105e5f00000000001976a914f82c1c9f44630fe1a9ab4cb1b5023c91ee4ddae688acf0066e1d000000001976a914521d713a3660b86d03ab6c68358433c30389ea1f88ac00000000000000000000000000000000000000"},{"txid":"c2ff1c3389be5c112f3586c879a12e5e4058d570782c830efbf201adf21decd5","version":4,"vin":[{"sequence":4294967295,"n":0,"isAddress":false,"coinbase":"03a1c90c0044656661756c7420732d6e6f6d7020706f6f6c2068747470733a2f2f6769746875622e636f6d2f732d6e6f6d702f732d6e6f6d702f77696b692f496e73696768742d706f6f6c2d6c696e6b"}],"vout":[{"value":"0","n":0,"hex":"76a914219d1bea95fc9c401d4073a20f840c71fc1a920288ac","addresses":["t1LwLWo1Mo3s4RPtUpeyUD1eYd47inL3bwX"],"isAddress":true},{"value":"125000000","n":1,"hex":"a914accba16ec3b9fa60ca3143419c81e9fc4217d05a87","addresses":["t3aKH6NiWN1ofGd8c19rZiqgYpkJ3n679ME"],"isAddress":true},{"value":"6250000","n":2,"spent":true,"hex":"76a914f82c1c9f44630fe1a9ab4cb1b5023c91ee4ddae688ac","addresses":["t1gVpRrLdr8R2M2RaGisWZRspEF8EZvLZHv"],"isAddress":true},{"value":"493750000","n":3,"spent":true,"hex":"76a914521d713a3660b86d03ab6c68358433c30389ea1f88ac","addresses":["t1RMngkaWf2F8EDrpzQ1fhLBhfi89L14tN2"],"isAddress":true}],"blockHash":"00000000007f764e8d2617be42bf862c41848f66e41e2c1f874f5f19473bad0e","blockHeight":838049,"confirmations":904,"blockTime":1590001194,"value":"625000000","valueIn":"0","fees":"0","hex":"0400008085202f89010000000000000000000000000000000000000000000000000000000000000000ffffffff5003a1c90c0044656661756c7420732d6e6f6d7020706f6f6c2068747470733a2f2f6769746875622e636f6d2f732d6e6f6d702f732d6e6f6d702f77696b692f496e73696768742d706f6f6c2d6c696e6bffffffff0400000000000000001976a914219d1bea95fc9c401d4073a20f840c71fc1a920288ac405973070000000017a914accba16ec3b9fa60ca3143419c81e9fc4217d05a87105e5f00000000001976a914f82c1c9f44630fe1a9ab4cb1b5023c91ee4ddae688acf0066e1d000000001976a914521d713a3660b86d03ab6c68358433c30389ea1f88ac00000000000000000000000000000000000000"},{"txid":"584593946525366bda4a42cb52a7b78dbd13b8d3ca1dbd579c7d5abd13674862","version":4,"vin":[{"sequence":4294967295,"n":0,"isAddress":false,"coinbase":"039fc70c0044656661756c7420732d6e6f6d7020706f6f6c2068747470733a2f2f6769746875622e636f6d2f732d6e6f6d702f732d6e6f6d702f77696b692f496e73696768742d706f6f6c2d6c696e6b"}],"vout":[{"value":"0","n":0,"hex":"76a914219d1bea95fc9c401d4073a20f840c71fc1a920288ac","addresses":["t1LwLWo1Mo3s4RPtUpeyUD1eYd47inL3bwX"],"isAddress":true},{"value":"125000000","n":1,"hex":"a914accba16ec3b9fa60ca3143419c81e9fc4217d05a87","addresses":["t3aKH6NiWN1ofGd8c19rZiqgYpkJ3n679ME"],"isAddress":true},{"value":"6250000","n":2,"spent":true,"hex":"76a914f82c1c9f44630fe1a9ab4cb1b5023c91ee4ddae688ac","addresses":["t1gVpRrLdr8R2M2RaGisWZRspEF8EZvLZHv"],"isAddress":true},{"value":"493750000","n":3,"spent":true,"hex":"76a914521d713a3660b86d03ab6c68358433c30389ea1f88ac","addresses":["t1RMngkaWf2F8EDrpzQ1fhLBhfi89L14tN2"],"isAddress":true}],"blockHash":"0000000002514210f04068274b6ef055abf89acc4cd4c9365aa45bced87f0a36","blockHeight":837535,"confirmations":1418,"blockTime":1589962474,"value":"625000000","valueIn":"0","fees":"0","hex":"0400008085202f89010000000000000000000000000000000000000000000000000000000000000000ffffffff50039fc70c0044656661756c7420732d6e6f6d7020706f6f6c2068747470733a2f2f6769746875622e636f6d2f732d6e6f6d702f732d6e6f6d702f77696b692f496e73696768742d706f6f6c2d6c696e6bffffffff0400000000000000001976a914219d1bea95fc9c401d4073a20f840c71fc1a920288ac405973070000000017a914accba16ec3b9fa60ca3143419c81e9fc4217d05a87105e5f00000000001976a914f82c1c9f44630fe1a9ab4cb1b5023c91ee4ddae688acf0066e1d000000001976a914521d713a3660b86d03ab6c68358433c30389ea1f88ac00000000000000000000000000000000000000"},{"txid":"f4719e5b969917fd036160472cb0f3a4897171e582bb9469850a3a973256e213","version":4,"vin":[{"sequence":4294967295,"n":0,"isAddress":false,"coinbase":"0364c70c0044656661756c7420732d6e6f6d7020706f6f6c2068747470733a2f2f6769746875622e636f6d2f732d6e6f6d702f732d6e6f6d702f77696b692f496e73696768742d706f6f6c2d6c696e6b"}],"vout":[{"value":"0","n":0,"hex":"76a914219d1bea95fc9c401d4073a20f840c71fc1a920288ac","addresses":["t1LwLWo1Mo3s4RPtUpeyUD1eYd47inL3bwX"],"isAddress":true},{"value":"125000000","n":1,"hex":"a914accba16ec3b9fa60ca3143419c81e9fc4217d05a87","addresses":["t3aKH6NiWN1ofGd8c19rZiqgYpkJ3n679ME"],"isAddress":true},{"value":"6250000","n":2,"spent":true,"hex":"76a914f82c1c9f44630fe1a9ab4cb1b5023c91ee4ddae688ac","addresses":["t1gVpRrLdr8R2M2RaGisWZRspEF8EZvLZHv"],"isAddress":true},{"value":"493750000","n":3,"spent":true,"hex":"76a914521d713a3660b86d03ab6c68358433c30389ea1f88ac","addresses":["t1RMngkaWf2F8EDrpzQ1fhLBhfi89L14tN2"],"isAddress":true}],"blockHash":"00000000002024dc913916a2fc57aad17251a3945a3d0ee10b70000d48cdac3d","blockHeight":837476,"confirmations":1477,"blockTime":1589958268,"value":"625000000","valueIn":"0","fees":"0","hex":"0400008085202f89010000000000000000000000000000000000000000000000000000000000000000ffffffff500364c70c0044656661756c7420732d6e6f6d7020706f6f6c2068747470733a2f2f6769746875622e636f6d2f732d6e6f6d702f732d6e6f6d702f77696b692f496e73696768742d706f6f6c2d6c696e6bffffffff0400000000000000001976a914219d1bea95fc9c401d4073a20f840c71fc1a920288ac405973070000000017a914accba16ec3b9fa60ca3143419c81e9fc4217d05a87105e5f00000000001976a914f82c1c9f44630fe1a9ab4cb1b5023c91ee4ddae688acf0066e1d000000001976a914521d713a3660b86d03ab6c68358433c30389ea1f88ac00000000000000000000000000000000000000"},{"txid":"19d3d66ee6ea94668fbe35c1b3a6d2b7406dae530d3ddbc83aa244b0f3b911f1","version":4,"vin":[{"sequence":4294967295,"n":0,"isAddress":false,"coinbase":"031dc70c0044656661756c7420732d6e6f6d7020706f6f6c2068747470733a2f2f6769746875622e636f6d2f732d6e6f6d702f732d6e6f6d702f77696b692f496e73696768742d706f6f6c2d6c696e6b"}],"vout":[{"value":"0","n":0,"hex":"76a914219d1bea95fc9c401d4073a20f840c71fc1a920288ac","addresses":["t1LwLWo1Mo3s4RPtUpeyUD1eYd47inL3bwX"],"isAddress":true},{"value":"125000000","n":1,"hex":"a914accba16ec3b9fa60ca3143419c81e9fc4217d05a87","addresses":["t3aKH6NiWN1ofGd8c19rZiqgYpkJ3n679ME"],"isAddress":true},{"value":"6250000","n":2,"spent":true,"hex":"76a914f82c1c9f44630fe1a9ab4cb1b5023c91ee4ddae688ac","addresses":["t1gVpRrLdr8R2M2RaGisWZRspEF8EZvLZHv"],"isAddress":true},{"value":"493750000","n":3,"spent":true,"hex":"76a914521d713a3660b86d03ab6c68358433c30389ea1f88ac","addresses":["t1RMngkaWf2F8EDrpzQ1fhLBhfi89L14tN2"],"isAddress":true}],"blockHash":"00000000011800bb8eebdc5dda838753c18c886a9867e86c9424ba29ddcd2593","blockHeight":837405,"confirmations":1548,"blockTime":1589953090,"value":"625000000","valueIn":"0","fees":"0","hex":"0400008085202f89010000000000000000000000000000000000000000000000000000000000000000ffffffff50031dc70c0044656661756c7420732d6e6f6d7020706f6f6c2068747470733a2f2f6769746875622e636f6d2f732d6e6f6d702f732d6e6f6d702f77696b692f496e73696768742d706f6f6c2d6c696e6bffffffff0400000000000000001976a914219d1bea95fc9c401d4073a20f840c71fc1a920288ac405973070000000017a914accba16ec3b9fa60ca3143419c81e9fc4217d05a87105e5f00000000001976a914f82c1c9f44630fe1a9ab4cb1b5023c91ee4ddae688acf0066e1d000000001976a914521d713a3660b86d03ab6c68358433c30389ea1f88ac00000000000000000000000000000000000000"}]} diff --git a/mock/ext-api-data/zcash-api_v2_xpub_xpub6CCXGBJ13akWuKSn4iU7CqQeXzLyDC2Y1Z83Mmg2xz11PX2EeZJJKRECz29iN4eHewRh8yfb7FpnCcjYbkqn6ynHnXW3jczPcJcenThfFeS__details_txs.json b/mock/ext-api-data/zcash-api_v2_xpub_xpub6CCXGBJ13akWuKSn4iU7CqQeXzLyDC2Y1Z83Mmg2xz11PX2EeZJJKRECz29iN4eHewRh8yfb7FpnCcjYbkqn6ynHnXW3jczPcJcenThfFeS__details_txs.json new file mode 100644 index 000000000..06a877601 --- /dev/null +++ b/mock/ext-api-data/zcash-api_v2_xpub_xpub6CCXGBJ13akWuKSn4iU7CqQeXzLyDC2Y1Z83Mmg2xz11PX2EeZJJKRECz29iN4eHewRh8yfb7FpnCcjYbkqn6ynHnXW3jczPcJcenThfFeS__details_txs.json @@ -0,0 +1,1770 @@ +{ + "page": 1, + "totalPages": 1, + "itemsOnPage": 1000, + "address": "xpub6CCXGBJ13akWuKSn4iU7CqQeXzLyDC2Y1Z83Mmg2xz11PX2EeZJJKRECz29iN4eHewRh8yfb7FpnCcjYbkqn6ynHnXW3jczPcJcenThfFeS", + "balance": "836466", + "totalReceived": "15140484", + "totalSent": "14304018", + "unconfirmedBalance": "0", + "unconfirmedTxs": 0, + "txs": 39, + "transactions": [ + { + "txid": "bdb6ae8ea9f5f37b304b382a2bc92208c2408b2d79cbc60777e27b618c70ca66", + "version": 4, + "vin": [ + { + "txid": "f2438a93039faf08d39bd3df1f7b5f19a2c29ffe8753127e2956ab4461adab35", + "vout": 1, + "n": 0, + "addresses": [ + "t1U4xs3qMxc2TL8wwYufmBngA5mewLHRwhM" + ], + "isAddress": true, + "value": "846466", + "hex": "473044022013f349ae165b1b96953081d47e588411387b7ecda4a7805d7f19dd369015c5ca022057313a41079ebf58e1ed35ad51425bf33011de475b55f5a085df7a9ab84a45e7012103fef9b9366755bd64a0579f1a5bfb92485c1f4ab33c53a1afb1899efa7e4782c1" + } + ], + "vout": [ + { + "value": "100000", + "n": 0, + "hex": "76a9146fd73e7c147d8ccc15fda31d8429e70f302b843988ac", + "addresses": [ + "t1U4xs3qMxc2TL8wwYufmBngA5mewLHRwhM" + ], + "isAddress": true + }, + { + "value": "736466", + "n": 1, + "hex": "76a9146fd73e7c147d8ccc15fda31d8429e70f302b843988ac", + "addresses": [ + "t1U4xs3qMxc2TL8wwYufmBngA5mewLHRwhM" + ], + "isAddress": true + } + ], + "blockHash": "00000000011b874449ef84ae97f18834d733c00a385fa2d099350071ea5113fe", + "blockHeight": 788618, + "confirmations": 41022, + "blockTime": 1586276485, + "value": "836466", + "valueIn": "846466", + "fees": "10000", + "hex": "0400008085202f890135abad6144ab56297e125387fe9fc2a2195f7b1fdfd39bd308af9f03938a43f2010000006a473044022013f349ae165b1b96953081d47e588411387b7ecda4a7805d7f19dd369015c5ca022057313a41079ebf58e1ed35ad51425bf33011de475b55f5a085df7a9ab84a45e7012103fef9b9366755bd64a0579f1a5bfb92485c1f4ab33c53a1afb1899efa7e4782c10000000002a0860100000000001976a9146fd73e7c147d8ccc15fda31d8429e70f302b843988acd23c0b00000000001976a9146fd73e7c147d8ccc15fda31d8429e70f302b843988ac00000000000000000000000000000000000000" + }, + { + "txid": "f2438a93039faf08d39bd3df1f7b5f19a2c29ffe8753127e2956ab4461adab35", + "version": 4, + "vin": [ + { + "txid": "ee120b714991e6166b8ff4b6419cbfee657eca87675245ce8585787be3b07d70", + "vout": 1, + "n": 0, + "addresses": [ + "t1LJWoRDU14zUG4TGumHiobd9WBUjqLE5FU" + ], + "isAddress": true, + "value": "956466", + "hex": "483045022100d2ac7b2b17218572f3dc163063463be5143a8d3c2126b52eb73d49c9c4959da00220057417baaad53c168e82dd44a7f964759c7d584e0770b6284a8e1b0261f1c7e0012102a71eeea42aa1b4e30a409f9186bd88dc84dec5c404964f386c323f557ad268d9" + } + ], + "vout": [ + { + "value": "100000", + "n": 0, + "spent": true, + "hex": "76a914a2511fc37f67f3b5627affce89fb3f7bb186412888ac", + "addresses": [ + "t1Yfrf1dssDLmaMBsq2LFKWPbS5vH3nGpa2" + ], + "isAddress": true + }, + { + "value": "846466", + "n": 1, + "spent": true, + "hex": "76a9146fd73e7c147d8ccc15fda31d8429e70f302b843988ac", + "addresses": [ + "t1U4xs3qMxc2TL8wwYufmBngA5mewLHRwhM" + ], + "isAddress": true + } + ], + "blockHash": "00000000005a238fecd893e55fba7072af65545fd43eaad63402c211cc172a61", + "blockHeight": 750255, + "confirmations": 79385, + "blockTime": 1583385097, + "value": "946466", + "valueIn": "956466", + "fees": "10000", + "hex": "0400008085202f8901707db0e37b788585ce45526787ca7e65eebf9c41b6f48f6b16e69149710b12ee010000006b483045022100d2ac7b2b17218572f3dc163063463be5143a8d3c2126b52eb73d49c9c4959da00220057417baaad53c168e82dd44a7f964759c7d584e0770b6284a8e1b0261f1c7e0012102a71eeea42aa1b4e30a409f9186bd88dc84dec5c404964f386c323f557ad268d90000000002a0860100000000001976a914a2511fc37f67f3b5627affce89fb3f7bb186412888ac82ea0c00000000001976a9146fd73e7c147d8ccc15fda31d8429e70f302b843988ac00000000000000000000000000000000000000" + }, + { + "txid": "ee120b714991e6166b8ff4b6419cbfee657eca87675245ce8585787be3b07d70", + "version": 4, + "vin": [ + { + "txid": "b49791a277ff137e37f9e163c8a5bc25492f741c275f9d36d5c0c713497c176c", + "vout": 1, + "sequence": 2147483646, + "n": 0, + "addresses": [ + "t1fuw3P3r5xbJXFqpaHUWb3TMz6xo9yPXEL" + ], + "isAddress": true, + "value": "996466", + "hex": "483045022100e7ddc39a2b976ee277d71f6130334084f1f21ef4f17cdd81514cf8af2181df1b02201c9a76a45b948c87940dc47525f1660d6c9c1e44ab22e4bcc16af0ce99c4c1890121031a03d4f4982aaa59d4087434907c9578fe77eadc73491b32f7373aaf9c17902e" + } + ], + "vout": [ + { + "value": "30000", + "n": 0, + "spent": true, + "hex": "76a914db49ca3524ee1e99aa097c6c9860ffcb5e5ed94a88ac", + "addresses": [ + "t1ds6PMeHUvAYtASPqCuEXzT1DsteXWwtTv" + ], + "isAddress": true + }, + { + "value": "956466", + "n": 1, + "spent": true, + "hex": "76a9141aa64e287339ad3fa041bc7a429bbcd57ac8a80088ac", + "addresses": [ + "t1LJWoRDU14zUG4TGumHiobd9WBUjqLE5FU" + ], + "isAddress": true + } + ], + "blockHash": "00000000008dcc62d679d7eaf05ac18403198f5f39b3e4e7f36869673855779b", + "blockHeight": 685806, + "confirmations": 143834, + "blockTime": 1578529212, + "value": "986466", + "valueIn": "996466", + "fees": "10000", + "hex": "0400008085202f89016c177c4913c7c0d5369d5f271c742f4925bca5c863e1f9377e13ff77a29197b4010000006b483045022100e7ddc39a2b976ee277d71f6130334084f1f21ef4f17cdd81514cf8af2181df1b02201c9a76a45b948c87940dc47525f1660d6c9c1e44ab22e4bcc16af0ce99c4c1890121031a03d4f4982aaa59d4087434907c9578fe77eadc73491b32f7373aaf9c17902efeffff7f0230750000000000001976a914db49ca3524ee1e99aa097c6c9860ffcb5e5ed94a88ac32980e00000000001976a9141aa64e287339ad3fa041bc7a429bbcd57ac8a80088ac00000000000000000000000000000000000000" + }, + { + "txid": "b49791a277ff137e37f9e163c8a5bc25492f741c275f9d36d5c0c713497c176c", + "version": 4, + "vin": [ + { + "txid": "4c3debb76fe8c9cb6fc4737de94212e91d4851945437d7852f44ad35439ce0fa", + "sequence": 2147483646, + "n": 0, + "addresses": [ + "t1WsYwrVPLHB4DzMrkAMCvY6h61RQPCJPkw" + ], + "isAddress": true, + "value": "1106466", + "hex": "473044022033c0e68231d1642e5028a480c6a47618975967b3a2f1f59d62d6d92d1b51d56102207a1e3385866e6a481a1f819946b07304660b72dbc437074da51caa089e965f3f012103a4065dbb978fe61c6ebb902a456af8f3240b17c5fb325cd2c05534a374a8ae21" + } + ], + "vout": [ + { + "value": "100000", + "n": 0, + "spent": true, + "hex": "76a914404d55f9d2bdeea3f1084b0aac4765384e3da4f488ac", + "addresses": [ + "t1Pjbu12gP3nTpjs36DRysrhwCFPLKhSKVk" + ], + "isAddress": true + }, + { + "value": "996466", + "n": 1, + "spent": true, + "hex": "76a914f1c37d2f80526621d728935b0ed624100f8493c388ac", + "addresses": [ + "t1fuw3P3r5xbJXFqpaHUWb3TMz6xo9yPXEL" + ], + "isAddress": true + } + ], + "blockHash": "000000000116d1e4a3b5d4264c98703e8be4486845fb3b286a25e167f84c0b0a", + "blockHeight": 685803, + "confirmations": 143837, + "blockTime": 1578529044, + "value": "1096466", + "valueIn": "1106466", + "fees": "10000", + "hex": "0400008085202f8901fae09c4335ad442f85d737549451481de91242e97d73c46fcbc9e86fb7eb3d4c000000006a473044022033c0e68231d1642e5028a480c6a47618975967b3a2f1f59d62d6d92d1b51d56102207a1e3385866e6a481a1f819946b07304660b72dbc437074da51caa089e965f3f012103a4065dbb978fe61c6ebb902a456af8f3240b17c5fb325cd2c05534a374a8ae21feffff7f02a0860100000000001976a914404d55f9d2bdeea3f1084b0aac4765384e3da4f488ac72340f00000000001976a914f1c37d2f80526621d728935b0ed624100f8493c388ac00000000000000000000000000000000000000" + }, + { + "txid": "4c3debb76fe8c9cb6fc4737de94212e91d4851945437d7852f44ad35439ce0fa", + "version": 4, + "vin": [ + { + "txid": "f5b76d963b246696b599d49302e401501c127d4f89cbcdf3cfd6e4d18f4cf659", + "vout": 1, + "n": 0, + "addresses": [ + "t1Q8ShbxcJ9pawxTx4ETFJMoQUSZrKCWzKr" + ], + "isAddress": true, + "value": "1116466", + "hex": "483045022100ec05147324a1a3720a1e5fb047d5323ba74c23b11b1f4cea25402d7972579b08022049624d957d303b05b0807f498376cc55dfdd0ae56df11a78dd77dd7555d9d690012103c55aec4f3d510a7fff0f2261ff3443bd93d516cfc4bcf02e9c4d246b4ff934f1" + } + ], + "vout": [ + { + "value": "1106466", + "n": 0, + "spent": true, + "hex": "76a9148e9714afd8e21ce9760bf49f6ac70ed32c0defa088ac", + "addresses": [ + "t1WsYwrVPLHB4DzMrkAMCvY6h61RQPCJPkw" + ], + "isAddress": true + } + ], + "blockHash": "000000000116d1e4a3b5d4264c98703e8be4486845fb3b286a25e167f84c0b0a", + "blockHeight": 685803, + "confirmations": 143837, + "blockTime": 1578529044, + "value": "1106466", + "valueIn": "1116466", + "fees": "10000", + "hex": "0400008085202f890159f64c8fd1e4d6cff3cdcb894f7d121c5001e40293d499b59666243b966db7f5010000006b483045022100ec05147324a1a3720a1e5fb047d5323ba74c23b11b1f4cea25402d7972579b08022049624d957d303b05b0807f498376cc55dfdd0ae56df11a78dd77dd7555d9d690012103c55aec4f3d510a7fff0f2261ff3443bd93d516cfc4bcf02e9c4d246b4ff934f1000000000122e21000000000001976a9148e9714afd8e21ce9760bf49f6ac70ed32c0defa088ac00000000000000000000000000000000000000" + }, + { + "txid": "f5b76d963b246696b599d49302e401501c127d4f89cbcdf3cfd6e4d18f4cf659", + "version": 4, + "vin": [ + { + "txid": "c3114bd9a0564c5609af3c4fe3f255760a2d996f85a2dfd871af85a429db909b", + "n": 0, + "addresses": [ + "t1dtiUUCSvFJYTm2XwdnJX2vUHeSxav6vhr" + ], + "isAddress": true, + "value": "1970000", + "hex": "473044022013e3683d230eee5fc307c283b39be0ff6e2f10d0eb3fa871d2c7ed7234be4fa60220360e34d9d5a6376a5d5596493d937817207e28166c720ae8c90b94834bc1f574012103507bb2cfbe1c83eaac54790b01159b505671d02241f7eb4ca756a7f906e3aaaa" + } + ], + "vout": [ + { + "value": "843534", + "n": 0, + "hex": "76a914a96bda74350574f56b30108b1cf7b13198aa74a188ac", + "addresses": [ + "t1ZKRQY3YnSSU3QvVPLw2qXHUvVNxpmaGjZ" + ], + "isAddress": true + }, + { + "value": "1116466", + "n": 1, + "spent": true, + "hex": "76a914449f39e1cf773b6ab8ca0a7b1f78b2b61ff887b388ac", + "addresses": [ + "t1Q8ShbxcJ9pawxTx4ETFJMoQUSZrKCWzKr" + ], + "isAddress": true + } + ], + "blockHash": "00000000004120e4e814488ef19d2bb67218c2c5ed9fcc607cd876f69e037aab", + "blockHeight": 661680, + "confirmations": 167960, + "blockTime": 1576711028, + "value": "1960000", + "valueIn": "1970000", + "fees": "10000", + "hex": "0400008085202f89019b90db29a485af71d8dfa2856f992d0a7655f2e34f3caf09564c56a0d94b11c3000000006a473044022013e3683d230eee5fc307c283b39be0ff6e2f10d0eb3fa871d2c7ed7234be4fa60220360e34d9d5a6376a5d5596493d937817207e28166c720ae8c90b94834bc1f574012103507bb2cfbe1c83eaac54790b01159b505671d02241f7eb4ca756a7f906e3aaaa00000000020edf0c00000000001976a914a96bda74350574f56b30108b1cf7b13198aa74a188ac32091100000000001976a914449f39e1cf773b6ab8ca0a7b1f78b2b61ff887b388ac00000000000000000000000000000000000000" + }, + { + "txid": "c3114bd9a0564c5609af3c4fe3f255760a2d996f85a2dfd871af85a429db909b", + "version": 4, + "vin": [ + { + "txid": "97537779723705ad8afe29cbfa352563ba1e9f637789f2650475420effce52a6", + "n": 0, + "addresses": [ + "t1VTcZ6fUY4Pctiwg3sRvr7Xtehd7t9oS8Y" + ], + "isAddress": true, + "value": "10000", + "hex": "47304402202f578d8ffedb4f18fa5de3d9d1397123259e6fdcae2c32b5545cf489a6d12236022056cac4deb4297d218cb8a8295779269c2d9047b521e15fe69fbd53c9b19176d0012103797ec761f2a682213010ba82e8d46e005f6421f683bc6ec733aaf303c193845d" + }, + { + "txid": "0ede27d0173c35fabede62340f1f86b29d3f834e06ed3cd5330bd2937d85a466", + "n": 1, + "addresses": [ + "t1S5DZbKS49jsGjdAGnVTG19kvqJCPmoaHK" + ], + "isAddress": true, + "value": "90000", + "hex": "48304502210093b597eebab4cc7c5acccd4946a3062ef703b6167dde3da43fece9663c021dac022039809adbd6b3f6bf52280ee01fd5b25eb9d5dfd983c264209aee0eb84ea9fe06012102c8dca1fa27e9f68a08511af6b60575670a039de832efd066f8c62a67d72df77b" + }, + { + "txid": "757eb1569c59609d0061a8fe7ec30a80a7103dded7f1b53ece4d70eb92d4a05c", + "n": 2, + "addresses": [ + "t1bkvrKbLLBT3vJFYt8SmoiyMBj7XmUGXf4" + ], + "isAddress": true, + "value": "100000", + "hex": "483045022100b4de7441499f166f1eeaba37c3cbbd19f186e90bf36edf87c3c0026099755ec50220644e76d23e67b706db3ec685f882bac62cd40176ec79b694b5f22cb73bf167ba012102422d0c15e66546d385bea2c732bc50ce4502c8d5189450201818a0ca375f5b05" + }, + { + "txid": "97f87c3ccaae4e136f89537ecbf69e3879003c4b3c2e3c63cb484e3f2aa8aee1", + "vout": 1, + "n": 3, + "addresses": [ + "t1U4xs3qMxc2TL8wwYufmBngA5mewLHRwhM" + ], + "isAddress": true, + "value": "1780000", + "hex": "483045022100a463c890a3d714b5d0e11cbee5ac87bb81ec5104227828c292d553870ed82ac7022023f98c6637d3a1a663e2f0630d06827e9c2486510dcbc8aba7c8a4f2bb1bbf52012103fef9b9366755bd64a0579f1a5bfb92485c1f4ab33c53a1afb1899efa7e4782c1" + } + ], + "vout": [ + { + "value": "1970000", + "n": 0, + "spent": true, + "hex": "76a914db9854a96c6ad7158b58537717bd8a9ef711675888ac", + "addresses": [ + "t1dtiUUCSvFJYTm2XwdnJX2vUHeSxav6vhr" + ], + "isAddress": true + } + ], + "blockHash": "0000000001d4b7e021a788bd8e0c610337e7dc539473d203526ce97b11b61d93", + "blockHeight": 658381, + "confirmations": 171259, + "blockTime": 1576462351, + "value": "1970000", + "valueIn": "1980000", + "fees": "10000", + "hex": "0400008085202f8904a652ceff0e42750465f28977639f1eba632535facb29fe8aad05377279775397000000006a47304402202f578d8ffedb4f18fa5de3d9d1397123259e6fdcae2c32b5545cf489a6d12236022056cac4deb4297d218cb8a8295779269c2d9047b521e15fe69fbd53c9b19176d0012103797ec761f2a682213010ba82e8d46e005f6421f683bc6ec733aaf303c193845d0000000066a4857d93d20b33d53ced064e833f9db2861f0f3462debefa353c17d027de0e000000006b48304502210093b597eebab4cc7c5acccd4946a3062ef703b6167dde3da43fece9663c021dac022039809adbd6b3f6bf52280ee01fd5b25eb9d5dfd983c264209aee0eb84ea9fe06012102c8dca1fa27e9f68a08511af6b60575670a039de832efd066f8c62a67d72df77b000000005ca0d492eb704dce3eb5f1d7de3d10a7800ac37efea861009d60599c56b17e75000000006b483045022100b4de7441499f166f1eeaba37c3cbbd19f186e90bf36edf87c3c0026099755ec50220644e76d23e67b706db3ec685f882bac62cd40176ec79b694b5f22cb73bf167ba012102422d0c15e66546d385bea2c732bc50ce4502c8d5189450201818a0ca375f5b0500000000e1aea82a3f4e48cb633c2e3c4b3c0079389ef6cb7e53896f134eaeca3c7cf897010000006b483045022100a463c890a3d714b5d0e11cbee5ac87bb81ec5104227828c292d553870ed82ac7022023f98c6637d3a1a663e2f0630d06827e9c2486510dcbc8aba7c8a4f2bb1bbf52012103fef9b9366755bd64a0579f1a5bfb92485c1f4ab33c53a1afb1899efa7e4782c10000000001500f1e00000000001976a914db9854a96c6ad7158b58537717bd8a9ef711675888ac00000000000000000000000000000000000000" + }, + { + "txid": "0ede27d0173c35fabede62340f1f86b29d3f834e06ed3cd5330bd2937d85a466", + "version": 4, + "vin": [ + { + "txid": "97f87c3ccaae4e136f89537ecbf69e3879003c4b3c2e3c63cb484e3f2aa8aee1", + "sequence": 2147483646, + "n": 0, + "addresses": [ + "t1Yfrf1dssDLmaMBsq2LFKWPbS5vH3nGpa2" + ], + "isAddress": true, + "value": "100000", + "hex": "483045022100b949a9404e721e19e0fe82f028f62e9f3380b27ab714317ea08f9549fae63b6f022015113c5fadd85209650629ce3ad50fe14f833e94a4e9750c8a20f098ddc2df3a012103e22a9f6ad90405c4a3674e1344c9eb8cc5d1275e18c79c38e33a6b40eb4e25a8" + } + ], + "vout": [ + { + "value": "90000", + "n": 0, + "spent": true, + "hex": "76a91459f3433be138218d9f07a5d32b58b71c7621c5d388ac", + "addresses": [ + "t1S5DZbKS49jsGjdAGnVTG19kvqJCPmoaHK" + ], + "isAddress": true + } + ], + "blockHash": "0000000000ad38725a94c47c162019a0a5f5c89f967b9b567d415f6a31484252", + "blockHeight": 655109, + "confirmations": 174531, + "blockTime": 1576215924, + "value": "90000", + "valueIn": "100000", + "fees": "10000", + "hex": "0400008085202f8901e1aea82a3f4e48cb633c2e3c4b3c0079389ef6cb7e53896f134eaeca3c7cf897000000006b483045022100b949a9404e721e19e0fe82f028f62e9f3380b27ab714317ea08f9549fae63b6f022015113c5fadd85209650629ce3ad50fe14f833e94a4e9750c8a20f098ddc2df3a012103e22a9f6ad90405c4a3674e1344c9eb8cc5d1275e18c79c38e33a6b40eb4e25a8feffff7f01905f0100000000001976a91459f3433be138218d9f07a5d32b58b71c7621c5d388ac00000000000000000000000000000000000000" + }, + { + "txid": "97f87c3ccaae4e136f89537ecbf69e3879003c4b3c2e3c63cb484e3f2aa8aee1", + "version": 4, + "vin": [ + { + "txid": "757eb1569c59609d0061a8fe7ec30a80a7103dded7f1b53ece4d70eb92d4a05c", + "vout": 1, + "n": 0, + "addresses": [ + "t1S5DZbKS49jsGjdAGnVTG19kvqJCPmoaHK" + ], + "isAddress": true, + "value": "1890000", + "hex": "483045022100810999450a12d4b339018a4b82b76b84182fdc66ea8cafafd2b5925d95b44c700220704b4a67b2b66142d211eea2de7919effa45ba67200e0c4fb36bec784707f83e012102c8dca1fa27e9f68a08511af6b60575670a039de832efd066f8c62a67d72df77b" + } + ], + "vout": [ + { + "value": "100000", + "n": 0, + "spent": true, + "hex": "76a914a2511fc37f67f3b5627affce89fb3f7bb186412888ac", + "addresses": [ + "t1Yfrf1dssDLmaMBsq2LFKWPbS5vH3nGpa2" + ], + "isAddress": true + }, + { + "value": "1780000", + "n": 1, + "spent": true, + "hex": "76a9146fd73e7c147d8ccc15fda31d8429e70f302b843988ac", + "addresses": [ + "t1U4xs3qMxc2TL8wwYufmBngA5mewLHRwhM" + ], + "isAddress": true + } + ], + "blockHash": "0000000001a0b8f060fc67bd6d3a6c1a4c1be5fc7207f8046275c6997a162b10", + "blockHeight": 655105, + "confirmations": 174535, + "blockTime": 1576215738, + "value": "1880000", + "valueIn": "1890000", + "fees": "10000", + "hex": "0400008085202f89015ca0d492eb704dce3eb5f1d7de3d10a7800ac37efea861009d60599c56b17e75010000006b483045022100810999450a12d4b339018a4b82b76b84182fdc66ea8cafafd2b5925d95b44c700220704b4a67b2b66142d211eea2de7919effa45ba67200e0c4fb36bec784707f83e012102c8dca1fa27e9f68a08511af6b60575670a039de832efd066f8c62a67d72df77b0000000002a0860100000000001976a914a2511fc37f67f3b5627affce89fb3f7bb186412888ac20291b00000000001976a9146fd73e7c147d8ccc15fda31d8429e70f302b843988ac00000000000000000000000000000000000000" + }, + { + "txid": "757eb1569c59609d0061a8fe7ec30a80a7103dded7f1b53ece4d70eb92d4a05c", + "version": 4, + "vin": [ + { + "txid": "6358ea195242ec9c2ae06e7be67c96ef901140e79d320eab9a42968ae2266b37", + "n": 0, + "addresses": [ + "t1dmuFMKkqoYs56Sqxg5Et5Yac2KFqtoGQe" + ], + "isAddress": true, + "value": "2000000", + "hex": "4830450221009c36192b84add900cc86bb110a7b82e4b28d8f016b598c4a5fa3373378d3e72d02204ffebee7e0be67f5660f54d7c83b983e24910e69b733fd14b3d96ed0fce0d4750121020d101a7957ebf37dae0fd0a86bf74d5e318a1507f358ddfe3d01f88808b70b06" + } + ], + "vout": [ + { + "value": "100000", + "n": 0, + "spent": true, + "hex": "76a914c42f154229ba025c563911a25116452f91aedeab88ac", + "addresses": [ + "t1bkvrKbLLBT3vJFYt8SmoiyMBj7XmUGXf4" + ], + "isAddress": true + }, + { + "value": "1890000", + "n": 1, + "spent": true, + "hex": "76a91459f3433be138218d9f07a5d32b58b71c7621c5d388ac", + "addresses": [ + "t1S5DZbKS49jsGjdAGnVTG19kvqJCPmoaHK" + ], + "isAddress": true + } + ], + "blockHash": "00000000034e557a024d485fadfcee86ab4d1c5436f8b3bcc405acd5ec22a97a", + "blockHeight": 654620, + "confirmations": 175020, + "blockTime": 1576179805, + "value": "1990000", + "valueIn": "2000000", + "fees": "10000", + "hex": "0400008085202f8901376b26e28a96429aab0e329de7401190ef967ce67b6ee02a9cec425219ea5863000000006b4830450221009c36192b84add900cc86bb110a7b82e4b28d8f016b598c4a5fa3373378d3e72d02204ffebee7e0be67f5660f54d7c83b983e24910e69b733fd14b3d96ed0fce0d4750121020d101a7957ebf37dae0fd0a86bf74d5e318a1507f358ddfe3d01f88808b70b060000000002a0860100000000001976a914c42f154229ba025c563911a25116452f91aedeab88acd0d61c00000000001976a91459f3433be138218d9f07a5d32b58b71c7621c5d388ac00000000000000000000000000000000000000" + }, + { + "txid": "97537779723705ad8afe29cbfa352563ba1e9f637789f2650475420effce52a6", + "version": 4, + "vin": [ + { + "txid": "ba6a3d21a328f62dae9c4bebd8d500918e2cdc6baa44a7984db3dc9a93c9652b", + "vout": 1, + "n": 0, + "addresses": [ + "t1KVd1yQGPBxNnH9e5jz4AHZsyezLJbeCpx" + ], + "isAddress": true, + "value": "46571", + "hex": "483045022100da924f0d853864baacd5e623612e05b0435477aa2299f91d414c6cd1f59b352502207a6bc1a148713fc3e6c05272536757be2f561d11182b509da9072406e8333d5f01210292cd04a3293951abedf0d16f233ebb9d34b9c16ce04ee617a712fa5a3ba40974" + } + ], + "vout": [ + { + "value": "10000", + "n": 0, + "spent": true, + "hex": "76a9147f17fbc46a8ccdc87e6ecfcdeafcafb42958ce2b88ac", + "addresses": [ + "t1VTcZ6fUY4Pctiwg3sRvr7Xtehd7t9oS8Y" + ], + "isAddress": true + }, + { + "value": "26571", + "n": 1, + "hex": "76a91442350ecf9013a7ef5aded68c21b88a6021019c4288ac", + "addresses": [ + "t1PugAXA5Vga3LV9SEicUZfEsx2KrtLTad7" + ], + "isAddress": true + } + ], + "blockHash": "00000000023add08ebb61e88e7ad48740c27570624f3508d5a21c5b65a39d7fa", + "blockHeight": 654372, + "confirmations": 175268, + "blockTime": 1576160170, + "value": "36571", + "valueIn": "46571", + "fees": "10000", + "hex": "0400008085202f89012b65c9939adcb34d98a744aa6bdc2c8e9100d5d8eb4b9cae2df628a3213d6aba010000006b483045022100da924f0d853864baacd5e623612e05b0435477aa2299f91d414c6cd1f59b352502207a6bc1a148713fc3e6c05272536757be2f561d11182b509da9072406e8333d5f01210292cd04a3293951abedf0d16f233ebb9d34b9c16ce04ee617a712fa5a3ba40974000000000210270000000000001976a9147f17fbc46a8ccdc87e6ecfcdeafcafb42958ce2b88accb670000000000001976a91442350ecf9013a7ef5aded68c21b88a6021019c4288ac00000000000000000000000000000000000000" + }, + { + "txid": "387939ff8eb07dd264376eeef2e126394ab139802b1d80e92b21c1a2ae54fe92", + "version": 4, + "vin": [ + { + "txid": "2381825cd9069a200944996257e25b9403ba3e296bbc1dd98b01019cc7028cde", + "sequence": 4294967295, + "n": 0, + "addresses": [ + "t1ejPK3moem9SjQAqXeKBVYiCVqcezw4xAn" + ], + "isAddress": true, + "value": "27615", + "hex": "483045022100be56b29f0198d2fb514da2e6e2e45b79990f77fc1d03ec15b7432c049600e2b002200c44f2734224663077298fd891fcfee15073ce64efa9165f8b2e17fc20fe38d00121025bda2a553a7d3e1ccb2133eef1f009855feb3f5b2d213a664698fd39cec9d359" + } + ], + "vout": [ + { + "value": "17615", + "n": 0, + "hex": "76a914c3bacb129d85288a3deb5890ca9b711f7f71392688ac", + "addresses": [ + "t1biXYN8wJahR76SqZTe1LBzTLf3JAsmT93" + ], + "isAddress": true + } + ], + "blockHash": "000000000184d53c01bfe9c0516d274145229993296d4e9fb44920008f1908c0", + "blockHeight": 654034, + "confirmations": 175606, + "blockTime": 1576134503, + "value": "17615", + "valueIn": "27615", + "fees": "10000", + "hex": "0400008085202f8901de8c02c79c01018bd91dbc6b293eba03945be25762994409209a06d95c828123000000006b483045022100be56b29f0198d2fb514da2e6e2e45b79990f77fc1d03ec15b7432c049600e2b002200c44f2734224663077298fd891fcfee15073ce64efa9165f8b2e17fc20fe38d00121025bda2a553a7d3e1ccb2133eef1f009855feb3f5b2d213a664698fd39cec9d359ffffffff01cf440000000000001976a914c3bacb129d85288a3deb5890ca9b711f7f71392688ac00000000000000000000000000000000000000" + }, + { + "txid": "6358ea195242ec9c2ae06e7be67c96ef901140e79d320eab9a42968ae2266b37", + "version": 4, + "vin": [ + { + "txid": "004802e071ad43e33f14a198a626386f445da9a20d85cdc6cbf2464dbc0f5d5d", + "sequence": 4294967295, + "n": 0, + "addresses": [ + "t1YUdySBxqnpA9dyJPwDqaY71EtiM9XqPXz" + ], + "isAddress": true, + "value": "4426404", + "hex": "483045022100adcba0664d7150a8b9d6bb14c61d88816d4cfde4b987dc7fdc0bac08f0bb069e02202e034144db8cff0a8b4a0a8c5017224b49a37a90a048c9e466ee2b642bbb2efc012103c05b6df7ed56a4c1e67f671e524f6d26bfca9fb2a2388a8af0a49399176b6355" + } + ], + "vout": [ + { + "value": "2000000", + "n": 0, + "spent": true, + "hex": "76a914da4e699a29b867c83a98987d99c46f8def145a3588ac", + "addresses": [ + "t1dmuFMKkqoYs56Sqxg5Et5Yac2KFqtoGQe" + ], + "isAddress": true + }, + { + "value": "2416404", + "n": 1, + "spent": true, + "hex": "76a9145d5cabf1815cbf48f581663c46a079f522e3e50a88ac", + "addresses": [ + "t1SPFs7dn3KQHYaXS8husDucMkTQJ6n3KH7" + ], + "isAddress": true + } + ], + "blockHash": "000000000285744d8b65e68d444438d5cd0cd4830cceb85eab51995ff07e153a", + "blockHeight": 653658, + "confirmations": 175982, + "blockTime": 1576106791, + "value": "4416404", + "valueIn": "4426404", + "fees": "10000", + "hex": "0400008085202f89015d5d0fbc4d46f2cbc6cd850da2a95d446f3826a698a1143fe343ad71e0024800000000006b483045022100adcba0664d7150a8b9d6bb14c61d88816d4cfde4b987dc7fdc0bac08f0bb069e02202e034144db8cff0a8b4a0a8c5017224b49a37a90a048c9e466ee2b642bbb2efc012103c05b6df7ed56a4c1e67f671e524f6d26bfca9fb2a2388a8af0a49399176b6355ffffffff0280841e00000000001976a914da4e699a29b867c83a98987d99c46f8def145a3588ac14df2400000000001976a9145d5cabf1815cbf48f581663c46a079f522e3e50a88ac0000000082f909000000000000000000000000" + }, + { + "txid": "2381825cd9069a200944996257e25b9403ba3e296bbc1dd98b01019cc7028cde", + "version": 4, + "vin": [ + { + "txid": "3cf0a895185be87b86f96ca213d0cceffc4ee402984505aeb491e379b122967b", + "n": 0, + "addresses": [ + "t1TwTPFb2ioL3H52XwnEYPk6FoU1awteAU9" + ], + "isAddress": true, + "value": "37615", + "hex": "4830450221009a42f5894abc9247d7253712c9fc33dd8b73b8196142d84009db4f2566bcf23d022035d5e555a84ce07c9f00db296d54ecf176bf6a88eeec4b1b3b434df32076f3bc012103ddf742213c30066ca096189e15540f34ad4d2bf7f0162115eb494a3034ed5c24" + } + ], + "vout": [ + { + "value": "27615", + "n": 0, + "spent": true, + "hex": "76a914e4ccb7831b849ae3fa8bfcd91b2242d9ef59ecb488ac", + "addresses": [ + "t1ejPK3moem9SjQAqXeKBVYiCVqcezw4xAn" + ], + "isAddress": true + } + ], + "blockHash": "0000000000de005c4451aea5f03920cf7b25cb206e5ece9042a2bd2172a911a7", + "blockHeight": 652406, + "confirmations": 177234, + "blockTime": 1575920739, + "value": "27615", + "valueIn": "37615", + "fees": "10000", + "hex": "0400008085202f89017b9622b179e391b4ae05459802e44efcefccd013a26cf9867be85b1895a8f03c000000006b4830450221009a42f5894abc9247d7253712c9fc33dd8b73b8196142d84009db4f2566bcf23d022035d5e555a84ce07c9f00db296d54ecf176bf6a88eeec4b1b3b434df32076f3bc012103ddf742213c30066ca096189e15540f34ad4d2bf7f0162115eb494a3034ed5c240000000001df6b0000000000001976a914e4ccb7831b849ae3fa8bfcd91b2242d9ef59ecb488ac00000000000000000000000000000000000000" + }, + { + "txid": "3cf0a895185be87b86f96ca213d0cceffc4ee402984505aeb491e379b122967b", + "version": 4, + "vin": [ + { + "txid": "1477d8b220b0215feef753f000f0dec7e8145b3a13748ca6f0dce21b67b07fd3", + "n": 0, + "addresses": [ + "t1U4xs3qMxc2TL8wwYufmBngA5mewLHRwhM" + ], + "isAddress": true, + "value": "47615", + "hex": "483045022100e4bff2389e0ee07ee3e8bf0c776f4e46f08d1f7d5de3759796d499bb61685778022052a69c063d988e6077afa07b9a6fcaff08b7c288300c2f80e15c5453d6fc30b7012103fef9b9366755bd64a0579f1a5bfb92485c1f4ab33c53a1afb1899efa7e4782c1" + } + ], + "vout": [ + { + "value": "37615", + "n": 0, + "spent": true, + "hex": "76a9146e6bb96b8ab0006157a931100d83cd14f65dde4b88ac", + "addresses": [ + "t1TwTPFb2ioL3H52XwnEYPk6FoU1awteAU9" + ], + "isAddress": true + } + ], + "blockHash": "00000000011b2ec58f64a619f89ded65c2d097bb0354d164db1376300679c06c", + "blockHeight": 652349, + "confirmations": 177291, + "blockTime": 1575914154, + "value": "37615", + "valueIn": "47615", + "fees": "10000", + "hex": "0400008085202f8901d37fb0671be2dcf0a68c74133a5b14e8c7def000f053f7ee5f21b020b2d87714000000006b483045022100e4bff2389e0ee07ee3e8bf0c776f4e46f08d1f7d5de3759796d499bb61685778022052a69c063d988e6077afa07b9a6fcaff08b7c288300c2f80e15c5453d6fc30b7012103fef9b9366755bd64a0579f1a5bfb92485c1f4ab33c53a1afb1899efa7e4782c10000000001ef920000000000001976a9146e6bb96b8ab0006157a931100d83cd14f65dde4b88ac00000000000000000000000000000000000000" + }, + { + "txid": "1477d8b220b0215feef753f000f0dec7e8145b3a13748ca6f0dce21b67b07fd3", + "version": 4, + "vin": [ + { + "txid": "636ef8deb08d859e2cb1317561b3ea7eb96336f09fb64d88f48e9f8cf7e87641", + "sequence": 2147483646, + "n": 0, + "addresses": [ + "t1ZtFQa5CfNPdqZX8oy2y2kqMA89ASWNEWS" + ], + "isAddress": true, + "value": "57615", + "hex": "473044022062702a7f1ae45ebe6f77c6f37b40c1e190bccca884cc0e5390b02f234ab465c4022032f4732be66ba68880e1d7395e9def044254212c2d962c8a67ca6c283f191ba00121023756884cdf5cc6719e5c8948c6221e7be17510fa4de4dd2d0697e0b05ded0dba" + } + ], + "vout": [ + { + "value": "47615", + "n": 0, + "spent": true, + "hex": "76a9146fd73e7c147d8ccc15fda31d8429e70f302b843988ac", + "addresses": [ + "t1U4xs3qMxc2TL8wwYufmBngA5mewLHRwhM" + ], + "isAddress": true + } + ], + "blockHash": "00000000009f7bf929ba73589b1c2f89c5fefd5bbee96db1d6e25eb8d5af3404", + "blockHeight": 636381, + "confirmations": 193259, + "blockTime": 1573508295, + "value": "47615", + "valueIn": "57615", + "fees": "10000", + "hex": "0400008085202f89014176e8f78c9f8ef4884db69ff03663b97eeab3617531b12c9e858db0def86e63000000006a473044022062702a7f1ae45ebe6f77c6f37b40c1e190bccca884cc0e5390b02f234ab465c4022032f4732be66ba68880e1d7395e9def044254212c2d962c8a67ca6c283f191ba00121023756884cdf5cc6719e5c8948c6221e7be17510fa4de4dd2d0697e0b05ded0dbafeffff7f01ffb90000000000001976a9146fd73e7c147d8ccc15fda31d8429e70f302b843988ac00000000000000000000000000000000000000" + }, + { + "txid": "636ef8deb08d859e2cb1317561b3ea7eb96336f09fb64d88f48e9f8cf7e87641", + "version": 4, + "vin": [ + { + "txid": "d8970d0c519ad553576ac4bf9151b553992c727b09654242c125afae9ea9d4c0", + "sequence": 2147483646, + "n": 0, + "addresses": [ + "t1U4xs3qMxc2TL8wwYufmBngA5mewLHRwhM" + ], + "isAddress": true, + "value": "67615", + "hex": "483045022100edbb8920f3292835ab04b35f1248651d56f260a1d47421dcf335e10ae96a4b7202207a44efbb7f4060e7fbcf27815da3c6856bb5d49e2fb76637278a0527d0ad1637012103fef9b9366755bd64a0579f1a5bfb92485c1f4ab33c53a1afb1899efa7e4782c1" + } + ], + "vout": [ + { + "value": "57615", + "n": 0, + "spent": true, + "hex": "76a914afa13ba5c9a11574d1f226fcb8aa55f9581d894f88ac", + "addresses": [ + "t1ZtFQa5CfNPdqZX8oy2y2kqMA89ASWNEWS" + ], + "isAddress": true + } + ], + "blockHash": "0000000000904db208136a8a16ada6db97e6e5c9c18b167f429af2fb1b022458", + "blockHeight": 601992, + "confirmations": 227648, + "blockTime": 1568325489, + "value": "57615", + "valueIn": "67615", + "fees": "10000", + "hex": "0400008085202f8901c0d4a99eaeaf25c1424265097b722c9953b55191bfc46a5753d59a510c0d97d8000000006b483045022100edbb8920f3292835ab04b35f1248651d56f260a1d47421dcf335e10ae96a4b7202207a44efbb7f4060e7fbcf27815da3c6856bb5d49e2fb76637278a0527d0ad1637012103fef9b9366755bd64a0579f1a5bfb92485c1f4ab33c53a1afb1899efa7e4782c1feffff7f010fe10000000000001976a914afa13ba5c9a11574d1f226fcb8aa55f9581d894f88ac00000000000000000000000000000000000000" + }, + { + "txid": "d8970d0c519ad553576ac4bf9151b553992c727b09654242c125afae9ea9d4c0", + "version": 4, + "vin": [ + { + "txid": "89db84acffdaa0d98d7b86351be3ba5abff842acdb8fbc31159f0b2e8da4368f", + "vout": 1, + "sequence": 2147483644, + "n": 0, + "addresses": [ + "t1LNfSM8HKK1iBmLty9LN1FrwiTTTmvU44J" + ], + "isAddress": true, + "value": "74396", + "hex": "483045022100abe0e95620f6eebc133cfe8c70dfa3d1d19a8d578328d9fc58de267fbe3cbff90220308cb9d2b539bede92482385c975992a3dd294df572ceae8d221ee9a56b11ebc0121030696c4d51da64931e563a9215953b8b734d38e307b4b08c9807b333d39cb711e" + }, + { + "txid": "89db84acffdaa0d98d7b86351be3ba5abff842acdb8fbc31159f0b2e8da4368f", + "sequence": 2147483645, + "n": 1, + "addresses": [ + "t1PjbgQCBHqvLLUAjGYhKMEXXvTpcLMzKAf" + ], + "isAddress": true, + "value": "2219", + "hex": "47304402201c07fab04d06567f557c1b9b5057dd0be83f9e50cf590d79913ff08f8e644ec702205d384e7ebb61420b8fb0e1df44ab3c4c9ef19f7db72e5530b3d16a74ab8c7101012103c8b1ed9a08e9b4ea4220c4035f3bc5723617bbccbef2091c9e74a89b24ed8bea" + }, + { + "txid": "7899e2e584b849a16d21dbbd6ac39e51b9ef23773022babe2868d10e6e772e06", + "sequence": 2147483646, + "n": 2, + "addresses": [ + "t1JKYSYmUS4tJMPEix2V8H3z8Grp51aTH2w" + ], + "isAddress": true, + "value": "1000", + "hex": "483045022100aee2bc7f92639e2657565cc0e70c982eaef2dbb1d316bea6e62759a1160f2e5b02204350ffaeffc76ff41ad856cf49b6a4b5e3afeac635b89b5b93f35538ef1371af01210200d8c5dca07ac681793dcac902634806553051398cf94c7c69bd144e14a225f4" + } + ], + "vout": [ + { + "value": "67615", + "n": 0, + "spent": true, + "hex": "76a9146fd73e7c147d8ccc15fda31d8429e70f302b843988ac", + "addresses": [ + "t1U4xs3qMxc2TL8wwYufmBngA5mewLHRwhM" + ], + "isAddress": true + } + ], + "blockHash": "000000000060868b8d2216f304339e5507e655d1988d4a0d949fb10ee0e58578", + "blockHeight": 595990, + "confirmations": 233650, + "blockTime": 1567420905, + "value": "67615", + "valueIn": "77615", + "fees": "10000", + "hex": "0400008085202f89038f36a48d2e0b9f1531bc8fdbac42f8bf5abae31b35867b8dd9a0daffac84db89010000006b483045022100abe0e95620f6eebc133cfe8c70dfa3d1d19a8d578328d9fc58de267fbe3cbff90220308cb9d2b539bede92482385c975992a3dd294df572ceae8d221ee9a56b11ebc0121030696c4d51da64931e563a9215953b8b734d38e307b4b08c9807b333d39cb711efcffff7f8f36a48d2e0b9f1531bc8fdbac42f8bf5abae31b35867b8dd9a0daffac84db89000000006a47304402201c07fab04d06567f557c1b9b5057dd0be83f9e50cf590d79913ff08f8e644ec702205d384e7ebb61420b8fb0e1df44ab3c4c9ef19f7db72e5530b3d16a74ab8c7101012103c8b1ed9a08e9b4ea4220c4035f3bc5723617bbccbef2091c9e74a89b24ed8beafdffff7f062e776e0ed16828beba22307723efb9519ec36abddb216da149b884e5e29978000000006b483045022100aee2bc7f92639e2657565cc0e70c982eaef2dbb1d316bea6e62759a1160f2e5b02204350ffaeffc76ff41ad856cf49b6a4b5e3afeac635b89b5b93f35538ef1371af01210200d8c5dca07ac681793dcac902634806553051398cf94c7c69bd144e14a225f4feffff7f011f080100000000001976a9146fd73e7c147d8ccc15fda31d8429e70f302b843988ac00000000000000000000000000000000000000" + }, + { + "txid": "89db84acffdaa0d98d7b86351be3ba5abff842acdb8fbc31159f0b2e8da4368f", + "version": 4, + "vin": [ + { + "txid": "7899e2e584b849a16d21dbbd6ac39e51b9ef23773022babe2868d10e6e772e06", + "vout": 1, + "n": 0, + "addresses": [ + "t1VS1A32gPbGPtuwhttEHw1QvAJfPwTKJqp" + ], + "isAddress": true, + "value": "86615", + "hex": "483045022100dbbee07fd60e136497aa735f93a96005493d66bb8f3fa38ecf526b5863588ae70220707de0dcc3fecee251fd7b06dc6a10598cabbfd867f5ef002aeac461462ad0df0121037452ab70acb399482583cadf20f957e4739c0e677a29ce01ba4fd3ef5fabba66" + } + ], + "vout": [ + { + "value": "2219", + "n": 0, + "spent": true, + "hex": "76a914404d278cacec4b336a2bd73f625a6dcce9d2666988ac", + "addresses": [ + "t1PjbgQCBHqvLLUAjGYhKMEXXvTpcLMzKAf" + ], + "isAddress": true + }, + { + "value": "74396", + "n": 1, + "spent": true, + "hex": "76a9141b6f2dc084506144cfe883bc72376223cd5386da88ac", + "addresses": [ + "t1LNfSM8HKK1iBmLty9LN1FrwiTTTmvU44J" + ], + "isAddress": true + } + ], + "blockHash": "00000000001b3fe5eaf8b919b35a4e3195d67ee3b88c6b50f7bd8f0cb6491daf", + "blockHeight": 595650, + "confirmations": 233990, + "blockTime": 1567370080, + "value": "76615", + "valueIn": "86615", + "fees": "10000", + "hex": "0400008085202f8901062e776e0ed16828beba22307723efb9519ec36abddb216da149b884e5e29978010000006b483045022100dbbee07fd60e136497aa735f93a96005493d66bb8f3fa38ecf526b5863588ae70220707de0dcc3fecee251fd7b06dc6a10598cabbfd867f5ef002aeac461462ad0df0121037452ab70acb399482583cadf20f957e4739c0e677a29ce01ba4fd3ef5fabba660000000002ab080000000000001976a914404d278cacec4b336a2bd73f625a6dcce9d2666988ac9c220100000000001976a9141b6f2dc084506144cfe883bc72376223cd5386da88ac00000000000000000000000000000000000000" + }, + { + "txid": "7899e2e584b849a16d21dbbd6ac39e51b9ef23773022babe2868d10e6e772e06", + "version": 4, + "vin": [ + { + "txid": "a8218f12908291332a2640c1c0c342a0c0d6ddf545c416201fdf86a1f355ce61", + "n": 0, + "addresses": [ + "t1Xrv6J9sU2gWY9eqb7PgsxGMd2WHpok1XE" + ], + "isAddress": true, + "value": "97615", + "hex": "473044022049935dd1b1485173457c4fc80d59acf1b25a309d262edc0f79c0dd7d558a7c83022024f8dc29c5342a1a42a1607ea3989cb6a06db16ec5ed8944165a6831acd93ab001210365ba1fc37153f8d1d13553cf802a2a6643a23d362ca285d51309c3c42fbc439d" + } + ], + "vout": [ + { + "value": "1000", + "n": 0, + "spent": true, + "hex": "76a91404e7d6beccc84d52cf61d8fb17c95d131293c35188ac", + "addresses": [ + "t1JKYSYmUS4tJMPEix2V8H3z8Grp51aTH2w" + ], + "isAddress": true + }, + { + "value": "86615", + "n": 1, + "spent": true, + "hex": "76a9147eca04e061da84a586631747c1bfc9340277a73d88ac", + "addresses": [ + "t1VS1A32gPbGPtuwhttEHw1QvAJfPwTKJqp" + ], + "isAddress": true + } + ], + "blockHash": "00000000010accd88dac9bf3546d2018a46ccdc9129c0b28f331c4d2f6467a08", + "blockHeight": 595226, + "confirmations": 234414, + "blockTime": 1567305310, + "value": "87615", + "valueIn": "97615", + "fees": "10000", + "hex": "0400008085202f890161ce55f3a186df1f2016c445f5ddd6c0a042c3c0c140262a33918290128f21a8000000006a473044022049935dd1b1485173457c4fc80d59acf1b25a309d262edc0f79c0dd7d558a7c83022024f8dc29c5342a1a42a1607ea3989cb6a06db16ec5ed8944165a6831acd93ab001210365ba1fc37153f8d1d13553cf802a2a6643a23d362ca285d51309c3c42fbc439d0000000002e8030000000000001976a91404e7d6beccc84d52cf61d8fb17c95d131293c35188ac57520100000000001976a9147eca04e061da84a586631747c1bfc9340277a73d88ac00000000000000000000000000000000000000" + }, + { + "txid": "a8218f12908291332a2640c1c0c342a0c0d6ddf545c416201fdf86a1f355ce61", + "version": 4, + "vin": [ + { + "txid": "78e3fb2512eda4de98a0afca606c01ce608a2a51679c5400349999c68d8af94e", + "sequence": 4294967294, + "n": 0, + "addresses": [ + "t1HsyCvdZZczFXgJJEXaoJujo2fVZeVpRxK" + ], + "isAddress": true, + "value": "107615", + "hex": "47304402200480f5dc34cc3fab8429bc29b7ef04bb59f4bf5016ac79a2e543e936dbce33be022063644c7d93a3e4ef7402ed544409e0faf6a6ec51d6164e2d84fad97cefb0e114012103df7baf7aece0effc84874c00b4a99fe143aeb36e1ac403c9dcf3037932d6d7e5" + } + ], + "vout": [ + { + "value": "97615", + "n": 0, + "spent": true, + "hex": "76a9149970712a7f2116b1de7f219ad3a337f3e77f3e7a88ac", + "addresses": [ + "t1Xrv6J9sU2gWY9eqb7PgsxGMd2WHpok1XE" + ], + "isAddress": true + } + ], + "blockHash": "0000000000e2b7074f5c3a02c99e54a1f4e447d3e710d57534058bc3904d1a8e", + "blockHeight": 587037, + "confirmations": 242603, + "blockTime": 1566071261, + "value": "97615", + "valueIn": "107615", + "fees": "10000", + "hex": "0400008085202f89014ef98a8dc699993400549c67512a8a60ce016c60caafa098dea4ed1225fbe378000000006a47304402200480f5dc34cc3fab8429bc29b7ef04bb59f4bf5016ac79a2e543e936dbce33be022063644c7d93a3e4ef7402ed544409e0faf6a6ec51d6164e2d84fad97cefb0e114012103df7baf7aece0effc84874c00b4a99fe143aeb36e1ac403c9dcf3037932d6d7e5feffffff014f7d0100000000001976a9149970712a7f2116b1de7f219ad3a337f3e77f3e7a88ac00000000000000000000000000000000000000" + }, + { + "txid": "78e3fb2512eda4de98a0afca606c01ce608a2a51679c5400349999c68d8af94e", + "version": 4, + "vin": [ + { + "txid": "3c0725a0e1f0d0de5b7810e0dc2cc75a9fb00835ab45f3e3b08b1cf96ee1f6a4", + "n": 0, + "addresses": [ + "t1Xrv6J9sU2gWY9eqb7PgsxGMd2WHpok1XE" + ], + "isAddress": true, + "value": "117615", + "hex": "473044022074bdb6b0c06625dc963a2ce028db78b0b95cfba7d228b05a0cf440b4c40ca4b0022018a98ef2516f4c8869b039e2428386f0b66812b36b2cdf97a854dde952d0427d01210365ba1fc37153f8d1d13553cf802a2a6643a23d362ca285d51309c3c42fbc439d" + } + ], + "vout": [ + { + "value": "107615", + "n": 0, + "spent": true, + "hex": "76a9140011b25c777caef601764607e7a302986eccb82588ac", + "addresses": [ + "t1HsyCvdZZczFXgJJEXaoJujo2fVZeVpRxK" + ], + "isAddress": true + } + ], + "blockHash": "00000000015c276dd33cac045fb755a86394acaa19615750fa3608bc4c8ff99e", + "blockHeight": 587035, + "confirmations": 242605, + "blockTime": 1566070856, + "value": "107615", + "valueIn": "117615", + "fees": "10000", + "hex": "0400008085202f8901a4f6e16ef91c8bb0e3f345ab3508b09f5ac72cdce010785bded0f0e1a025073c000000006a473044022074bdb6b0c06625dc963a2ce028db78b0b95cfba7d228b05a0cf440b4c40ca4b0022018a98ef2516f4c8869b039e2428386f0b66812b36b2cdf97a854dde952d0427d01210365ba1fc37153f8d1d13553cf802a2a6643a23d362ca285d51309c3c42fbc439d00000000015fa40100000000001976a9140011b25c777caef601764607e7a302986eccb82588ac00000000000000000000000000000000000000" + }, + { + "txid": "3c0725a0e1f0d0de5b7810e0dc2cc75a9fb00835ab45f3e3b08b1cf96ee1f6a4", + "version": 4, + "vin": [ + { + "txid": "bae4ead50cb6af925de4a800767467326009528d96698e547b4b3880cd0c774e", + "n": 0, + "addresses": [ + "t1SRU7H59hSyHCeZVSyQTy9eFWeZu58qCU5" + ], + "isAddress": true, + "value": "127615", + "hex": "483045022100fccbc13d0b0fb06eced6296b92d9810e6040a63506c604e226916301ae537ddd02207e0f0de7f0dfdc44a772e6eb5b40264eb9898011ea119fec0fbb9e2bc7830a24012103a07aa3081fe12b3d266b2dddd2cf03a8d064b532e992784583dfc3da89a9b19b" + } + ], + "vout": [ + { + "value": "117615", + "n": 0, + "spent": true, + "hex": "76a9149970712a7f2116b1de7f219ad3a337f3e77f3e7a88ac", + "addresses": [ + "t1Xrv6J9sU2gWY9eqb7PgsxGMd2WHpok1XE" + ], + "isAddress": true + } + ], + "blockHash": "0000000001457ae3eea0540bc6b0f2f7455e38dc8670af1c2f15f55d50a135ee", + "blockHeight": 552255, + "confirmations": 277385, + "blockTime": 1560830228, + "value": "117615", + "valueIn": "127615", + "fees": "10000", + "hex": "0400008085202f89014e770ccd80384b7b548e69968d5209603267747600a8e45d92afb60cd5eae4ba000000006b483045022100fccbc13d0b0fb06eced6296b92d9810e6040a63506c604e226916301ae537ddd02207e0f0de7f0dfdc44a772e6eb5b40264eb9898011ea119fec0fbb9e2bc7830a24012103a07aa3081fe12b3d266b2dddd2cf03a8d064b532e992784583dfc3da89a9b19b00000000016fcb0100000000001976a9149970712a7f2116b1de7f219ad3a337f3e77f3e7a88ac00000000000000000000000000000000000000" + }, + { + "txid": "bae4ead50cb6af925de4a800767467326009528d96698e547b4b3880cd0c774e", + "version": 4, + "vin": [ + { + "txid": "a9fe8bbc05bdd7ee41f5f5f23b09b55199426bb2a35dbe47010e08598f98e5c3", + "n": 0, + "addresses": [ + "t1PuJbdK5VEbMbQhQxZw5R2dAZXoBrRmQz2" + ], + "isAddress": true, + "value": "137615", + "hex": "483045022100dcf7b268d447abea180e21574aaa5be602c5fd6344e271b796c96814a6053f6f02201e7bff00a244b8d2be52fb186530461c75d8f1781ad896532a0dbfe5e045dcb4012103f4126fb596c4f86f2f252cd6b613601d4100881465deb0d18ea7f8a0b04ea590" + } + ], + "vout": [ + { + "value": "127615", + "n": 0, + "spent": true, + "hex": "76a9145dc7b9795d03a3c8fecb4278b764a4db8e1ee49488ac", + "addresses": [ + "t1SRU7H59hSyHCeZVSyQTy9eFWeZu58qCU5" + ], + "isAddress": true + } + ], + "blockHash": "00000000017e0ff0f957da216b91409ee1513fd365e0d65e6c06cc45cacf605b", + "blockHeight": 552253, + "confirmations": 277387, + "blockTime": 1560830099, + "value": "127615", + "valueIn": "137615", + "fees": "10000", + "hex": "0400008085202f8901c3e5988f59080e0147be5da3b26b429951b5093bf2f5f541eed7bd05bc8bfea9000000006b483045022100dcf7b268d447abea180e21574aaa5be602c5fd6344e271b796c96814a6053f6f02201e7bff00a244b8d2be52fb186530461c75d8f1781ad896532a0dbfe5e045dcb4012103f4126fb596c4f86f2f252cd6b613601d4100881465deb0d18ea7f8a0b04ea59000000000017ff20100000000001976a9145dc7b9795d03a3c8fecb4278b764a4db8e1ee49488ac00000000000000000000000000000000000000" + }, + { + "txid": "a9fe8bbc05bdd7ee41f5f5f23b09b55199426bb2a35dbe47010e08598f98e5c3", + "version": 4, + "vin": [ + { + "txid": "b2b4354a6f5c5e159e2bb2a0dc990c5f4ecfe365260ddb98921ad018b5030206", + "n": 0, + "addresses": [ + "t1aQHf67YqdbyNFzDpK4dXJsfjb4SPr9qRH" + ], + "isAddress": true, + "value": "60000", + "hex": "4730440220687c3b473abe367b46a88c51b36caf0d51926fbd4cc60df4cf7af30df53f4eec022068d34fdc54680ab3e574d8d1497c5b0832b00735929cd1e97e8ba03f3554aad6012103ec7908bb4a2ed3cf779f81691e30ccf867989b94e8cd79173796ffb6e18cf28c" + }, + { + "txid": "014795c69c6144f6c3b9be2b1f1f4d7617bac7e8a5f6e28673e3f901661c9444", + "vout": 1, + "n": 1, + "addresses": [ + "t1LmGZZN6oJsNV8wY9EDQYrhajg71YshkMo" + ], + "isAddress": true, + "value": "87615", + "hex": "4830450221009b4013ac2faa7d253b23bc7a05855130855332c39067fbc17e52d543cdce11e502201f640107c1a4f6415fbfd7b00cb66eaf047f45c5ca6a38f9e41ca526c036d2c5012102aa3981e0a468bc511b85746f1a33547105d16a244d23abe6f917c0b74777a24d" + } + ], + "vout": [ + { + "value": "137615", + "n": 0, + "spent": true, + "hex": "76a91442230df4c84c4dacb6945d0f7d300fd90557acca88ac", + "addresses": [ + "t1PuJbdK5VEbMbQhQxZw5R2dAZXoBrRmQz2" + ], + "isAddress": true + } + ], + "blockHash": "0000000000dc36e2f9d737c21143febc7f7a35a92769ca922c6321171d9b0886", + "blockHeight": 552248, + "confirmations": 277392, + "blockTime": 1560829106, + "value": "137615", + "valueIn": "147615", + "fees": "10000", + "hex": "0400008085202f8902060203b518d01a9298db0d2665e3cf4e5f0c99dca0b22b9e155e5c6f4a35b4b2000000006a4730440220687c3b473abe367b46a88c51b36caf0d51926fbd4cc60df4cf7af30df53f4eec022068d34fdc54680ab3e574d8d1497c5b0832b00735929cd1e97e8ba03f3554aad6012103ec7908bb4a2ed3cf779f81691e30ccf867989b94e8cd79173796ffb6e18cf28c0000000044941c6601f9e37386e2f6a5e8c7ba17764d1f1f2bbeb9c3f644619cc6954701010000006b4830450221009b4013ac2faa7d253b23bc7a05855130855332c39067fbc17e52d543cdce11e502201f640107c1a4f6415fbfd7b00cb66eaf047f45c5ca6a38f9e41ca526c036d2c5012102aa3981e0a468bc511b85746f1a33547105d16a244d23abe6f917c0b74777a24d00000000018f190200000000001976a91442230df4c84c4dacb6945d0f7d300fd90557acca88ac00000000000000000000000000000000000000" + }, + { + "txid": "b2b4354a6f5c5e159e2bb2a0dc990c5f4ecfe365260ddb98921ad018b5030206", + "version": 4, + "vin": [ + { + "txid": "4b061d48a56175194f35debff7cefdf2a738bcdccea5f0cebe4f5a95db9b6637", + "n": 0, + "addresses": [ + "t1WZBfArcTbjFo5By9tHg6aZ49u1XXokaPH" + ], + "isAddress": true, + "value": "10000", + "hex": "483045022100cf6f4bf09e1c9c64c1f8b6331e266c88d0402a4cfdf5d6176642f5d4c80dd5460220287b41c7c0000f34010310165bb44fd75c1e61f515c479918da467bd6e0b19c6012102eabba83fbfdb74b2e8a1f20dd9744682e34310535f6129bbd9f8005e917aef36" + }, + { + "txid": "ba6a3d21a328f62dae9c4bebd8d500918e2cdc6baa44a7984db3dc9a93c9652b", + "n": 1, + "addresses": [ + "t1azHScmQB3p7vsRaeEHR4xxAuiQ9SnC9GP" + ], + "isAddress": true, + "value": "20000", + "hex": "473044022039b4be3afde31864e91ba0b25837ed0e0b921709c95359c86497fa47e020d08f02203c7321c814d1cafbb010563e7ba02eb521b0982af59a08995c137e35765773f6012102abf02fc95b72e12a60ea199e9d33c1867687b31d6597ea6aaed07700c19952b6" + }, + { + "txid": "07597ac193a42bfd1a0370f26eb53c9cb6c383a43a15f689adc0f7fc6edf28c5", + "n": 2, + "addresses": [ + "t1ecYmJ9EtaU2Tq6MiEFe8dKtEbWDYM6EVV" + ], + "isAddress": true, + "value": "40000", + "hex": "483045022100bbb2369c802d32d26487ffd62fcdcb1c0d0690ac1d9521a86ad68d630ba1a5df022074ffbe6f532485e535814a2d2f502b2591f36b98a396c8bd49dcdfc5669230ee01210230ed84e0cb369ed38f38f58c39370e075a71dd4c9ef198c83dbb934140142281" + } + ], + "vout": [ + { + "value": "60000", + "n": 0, + "spent": true, + "hex": "76a914b54f971eeed8d512761bffe3403fb98dc68d1e5b88ac", + "addresses": [ + "t1aQHf67YqdbyNFzDpK4dXJsfjb4SPr9qRH" + ], + "isAddress": true + } + ], + "blockHash": "000000000065e2264cc41e0405783b6c5c53ae814f381fe2295344a74a264a19", + "blockHeight": 545291, + "confirmations": 284349, + "blockTime": 1559778739, + "value": "60000", + "valueIn": "70000", + "fees": "10000", + "hex": "0400008085202f890337669bdb955a4fbecef0a5cedcbc38a7f2fdcef7bfde354f197561a5481d064b000000006b483045022100cf6f4bf09e1c9c64c1f8b6331e266c88d0402a4cfdf5d6176642f5d4c80dd5460220287b41c7c0000f34010310165bb44fd75c1e61f515c479918da467bd6e0b19c6012102eabba83fbfdb74b2e8a1f20dd9744682e34310535f6129bbd9f8005e917aef36000000002b65c9939adcb34d98a744aa6bdc2c8e9100d5d8eb4b9cae2df628a3213d6aba000000006a473044022039b4be3afde31864e91ba0b25837ed0e0b921709c95359c86497fa47e020d08f02203c7321c814d1cafbb010563e7ba02eb521b0982af59a08995c137e35765773f6012102abf02fc95b72e12a60ea199e9d33c1867687b31d6597ea6aaed07700c19952b600000000c528df6efcf7c0ad89f6153aa483c3b69c3cb56ef270031afd2ba493c17a5907000000006b483045022100bbb2369c802d32d26487ffd62fcdcb1c0d0690ac1d9521a86ad68d630ba1a5df022074ffbe6f532485e535814a2d2f502b2591f36b98a396c8bd49dcdfc5669230ee01210230ed84e0cb369ed38f38f58c39370e075a71dd4c9ef198c83dbb934140142281000000000160ea0000000000001976a914b54f971eeed8d512761bffe3403fb98dc68d1e5b88ac00000000000000000000000000000000000000" + }, + { + "txid": "ba6a3d21a328f62dae9c4bebd8d500918e2cdc6baa44a7984db3dc9a93c9652b", + "version": 4, + "vin": [ + { + "txid": "2aa6a35c267895b2e69213ec76d97ce3e147e9e5ab8db4d14d97da8958efa9d0", + "vout": 1, + "n": 0, + "addresses": [ + "t1LEjcwGJyDNvMKDLB5k4CaghgfTZkjzzEw" + ], + "isAddress": true, + "value": "76571", + "hex": "483045022100dc687fa4a4c9548e110d44defafab7ea54d144f390944e357cfa26b6f790058d022069231e27f62ab31653b5c008118bb9869436fdb0d3a6eade372ea108d7daa7f601210213b1aae26c2f7ce235506548862a88ade9ffd3ce2b8b514d6bbbf7fc395bb590" + } + ], + "vout": [ + { + "value": "20000", + "n": 0, + "spent": true, + "hex": "76a914bbbd8db39d0f497de1ae92431a4b466e64293cd388ac", + "addresses": [ + "t1azHScmQB3p7vsRaeEHR4xxAuiQ9SnC9GP" + ], + "isAddress": true + }, + { + "value": "46571", + "n": 1, + "spent": true, + "hex": "76a91411c7f1c0835985c5ddd888c02c353f1bd8292e2f88ac", + "addresses": [ + "t1KVd1yQGPBxNnH9e5jz4AHZsyezLJbeCpx" + ], + "isAddress": true + } + ], + "blockHash": "00000000000b0040c2a6d132807a476ccfbe21905d00cb75d72dc40493714fa0", + "blockHeight": 536166, + "confirmations": 293474, + "blockTime": 1558404490, + "value": "66571", + "valueIn": "76571", + "fees": "10000", + "hex": "0400008085202f8901d0a9ef5889da974dd1b48dabe5e947e1e37cd976ec1392e6b29578265ca3a62a010000006b483045022100dc687fa4a4c9548e110d44defafab7ea54d144f390944e357cfa26b6f790058d022069231e27f62ab31653b5c008118bb9869436fdb0d3a6eade372ea108d7daa7f601210213b1aae26c2f7ce235506548862a88ade9ffd3ce2b8b514d6bbbf7fc395bb5900000000002204e0000000000001976a914bbbd8db39d0f497de1ae92431a4b466e64293cd388acebb50000000000001976a91411c7f1c0835985c5ddd888c02c353f1bd8292e2f88ac00000000000000000000000000000000000000" + }, + { + "txid": "4b061d48a56175194f35debff7cefdf2a738bcdccea5f0cebe4f5a95db9b6637", + "version": 4, + "vin": [ + { + "txid": "f50a4866f8903d33ca366c03b1532cf706332d1bdc7c6e750d6a7aff446e0c98", + "vout": 1, + "n": 0, + "addresses": [ + "t1VbtaqSjTYUTyE8Vd1kfiyyGanp6jgscU8" + ], + "isAddress": true, + "value": "116571", + "hex": "483045022100b7503d585b390559b925dcaed95fe1f8a16a016b5e5e951aa5ae7bb7de9594b8022054265524e2e5182f779a2ede0cbf6a9f1600ed008fdc73de898e4233b28cf5fc012102dcd6ea3c7eba94884ef03ca415da890518e577e3cfa94f0e77c9332be39d3602" + } + ], + "vout": [ + { + "value": "10000", + "n": 0, + "spent": true, + "hex": "76a9148b1dd2cea75b2d0d4c8d36c8a93439607b1e976088ac", + "addresses": [ + "t1WZBfArcTbjFo5By9tHg6aZ49u1XXokaPH" + ], + "isAddress": true + }, + { + "value": "96571", + "n": 1, + "spent": true, + "hex": "76a914e6d092ef8680c588ba47969614e2261d01d974e288ac", + "addresses": [ + "t1ev3HRtQ6ZtmeueaiXHWApFFVtMFnLxaf7" + ], + "isAddress": true + } + ], + "blockHash": "00000000002af42207e62b06294fdb4cc30f9f68b9997b2ba2c0408ee9c04243", + "blockHeight": 535691, + "confirmations": 293949, + "blockTime": 1558332379, + "value": "106571", + "valueIn": "116571", + "fees": "10000", + "hex": "0400008085202f8901980c6e44ff7a6a0d756e7cdc1b2d3306f72c53b1036c36ca333d90f866480af5010000006b483045022100b7503d585b390559b925dcaed95fe1f8a16a016b5e5e951aa5ae7bb7de9594b8022054265524e2e5182f779a2ede0cbf6a9f1600ed008fdc73de898e4233b28cf5fc012102dcd6ea3c7eba94884ef03ca415da890518e577e3cfa94f0e77c9332be39d3602000000000210270000000000001976a9148b1dd2cea75b2d0d4c8d36c8a93439607b1e976088ac3b790100000000001976a914e6d092ef8680c588ba47969614e2261d01d974e288ac00000000000000000000000000000000000000" + }, + { + "txid": "07597ac193a42bfd1a0370f26eb53c9cb6c383a43a15f689adc0f7fc6edf28c5", + "version": 4, + "vin": [ + { + "txid": "87a266b3f2a4b830b164a96a9e4b4b6061d7c5ffe1e30e57b642c571bf388e98", + "sequence": 2147483645, + "n": 0, + "addresses": [ + "t1SKY9rZvnTTS8ZoVjn4dAfCmUqmArtpFHi" + ], + "isAddress": true, + "value": "20000", + "hex": "4830450221009b6a147560a41c5285a7c35a21812b4be68bb52b1ce03e3bf0b475aa737c6eb2022048739d1c6c6ceca1f2e67d61752f97c81da4fcc09264867c6d4c299099b48bd30121026a9f1854fdd1c1ce3939d440c8840dbd2a63fc7008a18572d89ea2f1d63c9b32" + }, + { + "txid": "5741f65a1c49ba6f1baa4d1b82a3474c3789e9ba1b3e9bd5d60a8a0d479d750f", + "vout": 1, + "sequence": 2147483646, + "n": 1, + "addresses": [ + "t1dQQump9ZPt7urePRY8TgYvWv4xdmChAW6" + ], + "isAddress": true, + "value": "30000", + "hex": "4730440220712880521b4b31ebd9b424b9ec357280cd3fbed5dffa844aa7458da2724bbdf002203c725798727356eb4bae4689f9ced074a87310f10ff926503b7d492aa8e84128012102f97ce8805b15faa5eff060374e320d5f9e88169065debeff4d756ab345b3ec3b" + } + ], + "vout": [ + { + "value": "40000", + "n": 0, + "spent": true, + "hex": "76a914e381b21975ead95b7a21edd78f82b2f676b6e1bb88ac", + "addresses": [ + "t1ecYmJ9EtaU2Tq6MiEFe8dKtEbWDYM6EVV" + ], + "isAddress": true + } + ], + "blockHash": "000000000162ad34a620f5da8aaca7886ab814b42222fb3c19012d21e3f0076f", + "blockHeight": 530001, + "confirmations": 299639, + "blockTime": 1557475098, + "value": "40000", + "valueIn": "50000", + "fees": "10000", + "hex": "0400008085202f8902988e38bf71c542b6570ee3e1ffc5d761604b4b9e6aa964b130b8a4f2b366a287000000006b4830450221009b6a147560a41c5285a7c35a21812b4be68bb52b1ce03e3bf0b475aa737c6eb2022048739d1c6c6ceca1f2e67d61752f97c81da4fcc09264867c6d4c299099b48bd30121026a9f1854fdd1c1ce3939d440c8840dbd2a63fc7008a18572d89ea2f1d63c9b32fdffff7f0f759d470d8a0ad6d59b3e1bbae989374c47a3821b4daa1b6fba491c5af64157010000006a4730440220712880521b4b31ebd9b424b9ec357280cd3fbed5dffa844aa7458da2724bbdf002203c725798727356eb4bae4689f9ced074a87310f10ff926503b7d492aa8e84128012102f97ce8805b15faa5eff060374e320d5f9e88169065debeff4d756ab345b3ec3bfeffff7f01409c0000000000001976a914e381b21975ead95b7a21edd78f82b2f676b6e1bb88ac00000000000000000000000000000000000000" + }, + { + "txid": "87a266b3f2a4b830b164a96a9e4b4b6061d7c5ffe1e30e57b642c571bf388e98", + "version": 4, + "vin": [ + { + "txid": "6cb96616f80d3306b3d4fd070f8bbca86e2c6d07235e72d15c6594223660e3b4", + "n": 0, + "addresses": [ + "t1VuFmytzWfXkf4nFQ1qVyRVG6sA71Nb1XA" + ], + "isAddress": true, + "value": "186571", + "hex": "4830450221008a5d4a6844d7f8b57e8fd5a08e2f27da2197368b6679760601bfbfe36c2ee54b02202457c56bb0c5a4223cb2aa52eaf2a6f1d74b8d460aff3aa9a909f4ce1ab4164c012102d22925142a9dbfd799b338f234d23b89f9f7fdcf9ad00152b491dbb4eb116ec4" + } + ], + "vout": [ + { + "value": "20000", + "n": 0, + "spent": true, + "hex": "76a9145ca89ad87d3ea6efdaca1c6a27b556005d9b33e988ac", + "addresses": [ + "t1SKY9rZvnTTS8ZoVjn4dAfCmUqmArtpFHi" + ], + "isAddress": true + }, + { + "value": "156571", + "n": 1, + "spent": true, + "hex": "76a914bd5cdbfa6ff21f7bf3e608d75864fd80fb81d48f88ac", + "addresses": [ + "t1b8rxZuPquqUWECT4RZ2eCsFzUeRwmGzoW" + ], + "isAddress": true + } + ], + "blockHash": "00000000025e8dcff95a89e64a5f6e0e0276396c37122968b1df6778ebcfe793", + "blockHeight": 493797, + "confirmations": 335843, + "blockTime": 1552021263, + "value": "176571", + "valueIn": "186571", + "fees": "10000", + "hex": "0400008085202f8901b4e360362294655cd1725e23076d2c6ea8bc8b0f07fdd4b306330df81666b96c000000006b4830450221008a5d4a6844d7f8b57e8fd5a08e2f27da2197368b6679760601bfbfe36c2ee54b02202457c56bb0c5a4223cb2aa52eaf2a6f1d74b8d460aff3aa9a909f4ce1ab4164c012102d22925142a9dbfd799b338f234d23b89f9f7fdcf9ad00152b491dbb4eb116ec40000000002204e0000000000001976a9145ca89ad87d3ea6efdaca1c6a27b556005d9b33e988ac9b630200000000001976a914bd5cdbfa6ff21f7bf3e608d75864fd80fb81d48f88ac00000000000000000000000000000000000000" + }, + { + "txid": "5741f65a1c49ba6f1baa4d1b82a3474c3789e9ba1b3e9bd5d60a8a0d479d750f", + "version": 4, + "vin": [ + { + "txid": "bc5c5c66ad3ad122bb4d1c2496431e58fa14d574928f4c7e2460d8dcd4bd0e84", + "n": 0, + "addresses": [ + "t1YttEPhpzGVSYSp5R34wVqVPs2fyGiEZs2" + ], + "isAddress": true, + "value": "60205", + "hex": "47304402205721cbb1e623518d7ec2e830aa7460e58c42a9f787f11291f6c05a90afb6a657022069602db026217e31a8817d433a7f3e30f6659f57d6761e490acf7bc0a0521558012102b27a1fd41fce9b5b0f3dc90ffe2d535a2b86e608fba52a49c354c73e82bdd6a4" + } + ], + "vout": [ + { + "value": "20205", + "n": 0, + "spent": true, + "hex": "76a914955584a7abf343158e28cf3c0160796cbd12d08088ac", + "addresses": [ + "t1XVD8prU8TEAA1pxKyz6mrBNbBZ8wC4kTj" + ], + "isAddress": true + }, + { + "value": "30000", + "n": 1, + "spent": true, + "hex": "76a914d63e05b6989e6921c76479fc6ef0e7e9823d7c5c88ac", + "addresses": [ + "t1dQQump9ZPt7urePRY8TgYvWv4xdmChAW6" + ], + "isAddress": true + } + ], + "blockHash": "0000000001591c6609bb6c0edc720947abb7e712dbb8deea965b9246c3c1d0c8", + "blockHeight": 493429, + "confirmations": 336211, + "blockTime": 1551964242, + "value": "50205", + "valueIn": "60205", + "fees": "10000", + "hex": "0400008085202f8901840ebdd4dcd860247e4c8f9274d514fa581e4396241c4dbb22d13aad665c5cbc000000006a47304402205721cbb1e623518d7ec2e830aa7460e58c42a9f787f11291f6c05a90afb6a657022069602db026217e31a8817d433a7f3e30f6659f57d6761e490acf7bc0a0521558012102b27a1fd41fce9b5b0f3dc90ffe2d535a2b86e608fba52a49c354c73e82bdd6a40000000002ed4e0000000000001976a914955584a7abf343158e28cf3c0160796cbd12d08088ac30750000000000001976a914d63e05b6989e6921c76479fc6ef0e7e9823d7c5c88ac00000000000000000000000000000000000000" + }, + { + "txid": "bc5c5c66ad3ad122bb4d1c2496431e58fa14d574928f4c7e2460d8dcd4bd0e84", + "version": 4, + "vin": [ + { + "txid": "fbb42f66c7c89790d5dad4aa23e85dfc7b5ab1cfe5a4086527a23c7df20756b4", + "n": 0, + "addresses": [ + "t1YttEPhpzGVSYSp5R34wVqVPs2fyGiEZs2" + ], + "isAddress": true, + "value": "20000", + "hex": "463043022053699effba95c7d1bee5a8ae182dbcf0d86af5c082098dfae4ece7e54c3736e3021f355bfa5a836a92a441b6a4ff156bfdeba3f220d0003c9c9e6a4dc6d85752bf012102b27a1fd41fce9b5b0f3dc90ffe2d535a2b86e608fba52a49c354c73e82bdd6a4" + }, + { + "txid": "c82c968f0ac87b54466871720eef8c4d3f608d28438561c309f294b383aff17a", + "n": 1, + "addresses": [ + "t1Kcug9yvp6QLipTfd9RDrU5PQPsHzePhyv" + ], + "isAddress": true, + "value": "40545", + "hex": "483045022100fb9f78fb552c84334b81d2c3032b54c260fce7873500730c974ad34bba7644f102204ac0d79c0d5aef6f6f3c36ffe8254cc17cf92e33ff9571aead9523f300fec1a3012103dc373638b9cca448a4adb2c8e778a426c4a8216775498c7cf32feb810b3c4ec3" + } + ], + "vout": [ + { + "value": "60205", + "n": 0, + "spent": true, + "hex": "76a914a4c7d8c56f1ff151cbdeec12bc7b053b08ff52ac88ac", + "addresses": [ + "t1YttEPhpzGVSYSp5R34wVqVPs2fyGiEZs2" + ], + "isAddress": true + } + ], + "blockHash": "000000000158a121c2a75050705c45ff354af27544e229323d482e44d5914b06", + "blockHeight": 492785, + "confirmations": 336855, + "blockTime": 1551868143, + "value": "60205", + "valueIn": "60545", + "fees": "340", + "hex": "0400008085202f8902b45607f27d3ca2276508a4e5cfb15a7bfc5de823aad4dad59097c8c7662fb4fb0000000069463043022053699effba95c7d1bee5a8ae182dbcf0d86af5c082098dfae4ece7e54c3736e3021f355bfa5a836a92a441b6a4ff156bfdeba3f220d0003c9c9e6a4dc6d85752bf012102b27a1fd41fce9b5b0f3dc90ffe2d535a2b86e608fba52a49c354c73e82bdd6a4000000007af1af83b394f209c3618543288d603f4d8cef0e72716846547bc80a8f962cc8000000006b483045022100fb9f78fb552c84334b81d2c3032b54c260fce7873500730c974ad34bba7644f102204ac0d79c0d5aef6f6f3c36ffe8254cc17cf92e33ff9571aead9523f300fec1a3012103dc373638b9cca448a4adb2c8e778a426c4a8216775498c7cf32feb810b3c4ec300000000012deb0000000000001976a914a4c7d8c56f1ff151cbdeec12bc7b053b08ff52ac88ac00000000000000000000000000000000000000" + }, + { + "txid": "fbb42f66c7c89790d5dad4aa23e85dfc7b5ab1cfe5a4086527a23c7df20756b4", + "version": 4, + "vin": [ + { + "txid": "5d3f984c4563d5c363281e2be8de4122a5751bd502fb8782b0b12682a7ec5d42", + "n": 0, + "addresses": [ + "t1MTTLGaye2ZEPzKUc7EVLxAFx5B89rotcs" + ], + "isAddress": true, + "value": "94000", + "hex": "473044022079cc77a85e4465d4d176fda5cfde603d4721d93d3d4650b522b39efb24c17bbd022015bddf13c5cde76162cf7ccc2995d6851ba3bfaa99a6cc9016aaa41b46e0c2de012102baf4209fb6e235ad8c9705b2d4b9797b0f14545ffb1512e58b5d066548e03212" + } + ], + "vout": [ + { + "value": "20000", + "n": 0, + "spent": true, + "hex": "76a914a4c7d8c56f1ff151cbdeec12bc7b053b08ff52ac88ac", + "addresses": [ + "t1YttEPhpzGVSYSp5R34wVqVPs2fyGiEZs2" + ], + "isAddress": true + }, + { + "value": "73774", + "n": 1, + "spent": true, + "hex": "76a914e1794bf49a7ba4066ee119369e7b79430f34a52a88ac", + "addresses": [ + "t1eRoMLftw1xXFsSoL8ibmv8DFA3rzR6oeK" + ], + "isAddress": true + } + ], + "blockHash": "0000000001ac58459c37aa4254a1420711cd246737827936cdd9a78249236225", + "blockHeight": 492784, + "confirmations": 336856, + "blockTime": 1551867941, + "value": "93774", + "valueIn": "94000", + "fees": "226", + "hex": "0400008085202f8901425deca78226b1b08287fb02d51b75a52241dee82b1e2863c3d563454c983f5d000000006a473044022079cc77a85e4465d4d176fda5cfde603d4721d93d3d4650b522b39efb24c17bbd022015bddf13c5cde76162cf7ccc2995d6851ba3bfaa99a6cc9016aaa41b46e0c2de012102baf4209fb6e235ad8c9705b2d4b9797b0f14545ffb1512e58b5d066548e032120000000002204e0000000000001976a914a4c7d8c56f1ff151cbdeec12bc7b053b08ff52ac88ac2e200100000000001976a914e1794bf49a7ba4066ee119369e7b79430f34a52a88ac00000000000000000000000000000000000000" + }, + { + "txid": "c82c968f0ac87b54466871720eef8c4d3f608d28438561c309f294b383aff17a", + "version": 4, + "vin": [ + { + "txid": "eb15e83c5e3ad2b5cb18a2ce87d396bd3772f3332316ebbc7adf2fb33082c2f2", + "sequence": 2147483646, + "n": 0, + "addresses": [ + "t1VZp67AK9zgdXwa35kwYrJ1Mh4NWjUENrM" + ], + "isAddress": true, + "value": "50545", + "hex": "483045022100f401558fb69e77db46dc3fc50a9d133334004cb5e8c368a020bcf7f057ab6545022053e4c3cc1ee5f3f2b4559b5e9178428ceecdabf85786359be5d0fa0863655f0101210233258d2a0e50bb55ed56dc5bfc2d26295245a9e18ee95ac8b09f04f6618f70ec" + } + ], + "vout": [ + { + "value": "40545", + "n": 0, + "spent": true, + "hex": "76a9141328c3015cb87b03e8e6f0a5b9df3af2287e88d188ac", + "addresses": [ + "t1Kcug9yvp6QLipTfd9RDrU5PQPsHzePhyv" + ], + "isAddress": true + } + ], + "blockHash": "0000000001398c130afbd8c1fd48efaaf33e6ecb569e5af9cec2779af35bb440", + "blockHeight": 489873, + "confirmations": 339767, + "blockTime": 1551429261, + "value": "40545", + "valueIn": "50545", + "fees": "10000", + "hex": "0400008085202f8901f2c28230b32fdf7abceb162333f37237bd96d387cea218cbb5d23a5e3ce815eb000000006b483045022100f401558fb69e77db46dc3fc50a9d133334004cb5e8c368a020bcf7f057ab6545022053e4c3cc1ee5f3f2b4559b5e9178428ceecdabf85786359be5d0fa0863655f0101210233258d2a0e50bb55ed56dc5bfc2d26295245a9e18ee95ac8b09f04f6618f70ecfeffff7f01619e0000000000001976a9141328c3015cb87b03e8e6f0a5b9df3af2287e88d188ac00000000000000000000000000000000000000" + }, + { + "txid": "eb15e83c5e3ad2b5cb18a2ce87d396bd3772f3332316ebbc7adf2fb33082c2f2", + "version": 4, + "vin": [ + { + "txid": "5ba43d4ffc58827e896793f044f1bf78c382571761362dfa844422d575639d78", + "sequence": 2147483645, + "n": 0, + "addresses": [ + "t1ZBs9xvRypkjXmci2SS6zbNWVhuWH1h93L" + ], + "isAddress": true, + "value": "30545", + "hex": "483045022100ebc32cdf141e49adf2be0f0a70920f66ba3b206aaebcbc19a3f819ebc974d83102206175d4e979a0a0e2ff51b363552ac60b17dfc1d0a91c80395cb6ae2bfcf9476d012103132665bcf5b41abb7565ccfd53f748175cc42e9ddb4a845e79bcb79c8cd99f26" + }, + { + "txid": "5ba43d4ffc58827e896793f044f1bf78c382571761362dfa844422d575639d78", + "vout": 1, + "sequence": 2147483646, + "n": 1, + "addresses": [ + "t1Y5pJi1BzrppCFwVkaK1XTVv3BwCbytGaA" + ], + "isAddress": true, + "value": "30000", + "hex": "473044022076d426a3404a53ca2f93a4dcf1985fae899a373993d7c2e1fe94b05609b728d6022056116ac52a03b644f61456439a401a8f6d3ba061c17386dbf2fabbc0b306c01d01210201e594657c7cfbfe12a8c0943f39886d9cae06386275739bd7983a621c81c7c5" + } + ], + "vout": [ + { + "value": "50545", + "n": 0, + "spent": true, + "hex": "76a91480441b9ccba15c024878a39b9f85b98f9d333d6288ac", + "addresses": [ + "t1VZp67AK9zgdXwa35kwYrJ1Mh4NWjUENrM" + ], + "isAddress": true + } + ], + "blockHash": "0000000001dc7678276f7964adb7b932ae6d998cde2177e28e12d130759a7590", + "blockHeight": 485550, + "confirmations": 344090, + "blockTime": 1550776869, + "value": "50545", + "valueIn": "60545", + "fees": "10000", + "hex": "0400008085202f8902789d6375d5224484fa2d3661175782c378bff144f09367897e8258fc4f3da45b000000006b483045022100ebc32cdf141e49adf2be0f0a70920f66ba3b206aaebcbc19a3f819ebc974d83102206175d4e979a0a0e2ff51b363552ac60b17dfc1d0a91c80395cb6ae2bfcf9476d012103132665bcf5b41abb7565ccfd53f748175cc42e9ddb4a845e79bcb79c8cd99f26fdffff7f789d6375d5224484fa2d3661175782c378bff144f09367897e8258fc4f3da45b010000006a473044022076d426a3404a53ca2f93a4dcf1985fae899a373993d7c2e1fe94b05609b728d6022056116ac52a03b644f61456439a401a8f6d3ba061c17386dbf2fabbc0b306c01d01210201e594657c7cfbfe12a8c0943f39886d9cae06386275739bd7983a621c81c7c5feffff7f0171c50000000000001976a91480441b9ccba15c024878a39b9f85b98f9d333d6288ac00000000000000000000000000000000000000" + }, + { + "txid": "5ba43d4ffc58827e896793f044f1bf78c382571761362dfa844422d575639d78", + "version": 4, + "vin": [ + { + "txid": "37c7b9f9cebe1416d219ca05485ad778bc6f89856cba4c61bfaa7d9f458b2d55", + "vout": 1, + "sequence": 2147483646, + "n": 0, + "addresses": [ + "t1NbJzWWBkfUrxSN8FWNKSa9JUSTG26dStY" + ], + "isAddress": true, + "value": "70545", + "hex": "483045022100df78b552957f64a099afe79c2a6e1ec4acfa4c8577f7c0b1e8ad27ca468b26ca02203b530b1d959c049e4275a3fb5eef9605d96d1c58740a34a80bf4298a35d3a53a0121021f3209adeba8e2b478b4dec27e562b1203d6035333784da2af7cdc89ab33aace" + } + ], + "vout": [ + { + "value": "30545", + "n": 0, + "spent": true, + "hex": "76a914a7fe0506daff7402a5dd08659a86668a497614f988ac", + "addresses": [ + "t1ZBs9xvRypkjXmci2SS6zbNWVhuWH1h93L" + ], + "isAddress": true + }, + { + "value": "30000", + "n": 1, + "spent": true, + "hex": "76a9149be10506ef2c0a369929ca54873569ab55907d3f88ac", + "addresses": [ + "t1Y5pJi1BzrppCFwVkaK1XTVv3BwCbytGaA" + ], + "isAddress": true + } + ], + "blockHash": "000000000235fae347f9c305d34a76fc4b532d6f063eeb2304e37a31b183b281", + "blockHeight": 483265, + "confirmations": 346375, + "blockTime": 1550432494, + "value": "60545", + "valueIn": "70545", + "fees": "10000", + "hex": "0400008085202f8901552d8b459f7daabf614cba6c85896fbc78d75a4805ca19d21614becef9b9c737010000006b483045022100df78b552957f64a099afe79c2a6e1ec4acfa4c8577f7c0b1e8ad27ca468b26ca02203b530b1d959c049e4275a3fb5eef9605d96d1c58740a34a80bf4298a35d3a53a0121021f3209adeba8e2b478b4dec27e562b1203d6035333784da2af7cdc89ab33aacefeffff7f0251770000000000001976a914a7fe0506daff7402a5dd08659a86668a497614f988ac30750000000000001976a9149be10506ef2c0a369929ca54873569ab55907d3f88ac00000000000000000000000000000000000000" + }, + { + "txid": "37c7b9f9cebe1416d219ca05485ad778bc6f89856cba4c61bfaa7d9f458b2d55", + "version": 4, + "vin": [ + { + "txid": "1e4b4756b54858af5c93d916fd19e0e3bce148a84ee7bcf6200cb2252488791f", + "vout": 1, + "sequence": 1, + "n": 0, + "addresses": [ + "t1b4mu9ew2Ubf5pLBbNh9PbXfsdHR1aoQ99" + ], + "isAddress": true, + "value": "100771", + "hex": "483045022100b52a74148248ba2853bac2dd2cad4b6d1d46b8cdda51350384ff868411672c8d02203bf74c7cab9a615874e98aa3b63a6cf003a6f565a393c444553c300b9e881a8201210381c7ca3323110fdff2e27094d967cdf0ece3435793fc34c0af8140203bacaa89" + } + ], + "vout": [ + { + "value": "30000", + "n": 0, + "spent": true, + "hex": "76a914a2511fc37f67f3b5627affce89fb3f7bb186412888ac", + "addresses": [ + "t1Yfrf1dssDLmaMBsq2LFKWPbS5vH3nGpa2" + ], + "isAddress": true + }, + { + "value": "70545", + "n": 1, + "spent": true, + "hex": "76a91433c3c5503cb12ec7a87fcbb5f30ee8677d51a38688ac", + "addresses": [ + "t1NbJzWWBkfUrxSN8FWNKSa9JUSTG26dStY" + ], + "isAddress": true + } + ], + "blockHash": "000000000255e2cd35ef686be4492c8e84342945c1683cf108bfa8a480dc8266", + "blockHeight": 480644, + "confirmations": 348996, + "blockTime": 1550038730, + "value": "100545", + "valueIn": "100771", + "fees": "226", + "hex": "0400008085202f89011f79882425b20c20f6bce74ea848e1bce3e019fd16d9935caf5848b556474b1e010000006b483045022100b52a74148248ba2853bac2dd2cad4b6d1d46b8cdda51350384ff868411672c8d02203bf74c7cab9a615874e98aa3b63a6cf003a6f565a393c444553c300b9e881a8201210381c7ca3323110fdff2e27094d967cdf0ece3435793fc34c0af8140203bacaa89010000000230750000000000001976a914a2511fc37f67f3b5627affce89fb3f7bb186412888ac91130100000000001976a91433c3c5503cb12ec7a87fcbb5f30ee8677d51a38688ac00000000000000000000000000000000000000" + }, + { + "txid": "1e4b4756b54858af5c93d916fd19e0e3bce148a84ee7bcf6200cb2252488791f", + "version": 4, + "vin": [ + { + "txid": "a2d70bee124510c476f159fa83cdb34d663fc6020c81aad19b238601d679fed7", + "n": 0, + "addresses": [ + "t1U4xs3qMxc2TL8wwYufmBngA5mewLHRwhM" + ], + "isAddress": true, + "value": "200997", + "hex": "4730440220211441367b601960d81e802a74b92aedfe10d32c49c86e43186ab1e743c045af02207267c5c2dc3abbf71ec3e149d94736d3deac8c87be1d5ceae8648ce5cad416c9012103fef9b9366755bd64a0579f1a5bfb92485c1f4ab33c53a1afb1899efa7e4782c1" + } + ], + "vout": [ + { + "value": "100000", + "n": 0, + "spent": true, + "hex": "76a9145f17f252c1d48a7465f512c13ecc182a3c3e827788ac", + "addresses": [ + "t1SYQtPxi4BYbZpMWZb4F4aFnEBgfHuE5uW" + ], + "isAddress": true + }, + { + "value": "100771", + "n": 1, + "spent": true, + "hex": "76a914bc96f8f30d3e5a96cfa2b0143a4aa84fa60854ba88ac", + "addresses": [ + "t1b4mu9ew2Ubf5pLBbNh9PbXfsdHR1aoQ99" + ], + "isAddress": true + } + ], + "blockHash": "000000000046084d8c5331f53b4f91c9e4b5514854bedeac833882396900aa24", + "blockHeight": 479877, + "confirmations": 349763, + "blockTime": 1549921545, + "value": "200771", + "valueIn": "200997", + "fees": "226", + "hex": "0400008085202f8901d7fe79d60186239bd1aa810c02c63f664db3cd83fa59f176c4104512ee0bd7a2000000006a4730440220211441367b601960d81e802a74b92aedfe10d32c49c86e43186ab1e743c045af02207267c5c2dc3abbf71ec3e149d94736d3deac8c87be1d5ceae8648ce5cad416c9012103fef9b9366755bd64a0579f1a5bfb92485c1f4ab33c53a1afb1899efa7e4782c10000000002a0860100000000001976a9145f17f252c1d48a7465f512c13ecc182a3c3e827788aca3890100000000001976a914bc96f8f30d3e5a96cfa2b0143a4aa84fa60854ba88ac00000000000000000000000000000000000000" + }, + { + "txid": "a2d70bee124510c476f159fa83cdb34d663fc6020c81aad19b238601d679fed7", + "version": 4, + "vin": [ + { + "txid": "5a3664328ac4e1c0688729573296c2ec69dd9a7cf98d49967b41520be794229b", + "n": 0, + "addresses": [ + "t1T7cLkvDVScjw95WguoAZbbT8mrdqVtpiD" + ], + "isAddress": true, + "value": "387582", + "hex": "483045022100ec29a476dac49578339a92e6c20451aaf3ff6691efaf7d4d3113d07589771ca702203c0c173bdc356300edbd64cdfaa868b97c13ebc403026b283eb5e1fca398db8b012103729cc4211cf70f87c70c3cef90e0ca9b91e99b42364b8c600d5781277647de5f" + } + ], + "vout": [ + { + "value": "200997", + "n": 0, + "spent": true, + "hex": "76a9146fd73e7c147d8ccc15fda31d8429e70f302b843988ac", + "addresses": [ + "t1U4xs3qMxc2TL8wwYufmBngA5mewLHRwhM" + ], + "isAddress": true + }, + { + "value": "186359", + "n": 1, + "spent": true, + "hex": "76a91484f0258cb7974993e6af928921b7f699c51a309488ac", + "addresses": [ + "t1VzWtLj9CSAK3QnxA7uuiK6XhJrjGjKoy4" + ], + "isAddress": true + } + ], + "blockHash": "0000000000a8248c4a14a2dcb74d92855bf9440da9b7b1e6d4baa14ee7e3081c", + "blockHeight": 479017, + "confirmations": 350623, + "blockTime": 1549793065, + "value": "387356", + "valueIn": "387582", + "fees": "226", + "hex": "0400008085202f89019b2294e70b52417b96498df97c9add69ecc2963257298768c0e1c48a3264365a000000006b483045022100ec29a476dac49578339a92e6c20451aaf3ff6691efaf7d4d3113d07589771ca702203c0c173bdc356300edbd64cdfaa868b97c13ebc403026b283eb5e1fca398db8b012103729cc4211cf70f87c70c3cef90e0ca9b91e99b42364b8c600d5781277647de5f000000000225110300000000001976a9146fd73e7c147d8ccc15fda31d8429e70f302b843988acf7d70200000000001976a91484f0258cb7974993e6af928921b7f699c51a309488ac00000000000000000000000000000000000000" + } + ], + "usedTokens": 30, + "tokens": [ + { + "type": "XPUBAddress", + "name": "t1U4xs3qMxc2TL8wwYufmBngA5mewLHRwhM", + "path": "m/44'/133'/0'/0/0", + "transfers": 10, + "decimals": 8, + "balance": "836466", + "totalReceived": "3779159", + "totalSent": "2942693" + } + ] +} diff --git a/mock/ext-api-data/zcoin-api_v2_address_a8EF4cpenEgEn9hm2NL5KfFK1UmSZZaQVn__details_txs.json b/mock/ext-api-data/zcoin-api_v2_address_a8EF4cpenEgEn9hm2NL5KfFK1UmSZZaQVn__details_txs.json new file mode 100644 index 000000000..62dcfb166 --- /dev/null +++ b/mock/ext-api-data/zcoin-api_v2_address_a8EF4cpenEgEn9hm2NL5KfFK1UmSZZaQVn__details_txs.json @@ -0,0 +1 @@ +{"page":1,"totalPages":2,"itemsOnPage":10,"address":"a8EF4cpenEgEn9hm2NL5KfFK1UmSZZaQVn","balance":"63109110","totalReceived":"1565104974","totalSent":"1501995864","unconfirmedBalance":"0","unconfirmedTxs":0,"txs":18,"transactions":[{"txid":"f1db892b13a2cb34a9a1ed0890b85050c43b95e06dc085d7f063e9207e984609","version":1,"vin":[{"txid":"cd33ac3382c4a5b2eb70f6d7625289446430ff9484326ffc234bc498c274b564","vout":1,"n":0,"addresses":["a8EF4cpenEgEn9hm2NL5KfFK1UmSZZaQVn"],"isAddress":true,"value":"51916634","hex":"483045022100dc5a93fa3bd1f61115062700756163da79860b38fe348aa9c3bc5d9c578c8d55022048f2f300dce9858fa3a24e05084bb892287a623b40271289cb5fce9783e77b730121030987bda3c78bd6e2dd765f3767cc3611cd05c9e3c0d49873f2cd68d3fd305b15"}],"vout":[{"value":"13113178","n":0,"hex":"76a914526ac6dd84927e5e26dc6c89976d58ea4c1a4d4788ac","addresses":["a8EF4cpenEgEn9hm2NL5KfFK1UmSZZaQVn"],"isAddress":true},{"value":"38799388","n":1,"hex":"76a914526ac6dd84927e5e26dc6c89976d58ea4c1a4d4788ac","addresses":["a8EF4cpenEgEn9hm2NL5KfFK1UmSZZaQVn"],"isAddress":true}],"blockHash":"f85889dc565371828f3c0821f2507ca2fa2f83eae557b7d3ba7270eab6ac7328","blockHeight":251191,"confirmations":17949,"blockTime":1584663676,"value":"51912566","valueIn":"51916634","fees":"4068","hex":"010000000164b574c298c44b23fc6f328494ff306444895262d7f670ebb2a5c48233ac33cd010000006b483045022100dc5a93fa3bd1f61115062700756163da79860b38fe348aa9c3bc5d9c578c8d55022048f2f300dce9858fa3a24e05084bb892287a623b40271289cb5fce9783e77b730121030987bda3c78bd6e2dd765f3767cc3611cd05c9e3c0d49873f2cd68d3fd305b1500000000025a17c800000000001976a914526ac6dd84927e5e26dc6c89976d58ea4c1a4d4788ac1c085002000000001976a914526ac6dd84927e5e26dc6c89976d58ea4c1a4d4788ac00000000"},{"txid":"cd33ac3382c4a5b2eb70f6d7625289446430ff9484326ffc234bc498c274b564","version":1,"vin":[{"txid":"50cb7a384e031c2823147c440884dbbf6ecef313925f113768406ab7776229fd","vout":1,"n":0,"addresses":["a8EF4cpenEgEn9hm2NL5KfFK1UmSZZaQVn"],"isAddress":true,"value":"61920702","hex":"483045022100aff10fef2849988470ac3411bd463ae03a17a88336283290095f8247dc0531a4022064f2c0e60662effb5b46c2a70318331b007df7441a209e2bf6489924c73952f50121030987bda3c78bd6e2dd765f3767cc3611cd05c9e3c0d49873f2cd68d3fd305b15"}],"vout":[{"value":"10000000","n":0,"hex":"76a914526ac6dd84927e5e26dc6c89976d58ea4c1a4d4788ac","addresses":["a8EF4cpenEgEn9hm2NL5KfFK1UmSZZaQVn"],"isAddress":true},{"value":"51916634","n":1,"spent":true,"spentTxId":"f1db892b13a2cb34a9a1ed0890b85050c43b95e06dc085d7f063e9207e984609","spentHeight":251191,"hex":"76a914526ac6dd84927e5e26dc6c89976d58ea4c1a4d4788ac","addresses":["a8EF4cpenEgEn9hm2NL5KfFK1UmSZZaQVn"],"isAddress":true}],"blockHash":"f85889dc565371828f3c0821f2507ca2fa2f83eae557b7d3ba7270eab6ac7328","blockHeight":251191,"confirmations":17949,"blockTime":1584663676,"value":"61916634","valueIn":"61920702","fees":"4068","hex":"0100000001fd296277b76a406837115f9213f3ce6ebfdb8408447c1423281c034e387acb50010000006b483045022100aff10fef2849988470ac3411bd463ae03a17a88336283290095f8247dc0531a4022064f2c0e60662effb5b46c2a70318331b007df7441a209e2bf6489924c73952f50121030987bda3c78bd6e2dd765f3767cc3611cd05c9e3c0d49873f2cd68d3fd305b15000000000280969800000000001976a914526ac6dd84927e5e26dc6c89976d58ea4c1a4d4788ac5a2f1803000000001976a914526ac6dd84927e5e26dc6c89976d58ea4c1a4d4788ac00000000"},{"txid":"50cb7a384e031c2823147c440884dbbf6ecef313925f113768406ab7776229fd","version":1,"vin":[{"txid":"11a051ebde2108ba2b517f6513dffd34aa099c90a67a4e3e988bd5ddde9ddb45","vout":1,"n":0,"addresses":["a8EF4cpenEgEn9hm2NL5KfFK1UmSZZaQVn"],"isAddress":true,"value":"62924770","hex":"4830450221009e0fe641502a598f5f470ff3a5cb4bd46e2906e0e09c7a8c93d80bfd61cfb26e0220199247204747faf99e8605e7c6af4a1a8489c2a133b92f1f547990cef62cc9f60121030987bda3c78bd6e2dd765f3767cc3611cd05c9e3c0d49873f2cd68d3fd305b15"}],"vout":[{"value":"1000000","n":0,"hex":"76a914526ac6dd84927e5e26dc6c89976d58ea4c1a4d4788ac","addresses":["a8EF4cpenEgEn9hm2NL5KfFK1UmSZZaQVn"],"isAddress":true},{"value":"61920702","n":1,"spent":true,"spentTxId":"cd33ac3382c4a5b2eb70f6d7625289446430ff9484326ffc234bc498c274b564","spentHeight":251191,"hex":"76a914526ac6dd84927e5e26dc6c89976d58ea4c1a4d4788ac","addresses":["a8EF4cpenEgEn9hm2NL5KfFK1UmSZZaQVn"],"isAddress":true}],"blockHash":"1cb40b2f2d4618cd9606b0f476d2ccfeee4740bb76cd46e2c75df6e783017cb1","blockHeight":251156,"confirmations":17984,"blockTime":1584656561,"value":"62920702","valueIn":"62924770","fees":"4068","hex":"010000000145db9ddeddd58b983e4e7aa6909c09aa34fddf13657f512bba0821deeb51a011010000006b4830450221009e0fe641502a598f5f470ff3a5cb4bd46e2906e0e09c7a8c93d80bfd61cfb26e0220199247204747faf99e8605e7c6af4a1a8489c2a133b92f1f547990cef62cc9f60121030987bda3c78bd6e2dd765f3767cc3611cd05c9e3c0d49873f2cd68d3fd305b15000000000240420f00000000001976a914526ac6dd84927e5e26dc6c89976d58ea4c1a4d4788acbed5b003000000001976a914526ac6dd84927e5e26dc6c89976d58ea4c1a4d4788ac00000000"},{"txid":"11a051ebde2108ba2b517f6513dffd34aa099c90a67a4e3e988bd5ddde9ddb45","version":1,"vin":[{"txid":"86fb43e30f9bc2a8a6492e67e2b893680526987ae8b5ec56e2587381813927ef","vout":1,"n":0,"addresses":["a8EF4cpenEgEn9hm2NL5KfFK1UmSZZaQVn"],"isAddress":true,"value":"63028838","hex":"483045022100dde950aa0f6d73c2e78afdb66a138ff3ca481983977baad260c0632dfb2b4ee202202c840111ac82603f436bb698a8d9a50f97d0155b2d4c4576ed66ad4ad6b901020121030987bda3c78bd6e2dd765f3767cc3611cd05c9e3c0d49873f2cd68d3fd305b15"}],"vout":[{"value":"100000","n":0,"hex":"76a914526ac6dd84927e5e26dc6c89976d58ea4c1a4d4788ac","addresses":["a8EF4cpenEgEn9hm2NL5KfFK1UmSZZaQVn"],"isAddress":true},{"value":"62924770","n":1,"spent":true,"spentTxId":"50cb7a384e031c2823147c440884dbbf6ecef313925f113768406ab7776229fd","spentHeight":251156,"hex":"76a914526ac6dd84927e5e26dc6c89976d58ea4c1a4d4788ac","addresses":["a8EF4cpenEgEn9hm2NL5KfFK1UmSZZaQVn"],"isAddress":true}],"blockHash":"5ba0f8c0e58986d1eb5036e766e28ed541d0993cb717fc1aea46d714a89945e7","blockHeight":250864,"confirmations":18276,"blockTime":1584571576,"value":"63024770","valueIn":"63028838","fees":"4068","hex":"0100000001ef273981817358e256ecb5e87a9826056893b8e2672e49a6a8c29b0fe343fb86010000006b483045022100dde950aa0f6d73c2e78afdb66a138ff3ca481983977baad260c0632dfb2b4ee202202c840111ac82603f436bb698a8d9a50f97d0155b2d4c4576ed66ad4ad6b901020121030987bda3c78bd6e2dd765f3767cc3611cd05c9e3c0d49873f2cd68d3fd305b150000000002a0860100000000001976a914526ac6dd84927e5e26dc6c89976d58ea4c1a4d4788ace227c003000000001976a914526ac6dd84927e5e26dc6c89976d58ea4c1a4d4788ac00000000"},{"txid":"86fb43e30f9bc2a8a6492e67e2b893680526987ae8b5ec56e2587381813927ef","version":1,"vin":[{"txid":"5cf7ebaed000a76d67652ed9a91f6e1e57a6c0d74b4445a533bdda1f36be601e","vout":1,"sequence":4294967294,"n":0,"addresses":["a8EF4cpenEgEn9hm2NL5KfFK1UmSZZaQVn"],"isAddress":true,"value":"64032906","hex":"483045022100b3638e753ae9136ee38906754c8d7e44e10e3f1b08dc37948ba317a5e28eb8e60220391cca6fb14eb0392c03df3bfb9639ae76a523ad7bc3f669483d5afa7ed629570121030987bda3c78bd6e2dd765f3767cc3611cd05c9e3c0d49873f2cd68d3fd305b15"}],"vout":[{"value":"1000000","n":0,"spent":true,"spentTxId":"a0289b25937f9b682dd9f15a6c1af44eba405187bb5c23ea0f6310bb570c45e5","spentHeight":259026,"hex":"76a914cffef031eead7d332c245df1372dcf4980a0127c88ac","addresses":["aKgF22yWfjBqekrbkhkFYqenzsw9zfRch8"],"isAddress":true},{"value":"63028838","n":1,"spent":true,"spentTxId":"11a051ebde2108ba2b517f6513dffd34aa099c90a67a4e3e988bd5ddde9ddb45","spentHeight":250864,"hex":"76a914526ac6dd84927e5e26dc6c89976d58ea4c1a4d4788ac","addresses":["a8EF4cpenEgEn9hm2NL5KfFK1UmSZZaQVn"],"isAddress":true}],"blockHash":"fcfea4d17cde4cfc8d113d923e7e2978513e902448f1087fd448ae4162696f4f","blockHeight":244409,"confirmations":24731,"blockTime":1582620606,"value":"64028838","valueIn":"64032906","fees":"4068","hex":"01000000011e60be361fdabd33a545444bd7c0a6571e6e1fa9d92e65676da700d0aeebf75c010000006b483045022100b3638e753ae9136ee38906754c8d7e44e10e3f1b08dc37948ba317a5e28eb8e60220391cca6fb14eb0392c03df3bfb9639ae76a523ad7bc3f669483d5afa7ed629570121030987bda3c78bd6e2dd765f3767cc3611cd05c9e3c0d49873f2cd68d3fd305b15feffffff0240420f00000000001976a914cffef031eead7d332c245df1372dcf4980a0127c88ac66bec103000000001976a914526ac6dd84927e5e26dc6c89976d58ea4c1a4d4788ac00000000"},{"txid":"4178eb3a84a34a9b508dbb61abbe725de115de2daea619e1cfa68eadf001fe51","version":1,"vin":[{"txid":"6de60b862ef752e24f1417c255f750e8e2e2b64ce4160eccbcdd82663a36daeb","n":0,"addresses":["aDVvWiM5PTv3QrUbrWQW3hPVLiFTMmzAHr"],"isAddress":true,"value":"100000","hex":"483045022100e51595fc45741b1d43f5cef9b662605a98634644fc4281ddb471d5feee389bc402207b8b6d103f94ff1278a5d364b92b395021496c39b3f06241ca584036567fb54d012102ed835d6c0f1f4c0df53bbd728376362180010101f0ce9d79bf4ce61363d14b4b"}],"vout":[{"value":"96544","n":0,"hex":"76a914526ac6dd84927e5e26dc6c89976d58ea4c1a4d4788ac","addresses":["a8EF4cpenEgEn9hm2NL5KfFK1UmSZZaQVn"],"isAddress":true}],"blockHash":"e3d64bc33182f0b74b6247c7b37a9f8ff3c6852fe1c08116d460d067919345d1","blockHeight":241112,"confirmations":28028,"blockTime":1581616858,"value":"96544","valueIn":"100000","fees":"3456","hex":"0100000001ebda363a6682ddbccc0e16e44cb6e2e2e850f755c217144fe252f72e860be66d000000006b483045022100e51595fc45741b1d43f5cef9b662605a98634644fc4281ddb471d5feee389bc402207b8b6d103f94ff1278a5d364b92b395021496c39b3f06241ca584036567fb54d012102ed835d6c0f1f4c0df53bbd728376362180010101f0ce9d79bf4ce61363d14b4b000000000120790100000000001976a914526ac6dd84927e5e26dc6c89976d58ea4c1a4d4788ac00000000"},{"txid":"5cf7ebaed000a76d67652ed9a91f6e1e57a6c0d74b4445a533bdda1f36be601e","version":1,"vin":[{"txid":"5482cea818e70b136de121fb7a3443f4fb78b3e3f107712d7aa1dc671d0e3241","vout":1,"n":0,"addresses":["aL96Xr2E1pMW3vcsZ5QV6BYLFE9jdCVBJL"],"isAddress":true,"value":"364036974","hex":"483045022100c2a0003ab30fe8f3ffbb20e9cc38232256ce27b287c24293eff40fe4224f933502202882f50cb71e93fb432c8f244ae7dbe7f52f492452a1da68003cc0d43e9fea08012103cf5fc72d3c15e517443f8fc4295c816e5a791d7e8971943ce7c45a7bfd1ca8e8"}],"vout":[{"value":"300000000","n":0,"spent":true,"spentTxId":"736d2ed9a2398511cc98f30df178db721716c1996fd8ab67970a5ac41a795e72","spentIndex":2,"spentHeight":239559,"hex":"76a9147157fe38b8108bcc0f8b6ea5cab365e2233ed0e888ac","addresses":["aB3mWSqhFzszMJ3h8sxTedFYDhZCDBkeQT"],"isAddress":true},{"value":"64032906","n":1,"spent":true,"spentTxId":"86fb43e30f9bc2a8a6492e67e2b893680526987ae8b5ec56e2587381813927ef","spentHeight":244409,"hex":"76a914526ac6dd84927e5e26dc6c89976d58ea4c1a4d4788ac","addresses":["a8EF4cpenEgEn9hm2NL5KfFK1UmSZZaQVn"],"isAddress":true}],"blockHash":"07d7c24529ee402be1a94b6b5a70d000c6002f0fa7201c1f5ef4ef7dd87f0117","blockHeight":239551,"confirmations":29589,"blockTime":1581138788,"value":"364032906","valueIn":"364036974","fees":"4068","hex":"010000000141320e1d67dca17a2d7107f1e3b378fbf443347afb21e16d130be718a8ce8254010000006b483045022100c2a0003ab30fe8f3ffbb20e9cc38232256ce27b287c24293eff40fe4224f933502202882f50cb71e93fb432c8f244ae7dbe7f52f492452a1da68003cc0d43e9fea08012103cf5fc72d3c15e517443f8fc4295c816e5a791d7e8971943ce7c45a7bfd1ca8e8000000000200a3e111000000001976a9147157fe38b8108bcc0f8b6ea5cab365e2233ed0e888ac8a10d103000000001976a914526ac6dd84927e5e26dc6c89976d58ea4c1a4d4788ac00000000"},{"txid":"c4f897a1d64e6c870184ff26a3ad8f5f4a94a6667f6d3486f21e52530d8ecea2","version":1,"vin":[{"txid":"3054b05d5f9624264bf7bfbb140749472c58670cc935efa5aab4a96c6430ed19","sequence":4294967294,"n":0,"addresses":["a8EF4cpenEgEn9hm2NL5KfFK1UmSZZaQVn"],"isAddress":true,"value":"365045110","hex":"473044022062705d4b0f266a25646c410e3a735b7665dafb85655bf4b9f3ce89ecde4306f20220702f5fd1f3d6e593c3e3e9a37adf6431b1920b55151872dc9c8f4dc166df1a8f0121030987bda3c78bd6e2dd765f3767cc3611cd05c9e3c0d49873f2cd68d3fd305b15"}],"vout":[{"value":"365041042","n":0,"spent":true,"spentTxId":"5482cea818e70b136de121fb7a3443f4fb78b3e3f107712d7aa1dc671d0e3241","spentHeight":238210,"hex":"76a914e5712d04a22c551a8261aea3f4a8d98ddb057f5988ac","addresses":["aMde4RuTWiNzoZN53SWZ7i7tKNbhSwt57U"],"isAddress":true}],"blockHash":"1afa27baa3146c5ae36cb93612f928b794b306d4d8b552636fb3f35891a7adb8","blockHeight":238176,"confirmations":30964,"blockTime":1580709451,"value":"365041042","valueIn":"365045110","fees":"4068","hex":"010000000119ed30646ca9b4aaa5ef35c90c67582c47490714bbbff74b2624965f5db05430000000006a473044022062705d4b0f266a25646c410e3a735b7665dafb85655bf4b9f3ce89ecde4306f20220702f5fd1f3d6e593c3e3e9a37adf6431b1920b55151872dc9c8f4dc166df1a8f0121030987bda3c78bd6e2dd765f3767cc3611cd05c9e3c0d49873f2cd68d3fd305b15feffffff019215c215000000001976a914e5712d04a22c551a8261aea3f4a8d98ddb057f5988ac00000000"},{"txid":"3054b05d5f9624264bf7bfbb140749472c58670cc935efa5aab4a96c6430ed19","version":1,"vin":[{"txid":"c7cd71424b7165ae60fe998767a43dab338915ef3215782ae7b9ba9710fd9aab","n":0,"addresses":["aDqeCrv3YqSr3UtBT9W6xnFNEJonV87mSt"],"isAddress":true,"value":"365048566","hex":"4730440220603f06106ee740b0399bc72c801fb7e4e3a907d06cd54c61dcac674cdd9cf3be02202ad273482c6300bae8f655523913845d50a2c805a173db3fb2c1bc65a2d894a701210296a3500dfacb901de8c43eb79b368bd7c710a65f6723d67ca51fa83728b8e402"}],"vout":[{"value":"365045110","n":0,"spent":true,"spentTxId":"c4f897a1d64e6c870184ff26a3ad8f5f4a94a6667f6d3486f21e52530d8ecea2","spentHeight":238176,"hex":"76a914526ac6dd84927e5e26dc6c89976d58ea4c1a4d4788ac","addresses":["a8EF4cpenEgEn9hm2NL5KfFK1UmSZZaQVn"],"isAddress":true}],"blockHash":"419b039bfb0cdbe1a507c6ba5c1fa2828e6fe1785b748a29eb243186ab60430b","blockHeight":238161,"confirmations":30979,"blockTime":1580704843,"value":"365045110","valueIn":"365048566","fees":"3456","hex":"0100000001ab9afd1097bab9e72a781532ef158933ab3da4678799fe60ae65714b4271cdc7000000006a4730440220603f06106ee740b0399bc72c801fb7e4e3a907d06cd54c61dcac674cdd9cf3be02202ad273482c6300bae8f655523913845d50a2c805a173db3fb2c1bc65a2d894a701210296a3500dfacb901de8c43eb79b368bd7c710a65f6723d67ca51fa83728b8e40200000000017625c215000000001976a914526ac6dd84927e5e26dc6c89976d58ea4c1a4d4788ac00000000"},{"txid":"c7cd71424b7165ae60fe998767a43dab338915ef3215782ae7b9ba9710fd9aab","version":1,"vin":[{"txid":"5bb0f077e0cd6473c529db2f03b59150b6ea9f261f3d60fdc1e169d54c470a60","n":0,"addresses":["a8EF4cpenEgEn9hm2NL5KfFK1UmSZZaQVn"],"isAddress":true,"value":"1000000","hex":"483045022100c923f70b6f8dd9f7feee018e1c2009bece3255f8b317135ea635af1442325fd20220703ab8f539cbe261cf2836bb1659817afb17ea2ac382ba82ea30849266b28bdb0121030987bda3c78bd6e2dd765f3767cc3611cd05c9e3c0d49873f2cd68d3fd305b15"},{"txid":"dc46c8292b9f154a0f3114d3d899852e8e8fd30dfa8736e9c4869121ea3b5e08","n":1,"addresses":["aF61ZkGfZNFMLumooKrNNDqCq9KSAmew6G"],"isAddress":true,"value":"2000000","hex":"483045022100e8bc25770f43b416fde1f8471fc0afe483b8b1cd961ade28c54c83757d30b3d602206c0c51c0a61a37c34f6887c8609aeff9ad60ee883738d455fb9f290481ca8ba00121027d09e12a82828d3170ef73784a179c14e106e2f0ca0c1e11b54b2e4a2c23c55b"},{"txid":"dc46c8292b9f154a0f3114d3d899852e8e8fd30dfa8736e9c4869121ea3b5e08","vout":1,"n":2,"addresses":["aK7W1TtDD5wfz7o2TcRyf7XycXuQ4XaX7X"],"isAddress":true,"value":"362057350","hex":"483045022100fe7f5b7ca2dac6f35ef1ebead1a5b268e852998dbc3877218b6494bb4ec4314002204fc5b6dc94bf440f2c52b766cc96d03745a85d62ec5cc08295714bb62fbe42580121023230b3fa3b145df6249c1dc4f72aaba101a1283e85644e73fd20019e5aeed68d"}],"vout":[{"value":"365048566","n":0,"spent":true,"spentTxId":"3054b05d5f9624264bf7bfbb140749472c58670cc935efa5aab4a96c6430ed19","spentHeight":238161,"hex":"76a9148ff5484fd892d16012bfd95ab4a9b9e53dbc052388ac","addresses":["aDqeCrv3YqSr3UtBT9W6xnFNEJonV87mSt"],"isAddress":true}],"blockHash":"0e88334c147d222909e2c2e67ed8f854269eea168ef7c566ca0c29a4dffbbdb7","blockHeight":237361,"confirmations":31779,"blockTime":1580453676,"value":"365048566","valueIn":"365057350","fees":"8784","hex":"0100000003600a474cd569e1c1fd603d1f269feab65091b5032fdb29c57364cde077f0b05b000000006b483045022100c923f70b6f8dd9f7feee018e1c2009bece3255f8b317135ea635af1442325fd20220703ab8f539cbe261cf2836bb1659817afb17ea2ac382ba82ea30849266b28bdb0121030987bda3c78bd6e2dd765f3767cc3611cd05c9e3c0d49873f2cd68d3fd305b1500000000085e3bea219186c4e93687fa0dd38f8e2e8599d8d314310f4a159f2b29c846dc000000006b483045022100e8bc25770f43b416fde1f8471fc0afe483b8b1cd961ade28c54c83757d30b3d602206c0c51c0a61a37c34f6887c8609aeff9ad60ee883738d455fb9f290481ca8ba00121027d09e12a82828d3170ef73784a179c14e106e2f0ca0c1e11b54b2e4a2c23c55b00000000085e3bea219186c4e93687fa0dd38f8e2e8599d8d314310f4a159f2b29c846dc010000006b483045022100fe7f5b7ca2dac6f35ef1ebead1a5b268e852998dbc3877218b6494bb4ec4314002204fc5b6dc94bf440f2c52b766cc96d03745a85d62ec5cc08295714bb62fbe42580121023230b3fa3b145df6249c1dc4f72aaba101a1283e85644e73fd20019e5aeed68d0000000001f632c215000000001976a9148ff5484fd892d16012bfd95ab4a9b9e53dbc052388ac00000000"}]} diff --git a/mock/ext-api-data/zcoin-api_v2_xpub_xpub6Cgu6WtTyo99pRtTabwscog2ncj4BUbTWzk7bt7habdLYwgnXLEWH3TuR1789QSTPVsPjLMa2KQzHffyZHTkLQQyRxeEBmWHaETS2btF5fK__details_txs.json b/mock/ext-api-data/zcoin-api_v2_xpub_xpub6Cgu6WtTyo99pRtTabwscog2ncj4BUbTWzk7bt7habdLYwgnXLEWH3TuR1789QSTPVsPjLMa2KQzHffyZHTkLQQyRxeEBmWHaETS2btF5fK__details_txs.json new file mode 100644 index 000000000..6cbb02828 --- /dev/null +++ b/mock/ext-api-data/zcoin-api_v2_xpub_xpub6Cgu6WtTyo99pRtTabwscog2ncj4BUbTWzk7bt7habdLYwgnXLEWH3TuR1789QSTPVsPjLMa2KQzHffyZHTkLQQyRxeEBmWHaETS2btF5fK__details_txs.json @@ -0,0 +1 @@ +{"page":1,"totalPages":6,"itemsOnPage":10,"address":"xpub6Cgu6WtTyo99pRtTabwscog2ncj4BUbTWzk7bt7habdLYwgnXLEWH3TuR1789QSTPVsPjLMa2KQzHffyZHTkLQQyRxeEBmWHaETS2btF5fK","balance":"63109110","totalReceived":"19765346316","totalSent":"19702237206","unconfirmedBalance":"0","unconfirmedTxs":0,"txs":54,"transactions":[{"txid":"cd33ac3382c4a5b2eb70f6d7625289446430ff9484326ffc234bc498c274b564","version":1,"vin":[{"txid":"50cb7a384e031c2823147c440884dbbf6ecef313925f113768406ab7776229fd","vout":1,"n":0,"addresses":["a8EF4cpenEgEn9hm2NL5KfFK1UmSZZaQVn"],"isAddress":true,"value":"61920702","hex":"483045022100aff10fef2849988470ac3411bd463ae03a17a88336283290095f8247dc0531a4022064f2c0e60662effb5b46c2a70318331b007df7441a209e2bf6489924c73952f50121030987bda3c78bd6e2dd765f3767cc3611cd05c9e3c0d49873f2cd68d3fd305b15"}],"vout":[{"value":"10000000","n":0,"hex":"76a914526ac6dd84927e5e26dc6c89976d58ea4c1a4d4788ac","addresses":["a8EF4cpenEgEn9hm2NL5KfFK1UmSZZaQVn"],"isAddress":true},{"value":"51916634","n":1,"spent":true,"spentTxId":"f1db892b13a2cb34a9a1ed0890b85050c43b95e06dc085d7f063e9207e984609","spentHeight":251191,"hex":"76a914526ac6dd84927e5e26dc6c89976d58ea4c1a4d4788ac","addresses":["a8EF4cpenEgEn9hm2NL5KfFK1UmSZZaQVn"],"isAddress":true}],"blockHash":"f85889dc565371828f3c0821f2507ca2fa2f83eae557b7d3ba7270eab6ac7328","blockHeight":251191,"confirmations":17949,"blockTime":1584663676,"value":"61916634","valueIn":"61920702","fees":"4068","hex":"0100000001fd296277b76a406837115f9213f3ce6ebfdb8408447c1423281c034e387acb50010000006b483045022100aff10fef2849988470ac3411bd463ae03a17a88336283290095f8247dc0531a4022064f2c0e60662effb5b46c2a70318331b007df7441a209e2bf6489924c73952f50121030987bda3c78bd6e2dd765f3767cc3611cd05c9e3c0d49873f2cd68d3fd305b15000000000280969800000000001976a914526ac6dd84927e5e26dc6c89976d58ea4c1a4d4788ac5a2f1803000000001976a914526ac6dd84927e5e26dc6c89976d58ea4c1a4d4788ac00000000"},{"txid":"f1db892b13a2cb34a9a1ed0890b85050c43b95e06dc085d7f063e9207e984609","version":1,"vin":[{"txid":"cd33ac3382c4a5b2eb70f6d7625289446430ff9484326ffc234bc498c274b564","vout":1,"n":0,"addresses":["a8EF4cpenEgEn9hm2NL5KfFK1UmSZZaQVn"],"isAddress":true,"value":"51916634","hex":"483045022100dc5a93fa3bd1f61115062700756163da79860b38fe348aa9c3bc5d9c578c8d55022048f2f300dce9858fa3a24e05084bb892287a623b40271289cb5fce9783e77b730121030987bda3c78bd6e2dd765f3767cc3611cd05c9e3c0d49873f2cd68d3fd305b15"}],"vout":[{"value":"13113178","n":0,"hex":"76a914526ac6dd84927e5e26dc6c89976d58ea4c1a4d4788ac","addresses":["a8EF4cpenEgEn9hm2NL5KfFK1UmSZZaQVn"],"isAddress":true},{"value":"38799388","n":1,"hex":"76a914526ac6dd84927e5e26dc6c89976d58ea4c1a4d4788ac","addresses":["a8EF4cpenEgEn9hm2NL5KfFK1UmSZZaQVn"],"isAddress":true}],"blockHash":"f85889dc565371828f3c0821f2507ca2fa2f83eae557b7d3ba7270eab6ac7328","blockHeight":251191,"confirmations":17949,"blockTime":1584663676,"value":"51912566","valueIn":"51916634","fees":"4068","hex":"010000000164b574c298c44b23fc6f328494ff306444895262d7f670ebb2a5c48233ac33cd010000006b483045022100dc5a93fa3bd1f61115062700756163da79860b38fe348aa9c3bc5d9c578c8d55022048f2f300dce9858fa3a24e05084bb892287a623b40271289cb5fce9783e77b730121030987bda3c78bd6e2dd765f3767cc3611cd05c9e3c0d49873f2cd68d3fd305b1500000000025a17c800000000001976a914526ac6dd84927e5e26dc6c89976d58ea4c1a4d4788ac1c085002000000001976a914526ac6dd84927e5e26dc6c89976d58ea4c1a4d4788ac00000000"},{"txid":"50cb7a384e031c2823147c440884dbbf6ecef313925f113768406ab7776229fd","version":1,"vin":[{"txid":"11a051ebde2108ba2b517f6513dffd34aa099c90a67a4e3e988bd5ddde9ddb45","vout":1,"n":0,"addresses":["a8EF4cpenEgEn9hm2NL5KfFK1UmSZZaQVn"],"isAddress":true,"value":"62924770","hex":"4830450221009e0fe641502a598f5f470ff3a5cb4bd46e2906e0e09c7a8c93d80bfd61cfb26e0220199247204747faf99e8605e7c6af4a1a8489c2a133b92f1f547990cef62cc9f60121030987bda3c78bd6e2dd765f3767cc3611cd05c9e3c0d49873f2cd68d3fd305b15"}],"vout":[{"value":"1000000","n":0,"hex":"76a914526ac6dd84927e5e26dc6c89976d58ea4c1a4d4788ac","addresses":["a8EF4cpenEgEn9hm2NL5KfFK1UmSZZaQVn"],"isAddress":true},{"value":"61920702","n":1,"spent":true,"spentTxId":"cd33ac3382c4a5b2eb70f6d7625289446430ff9484326ffc234bc498c274b564","spentHeight":251191,"hex":"76a914526ac6dd84927e5e26dc6c89976d58ea4c1a4d4788ac","addresses":["a8EF4cpenEgEn9hm2NL5KfFK1UmSZZaQVn"],"isAddress":true}],"blockHash":"1cb40b2f2d4618cd9606b0f476d2ccfeee4740bb76cd46e2c75df6e783017cb1","blockHeight":251156,"confirmations":17984,"blockTime":1584656561,"value":"62920702","valueIn":"62924770","fees":"4068","hex":"010000000145db9ddeddd58b983e4e7aa6909c09aa34fddf13657f512bba0821deeb51a011010000006b4830450221009e0fe641502a598f5f470ff3a5cb4bd46e2906e0e09c7a8c93d80bfd61cfb26e0220199247204747faf99e8605e7c6af4a1a8489c2a133b92f1f547990cef62cc9f60121030987bda3c78bd6e2dd765f3767cc3611cd05c9e3c0d49873f2cd68d3fd305b15000000000240420f00000000001976a914526ac6dd84927e5e26dc6c89976d58ea4c1a4d4788acbed5b003000000001976a914526ac6dd84927e5e26dc6c89976d58ea4c1a4d4788ac00000000"},{"txid":"11a051ebde2108ba2b517f6513dffd34aa099c90a67a4e3e988bd5ddde9ddb45","version":1,"vin":[{"txid":"86fb43e30f9bc2a8a6492e67e2b893680526987ae8b5ec56e2587381813927ef","vout":1,"n":0,"addresses":["a8EF4cpenEgEn9hm2NL5KfFK1UmSZZaQVn"],"isAddress":true,"value":"63028838","hex":"483045022100dde950aa0f6d73c2e78afdb66a138ff3ca481983977baad260c0632dfb2b4ee202202c840111ac82603f436bb698a8d9a50f97d0155b2d4c4576ed66ad4ad6b901020121030987bda3c78bd6e2dd765f3767cc3611cd05c9e3c0d49873f2cd68d3fd305b15"}],"vout":[{"value":"100000","n":0,"hex":"76a914526ac6dd84927e5e26dc6c89976d58ea4c1a4d4788ac","addresses":["a8EF4cpenEgEn9hm2NL5KfFK1UmSZZaQVn"],"isAddress":true},{"value":"62924770","n":1,"spent":true,"spentTxId":"50cb7a384e031c2823147c440884dbbf6ecef313925f113768406ab7776229fd","spentHeight":251156,"hex":"76a914526ac6dd84927e5e26dc6c89976d58ea4c1a4d4788ac","addresses":["a8EF4cpenEgEn9hm2NL5KfFK1UmSZZaQVn"],"isAddress":true}],"blockHash":"5ba0f8c0e58986d1eb5036e766e28ed541d0993cb717fc1aea46d714a89945e7","blockHeight":250864,"confirmations":18276,"blockTime":1584571576,"value":"63024770","valueIn":"63028838","fees":"4068","hex":"0100000001ef273981817358e256ecb5e87a9826056893b8e2672e49a6a8c29b0fe343fb86010000006b483045022100dde950aa0f6d73c2e78afdb66a138ff3ca481983977baad260c0632dfb2b4ee202202c840111ac82603f436bb698a8d9a50f97d0155b2d4c4576ed66ad4ad6b901020121030987bda3c78bd6e2dd765f3767cc3611cd05c9e3c0d49873f2cd68d3fd305b150000000002a0860100000000001976a914526ac6dd84927e5e26dc6c89976d58ea4c1a4d4788ace227c003000000001976a914526ac6dd84927e5e26dc6c89976d58ea4c1a4d4788ac00000000"},{"txid":"86fb43e30f9bc2a8a6492e67e2b893680526987ae8b5ec56e2587381813927ef","version":1,"vin":[{"txid":"5cf7ebaed000a76d67652ed9a91f6e1e57a6c0d74b4445a533bdda1f36be601e","vout":1,"sequence":4294967294,"n":0,"addresses":["a8EF4cpenEgEn9hm2NL5KfFK1UmSZZaQVn"],"isAddress":true,"value":"64032906","hex":"483045022100b3638e753ae9136ee38906754c8d7e44e10e3f1b08dc37948ba317a5e28eb8e60220391cca6fb14eb0392c03df3bfb9639ae76a523ad7bc3f669483d5afa7ed629570121030987bda3c78bd6e2dd765f3767cc3611cd05c9e3c0d49873f2cd68d3fd305b15"}],"vout":[{"value":"1000000","n":0,"spent":true,"spentTxId":"a0289b25937f9b682dd9f15a6c1af44eba405187bb5c23ea0f6310bb570c45e5","spentHeight":259026,"hex":"76a914cffef031eead7d332c245df1372dcf4980a0127c88ac","addresses":["aKgF22yWfjBqekrbkhkFYqenzsw9zfRch8"],"isAddress":true},{"value":"63028838","n":1,"spent":true,"spentTxId":"11a051ebde2108ba2b517f6513dffd34aa099c90a67a4e3e988bd5ddde9ddb45","spentHeight":250864,"hex":"76a914526ac6dd84927e5e26dc6c89976d58ea4c1a4d4788ac","addresses":["a8EF4cpenEgEn9hm2NL5KfFK1UmSZZaQVn"],"isAddress":true}],"blockHash":"fcfea4d17cde4cfc8d113d923e7e2978513e902448f1087fd448ae4162696f4f","blockHeight":244409,"confirmations":24731,"blockTime":1582620606,"value":"64028838","valueIn":"64032906","fees":"4068","hex":"01000000011e60be361fdabd33a545444bd7c0a6571e6e1fa9d92e65676da700d0aeebf75c010000006b483045022100b3638e753ae9136ee38906754c8d7e44e10e3f1b08dc37948ba317a5e28eb8e60220391cca6fb14eb0392c03df3bfb9639ae76a523ad7bc3f669483d5afa7ed629570121030987bda3c78bd6e2dd765f3767cc3611cd05c9e3c0d49873f2cd68d3fd305b15feffffff0240420f00000000001976a914cffef031eead7d332c245df1372dcf4980a0127c88ac66bec103000000001976a914526ac6dd84927e5e26dc6c89976d58ea4c1a4d4788ac00000000"},{"txid":"4178eb3a84a34a9b508dbb61abbe725de115de2daea619e1cfa68eadf001fe51","version":1,"vin":[{"txid":"6de60b862ef752e24f1417c255f750e8e2e2b64ce4160eccbcdd82663a36daeb","n":0,"addresses":["aDVvWiM5PTv3QrUbrWQW3hPVLiFTMmzAHr"],"isAddress":true,"value":"100000","hex":"483045022100e51595fc45741b1d43f5cef9b662605a98634644fc4281ddb471d5feee389bc402207b8b6d103f94ff1278a5d364b92b395021496c39b3f06241ca584036567fb54d012102ed835d6c0f1f4c0df53bbd728376362180010101f0ce9d79bf4ce61363d14b4b"}],"vout":[{"value":"96544","n":0,"hex":"76a914526ac6dd84927e5e26dc6c89976d58ea4c1a4d4788ac","addresses":["a8EF4cpenEgEn9hm2NL5KfFK1UmSZZaQVn"],"isAddress":true}],"blockHash":"e3d64bc33182f0b74b6247c7b37a9f8ff3c6852fe1c08116d460d067919345d1","blockHeight":241112,"confirmations":28028,"blockTime":1581616858,"value":"96544","valueIn":"100000","fees":"3456","hex":"0100000001ebda363a6682ddbccc0e16e44cb6e2e2e850f755c217144fe252f72e860be66d000000006b483045022100e51595fc45741b1d43f5cef9b662605a98634644fc4281ddb471d5feee389bc402207b8b6d103f94ff1278a5d364b92b395021496c39b3f06241ca584036567fb54d012102ed835d6c0f1f4c0df53bbd728376362180010101f0ce9d79bf4ce61363d14b4b000000000120790100000000001976a914526ac6dd84927e5e26dc6c89976d58ea4c1a4d4788ac00000000"},{"txid":"5cf7ebaed000a76d67652ed9a91f6e1e57a6c0d74b4445a533bdda1f36be601e","version":1,"vin":[{"txid":"5482cea818e70b136de121fb7a3443f4fb78b3e3f107712d7aa1dc671d0e3241","vout":1,"n":0,"addresses":["aL96Xr2E1pMW3vcsZ5QV6BYLFE9jdCVBJL"],"isAddress":true,"value":"364036974","hex":"483045022100c2a0003ab30fe8f3ffbb20e9cc38232256ce27b287c24293eff40fe4224f933502202882f50cb71e93fb432c8f244ae7dbe7f52f492452a1da68003cc0d43e9fea08012103cf5fc72d3c15e517443f8fc4295c816e5a791d7e8971943ce7c45a7bfd1ca8e8"}],"vout":[{"value":"300000000","n":0,"spent":true,"spentTxId":"736d2ed9a2398511cc98f30df178db721716c1996fd8ab67970a5ac41a795e72","spentIndex":2,"spentHeight":239559,"hex":"76a9147157fe38b8108bcc0f8b6ea5cab365e2233ed0e888ac","addresses":["aB3mWSqhFzszMJ3h8sxTedFYDhZCDBkeQT"],"isAddress":true},{"value":"64032906","n":1,"spent":true,"spentTxId":"86fb43e30f9bc2a8a6492e67e2b893680526987ae8b5ec56e2587381813927ef","spentHeight":244409,"hex":"76a914526ac6dd84927e5e26dc6c89976d58ea4c1a4d4788ac","addresses":["a8EF4cpenEgEn9hm2NL5KfFK1UmSZZaQVn"],"isAddress":true}],"blockHash":"07d7c24529ee402be1a94b6b5a70d000c6002f0fa7201c1f5ef4ef7dd87f0117","blockHeight":239551,"confirmations":29589,"blockTime":1581138788,"value":"364032906","valueIn":"364036974","fees":"4068","hex":"010000000141320e1d67dca17a2d7107f1e3b378fbf443347afb21e16d130be718a8ce8254010000006b483045022100c2a0003ab30fe8f3ffbb20e9cc38232256ce27b287c24293eff40fe4224f933502202882f50cb71e93fb432c8f244ae7dbe7f52f492452a1da68003cc0d43e9fea08012103cf5fc72d3c15e517443f8fc4295c816e5a791d7e8971943ce7c45a7bfd1ca8e8000000000200a3e111000000001976a9147157fe38b8108bcc0f8b6ea5cab365e2233ed0e888ac8a10d103000000001976a914526ac6dd84927e5e26dc6c89976d58ea4c1a4d4788ac00000000"},{"txid":"5482cea818e70b136de121fb7a3443f4fb78b3e3f107712d7aa1dc671d0e3241","version":1,"vin":[{"txid":"c4f897a1d64e6c870184ff26a3ad8f5f4a94a6667f6d3486f21e52530d8ecea2","sequence":4294967294,"n":0,"addresses":["aMde4RuTWiNzoZN53SWZ7i7tKNbhSwt57U"],"isAddress":true,"value":"365041042","hex":"4730440220260b40074ffa84cf4f747433efdc524a347bf9f2b995a212a7c7fafeeb9105180220222edad73b70511698a9dc68ae246b78a7ba9daf3c1b44fb5d7fdd4d8d008d890121035209cb9a9c86a775cb9593b4c6fdde4f23e4bb4193cfeae0706080702189efa3"}],"vout":[{"value":"1000000","n":0,"spent":true,"spentTxId":"c70c9d3bf599a9e3553b6235f6468c69c1fa54aa0505e49d81e37aa1a749379a","spentHeight":238297,"hex":"76a91480be9e18824eae9cc7771291b7a017a458fb48b388ac","addresses":["aCTCaoLEy6ZbKQGKjBe1kprQ4foEa2cBVv"],"isAddress":true},{"value":"364036974","n":1,"spent":true,"spentTxId":"5cf7ebaed000a76d67652ed9a91f6e1e57a6c0d74b4445a533bdda1f36be601e","spentHeight":239551,"hex":"76a914d51315e0d5624c84e9da869bd34735926022ae5888ac","addresses":["aL96Xr2E1pMW3vcsZ5QV6BYLFE9jdCVBJL"],"isAddress":true}],"blockHash":"fc464897e8c6bcbd5bede4109a24075894a61d3a2d7aa06cc0bc1a37b07d1903","blockHeight":238210,"confirmations":30930,"blockTime":1580718580,"value":"365036974","valueIn":"365041042","fees":"4068","hex":"0100000001a2ce8e0d53521ef286346d7f66a6944a5f8fada326ff8401876c4ed6a197f8c4000000006a4730440220260b40074ffa84cf4f747433efdc524a347bf9f2b995a212a7c7fafeeb9105180220222edad73b70511698a9dc68ae246b78a7ba9daf3c1b44fb5d7fdd4d8d008d890121035209cb9a9c86a775cb9593b4c6fdde4f23e4bb4193cfeae0706080702189efa3feffffff0240420f00000000001976a91480be9e18824eae9cc7771291b7a017a458fb48b388ac6ec3b215000000001976a914d51315e0d5624c84e9da869bd34735926022ae5888ac00000000"},{"txid":"c4f897a1d64e6c870184ff26a3ad8f5f4a94a6667f6d3486f21e52530d8ecea2","version":1,"vin":[{"txid":"3054b05d5f9624264bf7bfbb140749472c58670cc935efa5aab4a96c6430ed19","sequence":4294967294,"n":0,"addresses":["a8EF4cpenEgEn9hm2NL5KfFK1UmSZZaQVn"],"isAddress":true,"value":"365045110","hex":"473044022062705d4b0f266a25646c410e3a735b7665dafb85655bf4b9f3ce89ecde4306f20220702f5fd1f3d6e593c3e3e9a37adf6431b1920b55151872dc9c8f4dc166df1a8f0121030987bda3c78bd6e2dd765f3767cc3611cd05c9e3c0d49873f2cd68d3fd305b15"}],"vout":[{"value":"365041042","n":0,"spent":true,"spentTxId":"5482cea818e70b136de121fb7a3443f4fb78b3e3f107712d7aa1dc671d0e3241","spentHeight":238210,"hex":"76a914e5712d04a22c551a8261aea3f4a8d98ddb057f5988ac","addresses":["aMde4RuTWiNzoZN53SWZ7i7tKNbhSwt57U"],"isAddress":true}],"blockHash":"1afa27baa3146c5ae36cb93612f928b794b306d4d8b552636fb3f35891a7adb8","blockHeight":238176,"confirmations":30964,"blockTime":1580709451,"value":"365041042","valueIn":"365045110","fees":"4068","hex":"010000000119ed30646ca9b4aaa5ef35c90c67582c47490714bbbff74b2624965f5db05430000000006a473044022062705d4b0f266a25646c410e3a735b7665dafb85655bf4b9f3ce89ecde4306f20220702f5fd1f3d6e593c3e3e9a37adf6431b1920b55151872dc9c8f4dc166df1a8f0121030987bda3c78bd6e2dd765f3767cc3611cd05c9e3c0d49873f2cd68d3fd305b15feffffff019215c215000000001976a914e5712d04a22c551a8261aea3f4a8d98ddb057f5988ac00000000"},{"txid":"3054b05d5f9624264bf7bfbb140749472c58670cc935efa5aab4a96c6430ed19","version":1,"vin":[{"txid":"c7cd71424b7165ae60fe998767a43dab338915ef3215782ae7b9ba9710fd9aab","n":0,"addresses":["aDqeCrv3YqSr3UtBT9W6xnFNEJonV87mSt"],"isAddress":true,"value":"365048566","hex":"4730440220603f06106ee740b0399bc72c801fb7e4e3a907d06cd54c61dcac674cdd9cf3be02202ad273482c6300bae8f655523913845d50a2c805a173db3fb2c1bc65a2d894a701210296a3500dfacb901de8c43eb79b368bd7c710a65f6723d67ca51fa83728b8e402"}],"vout":[{"value":"365045110","n":0,"spent":true,"spentTxId":"c4f897a1d64e6c870184ff26a3ad8f5f4a94a6667f6d3486f21e52530d8ecea2","spentHeight":238176,"hex":"76a914526ac6dd84927e5e26dc6c89976d58ea4c1a4d4788ac","addresses":["a8EF4cpenEgEn9hm2NL5KfFK1UmSZZaQVn"],"isAddress":true}],"blockHash":"419b039bfb0cdbe1a507c6ba5c1fa2828e6fe1785b748a29eb243186ab60430b","blockHeight":238161,"confirmations":30979,"blockTime":1580704843,"value":"365045110","valueIn":"365048566","fees":"3456","hex":"0100000001ab9afd1097bab9e72a781532ef158933ab3da4678799fe60ae65714b4271cdc7000000006a4730440220603f06106ee740b0399bc72c801fb7e4e3a907d06cd54c61dcac674cdd9cf3be02202ad273482c6300bae8f655523913845d50a2c805a173db3fb2c1bc65a2d894a701210296a3500dfacb901de8c43eb79b368bd7c710a65f6723d67ca51fa83728b8e40200000000017625c215000000001976a914526ac6dd84927e5e26dc6c89976d58ea4c1a4d4788ac00000000"}],"usedTokens":52,"tokens":[{"type":"XPUBAddress","name":"a8EF4cpenEgEn9hm2NL5KfFK1UmSZZaQVn","path":"m/44'/136'/0'/0/0","transfers":18,"decimals":8,"balance":"63109110","totalReceived":"1565104974","totalSent":"1501995864"}]} diff --git a/mock/ext-api-data/zelcash-api_v2_address_t1JKRwXGfKTGfPV1z48rvoLyabk31z3xwHa__details_txs.json b/mock/ext-api-data/zelcash-api_v2_address_t1JKRwXGfKTGfPV1z48rvoLyabk31z3xwHa__details_txs.json new file mode 100644 index 000000000..66fe7e7a5 --- /dev/null +++ b/mock/ext-api-data/zelcash-api_v2_address_t1JKRwXGfKTGfPV1z48rvoLyabk31z3xwHa__details_txs.json @@ -0,0 +1 @@ +{"page":1,"totalPages":12736,"itemsOnPage":10,"address":"t1JKRwXGfKTGfPV1z48rvoLyabk31z3xwHa","balance":"900000590194","totalReceived":"1340993049284812","totalSent":"1340093048694618","unconfirmedBalance":"0","unconfirmedTxs":0,"txs":127356,"transactions":[{"txid":"4ec60a6461233aef764b3b7701155d0c0701e064ad27b4864135e4819e46ed6a","version":4,"vin":[{"sequence":4294967295,"n":0,"coinbase":"03c4340900324d696e6572732068747470733a2f2f326d696e6572732e636f6d"}],"vout":[{"value":"11250010000","n":0,"hex":"76a91404e2699cec5f44280540fb752c7660aa3ba857cc88ac","addresses":["t1JKRwXGfKTGfPV1z48rvoLyabk31z3xwHa"]},{"value":"562500000","n":1,"hex":"76a914ab8196e08b70ec6ec9b487a9546b554933f0920c88ac","addresses":["t1ZWSoAYkMLUyWTSF1KydkEeYxffvTCmGu3"]},{"value":"937500000","n":2,"hex":"76a914b8a6ab978880f5241e9488f3547ae18a2ea9ecc788ac","addresses":["t1ahx15yHu6SFQXvss3W44GZC28SoBYjGJH"]},{"value":"2250000000","n":3,"hex":"76a914680be69289a1f0b5a67c62576513d8467172a43a88ac","addresses":["t1TMkYABufakzp4sSGAQQ7d4AHdKxkxv34d"]}],"blockHash":"0000007a7284c006997f38cb798f52e64c20122bbd606dfb519bfa446c1d51ad","blockHeight":603332,"confirmations":2,"blockTime":1590069744,"value":"15000010000","valueIn":"0","fees":"0","hex":"0400008085202f89010000000000000000000000000000000000000000000000000000000000000000ffffffff2003c4340900324d696e6572732068747470733a2f2f326d696e6572732e636f6dffffffff0490878d9e020000001976a91404e2699cec5f44280540fb752c7660aa3ba857cc88aca0118721000000001976a914ab8196e08b70ec6ec9b487a9546b554933f0920c88ac601de137000000001976a914b8a6ab978880f5241e9488f3547ae18a2ea9ecc788ac80461c86000000001976a914680be69289a1f0b5a67c62576513d8467172a43a88ac00000000000000000000000000000000000000"},{"txid":"c8899f9bd2f80474383d72daa2bb8b81cac3e66d0c4fa543f00471d249931549","version":4,"vin":[{"sequence":4294967295,"n":0,"coinbase":"03c3340900324d696e6572732068747470733a2f2f326d696e6572732e636f6d"}],"vout":[{"value":"11250001000","n":0,"hex":"76a91404e2699cec5f44280540fb752c7660aa3ba857cc88ac","addresses":["t1JKRwXGfKTGfPV1z48rvoLyabk31z3xwHa"]},{"value":"562500000","n":1,"hex":"76a914ded2dec28f6414578208d69e6305319ccaf9dc1f88ac","addresses":["t1eBndSK9bCRJ82wpxWxjqWoRno6zKjxJjn"]},{"value":"937500000","n":2,"hex":"76a914422fd29f94a792a3c189b57d52b74d5c45091b6588ac","addresses":["t1PuZtn9GEaJk7PbqzWa7oiW4MqQRhCE6DU"]},{"value":"2250000000","n":3,"hex":"76a9141de04cabb3724f4c750fb62f0546a1f70fd6426088ac","addresses":["t1LbaJVztxuY4oSbXHKBFmNfqrASM8Wsv5Y"]}],"blockHash":"00000011d100045d55c701cfdedaab7e62ca29fb581a51ff6c924393f695d045","blockHeight":603331,"confirmations":3,"blockTime":1590069594,"value":"15000001000","valueIn":"0","fees":"0","hex":"0400008085202f89010000000000000000000000000000000000000000000000000000000000000000ffffffff2003c3340900324d696e6572732068747470733a2f2f326d696e6572732e636f6dffffffff0468648d9e020000001976a91404e2699cec5f44280540fb752c7660aa3ba857cc88aca0118721000000001976a914ded2dec28f6414578208d69e6305319ccaf9dc1f88ac601de137000000001976a914422fd29f94a792a3c189b57d52b74d5c45091b6588ac80461c86000000001976a9141de04cabb3724f4c750fb62f0546a1f70fd6426088ac00000000000000000000000000000000000000"},{"txid":"91132541ca3c72884ba0bba9a8db785e2e45b5425d20a5c499dca5fac8128dc7","version":4,"vin":[{"sequence":4294967295,"n":0,"coinbase":"03c2340900324d696e6572732068747470733a2f2f326d696e6572732e636f6d"}],"vout":[{"value":"11250000000","n":0,"hex":"76a91404e2699cec5f44280540fb752c7660aa3ba857cc88ac","addresses":["t1JKRwXGfKTGfPV1z48rvoLyabk31z3xwHa"]},{"value":"562500000","n":1,"hex":"76a914c85c93462875819a331a9ae7dc36f12bbed327ef88ac","addresses":["t1c923wo15tdZg3ziVPzL3GbYX6jzJEG377"]},{"value":"937500000","n":2,"hex":"76a914fa0fe057eb22bd5df1022ddf5658d05fae13857988ac","addresses":["t1gfoxQCK8yg2PLSYWy8DXMmQZFpw11CDiH"]},{"value":"2250000000","n":3,"hex":"76a914c8e005c8ea2bd432970172ef1d6d90bd221ee93a88ac","addresses":["t1cBjX4hVfYMBPE3T6FJbtRWvu9YQg4syc8"]}],"blockHash":"0000009e780901d002b05706e0bf663443efc01e7beb7105ab3a2bad0a02e4ad","blockHeight":603330,"confirmations":4,"blockTime":1590069261,"value":"15000000000","valueIn":"0","fees":"0","hex":"0400008085202f89010000000000000000000000000000000000000000000000000000000000000000ffffffff2003c2340900324d696e6572732068747470733a2f2f326d696e6572732e636f6dffffffff0480608d9e020000001976a91404e2699cec5f44280540fb752c7660aa3ba857cc88aca0118721000000001976a914c85c93462875819a331a9ae7dc36f12bbed327ef88ac601de137000000001976a914fa0fe057eb22bd5df1022ddf5658d05fae13857988ac80461c86000000001976a914c8e005c8ea2bd432970172ef1d6d90bd221ee93a88ac00000000000000000000000000000000000000"},{"txid":"0c2fa3526e6c6236ca0047cc6e0f455e36607ad0abfbde4ebd62d47451cab3d5","version":4,"vin":[{"sequence":4294967295,"n":0,"coinbase":"03c1340900324d696e6572732068747470733a2f2f326d696e6572732e636f6d"}],"vout":[{"value":"11250040721","n":0,"hex":"76a91404e2699cec5f44280540fb752c7660aa3ba857cc88ac","addresses":["t1JKRwXGfKTGfPV1z48rvoLyabk31z3xwHa"]},{"value":"562500000","n":1,"hex":"76a9145f3f89ba88e3d738f97e5905e33c799fee3a17ca88ac","addresses":["t1SZEKFsjzQSctXnVc3da5RRxMkcVmqvgPx"]},{"value":"937500000","n":2,"hex":"76a9144089337f98c9b083d3f96735176c7a6813cbbe1e88ac","addresses":["t1PkqcWvupQaBZ2g26UAuhH3nvWSqE1iH6z"]},{"value":"2250000000","n":3,"hex":"76a914902d58ccbb395ab2f56e5e400f3bba367113865b88ac","addresses":["t1X1wdiSBDPd1C6ujaxNgzH8a5Tj8TM6LNb"]}],"blockHash":"000000339a081532aff027fe30e7ae60d722b29fcbf906b43221daf78ee045eb","blockHeight":603329,"confirmations":5,"blockTime":1590069102,"value":"15000040721","valueIn":"0","fees":"0","hex":"0400008085202f89010000000000000000000000000000000000000000000000000000000000000000ffffffff2003c1340900324d696e6572732068747470733a2f2f326d696e6572732e636f6dffffffff0491ff8d9e020000001976a91404e2699cec5f44280540fb752c7660aa3ba857cc88aca0118721000000001976a9145f3f89ba88e3d738f97e5905e33c799fee3a17ca88ac601de137000000001976a9144089337f98c9b083d3f96735176c7a6813cbbe1e88ac80461c86000000001976a914902d58ccbb395ab2f56e5e400f3bba367113865b88ac00000000000000000000000000000000000000"},{"txid":"76b5298831a3eb8919c34cfd6e434ba1b319ad9361341fd446d0f60c12e64960","version":4,"vin":[{"sequence":4294967295,"n":0,"coinbase":"03c0340900324d696e6572732068747470733a2f2f326d696e6572732e636f6d"}],"vout":[{"value":"11250010000","n":0,"hex":"76a91404e2699cec5f44280540fb752c7660aa3ba857cc88ac","addresses":["t1JKRwXGfKTGfPV1z48rvoLyabk31z3xwHa"]},{"value":"562500000","n":1,"hex":"76a91472b3326f7c20cda07ea9e337f2715313b3b3cd1488ac","addresses":["t1UL5i2ke2H2CCmaCimWM5xNf97SpcUZy89"]},{"value":"937500000","n":2,"hex":"76a9145aa0cd79ab6f52aad05cb950b2e1215827c2f9eb88ac","addresses":["t1S8oTN2wBzXnWSwz7TpsSsQkNiYJYqeHRQ"]},{"value":"2250000000","n":3,"hex":"76a914c2af4d039c06fc03721a0a7c623ec2764211b25188ac","addresses":["t1bd16fbkY2mS54ka6zKeVb8rwvWQ76r5iS"]}],"blockHash":"0000001f328281cf72af7f273333e2a67e708e13d08bab269a732ec9d2b93f14","blockHeight":603328,"confirmations":6,"blockTime":1590068652,"value":"15000010000","valueIn":"0","fees":"0","hex":"0400008085202f89010000000000000000000000000000000000000000000000000000000000000000ffffffff2003c0340900324d696e6572732068747470733a2f2f326d696e6572732e636f6dffffffff0490878d9e020000001976a91404e2699cec5f44280540fb752c7660aa3ba857cc88aca0118721000000001976a91472b3326f7c20cda07ea9e337f2715313b3b3cd1488ac601de137000000001976a9145aa0cd79ab6f52aad05cb950b2e1215827c2f9eb88ac80461c86000000001976a914c2af4d039c06fc03721a0a7c623ec2764211b25188ac00000000000000000000000000000000000000"},{"txid":"d8c2edd3a3e73e823bdfb53e0a16ea78513c3fb36ccf3a5227fefeaf3d53b4cb","version":4,"vin":[{"sequence":4294967295,"n":0,"coinbase":"03bf340900324d696e6572732068747470733a2f2f326d696e6572732e636f6d"}],"vout":[{"value":"11250000000","n":0,"hex":"76a91404e2699cec5f44280540fb752c7660aa3ba857cc88ac","addresses":["t1JKRwXGfKTGfPV1z48rvoLyabk31z3xwHa"]},{"value":"562500000","n":1,"hex":"76a914e11f474e1e6a3d48fc20d83f853f95620467d28388ac","addresses":["t1ePwWmWS2T5PRo4z9zKcvNnHam91tcupnm"]},{"value":"937500000","n":2,"hex":"76a9144d8ea2df3c9c44e23ca0eddf148f4e6bfaa3b4bd88ac","addresses":["t1QwgueMBetkiPTkJMowkSFgohiT68p54UD"]},{"value":"2250000000","n":3,"hex":"76a91468c01116ec9b9811267dadf5c37735ffe57ab92688ac","addresses":["t1TRUNKQMx1DVzym4d2Ay5E1dudEcHiyk9C"]}],"blockHash":"000000d2350de7e8ef59c2881d53f30876324def22d63ffc26024ef866621127","blockHeight":603327,"confirmations":7,"blockTime":1590068550,"value":"15000000000","valueIn":"0","fees":"0","hex":"0400008085202f89010000000000000000000000000000000000000000000000000000000000000000ffffffff2003bf340900324d696e6572732068747470733a2f2f326d696e6572732e636f6dffffffff0480608d9e020000001976a91404e2699cec5f44280540fb752c7660aa3ba857cc88aca0118721000000001976a914e11f474e1e6a3d48fc20d83f853f95620467d28388ac601de137000000001976a9144d8ea2df3c9c44e23ca0eddf148f4e6bfaa3b4bd88ac80461c86000000001976a91468c01116ec9b9811267dadf5c37735ffe57ab92688ac00000000000000000000000000000000000000"},{"txid":"0712452932e94b21106e3a729bad1ac2dc1132dbbd8b510828de507c73af5362","version":4,"vin":[{"sequence":4294967295,"n":0,"coinbase":"03be340900324d696e6572732068747470733a2f2f326d696e6572732e636f6d"}],"vout":[{"value":"11250020000","n":0,"hex":"76a91404e2699cec5f44280540fb752c7660aa3ba857cc88ac","addresses":["t1JKRwXGfKTGfPV1z48rvoLyabk31z3xwHa"]},{"value":"562500000","n":1,"hex":"76a914c718ff5e608276a84b76f286408340ce17bf7ac988ac","addresses":["t1c2LRNMLZb4zs9oecko6pHv14QWUKQwJkd"]},{"value":"937500000","n":2,"hex":"76a914334765007510b372da5e5ef25e654b01ca092e3f88ac","addresses":["t1NYjzhThu7YdTSK48tGEdnRc9eTkDfWTxb"]},{"value":"2250000000","n":3,"hex":"76a914eb89013136c8d505e7e2d50205e780c3461d7b1188ac","addresses":["t1fLzvfbKnNYeQBUB8aCEYVnyXXvxUtbVja"]}],"blockHash":"00000082b40daa8db4cd0f75c0893f59c9a6afd89a0e1f44abf3885bd59dd85b","blockHeight":603326,"confirmations":8,"blockTime":1590068543,"value":"15000020000","valueIn":"0","fees":"0","hex":"0400008085202f89010000000000000000000000000000000000000000000000000000000000000000ffffffff2003be340900324d696e6572732068747470733a2f2f326d696e6572732e636f6dffffffff04a0ae8d9e020000001976a91404e2699cec5f44280540fb752c7660aa3ba857cc88aca0118721000000001976a914c718ff5e608276a84b76f286408340ce17bf7ac988ac601de137000000001976a914334765007510b372da5e5ef25e654b01ca092e3f88ac80461c86000000001976a914eb89013136c8d505e7e2d50205e780c3461d7b1188ac00000000000000000000000000000000000000"},{"txid":"fef38b2bf0644a076771a3915150342fb6c1ed6dea3cc76b9c5c617fb377d56c","version":4,"vin":[{"sequence":4294967295,"n":0,"coinbase":"03bc340900324d696e6572732068747470733a2f2f326d696e6572732e636f6d"}],"vout":[{"value":"11250000000","n":0,"hex":"76a91404e2699cec5f44280540fb752c7660aa3ba857cc88ac","addresses":["t1JKRwXGfKTGfPV1z48rvoLyabk31z3xwHa"]},{"value":"562500000","n":1,"hex":"76a914fcdbb728a535aec6d81b366fd22af437457a385488ac","addresses":["t1gvbVmu4E8sDziJXPCWd3ggdBUpbZ8kVN8"]},{"value":"937500000","n":2,"hex":"76a914f9c4b9822fa37c937fdb78602cebd222c940d49588ac","addresses":["t1geFvmZhWNitgmgipJLnswq6AHHuj777Vp"]},{"value":"2250000000","n":3,"hex":"76a9143d94fc18dd332c386014f9e5b05cce17710a2ce688ac","addresses":["t1PVDhgMueDh8vY3JfkZoXcGrwATCfkwaL9"]}],"blockHash":"0000005936823db3f9a971fb8d3c3fbef6ea9da0761d88815836ce9dc30ae937","blockHeight":603324,"confirmations":10,"blockTime":1590067974,"value":"15000000000","valueIn":"0","fees":"0","hex":"0400008085202f89010000000000000000000000000000000000000000000000000000000000000000ffffffff2003bc340900324d696e6572732068747470733a2f2f326d696e6572732e636f6dffffffff0480608d9e020000001976a91404e2699cec5f44280540fb752c7660aa3ba857cc88aca0118721000000001976a914fcdbb728a535aec6d81b366fd22af437457a385488ac601de137000000001976a914f9c4b9822fa37c937fdb78602cebd222c940d49588ac80461c86000000001976a9143d94fc18dd332c386014f9e5b05cce17710a2ce688ac00000000000000000000000000000000000000"},{"txid":"6356612d62b81566774bee79a4a23689a218558d92ab3a93f84baa396c19bb54","version":4,"vin":[{"sequence":4294967295,"n":0,"coinbase":"03bb340900324d696e6572732068747470733a2f2f326d696e6572732e636f6d"}],"vout":[{"value":"11250000000","n":0,"hex":"76a91404e2699cec5f44280540fb752c7660aa3ba857cc88ac","addresses":["t1JKRwXGfKTGfPV1z48rvoLyabk31z3xwHa"]},{"value":"562500000","n":1,"hex":"76a91402eaf41ee9372e92e25d25bf196ed82dee08137388ac","addresses":["t1J92pafqy7CXPdPfGYPKw7NXpU4M5594zv"]},{"value":"937500000","n":2,"hex":"76a91493e5a686a7b343097fb7325840cb098bd4f85f4e88ac","addresses":["t1XMcSvvj4aLbwzWpeMJWvwnesK2pcWsVoM"]},{"value":"2250000000","n":3,"hex":"76a914b42021e23a66f80148741e9ce5d08b592bba0ef088ac","addresses":["t1aJ28TfBXyvZaAsxD8GnJdfjqpx72yRCsA"]}],"blockHash":"00000013e741f51d2c17c61ec1f2739fb26df31a51ed296534c9c426027fcf30","blockHeight":603323,"confirmations":11,"blockTime":1590067957,"value":"15000000000","valueIn":"0","fees":"0","hex":"0400008085202f89010000000000000000000000000000000000000000000000000000000000000000ffffffff2003bb340900324d696e6572732068747470733a2f2f326d696e6572732e636f6dffffffff0480608d9e020000001976a91404e2699cec5f44280540fb752c7660aa3ba857cc88aca0118721000000001976a91402eaf41ee9372e92e25d25bf196ed82dee08137388ac601de137000000001976a91493e5a686a7b343097fb7325840cb098bd4f85f4e88ac80461c86000000001976a914b42021e23a66f80148741e9ce5d08b592bba0ef088ac00000000000000000000000000000000000000"},{"txid":"bc4de1a0197710be803bddeb6e4f24e5438abede4c2c68c623f4c5cc77ee28e2","version":4,"vin":[{"sequence":4294967295,"n":0,"coinbase":"03b8340900324d696e6572732068747470733a2f2f326d696e6572732e636f6d"}],"vout":[{"value":"11250010245","n":0,"hex":"76a91404e2699cec5f44280540fb752c7660aa3ba857cc88ac","addresses":["t1JKRwXGfKTGfPV1z48rvoLyabk31z3xwHa"]},{"value":"562500000","n":1,"hex":"76a914d900399ef7162894cc2a2865712fcbc6279b969788ac","addresses":["t1dezubrWdABDDhNL9TLn8nfNwQovhB2FXF"]},{"value":"937500000","n":2,"hex":"76a91483f17701299e54c4b8f1c97c5935ec3bdc3cb56e88ac","addresses":["t1VuFnjm6wQCzPzVoZWVcCKZ4ybqk4q9JWW"]},{"value":"2250000000","n":3,"hex":"76a914bd05fba3d61efdff58aa527d18e8d05a36cd05c688ac","addresses":["t1b74tJ6FNsKS5SMScmXRtqVi5o6ZHGnxv1"]}],"blockHash":"0000001259bdff5b52c495e48ccb3bc6de494b6f8bc0d897478996bc4d683487","blockHeight":603320,"confirmations":14,"blockTime":1590067530,"value":"15000010245","valueIn":"0","fees":"0","hex":"0400008085202f89010000000000000000000000000000000000000000000000000000000000000000ffffffff2003b8340900324d696e6572732068747470733a2f2f326d696e6572732e636f6dffffffff0485888d9e020000001976a91404e2699cec5f44280540fb752c7660aa3ba857cc88aca0118721000000001976a914d900399ef7162894cc2a2865712fcbc6279b969788ac601de137000000001976a91483f17701299e54c4b8f1c97c5935ec3bdc3cb56e88ac80461c86000000001976a914bd05fba3d61efdff58aa527d18e8d05a36cd05c688ac00000000000000000000000000000000000000"}]} diff --git a/mock/ext-api-data/zelcash-api_v2_xpub_xpub6C5soBeFd2uZLCcEvsqaoGXuh9UposMMfk2jSiBKMN8rJKs9NLqjPK51gWv9mYBpUY95GtHYsofwpPRdB6FJ56cEaTJGCba5GKv55wPNZNf__details_txs.json b/mock/ext-api-data/zelcash-api_v2_xpub_xpub6C5soBeFd2uZLCcEvsqaoGXuh9UposMMfk2jSiBKMN8rJKs9NLqjPK51gWv9mYBpUY95GtHYsofwpPRdB6FJ56cEaTJGCba5GKv55wPNZNf__details_txs.json new file mode 100644 index 000000000..463036686 --- /dev/null +++ b/mock/ext-api-data/zelcash-api_v2_xpub_xpub6C5soBeFd2uZLCcEvsqaoGXuh9UposMMfk2jSiBKMN8rJKs9NLqjPK51gWv9mYBpUY95GtHYsofwpPRdB6FJ56cEaTJGCba5GKv55wPNZNf__details_txs.json @@ -0,0 +1,1463 @@ +{ + "page": 1, + "totalPages": 1, + "itemsOnPage": 1000, + "address": "xpub6C5soBeFd2uZLCcEvsqaoGXuh9UposMMfk2jSiBKMN8rJKs9NLqjPK51gWv9mYBpUY95GtHYsofwpPRdB6FJ56cEaTJGCba5GKv55wPNZNf", + "balance": "9209317640", + "totalReceived": "135114824440", + "totalSent": "125905506800", + "unconfirmedBalance": "0", + "unconfirmedTxs": 0, + "txs": 29, + "transactions": [ + { + "txid": "c7beecf9ee82e09319012defde98abe58f4227265a3946d2052019c477b930e9", + "version": 4, + "vin": [ + { + "txid": "16757f263140419a557425ec7d286995491160ceebca53ac07bbe3021a49d93c", + "sequence": 2147483641, + "n": 0, + "addresses": [ + "t1PHmJzMdeErPQGL9WEavrVakYiCzxKXi9z" + ], + "value": "12300000", + "hex": "483045022100c91ed67b1f0859b559bf83f4ae94b46d8249117b3e6263f20dffb80979eaaca0022012bebce65ff538408acadd8d86ad23021d08dbe5026d46ad781e81b8c8e793bb012103aa6d9069ced0b9b556ac6eb7468d5f15422b16903507e8651824c1b7e6e36644" + }, + { + "txid": "640ea080f060fbfcc6722f861c93483551a831020f6731a37ba5383da71b4972", + "sequence": 2147483642, + "n": 1, + "addresses": [ + "t1PHmJzMdeErPQGL9WEavrVakYiCzxKXi9z" + ], + "value": "100000", + "hex": "483045022100f702c86f237035747db777e28cddc7f1d00bb608076eb0a3b90e38dfb9d63627022075bbb974a89ade1bfbf36ab249c42186ec21421454c0b170126b3cd0d6b95f6a012103aa6d9069ced0b9b556ac6eb7468d5f15422b16903507e8651824c1b7e6e36644" + }, + { + "txid": "640ea080f060fbfcc6722f861c93483551a831020f6731a37ba5383da71b4972", + "vout": 1, + "sequence": 2147483643, + "n": 2, + "addresses": [ + "t1PHmJzMdeErPQGL9WEavrVakYiCzxKXi9z" + ], + "value": "890000", + "hex": "47304402206e642c188a9a3cc160edacdf637586fbf621ebd83b9bcd3bf69809259cc1bcaa02200b526e4011d173bf454b3592a9e134c94af4bc7ef5468cbdd450de8ebf0ed62a012103aa6d9069ced0b9b556ac6eb7468d5f15422b16903507e8651824c1b7e6e36644" + }, + { + "txid": "a3db9e10aa146805477b9012130e6f68d473975095b82c7e6e6ab5f409da9eef", + "vout": 1, + "sequence": 2147483644, + "n": 3, + "addresses": [ + "t1PHmJzMdeErPQGL9WEavrVakYiCzxKXi9z" + ], + "value": "898950000", + "hex": "483045022100aaa260947b85fe11edd6ce9b71c496cbe00c148d97ebeeefedbd743591b63f95022054e4938c4cee3587ed625563ef732dc097252286b5feb98280f5935ee53f9924012103aa6d9069ced0b9b556ac6eb7468d5f15422b16903507e8651824c1b7e6e36644" + }, + { + "txid": "d6669b431916c5794fe1be5ffb0594aed0a3828c9ff7614c2f2a3e1eacce7360", + "vout": 1, + "sequence": 2147483645, + "n": 4, + "addresses": [ + "t1ZdL1GA9PFrU2sPqWZGBCjbbmb6bKoaLRR" + ], + "value": "8296087640", + "hex": "4830450221009b6e1d3b1d5d578d4c7f6f34be73de3764c83e5a55b663e8eafc66ac2722d1e5022020e420e0b21989791775f53db76c30373b790f75a4009a815919110c688fb33d012102986c87346f73a3ac0b601782d2463b1e6d69f75a6ffac305319fa27d6e4ffffc" + }, + { + "txid": "d6669b431916c5794fe1be5ffb0594aed0a3828c9ff7614c2f2a3e1eacce7360", + "sequence": 2147483646, + "n": 5, + "addresses": [ + "t1c3uqCTSGfyia7rotNoNLm7cV7UqCpXT21" + ], + "value": "1000000", + "hex": "47304402201f3f367f2b476bb333b1bd7ed91648b44a88598599a20153f6b4a5fea423369702203a16248718cfaac42ab4239708d6f327c0fe6c8e49527f451f2de0fed4c2c0040121028eb47e98c32ad1d7a2ac0e1524431b2c7fb2142b3a036adaab3aaf07be82c026" + } + ], + "vout": [ + { + "value": "1000000", + "n": 0, + "hex": "76a914ec5240b297e3c8e6f0b38103c43686d618c91f8d88ac", + "addresses": [ + "t1fRA1dKnK7Z78ZhMqKP2VxdS9VfYeGvLYm" + ] + }, + { + "value": "9208317640", + "n": 1, + "hex": "76a9140f6081e0b391e1f5795c4ff86b3edad2b267196f88ac", + "addresses": [ + "t1KGukfFELYq5cYpCgieyes3dCuaxNMUcb1" + ] + } + ], + "blockHash": "00000002031260dc8b9ec8c19aa16a2aabd2edc6e21fa57df7fad0fa963f319d", + "blockHeight": 562339, + "confirmations": 35171, + "blockTime": 1585117482, + "value": "9209317640", + "valueIn": "9209327640", + "fees": "10000", + "hex": "0400008085202f89063cd9491a02e3bb07ac53caebce6011499569287dec2574559a414031267f7516000000006b483045022100c91ed67b1f0859b559bf83f4ae94b46d8249117b3e6263f20dffb80979eaaca0022012bebce65ff538408acadd8d86ad23021d08dbe5026d46ad781e81b8c8e793bb012103aa6d9069ced0b9b556ac6eb7468d5f15422b16903507e8651824c1b7e6e36644f9ffff7f72491ba73d38a57ba331670f0231a8513548931c862f72c6fcfb60f080a00e64000000006b483045022100f702c86f237035747db777e28cddc7f1d00bb608076eb0a3b90e38dfb9d63627022075bbb974a89ade1bfbf36ab249c42186ec21421454c0b170126b3cd0d6b95f6a012103aa6d9069ced0b9b556ac6eb7468d5f15422b16903507e8651824c1b7e6e36644faffff7f72491ba73d38a57ba331670f0231a8513548931c862f72c6fcfb60f080a00e64010000006a47304402206e642c188a9a3cc160edacdf637586fbf621ebd83b9bcd3bf69809259cc1bcaa02200b526e4011d173bf454b3592a9e134c94af4bc7ef5468cbdd450de8ebf0ed62a012103aa6d9069ced0b9b556ac6eb7468d5f15422b16903507e8651824c1b7e6e36644fbffff7fef9eda09f4b56a6e7e2cb895509773d4686f0e1312907b47056814aa109edba3010000006b483045022100aaa260947b85fe11edd6ce9b71c496cbe00c148d97ebeeefedbd743591b63f95022054e4938c4cee3587ed625563ef732dc097252286b5feb98280f5935ee53f9924012103aa6d9069ced0b9b556ac6eb7468d5f15422b16903507e8651824c1b7e6e36644fcffff7f6073ceac1e3e2a2f4c61f79f8c82a3d0ae9405fb5fbee14f79c51619439b66d6010000006b4830450221009b6e1d3b1d5d578d4c7f6f34be73de3764c83e5a55b663e8eafc66ac2722d1e5022020e420e0b21989791775f53db76c30373b790f75a4009a815919110c688fb33d012102986c87346f73a3ac0b601782d2463b1e6d69f75a6ffac305319fa27d6e4ffffcfdffff7f6073ceac1e3e2a2f4c61f79f8c82a3d0ae9405fb5fbee14f79c51619439b66d6000000006a47304402201f3f367f2b476bb333b1bd7ed91648b44a88598599a20153f6b4a5fea423369702203a16248718cfaac42ab4239708d6f327c0fe6c8e49527f451f2de0fed4c2c0040121028eb47e98c32ad1d7a2ac0e1524431b2c7fb2142b3a036adaab3aaf07be82c026feffff7f0240420f00000000001976a914ec5240b297e3c8e6f0b38103c43686d618c91f8d88acc8c6db24020000001976a9140f6081e0b391e1f5795c4ff86b3edad2b267196f88ac00000000000000000000000000000000000000" + }, + { + "txid": "16757f263140419a557425ec7d286995491160ceebca53ac07bbe3021a49d93c", + "version": 4, + "vin": [ + { + "txid": "b8843a9c37d921ef3d3f22e0ed7a4241c819403148e53f7da52000e194688af0", + "n": 0, + "addresses": [ + "t1fu9mBwE7T9MYcLMiQjcXiS2tfUFcJK14F" + ], + "value": "100000000", + "hex": "483045022100c61a676888765a783afeb24cf7351bfa55213c99979e4472db6f09c4083364e9022033065f3d7ec5511fb29349a698b82866d3d8106284e991a9984e26ef7a430ede012102a5fd93af1e208f0b9652a21674f5800d60c83323406ebd2c69be74dfb493ea1e" + } + ], + "vout": [ + { + "value": "12300000", + "n": 0, + "spent": true, + "hex": "76a9143b6a6100245510218dc29b313b988df0628ab36388ac", + "addresses": [ + "t1PHmJzMdeErPQGL9WEavrVakYiCzxKXi9z" + ] + }, + { + "value": "87690000", + "n": 1, + "hex": "76a9147f1271095e3e2063ca859588b40dad6c13995dce88ac", + "addresses": [ + "t1VTVv3Ebwo2zvEdE3PDrJyTATKDTXg7CvB" + ] + } + ], + "blockHash": "000000835a29d9743a37f7fa03613163a206ede7adbdb33b2626540697cc4e24", + "blockHeight": 561716, + "confirmations": 35794, + "blockTime": 1585043485, + "value": "99990000", + "valueIn": "100000000", + "fees": "10000", + "hex": "0400008085202f8901f08a6894e10020a57d3fe548314019c841427aede0223f3def21d9379c3a84b8000000006b483045022100c61a676888765a783afeb24cf7351bfa55213c99979e4472db6f09c4083364e9022033065f3d7ec5511fb29349a698b82866d3d8106284e991a9984e26ef7a430ede012102a5fd93af1e208f0b9652a21674f5800d60c83323406ebd2c69be74dfb493ea1e0000000002e0aebb00000000001976a9143b6a6100245510218dc29b313b988df0628ab36388ac100b3a05000000001976a9147f1271095e3e2063ca859588b40dad6c13995dce88ac00000000000000000000000000000000000000" + }, + { + "txid": "640ea080f060fbfcc6722f861c93483551a831020f6731a37ba5383da71b4972", + "version": 4, + "vin": [ + { + "txid": "a3db9e10aa146805477b9012130e6f68d473975095b82c7e6e6ab5f409da9eef", + "n": 0, + "addresses": [ + "t1PHmJzMdeErPQGL9WEavrVakYiCzxKXi9z" + ], + "value": "1000000", + "hex": "47304402205f7e4f5c17f6bf9880bd0afecec581253419a7b94a440fc9d4a4f4c35ee5b69102203a5c1ba8fc40098e9de6d4df71bb364e9028ddf9eb6ec31e42a1293c19170d8d012103aa6d9069ced0b9b556ac6eb7468d5f15422b16903507e8651824c1b7e6e36644" + } + ], + "vout": [ + { + "value": "100000", + "n": 0, + "spent": true, + "hex": "76a9143b6a6100245510218dc29b313b988df0628ab36388ac", + "addresses": [ + "t1PHmJzMdeErPQGL9WEavrVakYiCzxKXi9z" + ] + }, + { + "value": "890000", + "n": 1, + "spent": true, + "hex": "76a9143b6a6100245510218dc29b313b988df0628ab36388ac", + "addresses": [ + "t1PHmJzMdeErPQGL9WEavrVakYiCzxKXi9z" + ] + } + ], + "blockHash": "0000004957cd52c4654e44b0a02cd33be907ae3ae47949e44984cccaf0e34e96", + "blockHeight": 560762, + "confirmations": 36748, + "blockTime": 1584928030, + "value": "990000", + "valueIn": "1000000", + "fees": "10000", + "hex": "0400008085202f8901ef9eda09f4b56a6e7e2cb895509773d4686f0e1312907b47056814aa109edba3000000006a47304402205f7e4f5c17f6bf9880bd0afecec581253419a7b94a440fc9d4a4f4c35ee5b69102203a5c1ba8fc40098e9de6d4df71bb364e9028ddf9eb6ec31e42a1293c19170d8d012103aa6d9069ced0b9b556ac6eb7468d5f15422b16903507e8651824c1b7e6e366440000000002a0860100000000001976a9143b6a6100245510218dc29b313b988df0628ab36388ac90940d00000000001976a9143b6a6100245510218dc29b313b988df0628ab36388ac00000000000000000000000000000000000000" + }, + { + "txid": "a3db9e10aa146805477b9012130e6f68d473975095b82c7e6e6ab5f409da9eef", + "version": 4, + "vin": [ + { + "txid": "2de19629bbf78af114ff9cf3332229dc336be4758481b72828f1bd786e8cc41e", + "vout": 1, + "n": 0, + "addresses": [ + "t1PHmJzMdeErPQGL9WEavrVakYiCzxKXi9z" + ], + "value": "899960000", + "hex": "4830450221008f14795cde861210cbd9a1c3d89a29f0efe5c3cdceb2049795d5a9a84cc2571f02203c4e360575b7e5a45b067382b7d4e3fadbc80382eaa32e08a0bba46ae9bc7cb9012103aa6d9069ced0b9b556ac6eb7468d5f15422b16903507e8651824c1b7e6e36644" + } + ], + "vout": [ + { + "value": "1000000", + "n": 0, + "spent": true, + "hex": "76a9143b6a6100245510218dc29b313b988df0628ab36388ac", + "addresses": [ + "t1PHmJzMdeErPQGL9WEavrVakYiCzxKXi9z" + ] + }, + { + "value": "898950000", + "n": 1, + "spent": true, + "hex": "76a9143b6a6100245510218dc29b313b988df0628ab36388ac", + "addresses": [ + "t1PHmJzMdeErPQGL9WEavrVakYiCzxKXi9z" + ] + } + ], + "blockHash": "0000008979ea8aac4d45ae6b5db721845d2d909e723b8fbb87d81f528a7ceefe", + "blockHeight": 558864, + "confirmations": 38646, + "blockTime": 1584697832, + "value": "899950000", + "valueIn": "899960000", + "fees": "10000", + "hex": "0400008085202f89011ec48c6e78bdf12828b7818475e46b33dc292233f39cff14f18af7bb2996e12d010000006b4830450221008f14795cde861210cbd9a1c3d89a29f0efe5c3cdceb2049795d5a9a84cc2571f02203c4e360575b7e5a45b067382b7d4e3fadbc80382eaa32e08a0bba46ae9bc7cb9012103aa6d9069ced0b9b556ac6eb7468d5f15422b16903507e8651824c1b7e6e36644000000000240420f00000000001976a9143b6a6100245510218dc29b313b988df0628ab36388ac70e39435000000001976a9143b6a6100245510218dc29b313b988df0628ab36388ac00000000000000000000000000000000000000" + }, + { + "txid": "2de19629bbf78af114ff9cf3332229dc336be4758481b72828f1bd786e8cc41e", + "version": 4, + "vin": [ + { + "txid": "7db9135b1dabcecccff9e4d403802d1bf0d7850438233b3091b876331bab551b", + "n": 0, + "addresses": [ + "t1MpHLd2vryyTufEMF3WBHy7VP63YKigi53" + ], + "value": "999970000", + "hex": "473044022040534cefd8cfbe8f2705032a3636067fb8612ec3449f75699fcd894e5f2dc9960220363c26ddbbdb840fc76fbb950aecbfd6fa7d03e64da1c5890c302f0bb6f007a8012103d6bf5faa2c95ae8c4572f0755f45dba20dcd806ef8344a5dc2a54996874661c4" + } + ], + "vout": [ + { + "value": "100000000", + "n": 0, + "hex": "76a914a394f62bbe0a47af97171e99bd8ff4fed9cae33188ac", + "addresses": [ + "t1YnYbdwU1ReMUbN46byAQNtnDPqMRYxFPJ" + ] + }, + { + "value": "899960000", + "n": 1, + "spent": true, + "hex": "76a9143b6a6100245510218dc29b313b988df0628ab36388ac", + "addresses": [ + "t1PHmJzMdeErPQGL9WEavrVakYiCzxKXi9z" + ] + } + ], + "blockHash": "0000007f0db0ed2ac5f5747e7746dc5e016e1f2a84df54115e85eee4d7aecb3b", + "blockHeight": 547987, + "confirmations": 49523, + "blockTime": 1583385317, + "value": "999960000", + "valueIn": "999970000", + "fees": "10000", + "hex": "0400008085202f89011b55ab1b3376b891303b23380485d7f01b2d8003d4e4f9cfccceab1d5b13b97d000000006a473044022040534cefd8cfbe8f2705032a3636067fb8612ec3449f75699fcd894e5f2dc9960220363c26ddbbdb840fc76fbb950aecbfd6fa7d03e64da1c5890c302f0bb6f007a8012103d6bf5faa2c95ae8c4572f0755f45dba20dcd806ef8344a5dc2a54996874661c4000000000200e1f505000000001976a914a394f62bbe0a47af97171e99bd8ff4fed9cae33188acc04ca435000000001976a9143b6a6100245510218dc29b313b988df0628ab36388ac00000000000000000000000000000000000000" + }, + { + "txid": "7db9135b1dabcecccff9e4d403802d1bf0d7850438233b3091b876331bab551b", + "version": 4, + "vin": [ + { + "txid": "3ce3913910d9aab7ddb308b16abd6d5d66c258737b5f86e829cc741fa317820b", + "n": 0, + "addresses": [ + "t1YnYbdwU1ReMUbN46byAQNtnDPqMRYxFPJ" + ], + "value": "999980000", + "hex": "483045022100fdf9542e8c44a218601d427ac9d8262866083c3ac1312c1448c345ed54782901022077a4c5e1d22657e000a2c76dc6f873fcb70b7298bd627dd3dc7bb24fa6175ab10121033985b538c7c62cd419a5b24e0dd8d322174303f376e025fddd1f19da2cebcc50" + } + ], + "vout": [ + { + "value": "999970000", + "n": 0, + "spent": true, + "hex": "76a9142b3fac242eb3d7e20130082190605a5f7750037788ac", + "addresses": [ + "t1MpHLd2vryyTufEMF3WBHy7VP63YKigi53" + ] + } + ], + "blockHash": "00000021b6af345a3d3010cdf9811fa9ca1f1163841519f2906ababa766b21ec", + "blockHeight": 494906, + "confirmations": 102604, + "blockTime": 1576977235, + "value": "999970000", + "valueIn": "999980000", + "fees": "10000", + "hex": "0400008085202f89010b8217a31f74cc29e8865f7b7358c2665d6dbd6ab108b3ddb7aad9103991e33c000000006b483045022100fdf9542e8c44a218601d427ac9d8262866083c3ac1312c1448c345ed54782901022077a4c5e1d22657e000a2c76dc6f873fcb70b7298bd627dd3dc7bb24fa6175ab10121033985b538c7c62cd419a5b24e0dd8d322174303f376e025fddd1f19da2cebcc500000000001d0549a3b000000001976a9142b3fac242eb3d7e20130082190605a5f7750037788ac00000000000000000000000000000000000000" + }, + { + "txid": "d6669b431916c5794fe1be5ffb0594aed0a3828c9ff7614c2f2a3e1eacce7360", + "version": 4, + "vin": [ + { + "txid": "b8843a9c37d921ef3d3f22e0ed7a4241c819403148e53f7da52000e194688af0", + "vout": 1, + "n": 0, + "addresses": [ + "t1JF7Y8w4gG9DCKRq3dkqgAPnhFaRZ5CpYP" + ], + "value": "8297097640", + "hex": "483045022100f8a66fee4cfd5e1f58539bfcc0b901c0197a2f92c3e667665ead8ae7b589a72b02202d17a5fc783fd7ece35682d967f7fe0fd74899feefe8751cc3946bd538cb91f701210308fcc9e30b408352f32f7899b27bce32569ed790ae582220880dd2cb8104dbea" + } + ], + "vout": [ + { + "value": "1000000", + "n": 0, + "spent": true, + "hex": "76a914c7654db037525b8de1a9e925f8aa8df9a948170c88ac", + "addresses": [ + "t1c3uqCTSGfyia7rotNoNLm7cV7UqCpXT21" + ] + }, + { + "value": "8296087640", + "n": 1, + "spent": true, + "hex": "76a914acced4f6d3ae68dfe384c349a95475dbd2ea6eba88ac", + "addresses": [ + "t1ZdL1GA9PFrU2sPqWZGBCjbbmb6bKoaLRR" + ] + } + ], + "blockHash": "000000143de9914e1b7b3a86bdfada47bfa68b7cf50a8b7950a2ff65b7ea8895", + "blockHeight": 488284, + "confirmations": 109226, + "blockTime": 1576179943, + "value": "8297087640", + "valueIn": "8297097640", + "fees": "10000", + "hex": "0400008085202f8901f08a6894e10020a57d3fe548314019c841427aede0223f3def21d9379c3a84b8010000006b483045022100f8a66fee4cfd5e1f58539bfcc0b901c0197a2f92c3e667665ead8ae7b589a72b02202d17a5fc783fd7ece35682d967f7fe0fd74899feefe8751cc3946bd538cb91f701210308fcc9e30b408352f32f7899b27bce32569ed790ae582220880dd2cb8104dbea000000000240420f00000000001976a914c7654db037525b8de1a9e925f8aa8df9a948170c88ac58407cee010000001976a914acced4f6d3ae68dfe384c349a95475dbd2ea6eba88ac00000000000000000000000000000000000000" + }, + { + "txid": "b8843a9c37d921ef3d3f22e0ed7a4241c819403148e53f7da52000e194688af0", + "version": 4, + "vin": [ + { + "txid": "7feac61d5721b3248fe5165666ccbc0911c1dcfd66a335c7c4e239e4b29deeb2", + "n": 0, + "addresses": [ + "t1a6HWWPH7TgJVhqjHYoNu4F7SPHZaLGuBg" + ], + "value": "8397107640", + "hex": "4830450221009356bcac0f406e79e2bb61d7566e5d60bed87a0f7683024e343ea7ff5bccb6da022031ccc587fa326087d6319190127fbd71ba1c3f98aeb5e4eb3343b8c2d76a3e2a012102c9764269807a6f8600a14e15ea90adbcb7608dd022c00e8507468436ec5e2cf5" + } + ], + "vout": [ + { + "value": "100000000", + "n": 0, + "spent": true, + "hex": "76a914f19db11ddaf48cb289080b98d132257bcd534dbd88ac", + "addresses": [ + "t1fu9mBwE7T9MYcLMiQjcXiS2tfUFcJK14F" + ] + }, + { + "value": "8297097640", + "n": 1, + "spent": true, + "hex": "76a914041162f12c4959cfa081f551a451fe23ed94717688ac", + "addresses": [ + "t1JF7Y8w4gG9DCKRq3dkqgAPnhFaRZ5CpYP" + ] + } + ], + "blockHash": "00000055b79ef86e240667b6a507f2d64359a7ef827e66f03a171b9c86b4c3e1", + "blockHeight": 488122, + "confirmations": 109388, + "blockTime": 1576160510, + "value": "8397097640", + "valueIn": "8397107640", + "fees": "10000", + "hex": "0400008085202f8901b2ee9db2e439e2c4c735a366fddcc11109bccc665616e58f24b321571dc6ea7f000000006b4830450221009356bcac0f406e79e2bb61d7566e5d60bed87a0f7683024e343ea7ff5bccb6da022031ccc587fa326087d6319190127fbd71ba1c3f98aeb5e4eb3343b8c2d76a3e2a012102c9764269807a6f8600a14e15ea90adbcb7608dd022c00e8507468436ec5e2cf5000000000200e1f505000000001976a914f19db11ddaf48cb289080b98d132257bcd534dbd88aca8a98bee010000001976a914041162f12c4959cfa081f551a451fe23ed94717688ac00000000000000000000000000000000000000" + }, + { + "txid": "7feac61d5721b3248fe5165666ccbc0911c1dcfd66a335c7c4e239e4b29deeb2", + "version": 4, + "vin": [ + { + "txid": "3b75d26bc474aaf1bab27fb890c439e99c4a83092797e8acfcbfa88713d99a4f", + "n": 0, + "addresses": [ + "t1Ps4cyeWT5sTxoNabuMmhRD3c2j5SdmVP8" + ], + "value": "100000", + "hex": "47304402201bfa05833ba6ef1c893a1cfab205d7931d9f5e5c41bdcdce503645c2ca170cf502206bbcfb59d76a7b3324bb34678f9b3dc3fbb769ee2b4253982ccb2bd4dd23407c012103758ac64bf8fef07ca3eff6cdf48255d53e0c6c559bed57a2b45e03b28727afcc" + }, + { + "txid": "88450e5030b295935e6dd558bc08e1a0af70f42e0cd3c9eda75c4cbd1e1da728", + "n": 1, + "addresses": [ + "t1PJCnDXNZuoKU5sCAJm15YGqnQdJTQw4Jy" + ], + "value": "1000000", + "hex": "47304402200e6be05443eade67815792991cea7c7a217ab6add0600e96d9603b25902f15140220699d63231f9e93c163ff0d740af1593e15ccc1b9a8f994e4537f3ec8659d96ec01210268e3b9550b815d540c9095d8f9851add0b783c6e37646f2b24a4c9fb5bbf1b64" + }, + { + "txid": "88450e5030b295935e6dd558bc08e1a0af70f42e0cd3c9eda75c4cbd1e1da728", + "vout": 1, + "n": 2, + "addresses": [ + "t1TDT81WmcqUXeBxV1JjTEb4usYbMPtqBJU" + ], + "value": "8880000", + "hex": "4730440220399cf1468ec607160f21259c0ee5351aed6f18c4f3a1bd6eaecc87afd6e42ac302204a958dd1579c92bce445af8e57dfa55e6efc77e602c20f2f6cba8edfbd92ace7012102f54777c45b02213eb5c81207a2477c915c1409dadc837e6040184e7b4a44800a" + }, + { + "txid": "14b090db86ab475ebbd9726489b30d27ed0edb3048ada7979df40f8541431e13", + "vout": 1, + "n": 3, + "addresses": [ + "t1PWD48DZfotRZLerFP6gzxQUqggbJ78Chb" + ], + "value": "87423640", + "hex": "483045022100f15454b8464f7d9d61b55bc429d1f19a43203c65e1f4c2cd94a2f645bdb6c8a402200a79568c70eae3bf0f9dee20dfd06f296d36b4f7be66d1456235f107e595c2e40121032ce19f2a74593a655d7bf9b78621bae60126d196bca77e720a27704be8dd1d79" + }, + { + "txid": "d9219d1700edf561928502db23a4cc3ac170bb1613b6f45776a17198ac091a02", + "n": 4, + "addresses": [ + "t1geFpG91gvaF7AKdbGskigvbaVVU9PzRy2" + ], + "value": "100000000", + "hex": "483045022100980b258ac75a3bea4e4b9147393d8dd697a314f1d1ba5076b8ddba90e037377102207847eca2541c4d48bf23d00588a01905b8278e3f49a475b2990be3844ff506420121031331dd0ba0ec99a31f29b28fd81672deea62d0b85ac92f526e98f77248e16850" + }, + { + "txid": "8c15c29ebba85a7bc6890e83e631f450c8910fe7c4489c7e7f342bc066fa7fb8", + "n": 5, + "addresses": [ + "t1ebDFfLgbfMwkq5aV18qBuF5uTUfXWtBNp" + ], + "value": "100000000", + "hex": "47304402201770c03c47411c0323652221b71c12e5093bca73c8bab929c42a3d4471aa6db5022034811d195eb0bba3015d9e493343b0e80f5da073431780de8f7ca61d4b0bc8f601210385f796e7c269bddd30f9e2ec5ade628e902e60ecfaf33bedcab8d51f21544ee6" + }, + { + "txid": "4b0ef37fa5f5e3d9f338b0db84a1ed79557a74bf9dfe648041e770b8ecbf88ac", + "n": 6, + "addresses": [ + "t1a6HWWPH7TgJVhqjHYoNu4F7SPHZaLGuBg" + ], + "value": "100000000", + "hex": "483045022100ad770d1107449f7c9a786b1114058255639d36a02df62ee9b5f240ae5d9b068502200b6f99ab8dfa928ce25e9e04ae1068ecf00c1a19fbddcc048e17388966b6480f012102c9764269807a6f8600a14e15ea90adbcb7608dd022c00e8507468436ec5e2cf5" + }, + { + "txid": "4b0ef37fa5f5e3d9f338b0db84a1ed79557a74bf9dfe648041e770b8ecbf88ac", + "vout": 1, + "n": 7, + "addresses": [ + "t1JG5Jg84RDtdyfg8wX521kbfGpirH1yx8g" + ], + "value": "699960000", + "hex": "483045022100eacf96e3df6249a92de030d61d0e19611e9b1d45d5223117463289049de58ee3022034e2be6bc7fa6053faee42a80b2d46707a0429d24a9d07415af8582ae64af86b01210288fde1c8d0c560e9b0885b2f2a6c2dc153fad665f09d8d421e2dcaa3ffef8b11" + }, + { + "txid": "a5d46a20f4918e7fead31889a67d7fe191c54dd780ea7184c5c369833537fc86", + "vout": 1, + "n": 8, + "addresses": [ + "t1Q4YXf89ReUrron31TEr7v4zhgxcRZhi5r" + ], + "value": "7299754000", + "hex": "473044022060e50791e1334cc91694f16899e4a4a4e52954d4dd818208e81e6bde579abd1902200568999f1fc2d2c6d52b416a198e787e91fe001efc0a3c8a615494824e2f327d0121020adc2d256b07692d746e900811c61b8b31422628fb0e1e311455dc072c68da12" + } + ], + "vout": [ + { + "value": "8397107640", + "n": 0, + "spent": true, + "hex": "76a914b1e7fac02d708380ce081c1b7af039ce1ab4a01288ac", + "addresses": [ + "t1a6HWWPH7TgJVhqjHYoNu4F7SPHZaLGuBg" + ] + } + ], + "blockHash": "0000004273cafef2af8bcae09a59953d9dd7088f9ad3a36e661b61fb655cdf3f", + "blockHeight": 488119, + "confirmations": 109391, + "blockTime": 1576159919, + "value": "8397107640", + "valueIn": "8397117640", + "fees": "10000", + "hex": "0400008085202f89094f9ad91387a8bffcace8972709834a9ce939c490b87fb2baf1aa74c46bd2753b000000006a47304402201bfa05833ba6ef1c893a1cfab205d7931d9f5e5c41bdcdce503645c2ca170cf502206bbcfb59d76a7b3324bb34678f9b3dc3fbb769ee2b4253982ccb2bd4dd23407c012103758ac64bf8fef07ca3eff6cdf48255d53e0c6c559bed57a2b45e03b28727afcc0000000028a71d1ebd4c5ca7edc9d30c2ef470afa0e108bc58d56d5e9395b230500e4588000000006a47304402200e6be05443eade67815792991cea7c7a217ab6add0600e96d9603b25902f15140220699d63231f9e93c163ff0d740af1593e15ccc1b9a8f994e4537f3ec8659d96ec01210268e3b9550b815d540c9095d8f9851add0b783c6e37646f2b24a4c9fb5bbf1b640000000028a71d1ebd4c5ca7edc9d30c2ef470afa0e108bc58d56d5e9395b230500e4588010000006a4730440220399cf1468ec607160f21259c0ee5351aed6f18c4f3a1bd6eaecc87afd6e42ac302204a958dd1579c92bce445af8e57dfa55e6efc77e602c20f2f6cba8edfbd92ace7012102f54777c45b02213eb5c81207a2477c915c1409dadc837e6040184e7b4a44800a00000000131e4341850ff49d97a7ad4830db0eed270db3896472d9bb5e47ab86db90b014010000006b483045022100f15454b8464f7d9d61b55bc429d1f19a43203c65e1f4c2cd94a2f645bdb6c8a402200a79568c70eae3bf0f9dee20dfd06f296d36b4f7be66d1456235f107e595c2e40121032ce19f2a74593a655d7bf9b78621bae60126d196bca77e720a27704be8dd1d7900000000021a09ac9871a17657f4b61316bb70c13acca423db02859261f5ed00179d21d9000000006b483045022100980b258ac75a3bea4e4b9147393d8dd697a314f1d1ba5076b8ddba90e037377102207847eca2541c4d48bf23d00588a01905b8278e3f49a475b2990be3844ff506420121031331dd0ba0ec99a31f29b28fd81672deea62d0b85ac92f526e98f77248e1685000000000b87ffa66c02b347f7e9c48c4e70f91c850f431e6830e89c67b5aa8bb9ec2158c000000006a47304402201770c03c47411c0323652221b71c12e5093bca73c8bab929c42a3d4471aa6db5022034811d195eb0bba3015d9e493343b0e80f5da073431780de8f7ca61d4b0bc8f601210385f796e7c269bddd30f9e2ec5ade628e902e60ecfaf33bedcab8d51f21544ee600000000ac88bfecb870e7418064fe9dbf747a5579eda184dbb038f3d9e3f5a57ff30e4b000000006b483045022100ad770d1107449f7c9a786b1114058255639d36a02df62ee9b5f240ae5d9b068502200b6f99ab8dfa928ce25e9e04ae1068ecf00c1a19fbddcc048e17388966b6480f012102c9764269807a6f8600a14e15ea90adbcb7608dd022c00e8507468436ec5e2cf500000000ac88bfecb870e7418064fe9dbf747a5579eda184dbb038f3d9e3f5a57ff30e4b010000006b483045022100eacf96e3df6249a92de030d61d0e19611e9b1d45d5223117463289049de58ee3022034e2be6bc7fa6053faee42a80b2d46707a0429d24a9d07415af8582ae64af86b01210288fde1c8d0c560e9b0885b2f2a6c2dc153fad665f09d8d421e2dcaa3ffef8b110000000086fc37358369c3c58471ea80d74dc591e17f7da68918d3ea7f8e91f4206ad4a5010000006a473044022060e50791e1334cc91694f16899e4a4a4e52954d4dd818208e81e6bde579abd1902200568999f1fc2d2c6d52b416a198e787e91fe001efc0a3c8a615494824e2f327d0121020adc2d256b07692d746e900811c61b8b31422628fb0e1e311455dc072c68da120000000001b8b181f4010000001976a914b1e7fac02d708380ce081c1b7af039ce1ab4a01288ac00000000000000000000000000000000000000" + }, + { + "txid": "4b0ef37fa5f5e3d9f338b0db84a1ed79557a74bf9dfe648041e770b8ecbf88ac", + "version": 4, + "vin": [ + { + "txid": "d9219d1700edf561928502db23a4cc3ac170bb1613b6f45776a17198ac091a02", + "vout": 1, + "n": 0, + "addresses": [ + "t1W8AuGBCy1VMQWy7JUrKogQbpsQJSV7efV" + ], + "value": "799970000", + "hex": "473044022078790509c123dca7891ac77fac4b2f764dca7ebb677083fb00b9ab42a845ad4302203a0ebf51edae13061edd60b74ab9462be1853091064f43803e8bff7c43a105de0121038375e6a728b548f1d3fcd24a538195ac6a5d9f8b7c31f1d56870c3f62dfa0045" + } + ], + "vout": [ + { + "value": "100000000", + "n": 0, + "spent": true, + "hex": "76a914b1e7fac02d708380ce081c1b7af039ce1ab4a01288ac", + "addresses": [ + "t1a6HWWPH7TgJVhqjHYoNu4F7SPHZaLGuBg" + ] + }, + { + "value": "699960000", + "n": 1, + "spent": true, + "hex": "76a914043ff06e66c8b70071a1a90c1bf0328e3550bcbc88ac", + "addresses": [ + "t1JG5Jg84RDtdyfg8wX521kbfGpirH1yx8g" + ] + } + ], + "blockHash": "000000560c905936b77d72bb0baa1acea23f4a5081412f57358d68bb086297c0", + "blockHeight": 487934, + "confirmations": 109576, + "blockTime": 1576137717, + "value": "799960000", + "valueIn": "799970000", + "fees": "10000", + "hex": "0400008085202f8901021a09ac9871a17657f4b61316bb70c13acca423db02859261f5ed00179d21d9010000006a473044022078790509c123dca7891ac77fac4b2f764dca7ebb677083fb00b9ab42a845ad4302203a0ebf51edae13061edd60b74ab9462be1853091064f43803e8bff7c43a105de0121038375e6a728b548f1d3fcd24a538195ac6a5d9f8b7c31f1d56870c3f62dfa0045000000000200e1f505000000001976a914b1e7fac02d708380ce081c1b7af039ce1ab4a01288acc08ab829000000001976a914043ff06e66c8b70071a1a90c1bf0328e3550bcbc88ac00000000000000000000000000000000000000" + }, + { + "txid": "88450e5030b295935e6dd558bc08e1a0af70f42e0cd3c9eda75c4cbd1e1da728", + "version": 4, + "vin": [ + { + "txid": "3b75d26bc474aaf1bab27fb890c439e99c4a83092797e8acfcbfa88713d99a4f", + "vout": 1, + "n": 0, + "addresses": [ + "t1JqpFtnqTHeuxHhP2eXcEUp111WWoQ3Fj2" + ], + "value": "9890000", + "hex": "47304402200e36bcaee420658c15eefadfe0d06211d2f825de15fc15b5a470e46c25f603290220297f5bbaf4ad468bb7b97f9fc0e1932099197a837a12149ad77c7c0bb04738630121022bdc67121f765090084b56ae8dac9166637d467bb5b90231dc8ceae63880474a" + } + ], + "vout": [ + { + "value": "1000000", + "n": 0, + "spent": true, + "hex": "76a9143b7fa3c4a3cc8640a4cb48d8065d802c7698750d88ac", + "addresses": [ + "t1PJCnDXNZuoKU5sCAJm15YGqnQdJTQw4Jy" + ] + }, + { + "value": "8880000", + "n": 1, + "spent": true, + "hex": "76a914667a08d692c001b0dc895e1efb115cc54a32eec288ac", + "addresses": [ + "t1TDT81WmcqUXeBxV1JjTEb4usYbMPtqBJU" + ] + } + ], + "blockHash": "0000002f5d2c5ce0762500fa7fd0ce7ce077fba4b1b290fdc73cc605ccc57c04", + "blockHeight": 418360, + "confirmations": 179150, + "blockTime": 1567734616, + "value": "9880000", + "valueIn": "9890000", + "fees": "10000", + "hex": "0400008085202f89014f9ad91387a8bffcace8972709834a9ce939c490b87fb2baf1aa74c46bd2753b010000006a47304402200e36bcaee420658c15eefadfe0d06211d2f825de15fc15b5a470e46c25f603290220297f5bbaf4ad468bb7b97f9fc0e1932099197a837a12149ad77c7c0bb04738630121022bdc67121f765090084b56ae8dac9166637d467bb5b90231dc8ceae63880474a000000000240420f00000000001976a9143b7fa3c4a3cc8640a4cb48d8065d802c7698750d88ac807f8700000000001976a914667a08d692c001b0dc895e1efb115cc54a32eec288ac00000000000000000000000000000000000000" + }, + { + "txid": "d9219d1700edf561928502db23a4cc3ac170bb1613b6f45776a17198ac091a02", + "version": 4, + "vin": [ + { + "txid": "8c15c29ebba85a7bc6890e83e631f450c8910fe7c4489c7e7f342bc066fa7fb8", + "vout": 1, + "n": 0, + "addresses": [ + "t1f4Kyg1bRWTt2YDWxCQWvHNA8sejSuLgZz" + ], + "value": "899980000", + "hex": "4730440220037132d99a1a19d1e0302e22b4952609a08668286fa57083fab6cc605eee07c302200446536f492497d74bb2823d2b2c602e2f64807c20af39442bfe151f72dbdee0012102621d97835d046d2a404d4f6a1fa719a6654f092e4f0bf2d50c86a2366e010323" + } + ], + "vout": [ + { + "value": "100000000", + "n": 0, + "spent": true, + "hex": "76a914f9c4a188575f9c84b36d44ac45840e1961b384d488ac", + "addresses": [ + "t1geFpG91gvaF7AKdbGskigvbaVVU9PzRy2" + ] + }, + { + "value": "799970000", + "n": 1, + "spent": true, + "hex": "76a9148662cadfc04a343c5dba3ee75116922a9a2a512188ac", + "addresses": [ + "t1W8AuGBCy1VMQWy7JUrKogQbpsQJSV7efV" + ] + } + ], + "blockHash": "00000039b2eb21aa867598c3907dc73205c2d3864abe3d655c21a7ffcfbd0249", + "blockHeight": 418352, + "confirmations": 179158, + "blockTime": 1567733843, + "value": "899970000", + "valueIn": "899980000", + "fees": "10000", + "hex": "0400008085202f8901b87ffa66c02b347f7e9c48c4e70f91c850f431e6830e89c67b5aa8bb9ec2158c010000006a4730440220037132d99a1a19d1e0302e22b4952609a08668286fa57083fab6cc605eee07c302200446536f492497d74bb2823d2b2c602e2f64807c20af39442bfe151f72dbdee0012102621d97835d046d2a404d4f6a1fa719a6654f092e4f0bf2d50c86a2366e010323000000000200e1f505000000001976a914f9c4a188575f9c84b36d44ac45840e1961b384d488acd092ae2f000000001976a9148662cadfc04a343c5dba3ee75116922a9a2a512188ac00000000000000000000000000000000000000" + }, + { + "txid": "8c15c29ebba85a7bc6890e83e631f450c8910fe7c4489c7e7f342bc066fa7fb8", + "version": 4, + "vin": [ + { + "txid": "17fa0cd349b820474816bc4b6482cd212f9897eeceb26db6133256c9c8fc445a", + "n": 0, + "addresses": [ + "t1bQhfSPZE8Do6qf1ohYcG5j591i3PpNykJ" + ], + "value": "999990000", + "hex": "47304402204ef82fa2370116d8c61bb2c7a744f7b8ae0abe222262a0b6d2c9b2663f1182b2022044539e387abeee1943b834a80efd142b31b4045aed03f0f89492032d949167d9012103834594213870cb448637157b78a115d0ee38db8affa982526511a84f92252b0e" + } + ], + "vout": [ + { + "value": "100000000", + "n": 0, + "spent": true, + "hex": "76a914e340fe29e1bcf32d1ff41716fe781b8ea8e3cdf388ac", + "addresses": [ + "t1ebDFfLgbfMwkq5aV18qBuF5uTUfXWtBNp" + ] + }, + { + "value": "899980000", + "n": 1, + "spent": true, + "hex": "76a914e861d644e9a6fce70751d186034df7440a2cb1bf88ac", + "addresses": [ + "t1f4Kyg1bRWTt2YDWxCQWvHNA8sejSuLgZz" + ] + } + ], + "blockHash": "0000002a163eff0d20cdf72672cbd5b56f1e5e03364a2b547326560e99141b0c", + "blockHeight": 415334, + "confirmations": 182176, + "blockTime": 1567370685, + "value": "999980000", + "valueIn": "999990000", + "fees": "10000", + "hex": "0400008085202f89015a44fcc8c9563213b66db2ceee97982f21cd82644bbc16484720b849d30cfa17000000006a47304402204ef82fa2370116d8c61bb2c7a744f7b8ae0abe222262a0b6d2c9b2663f1182b2022044539e387abeee1943b834a80efd142b31b4045aed03f0f89492032d949167d9012103834594213870cb448637157b78a115d0ee38db8affa982526511a84f92252b0e000000000200e1f505000000001976a914e340fe29e1bcf32d1ff41716fe781b8ea8e3cdf388ace09aa435000000001976a914e861d644e9a6fce70751d186034df7440a2cb1bf88ac00000000000000000000000000000000000000" + }, + { + "txid": "3b75d26bc474aaf1bab27fb890c439e99c4a83092797e8acfcbfa88713d99a4f", + "version": 4, + "vin": [ + { + "txid": "d50b535474820e492e983ac1e28f35f3a438f75de4608bd607de3f353b4734e1", + "n": 0, + "addresses": [ + "t1NxxzpojGhvtLHwiJvdivokWY4KfJuT1pd" + ], + "value": "10000000", + "hex": "483045022100df19f9252513678259f56acb5fdcb437890a25ee77aa8bc97523922c2f10169b022041f6e0701564228d6a5949a67533ae22096956f40efcdd2f67b9341174696967012102f5a3ac1537190c715de17ca1f105fcac8dffd761244adca9ba36105da3788aa3" + } + ], + "vout": [ + { + "value": "100000", + "n": 0, + "spent": true, + "hex": "76a91441b68e2ffc0bf598c376842c007fd831beb7917988ac", + "addresses": [ + "t1Ps4cyeWT5sTxoNabuMmhRD3c2j5SdmVP8" + ] + }, + { + "value": "9890000", + "n": 1, + "spent": true, + "hex": "76a9140aa1853e57472c179d09457201ca02cc08838e0f88ac", + "addresses": [ + "t1JqpFtnqTHeuxHhP2eXcEUp111WWoQ3Fj2" + ] + } + ], + "blockHash": "000000039f8a845ebd4607ab16391f00611f94853263e222a6c951e88fed69dd", + "blockHeight": 414780, + "confirmations": 182730, + "blockTime": 1567304242, + "value": "9990000", + "valueIn": "10000000", + "fees": "10000", + "hex": "0400008085202f8901e134473b353fde07d68b60e45df738a4f3358fe2c13a982e490e827454530bd5000000006b483045022100df19f9252513678259f56acb5fdcb437890a25ee77aa8bc97523922c2f10169b022041f6e0701564228d6a5949a67533ae22096956f40efcdd2f67b9341174696967012102f5a3ac1537190c715de17ca1f105fcac8dffd761244adca9ba36105da3788aa30000000002a0860100000000001976a91441b68e2ffc0bf598c376842c007fd831beb7917988acd0e89600000000001976a9140aa1853e57472c179d09457201ca02cc08838e0f88ac00000000000000000000000000000000000000" + }, + { + "txid": "17fa0cd349b820474816bc4b6482cd212f9897eeceb26db6133256c9c8fc445a", + "version": 4, + "vin": [ + { + "txid": "a5d46a20f4918e7fead31889a67d7fe191c54dd780ea7184c5c369833537fc86", + "sequence": 4294967294, + "n": 0, + "addresses": [ + "t1S2iUUwT3rjQeU6kcucbunr4avRNH3W34V" + ], + "value": "1000000000", + "hex": "483045022100b2a76edd1b63c6d575047556d88d1728931825f21e812d5a091f31f2012abbba02204461ec8971d81413b6e04dde57b325982d5a59688f761cbe58916a44a7ac5ad00121022337efa16ee696bfc459b7d0c0a202044bc62c14c12c1e7310de57ccc59d5c22" + } + ], + "vout": [ + { + "value": "999990000", + "n": 0, + "spent": true, + "hex": "76a914c05bc15cc814aedb18b50ed152cf930df8eeda4488ac", + "addresses": [ + "t1bQhfSPZE8Do6qf1ohYcG5j591i3PpNykJ" + ] + } + ], + "blockHash": "00000033eb355a1da3bd1c2441b4c1a238cd7063dfc4676387b4c25978c84dce", + "blockHeight": 404602, + "confirmations": 192908, + "blockTime": 1566071583, + "value": "999990000", + "valueIn": "1000000000", + "fees": "10000", + "hex": "0400008085202f890186fc37358369c3c58471ea80d74dc591e17f7da68918d3ea7f8e91f4206ad4a5000000006b483045022100b2a76edd1b63c6d575047556d88d1728931825f21e812d5a091f31f2012abbba02204461ec8971d81413b6e04dde57b325982d5a59688f761cbe58916a44a7ac5ad00121022337efa16ee696bfc459b7d0c0a202044bc62c14c12c1e7310de57ccc59d5c22feffffff01f0a29a3b000000001976a914c05bc15cc814aedb18b50ed152cf930df8eeda4488ac00000000000000000000000000000000000000" + }, + { + "txid": "a5d46a20f4918e7fead31889a67d7fe191c54dd780ea7184c5c369833537fc86", + "version": 4, + "vin": [ + { + "txid": "fc66fbfa6531984d26301d0599a555bdab9612dbfe35ea53997f7633d097f672", + "vout": 1, + "n": 0, + "addresses": [ + "t1bQhfSPZE8Do6qf1ohYcG5j591i3PpNykJ" + ], + "value": "8299764000", + "hex": "47304402206974f18033a7ae20ecb6700c848e517409fec6fe2103a6516de62eaec13528b30220676f6a9ce3c14ab2b4e7be47ee4a1c0e756d5e346a4c982281ca1a9e6d9bac2d012103834594213870cb448637157b78a115d0ee38db8affa982526511a84f92252b0e" + } + ], + "vout": [ + { + "value": "1000000000", + "n": 0, + "spent": true, + "hex": "76a914597a2630de1576e75fad04f4122f81dcb6cea8f788ac", + "addresses": [ + "t1S2iUUwT3rjQeU6kcucbunr4avRNH3W34V" + ] + }, + { + "value": "7299754000", + "n": 1, + "spent": true, + "hex": "76a91443e26d7b61b9b8426c3cb7099cad858a2319362488ac", + "addresses": [ + "t1Q4YXf89ReUrron31TEr7v4zhgxcRZhi5r" + ] + } + ], + "blockHash": "00000037543ab8923662e5928364e2dd2a82318c253ab9b9aa92b83521b6ff8b", + "blockHeight": 404601, + "confirmations": 192909, + "blockTime": 1566071132, + "value": "8299754000", + "valueIn": "8299764000", + "fees": "10000", + "hex": "0400008085202f890172f697d033767f9953ea35fedb1296abbd55a599051d30264d983165fafb66fc010000006a47304402206974f18033a7ae20ecb6700c848e517409fec6fe2103a6516de62eaec13528b30220676f6a9ce3c14ab2b4e7be47ee4a1c0e756d5e346a4c982281ca1a9e6d9bac2d012103834594213870cb448637157b78a115d0ee38db8affa982526511a84f92252b0e000000000200ca9a3b000000001976a914597a2630de1576e75fad04f4122f81dcb6cea8f788ac106819b3010000001976a91443e26d7b61b9b8426c3cb7099cad858a2319362488ac00000000000000000000000000000000000000" + }, + { + "txid": "fc66fbfa6531984d26301d0599a555bdab9612dbfe35ea53997f7633d097f672", + "version": 4, + "vin": [ + { + "txid": "7568654a592eb35c8c8cec7c7e9d93ffb2f1d6770576369991e8eefb9da97df1", + "vout": 1, + "n": 0, + "addresses": [ + "t1V1f4WNQB8zeTA8z27zqcFwpsGrbcSo7Eo" + ], + "value": "9299774000", + "hex": "473044022028e6f1f002911c7f0503187b0750b114e8cd36eaec2ad32dfb0aad44b820f078022008e03c1058128e99698165c0de3691acd0a9f314d535c55827f0d3269bbbcbdd01210266fb4c06ad0a274aba63820224d142ed1db4781abd5909702f71900e4c2d0340" + } + ], + "vout": [ + { + "value": "1000000000", + "n": 0, + "hex": "76a9147f1271095e3e2063ca859588b40dad6c13995dce88ac", + "addresses": [ + "t1VTVv3Ebwo2zvEdE3PDrJyTATKDTXg7CvB" + ] + }, + { + "value": "8299764000", + "n": 1, + "spent": true, + "hex": "76a914c05bc15cc814aedb18b50ed152cf930df8eeda4488ac", + "addresses": [ + "t1bQhfSPZE8Do6qf1ohYcG5j591i3PpNykJ" + ] + } + ], + "blockHash": "00000013cd50f912ef02928735f3aaa8dd75c2a1b075f5f336e73d85220f862c", + "blockHeight": 403671, + "confirmations": 193839, + "blockTime": 1565958928, + "value": "9299764000", + "valueIn": "9299774000", + "fees": "10000", + "hex": "0400008085202f8901f17da99dfbeee8919936760577d6f1b2ff939d7e7cec8c8c5cb32e594a656875010000006a473044022028e6f1f002911c7f0503187b0750b114e8cd36eaec2ad32dfb0aad44b820f078022008e03c1058128e99698165c0de3691acd0a9f314d535c55827f0d3269bbbcbdd01210266fb4c06ad0a274aba63820224d142ed1db4781abd5909702f71900e4c2d0340000000000200ca9a3b000000001976a9147f1271095e3e2063ca859588b40dad6c13995dce88ac2059b4ee010000001976a914c05bc15cc814aedb18b50ed152cf930df8eeda4488ac00000000000000000000000000000000000000" + }, + { + "txid": "d50b535474820e492e983ac1e28f35f3a438f75de4608bd607de3f353b4734e1", + "version": 4, + "vin": [ + { + "txid": "14b090db86ab475ebbd9726489b30d27ed0edb3048ada7979df40f8541431e13", + "sequence": 2147483646, + "n": 0, + "addresses": [ + "t1URfpa81UtVrj4kbKpsW3Yq9QhKBxx6mSQ" + ], + "value": "112300000", + "hex": "4830450221008b0569773b9b10607bf07f31376d02a7fb6a777b16302479ec29b3464c41389002202a31dc5d02630e72ad9627f39cc7357f7f3d7090cf00c41f727c9a4ada704673012102826f2aebbdad38b97d070fff71d5e9c87e926e682e02601ffc8f82450b9bd33e" + } + ], + "vout": [ + { + "value": "10000000", + "n": 0, + "spent": true, + "hex": "76a91437dc3b364dab71edf5ad84578ec901b10eb6c71788ac", + "addresses": [ + "t1NxxzpojGhvtLHwiJvdivokWY4KfJuT1pd" + ] + }, + { + "value": "102074000", + "n": 1, + "spent": true, + "hex": "76a9149d8b8c5ddd77a98b1cb09ba93f5cd0c11e74fb5f88ac", + "addresses": [ + "t1YEdGSS9ErsDbtfKzZN39kLr3LGP8xRu1G" + ] + } + ], + "blockHash": "000000145ea129bb32d171e2050b764dff4e30d13a3a2b0974e72f8d0aaf9a57", + "blockHeight": 337841, + "confirmations": 259669, + "blockTime": 1557995255, + "value": "112074000", + "valueIn": "112300000", + "fees": "226000", + "hex": "0400008085202f8901131e4341850ff49d97a7ad4830db0eed270db3896472d9bb5e47ab86db90b014000000006b4830450221008b0569773b9b10607bf07f31376d02a7fb6a777b16302479ec29b3464c41389002202a31dc5d02630e72ad9627f39cc7357f7f3d7090cf00c41f727c9a4ada704673012102826f2aebbdad38b97d070fff71d5e9c87e926e682e02601ffc8f82450b9bd33efeffff7f0280969800000000001976a91437dc3b364dab71edf5ad84578ec901b10eb6c71788ac90861506000000001976a9149d8b8c5ddd77a98b1cb09ba93f5cd0c11e74fb5f88ac00000000000000000000000000000000000000" + }, + { + "txid": "14b090db86ab475ebbd9726489b30d27ed0edb3048ada7979df40f8541431e13", + "version": 4, + "vin": [ + { + "txid": "9349dc789e58ae48cf7c0e0200237aeb2d71e03ea75422dbb0d08a9cea86022b", + "n": 0, + "addresses": [ + "t1NxxzpojGhvtLHwiJvdivokWY4KfJuT1pd" + ], + "value": "199733640", + "hex": "483045022100ac753e2e0ad2b248d6aaa3e50cf9f82d6b478b922aaaf6f8d9446b265a0a085c02206a5676e6334a66f770a02e753edf26fd22fa7cb7797386a8043cae121a78d071012102f5a3ac1537190c715de17ca1f105fcac8dffd761244adca9ba36105da3788aa3" + } + ], + "vout": [ + { + "value": "112300000", + "n": 0, + "spent": true, + "hex": "76a91473c1c0b3022da242b74bddba0dc556d0ef96ea4488ac", + "addresses": [ + "t1URfpa81UtVrj4kbKpsW3Yq9QhKBxx6mSQ" + ] + }, + { + "value": "87423640", + "n": 1, + "spent": true, + "hex": "76a9143dc4dc377fd0b413affda4d928294f99ed987f6a88ac", + "addresses": [ + "t1PWD48DZfotRZLerFP6gzxQUqggbJ78Chb" + ] + } + ], + "blockHash": "000000329c8e95b91fe0dbf20960435fb3525c440edd90ed35714a8d92020883", + "blockHeight": 337812, + "confirmations": 259698, + "blockTime": 1557991696, + "value": "199723640", + "valueIn": "199733640", + "fees": "10000", + "hex": "0400008085202f89012b0286ea9c8ad0b0db2254a73ee0712deb7a2300020e7ccf48ae589e78dc4993000000006b483045022100ac753e2e0ad2b248d6aaa3e50cf9f82d6b478b922aaaf6f8d9446b265a0a085c02206a5676e6334a66f770a02e753edf26fd22fa7cb7797386a8043cae121a78d071012102f5a3ac1537190c715de17ca1f105fcac8dffd761244adca9ba36105da3788aa30000000002e08fb106000000001976a91473c1c0b3022da242b74bddba0dc556d0ef96ea4488ac98fa3505000000001976a9143dc4dc377fd0b413affda4d928294f99ed987f6a88ac00000000000000000000000000000000000000" + }, + { + "txid": "9349dc789e58ae48cf7c0e0200237aeb2d71e03ea75422dbb0d08a9cea86022b", + "version": 4, + "vin": [ + { + "txid": "7568654a592eb35c8c8cec7c7e9d93ffb2f1d6770576369991e8eefb9da97df1", + "sequence": 2147483644, + "n": 0, + "addresses": [ + "t1PJfL2QqQSERTXHDqSBw6WKKE4bXGJjLB7" + ], + "value": "340169480", + "hex": "473044022021f5f09419eaf1896a1f9e7b108780e04136bd083395a167ba7803b5d27cc473022040fdfc66536f8910927032c9b4d90e408aceb431626c47e8b33812af10c18aee01210290f437489bf989f9f74597799262d0e6ffa5fa6cb83922b2a2fe5856420c528a" + }, + { + "txid": "4dc556de97672632e5b4d5e06562b1225e83f461d713928142a5582a117c69de", + "sequence": 2147483645, + "n": 1, + "addresses": [ + "t1PJfL2QqQSERTXHDqSBw6WKKE4bXGJjLB7" + ], + "value": "100000000", + "hex": "48304502210098257b740550470d0213f3e25ac0c0a70762f149953cbaa4ff06058cf6be7bce022068a8967485b476fa8ad94b1fe0667e07c7323e38213c00dac155a3b79b1b659001210290f437489bf989f9f74597799262d0e6ffa5fa6cb83922b2a2fe5856420c528a" + }, + { + "txid": "49575259c2f421bd6586e7506353c2e2c4c04eca9355c2c61e8ff22b69a98f68", + "sequence": 2147483646, + "n": 2, + "addresses": [ + "t1PJfL2QqQSERTXHDqSBw6WKKE4bXGJjLB7" + ], + "value": "259564160", + "hex": "483045022100dab8d58404248321208cbde2b95d399ec33a0d023e18108833b27e2705118d660220736d69b128e2474996442e58d5f72b24820105004e32c020c85a57bc382b459801210290f437489bf989f9f74597799262d0e6ffa5fa6cb83922b2a2fe5856420c528a" + } + ], + "vout": [ + { + "value": "199733640", + "n": 0, + "spent": true, + "hex": "76a91437dc3b364dab71edf5ad84578ec901b10eb6c71788ac", + "addresses": [ + "t1NxxzpojGhvtLHwiJvdivokWY4KfJuT1pd" + ] + }, + { + "value": "499774000", + "n": 1, + "hex": "76a914ec1bc34cc218f75a453e476bf3fee959f6859cbe88ac", + "addresses": [ + "t1fQ2jcA6zm59QzACiiQdZCe85uQJghkbiN" + ] + } + ], + "blockHash": "00000012362103edf57021e6f7f73743062f7935d15d0f13a88a6da2b9f5a7a0", + "blockHeight": 337460, + "confirmations": 260050, + "blockTime": 1557949204, + "value": "699507640", + "valueIn": "699733640", + "fees": "226000", + "hex": "0400008085202f8903f17da99dfbeee8919936760577d6f1b2ff939d7e7cec8c8c5cb32e594a656875000000006a473044022021f5f09419eaf1896a1f9e7b108780e04136bd083395a167ba7803b5d27cc473022040fdfc66536f8910927032c9b4d90e408aceb431626c47e8b33812af10c18aee01210290f437489bf989f9f74597799262d0e6ffa5fa6cb83922b2a2fe5856420c528afcffff7fde697c112a58a542819213d761f4835e22b16265e0d5b4e532266797de56c54d000000006b48304502210098257b740550470d0213f3e25ac0c0a70762f149953cbaa4ff06058cf6be7bce022068a8967485b476fa8ad94b1fe0667e07c7323e38213c00dac155a3b79b1b659001210290f437489bf989f9f74597799262d0e6ffa5fa6cb83922b2a2fe5856420c528afdffff7f688fa9692bf28f1ec6c25593ca4ec0c4e2c2536350e78665bd21f4c259525749000000006b483045022100dab8d58404248321208cbde2b95d399ec33a0d023e18108833b27e2705118d660220736d69b128e2474996442e58d5f72b24820105004e32c020c85a57bc382b459801210290f437489bf989f9f74597799262d0e6ffa5fa6cb83922b2a2fe5856420c528afeffff7f0288b1e70b000000001976a91437dc3b364dab71edf5ad84578ec901b10eb6c71788ac30f2c91d000000001976a914ec1bc34cc218f75a453e476bf3fee959f6859cbe88ac00000000000000000000000000000000000000" + }, + { + "txid": "7568654a592eb35c8c8cec7c7e9d93ffb2f1d6770576369991e8eefb9da97df1", + "version": 4, + "vin": [ + { + "txid": "4dc556de97672632e5b4d5e06562b1225e83f461d713928142a5582a117c69de", + "vout": 1, + "sequence": 2147483646, + "n": 0, + "addresses": [ + "t1NxxzpojGhvtLHwiJvdivokWY4KfJuT1pd" + ], + "value": "9640169480", + "hex": "483045022100c3fab53af64f87850dc757b7db2195f8c5058bc3711af11b57a4c5b3105ab877022012f11149aefd859a554b09b54f44ed2307a2c17714f638587f39bb95eeaf81a6012102f5a3ac1537190c715de17ca1f105fcac8dffd761244adca9ba36105da3788aa3" + } + ], + "vout": [ + { + "value": "340169480", + "n": 0, + "spent": true, + "hex": "76a9143b95cd1d119904d38c4e250e52253c66066ed60c88ac", + "addresses": [ + "t1PJfL2QqQSERTXHDqSBw6WKKE4bXGJjLB7" + ] + }, + { + "value": "9299774000", + "n": 1, + "spent": true, + "hex": "76a9147a2f42e0673605fb11884b35e79bbcc525ac7b1088ac", + "addresses": [ + "t1V1f4WNQB8zeTA8z27zqcFwpsGrbcSo7Eo" + ] + } + ], + "blockHash": "00000030651071f9961b36bf9f7183a7b4428f438af5f42eca1512fb09575175", + "blockHeight": 337456, + "confirmations": 260054, + "blockTime": 1557948761, + "value": "9639943480", + "valueIn": "9640169480", + "fees": "226000", + "hex": "0400008085202f8901de697c112a58a542819213d761f4835e22b16265e0d5b4e532266797de56c54d010000006b483045022100c3fab53af64f87850dc757b7db2195f8c5058bc3711af11b57a4c5b3105ab877022012f11149aefd859a554b09b54f44ed2307a2c17714f638587f39bb95eeaf81a6012102f5a3ac1537190c715de17ca1f105fcac8dffd761244adca9ba36105da3788aa3feffff7f0208934614000000001976a9143b95cd1d119904d38c4e250e52253c66066ed60c88ac304a4f2a020000001976a9147a2f42e0673605fb11884b35e79bbcc525ac7b1088ac00000000000000000000000000000000000000" + }, + { + "txid": "4dc556de97672632e5b4d5e06562b1225e83f461d713928142a5582a117c69de", + "version": 4, + "vin": [ + { + "txid": "49575259c2f421bd6586e7506353c2e2c4c04eca9355c2c61e8ff22b69a98f68", + "vout": 1, + "sequence": 2147483646, + "n": 0, + "addresses": [ + "t1aCdgJD9R5tumv4Lj5sDNyQkfpwSjYj34A" + ], + "value": "9740395480", + "hex": "483045022100f23c9c3ee498fc654a32eeb094de699e704e4af118d2a5fc852bb808d4b04ae10220497da33b6a8a3011244bd9c3d1e6a6d7b15b1e6e52d690a10ccbd6cba05028bb012102b0f3aa87ed650b61719eb7019683de78a77d9166a5b6924cbc2eaac9da650445" + } + ], + "vout": [ + { + "value": "100000000", + "n": 0, + "spent": true, + "hex": "76a9143b95cd1d119904d38c4e250e52253c66066ed60c88ac", + "addresses": [ + "t1PJfL2QqQSERTXHDqSBw6WKKE4bXGJjLB7" + ] + }, + { + "value": "9640169480", + "n": 1, + "spent": true, + "hex": "76a91437dc3b364dab71edf5ad84578ec901b10eb6c71788ac", + "addresses": [ + "t1NxxzpojGhvtLHwiJvdivokWY4KfJuT1pd" + ] + } + ], + "blockHash": "0000000a2cbdac0d5d68b2bd53e136901de71badef2953449f91eb5dbecf5e7e", + "blockHeight": 336048, + "confirmations": 261462, + "blockTime": 1557776516, + "value": "9740169480", + "valueIn": "9740395480", + "fees": "226000", + "hex": "0400008085202f8901688fa9692bf28f1ec6c25593ca4ec0c4e2c2536350e78665bd21f4c259525749010000006b483045022100f23c9c3ee498fc654a32eeb094de699e704e4af118d2a5fc852bb808d4b04ae10220497da33b6a8a3011244bd9c3d1e6a6d7b15b1e6e52d690a10ccbd6cba05028bb012102b0f3aa87ed650b61719eb7019683de78a77d9166a5b6924cbc2eaac9da650445feffff7f0200e1f505000000001976a9143b95cd1d119904d38c4e250e52253c66066ed60c88ac0850993e020000001976a91437dc3b364dab71edf5ad84578ec901b10eb6c71788ac00000000000000000000000000000000000000" + }, + { + "txid": "49575259c2f421bd6586e7506353c2e2c4c04eca9355c2c61e8ff22b69a98f68", + "version": 4, + "vin": [ + { + "txid": "608bc6d8a25d368f63816087e8760fddac7522776dd3cba2109d7cd3a93ee7bf", + "sequence": 2147483645, + "n": 0, + "addresses": [ + "t1ZYbmtqhQrmEhhQx4qjn1pE1nm3xQvZzv4" + ], + "value": "307888200", + "hex": "47304402201d4884ba653ad26e0d8f25358c80d39ac80403f48bdfefdb4daec9be039d24ab02206e4fad2814b69417ffc3e65e033c01e4fe90a715e35224cc78b470935e165279012102f7bb101f35466e6264aea052956beda92b309f99fa322388c7a003f57cd318bd" + }, + { + "txid": "54c13888cb5b85383d008a02aad2187fcff03feb6c0f5ab963c1d916bc9ef0d1", + "vout": 1, + "sequence": 2147483646, + "n": 1, + "addresses": [ + "t1N1d1XJqrNzorBZUJb4cUWitAC9B5RcUoX" + ], + "value": "9692075960", + "hex": "47304402200e1716c15faae00a049d7979e60ddd039b59f64181f9fa5222ffad76a51eab46022005fa1b5ed1659e5fd48cabb20e8c6a56e4a80453142b743412632dd93ccaf10401210320893fa384153625abfd90b12ecd180b3d73c64fdfc783207b5354c3b61ecadd" + } + ], + "vout": [ + { + "value": "259564160", + "n": 0, + "spent": true, + "hex": "76a9143b95cd1d119904d38c4e250e52253c66066ed60c88ac", + "addresses": [ + "t1PJfL2QqQSERTXHDqSBw6WKKE4bXGJjLB7" + ] + }, + { + "value": "9740395480", + "n": 1, + "spent": true, + "hex": "76a914b31b4fb329e7bbf7e2f20719d78d79685963670c88ac", + "addresses": [ + "t1aCdgJD9R5tumv4Lj5sDNyQkfpwSjYj34A" + ] + } + ], + "blockHash": "0000001162097734f4e2e45aa56c3ecab443a0d687af8402c7b7f63170830318", + "blockHeight": 335709, + "confirmations": 261801, + "blockTime": 1557736095, + "value": "9999959640", + "valueIn": "9999964160", + "fees": "4520", + "hex": "0400008085202f8902bfe73ea9d37c9d10a2cbd36d772275acdd0f76e8876081638f365da2d8c68b60000000006a47304402201d4884ba653ad26e0d8f25358c80d39ac80403f48bdfefdb4daec9be039d24ab02206e4fad2814b69417ffc3e65e033c01e4fe90a715e35224cc78b470935e165279012102f7bb101f35466e6264aea052956beda92b309f99fa322388c7a003f57cd318bdfdffff7fd1f09ebc16d9c163b95a0f6ceb3ff0cf7f18d2aa028a003d38855bcb8838c154010000006a47304402200e1716c15faae00a049d7979e60ddd039b59f64181f9fa5222ffad76a51eab46022005fa1b5ed1659e5fd48cabb20e8c6a56e4a80453142b743412632dd93ccaf10401210320893fa384153625abfd90b12ecd180b3d73c64fdfc783207b5354c3b61ecaddfeffff7f0280a2780f000000001976a9143b95cd1d119904d38c4e250e52253c66066ed60c88acd8a39244020000001976a914b31b4fb329e7bbf7e2f20719d78d79685963670c88ac00000000000000000000000000000000000000" + }, + { + "txid": "608bc6d8a25d368f63816087e8760fddac7522776dd3cba2109d7cd3a93ee7bf", + "version": 4, + "vin": [ + { + "txid": "54c13888cb5b85383d008a02aad2187fcff03feb6c0f5ab963c1d916bc9ef0d1", + "sequence": 2147483645, + "n": 0, + "addresses": [ + "t1fvxYkVjkmYJFaSR4254YNa6kwxXe2wEQA" + ], + "value": "112345000", + "hex": "473044022033609c40da85357f58a0edb2fd6f02efac74a1422c1e2882ababd6576cb94f2002207180a21a0db61296fd22d4bbd1302ea7fc70f3540b6b5b1ab0b2594ed0443c310121023f0760e051894921eb0da99a97bf45b5279a1f19daab7144c060c4a6cbdad263" + }, + { + "txid": "2b9a6838fa428396f8ef34119b951480d676d022cbb29f0a9575e1fd185a96a3", + "sequence": 2147483646, + "n": 1, + "addresses": [ + "t1fvxYkVjkmYJFaSR4254YNa6kwxXe2wEQA" + ], + "value": "195550000", + "hex": "473044022043c21784a268c2c99dc0f54a8da62dc2367dfc3739aace1a9035117c4ef514ae022034586a0a13eeb0b3336c722d9fd10504d71cd57e1d2dff3868c37dc37defe90d0121023f0760e051894921eb0da99a97bf45b5279a1f19daab7144c060c4a6cbdad263" + } + ], + "vout": [ + { + "value": "307888200", + "n": 0, + "spent": true, + "hex": "76a914abe9ea731a821de6c87b3d0184fc405c0b8dcdc888ac", + "addresses": [ + "t1ZYbmtqhQrmEhhQx4qjn1pE1nm3xQvZzv4" + ] + } + ], + "blockHash": "0000000a6cbd7756c970f1f0fa2e32b62872f1ded7af827b3eaa0665baa7df9d", + "blockHeight": 335704, + "confirmations": 261806, + "blockTime": 1557735455, + "value": "307888200", + "valueIn": "307895000", + "fees": "6800", + "hex": "0400008085202f8902d1f09ebc16d9c163b95a0f6ceb3ff0cf7f18d2aa028a003d38855bcb8838c154000000006a473044022033609c40da85357f58a0edb2fd6f02efac74a1422c1e2882ababd6576cb94f2002207180a21a0db61296fd22d4bbd1302ea7fc70f3540b6b5b1ab0b2594ed0443c310121023f0760e051894921eb0da99a97bf45b5279a1f19daab7144c060c4a6cbdad263fdffff7fa3965a18fde175950a9fb2cb22d076d68014959b1134eff8968342fa38689a2b000000006a473044022043c21784a268c2c99dc0f54a8da62dc2367dfc3739aace1a9035117c4ef514ae022034586a0a13eeb0b3336c722d9fd10504d71cd57e1d2dff3868c37dc37defe90d0121023f0760e051894921eb0da99a97bf45b5279a1f19daab7144c060c4a6cbdad263feffff7f0148005a12000000001976a914abe9ea731a821de6c87b3d0184fc405c0b8dcdc888ac00000000000000000000000000000000000000" + }, + { + "txid": "54c13888cb5b85383d008a02aad2187fcff03feb6c0f5ab963c1d916bc9ef0d1", + "version": 4, + "vin": [ + { + "txid": "2b9a6838fa428396f8ef34119b951480d676d022cbb29f0a9575e1fd185a96a3", + "vout": 1, + "sequence": 2147483646, + "n": 0, + "addresses": [ + "t1dfCmUsQAD73vkFSsHPC1ak9b7ven8P7pe" + ], + "value": "9804425480", + "hex": "483045022100b25ab6c1a994d0f99c874187427802f1a2e8ee3746784fd32fc358b522d5467402207ea330c77121f8b426d79f9778f16be2d3f625afc8fc851ae9b0aa7418c6a938012103c85acfe75a3bb4418d5f604aced599253cb639a417c9920103016ca79402a0de" + } + ], + "vout": [ + { + "value": "112345000", + "n": 0, + "spent": true, + "hex": "76a914f1f52994ca1ca3b41cb3a56de4f8b79f71297d5f88ac", + "addresses": [ + "t1fvxYkVjkmYJFaSR4254YNa6kwxXe2wEQA" + ] + }, + { + "value": "9692075960", + "n": 1, + "spent": true, + "hex": "76a9142d64ab150e654be79bcdbdd5dbf207e15ae90d3688ac", + "addresses": [ + "t1N1d1XJqrNzorBZUJb4cUWitAC9B5RcUoX" + ] + } + ], + "blockHash": "00000009610f94d5f51aceb2db2e7fb1ea0ebcb8c6857be2927b24a69ed59fc3", + "blockHeight": 335702, + "confirmations": 261808, + "blockTime": 1557735070, + "value": "9804420960", + "valueIn": "9804425480", + "fees": "4520", + "hex": "0400008085202f8901a3965a18fde175950a9fb2cb22d076d68014959b1134eff8968342fa38689a2b010000006b483045022100b25ab6c1a994d0f99c874187427802f1a2e8ee3746784fd32fc358b522d5467402207ea330c77121f8b426d79f9778f16be2d3f625afc8fc851ae9b0aa7418c6a938012103c85acfe75a3bb4418d5f604aced599253cb639a417c9920103016ca79402a0defeffff7f02a83fb206000000001976a914f1f52994ca1ca3b41cb3a56de4f8b79f71297d5f88acb857b141020000001976a9142d64ab150e654be79bcdbdd5dbf207e15ae90d3688ac00000000000000000000000000000000000000" + }, + { + "txid": "2b9a6838fa428396f8ef34119b951480d676d022cbb29f0a9575e1fd185a96a3", + "version": 4, + "vin": [ + { + "txid": "62182822cdbd2b7ad71b16367ccf596d8544ee4450b2c35a5b41fae161d9dfbc", + "vout": 1, + "sequence": 2147483644, + "n": 0, + "addresses": [ + "t1SgcKEowio345qNu4WP7XTYiveQfqbCCAR" + ], + "value": "9999780000", + "hex": "483045022100fdda44566c57e863456a2b484b23d428862004373fd1ffbb58c259b21e7c6420022034def3b5529041c618beeb42b0df14c72ea1f809c69bda7a45015f85bfabfd03012102f7db5b974c39646b235a4cc595e02667e3a49f6abe85e7a6abf22d1175e507bf" + }, + { + "txid": "62182822cdbd2b7ad71b16367ccf596d8544ee4450b2c35a5b41fae161d9dfbc", + "sequence": 2147483645, + "n": 1, + "addresses": [ + "t1bhSBfm7skGsVTsviTWJXfnemYkALxu6DQ" + ], + "value": "100000", + "hex": "483045022100f629a4105fc6b570c2fd77ccf0c4fc8cf1736014636eab5f2371d07bf63162270220338d1a472f71a7422b22522a11a287e2df5447d91e37ad5061d37ca6d7ab6246012102ac2c1cf8d7d5544a561e24dc2248d9d902d23b05f07b2e5b956caa58c43e967c" + }, + { + "txid": "3a88dcfb1a9a463b4f84518dab55ac163b9268aac79892a8d78be871368413e2", + "sequence": 2147483646, + "n": 2, + "addresses": [ + "t1aq5qqeEHCDRiZqxD66Ep8rG4C4t5bzfxj" + ], + "value": "100000", + "hex": "473044022033835423ef187b91284117d613dda15d0ad207480cf5bd4b1fe0bfa6640a90a0022055dd8d1bcdd9a01b5ae62d12602201e62baf9211fe67c2bd0fa224d97dbca181012102372994d86b56a483bc44e3ee25f53c97da15cc62dd3d7ae7bf89a678beaa56dc" + } + ], + "vout": [ + { + "value": "195550000", + "n": 0, + "spent": true, + "hex": "76a914f1f52994ca1ca3b41cb3a56de4f8b79f71297d5f88ac", + "addresses": [ + "t1fvxYkVjkmYJFaSR4254YNa6kwxXe2wEQA" + ] + }, + { + "value": "9804425480", + "n": 1, + "spent": true, + "hex": "76a914d90a2013ffe67484c05734b43b67955b6204301e88ac", + "addresses": [ + "t1dfCmUsQAD73vkFSsHPC1ak9b7ven8P7pe" + ] + } + ], + "blockHash": "000000117a47ddada66503612c032fd535243e04a771f8f04165623462b414ce", + "blockHeight": 335698, + "confirmations": 261812, + "blockTime": 1557734698, + "value": "9999975480", + "valueIn": "9999980000", + "fees": "4520", + "hex": "0400008085202f8903bcdfd961e1fa415b5ac3b25044ee44856d59cf7c36161bd77a2bbdcd22281862010000006b483045022100fdda44566c57e863456a2b484b23d428862004373fd1ffbb58c259b21e7c6420022034def3b5529041c618beeb42b0df14c72ea1f809c69bda7a45015f85bfabfd03012102f7db5b974c39646b235a4cc595e02667e3a49f6abe85e7a6abf22d1175e507bffcffff7fbcdfd961e1fa415b5ac3b25044ee44856d59cf7c36161bd77a2bbdcd22281862000000006b483045022100f629a4105fc6b570c2fd77ccf0c4fc8cf1736014636eab5f2371d07bf63162270220338d1a472f71a7422b22522a11a287e2df5447d91e37ad5061d37ca6d7ab6246012102ac2c1cf8d7d5544a561e24dc2248d9d902d23b05f07b2e5b956caa58c43e967cfdffff7fe213843671e88bd7a89298c7aa68923b16ac55ab8d51844f3b469a1afbdc883a000000006a473044022033835423ef187b91284117d613dda15d0ad207480cf5bd4b1fe0bfa6640a90a0022055dd8d1bcdd9a01b5ae62d12602201e62baf9211fe67c2bd0fa224d97dbca181012102372994d86b56a483bc44e3ee25f53c97da15cc62dd3d7ae7bf89a678beaa56dcfeffff7f0230dba70b000000001976a914f1f52994ca1ca3b41cb3a56de4f8b79f71297d5f88ac08a96348020000001976a914d90a2013ffe67484c05734b43b67955b6204301e88ac00000000000000000000000000000000000000" + }, + { + "txid": "62182822cdbd2b7ad71b16367ccf596d8544ee4450b2c35a5b41fae161d9dfbc", + "version": 4, + "vin": [ + { + "txid": "3a88dcfb1a9a463b4f84518dab55ac163b9268aac79892a8d78be871368413e2", + "vout": 1, + "n": 0, + "addresses": [ + "t1Uw7KatAex6XFc9pJGQBHZyVZWHJXMbvcz" + ], + "value": "9999890000", + "hex": "483045022100d90f5d69666a57a174b0092a150f7d59057bf6bcb9ef8dcf0839026dc2d9fbd902200ca850dbb66e1a10354f568471e10fa84ceb08f0805bc71259c04575b43ace7a012103c54ccc3fb56214fb90806fab5ff6807714060d25a0e4e8b59043fa3036f9fc44" + } + ], + "vout": [ + { + "value": "100000", + "n": 0, + "spent": true, + "hex": "76a914c385e7d7a9acce2dd1b8b2ff5fad07a7ce3e9fee88ac", + "addresses": [ + "t1bhSBfm7skGsVTsviTWJXfnemYkALxu6DQ" + ] + }, + { + "value": "9999780000", + "n": 1, + "spent": true, + "hex": "76a91460a4d06bdc93a79772d8915d9283974b1b8e16cd88ac", + "addresses": [ + "t1SgcKEowio345qNu4WP7XTYiveQfqbCCAR" + ] + } + ], + "blockHash": "0000002b39c084a105209115a1286fea6c4bb42556bc7b32db31d82b1c68f739", + "blockHeight": 335465, + "confirmations": 262045, + "blockTime": 1557705637, + "value": "9999880000", + "valueIn": "9999890000", + "fees": "10000", + "hex": "0400008085202f8901e213843671e88bd7a89298c7aa68923b16ac55ab8d51844f3b469a1afbdc883a010000006b483045022100d90f5d69666a57a174b0092a150f7d59057bf6bcb9ef8dcf0839026dc2d9fbd902200ca850dbb66e1a10354f568471e10fa84ceb08f0805bc71259c04575b43ace7a012103c54ccc3fb56214fb90806fab5ff6807714060d25a0e4e8b59043fa3036f9fc440000000002a0860100000000001976a914c385e7d7a9acce2dd1b8b2ff5fad07a7ce3e9fee88aca0880854020000001976a91460a4d06bdc93a79772d8915d9283974b1b8e16cd88ac00000000000000000000000000000000000000" + }, + { + "txid": "3a88dcfb1a9a463b4f84518dab55ac163b9268aac79892a8d78be871368413e2", + "version": 4, + "vin": [ + { + "txid": "2d02c105ac454698edacd39e4ff848b9756aae6732a060f73a20adf403688b25", + "n": 0, + "addresses": [ + "t1PHmJzMdeErPQGL9WEavrVakYiCzxKXi9z" + ], + "value": "10000000000", + "hex": "47304402204b239697ced2ce8dc71bf5b58a1d8a13b0ac3c13799e0712454ffbfdc5b9568902205682bfa6f5b040f95e7931afeb64c67388b20566220ea0f4fafca66116a54313012103aa6d9069ced0b9b556ac6eb7468d5f15422b16903507e8651824c1b7e6e36644" + } + ], + "vout": [ + { + "value": "100000", + "n": 0, + "spent": true, + "hex": "76a914ba0020826df8b9c6666ebd22345e79fe569eb01b88ac", + "addresses": [ + "t1aq5qqeEHCDRiZqxD66Ep8rG4C4t5bzfxj" + ] + }, + { + "value": "9999890000", + "n": 1, + "spent": true, + "hex": "76a91479531a25ddc6e1196ebc275a6ca8211a6bbf077f88ac", + "addresses": [ + "t1Uw7KatAex6XFc9pJGQBHZyVZWHJXMbvcz" + ] + } + ], + "blockHash": "00000014c2f3537ad6b930e329f483f025b87e0528b7dce2a901043dde3eb5f6", + "blockHeight": 335455, + "confirmations": 262055, + "blockTime": 1557705029, + "value": "9999990000", + "valueIn": "10000000000", + "fees": "10000", + "hex": "0400008085202f8901258b6803f4ad203af760a03267ae6a75b948f84f9ed3aced984645ac05c1022d000000006a47304402204b239697ced2ce8dc71bf5b58a1d8a13b0ac3c13799e0712454ffbfdc5b9568902205682bfa6f5b040f95e7931afeb64c67388b20566220ea0f4fafca66116a54313012103aa6d9069ced0b9b556ac6eb7468d5f15422b16903507e8651824c1b7e6e366440000000002a0860100000000001976a914ba0020826df8b9c6666ebd22345e79fe569eb01b88ac50360a54020000001976a91479531a25ddc6e1196ebc275a6ca8211a6bbf077f88ac00000000000000000000000000000000000000" + }, + { + "txid": "2d02c105ac454698edacd39e4ff848b9756aae6732a060f73a20adf403688b25", + "version": 4, + "vin": [ + { + "txid": "870055cfff44ee7dd33e66b2b2246ee3f02b1dffd6c510e2e43e11da0f59bc15", + "sequence": 4294967295, + "n": 0, + "addresses": [ + "t1bJ2ot9ifKpiCn4FkhLJSDr1zxhB5x1AED" + ], + "value": "776500000000", + "hex": "4730440220438664cefb58d3b262b1acc91b02b7c2775385010f517f172e5d128b063c599d02203e1f6bc61e5a5538a384294e8bec7495bd167653cf040201ba651114565356fc012102fd6409055f25dcecf801a024a204b38d3d00ab6113f8c940000757070922b4ff" + } + ], + "vout": [ + { + "value": "10000000000", + "n": 0, + "spent": true, + "hex": "76a9143b6a6100245510218dc29b313b988df0628ab36388ac", + "addresses": [ + "t1PHmJzMdeErPQGL9WEavrVakYiCzxKXi9z" + ] + }, + { + "value": "766499996260", + "n": 1, + "spent": true, + "hex": "76a914bf18d3556e440187a15ff49f0bb3b16a3ded8b3d88ac", + "addresses": [ + "t1bJ2ot9ifKpiCn4FkhLJSDr1zxhB5x1AED" + ] + }, + { + "value": "0", + "n": 2, + "hex": "6a095a656c205465737420", + "addresses": [ + "OP_RETURN (Zel Test )" + ] + } + ], + "blockHash": "00000005b411a80eded51d3d934f947be0678d536007319e588d1b3af80e25c8", + "blockHeight": 335454, + "confirmations": 262056, + "blockTime": 1557704853, + "value": "776499996260", + "valueIn": "776500000000", + "fees": "3740", + "hex": "0400008085202f890115bc590fda113ee4e210c5d6ff1d2bf0e36e24b2b2663ed37dee44ffcf550087000000006a4730440220438664cefb58d3b262b1acc91b02b7c2775385010f517f172e5d128b063c599d02203e1f6bc61e5a5538a384294e8bec7495bd167653cf040201ba651114565356fc012102fd6409055f25dcecf801a024a204b38d3d00ab6113f8c940000757070922b4ffffffffff0300e40b54020000001976a9143b6a6100245510218dc29b313b988df0628ab36388ac64c2f576b20000001976a914bf18d3556e440187a15ff49f0bb3b16a3ded8b3d88ac00000000000000000b6a095a656c205465737420000000009d2005000000000000000000000000" + } + ], + "usedTokens": 30, + "tokens": [ + { + "type": "XPUBAddress", + "name": "t1fRA1dKnK7Z78ZhMqKP2VxdS9VfYeGvLYm", + "path": "m/44'/19167'/0'/0/11", + "transfers": 1, + "decimals": 8, + "balance": "1000000", + "totalReceived": "1000000", + "totalSent": "0" + }, + { + "type": "XPUBAddress", + "name": "t1KGukfFELYq5cYpCgieyes3dCuaxNMUcb1", + "path": "m/44'/19167'/0'/1/17", + "transfers": 1, + "decimals": 8, + "balance": "9208317640", + "totalReceived": "9208317640", + "totalSent": "0" + } + ] +} diff --git a/mock/ext-api-data/zilliqa-api_addresses_zil1l8ddxvejeam70qang54wnqkgtmlu5mwlgzy64z_txs.json b/mock/ext-api-data/zilliqa-api_addresses_zil1l8ddxvejeam70qang54wnqkgtmlu5mwlgzy64z_txs.json new file mode 100644 index 000000000..6b197bf28 --- /dev/null +++ b/mock/ext-api-data/zilliqa-api_addresses_zil1l8ddxvejeam70qang54wnqkgtmlu5mwlgzy64z_txs.json @@ -0,0 +1,30 @@ +[ + { + "hash": "0xa5d0e0cefd6f114e9659f15016f9f4a303a8367eb373beb6909ee44f7f39834d", + "blockHeight": 459052, + "from": "zil10lx2eurx5hexaca0lshdr75czr025cevqu83uz", + "to": "zil1l8ddxvejeam70qang54wnqkgtmlu5mwlgzy64z", + "value": "1000000000000", + "fee": "1000000000", + "timestamp": 1583384813191, + "signature": "0x00AF9733DF8FAEFA0FCC9BBAD21DB30A4815749C19CBFFA5A3BCE75A199E4C84FB4728CB946A2F043B8FCA338C8EEC26855CD7B88D8925E69F87CADF5D072343", + "direction": "in", + "nonce": 25, + "receiptSuccess": true, + "events": [] + }, + { + "hash": "0xe29a7e17402c0c067af4c285dedc79114fe62f23d39843c15756db4641f1a00d", + "blockHeight": 414452, + "from": "zil1l8ddxvejeam70qang54wnqkgtmlu5mwlgzy64z", + "to": "zil1l8ddxvejeam70qang54wnqkgtmlu5mwlgzy64z", + "value": "10000000000", + "fee": "1000000000", + "timestamp": 1580891803587, + "signature": "0xA5F2C86098A37149CDDD0884009FF1032714DDAC07B2831C87E1FEEB16B8D9B5EB5D310D042003B3AA27A31BE16FD62CD41E5B1F5108475FEB3EB5B8524DA3F4", + "direction": "self", + "nonce": 47, + "receiptSuccess": true, + "events": [] + } +] diff --git a/mock/mockserver/mock-healthcheck.json b/mock/mockserver/mock-healthcheck.json new file mode 100644 index 000000000..17741549f --- /dev/null +++ b/mock/mockserver/mock-healthcheck.json @@ -0,0 +1,4 @@ +{ + "status": true, + "msg": "Mockserver is alive" +} diff --git a/mock/mockserver/mockserver.go b/mock/mockserver/mockserver.go new file mode 100644 index 000000000..45a958dd1 --- /dev/null +++ b/mock/mockserver/mockserver.go @@ -0,0 +1,232 @@ +// Tool to update test data files. Real URLs are derived from test data file names and urlmap.yaml + +package main + +import ( + "errors" + "fmt" + "gopkg.in/yaml.v2" + "io/ioutil" + "log" + "net/http" + "net/url" + "strconv" + "strings" +) + +type TestDataEntry struct { + Filename string `yaml:"file"` + MockURL string `yaml:"mockURL"` + Method string `yaml:"method"` + ExtURL string `yaml:"extURL,omitempty"` + ReqFile string `yaml:"reqFile,omitempty"` + ReqField string `yaml:"reqField,omitempty"` +} + +type TestDataEntryInternal struct { + TestDataEntry + ParsedURL *url.URL `yaml:"-"` +} + +var files []TestDataEntryInternal + +// matchQueryParams compares HTTP GET params, checks that all provided params contain all parameters from the expected params, with the same values +func matchQueryParams(expected, actual string) bool { + if len(expected) == 0 { + return true + } + valuesExp, err := url.ParseQuery(expected) + if err != nil { + return false + } + valuesAct, err := url.ParseQuery(actual) + if err != nil { + return false + } + for vv := range valuesExp { + if _, ok := valuesAct[vv]; !ok { + // param vv from valuesExp is not present in valuesAct + return false + } + if valuesAct[vv][0] != valuesExp[vv][0] { + // param is present in both, but value is different + return false + } + } + // all present with same values + return true +} + +func readFileList(directory string) error { + filename := directory + "/datafiles.yaml" + yamlFile, err := ioutil.ReadFile(filename) + if err != nil { + log.Fatalf("Could not read index err %v file %v", err.Error(), filename) + return errors.New("Could not read index file, err " + err.Error() + " file " + filename) + } + files1 := []TestDataEntry{} + err = yaml.Unmarshal(yamlFile, &files1) + if err != nil { + log.Fatalf("Could not read index err %v file %v", err.Error(), filename) + return errors.New("Could not read index file, err " + err.Error() + " file " + filename) + } + + // some preprocessing + files = []TestDataEntryInternal{} + for _, e := range files1 { + parsedURL, err := url.Parse(e.MockURL) + if err == nil { + files = append(files, TestDataEntryInternal{e, parsedURL}) + } + } + fmt.Printf("Info about %v data files read\n", len(files)) + return nil +} + +func fieldValueFromJson(json, field string) (string, error) { + fieldIdx := strings.Index(json, field) + if fieldIdx < 0 { + return "", errors.New("Field not found") + } + rest := json[fieldIdx+len(field)+1:] + firstQuote := strings.Index(rest, "\"") + if fieldIdx < 0 { + return "", errors.New("1st quote not found") + } + rest = rest[firstQuote+1:] + secondQuote := strings.Index(rest, "\"") + if fieldIdx < 0 { + return "", errors.New("1st quote not found") + } + val := rest[:secondQuote] + return val, nil +} + +func preprocessRequestJson(j string) string { + j = strings.Replace(j, "\"", "", -1) + j = strings.Replace(j, "'", "", -1) + j = strings.Replace(j, " ", "", -1) + j = strings.Replace(j, "\n", "", -1) + j = strings.Replace(j, "\t", "", -1) + return j +} + +func matchRequestDataJson(actualReqData, expReqData, fieldDiscriminator string) error { + if len(fieldDiscriminator) > 0 { + valActual, err := fieldValueFromJson(actualReqData, fieldDiscriminator) + if err != nil { + return err + } + valExp, err := fieldValueFromJson(expReqData, fieldDiscriminator) + if err != nil { + return err + } + if valExp == valActual { + // OK, match + log.Println("Request data match based on discriminator field " + fieldDiscriminator + " val " + valActual) + return nil + } + return errors.New("Request data mismatch, discriminator field " + fieldDiscriminator + " actual " + valActual + " expected " + valExp) + } + // no field separator, full match + if actualReqData == expReqData { + return nil + } + v1r := preprocessRequestJson(actualReqData) + v2r := preprocessRequestJson(expReqData) + if v1r == v2r { + return nil + } + return errors.New("Mismatch in request data, actual '" + actualReqData + "' expected '" + expReqData + "'") +} + +func findFileForMockURL(mockURL, method, queryParams, requestBody string) (TestDataEntryInternal, error) { + lasterr := "" + for _, ff := range files { + if method != ff.Method { + continue + } + // simple check + if mockURL != ff.ParsedURL.Path { + continue + } + // check query params + if len(queryParams) > 0 { + if !matchQueryParams(ff.ParsedURL.RawQuery, queryParams) { + // mismatch in query, remember message, but continue trying + lasterr = "Mismatch in query params, expected " + ff.ParsedURL.RawQuery + ", actual " + queryParams + continue + } + } + // check request data + if len(requestBody) > 0 { + // read request file + reqFileB, err := ioutil.ReadFile(ff.ReqFile) + if err == nil { + expectedRequestData := string(reqFileB) + if err = matchRequestDataJson(requestBody, expectedRequestData, ff.ReqField); err != nil { + // mismatch in request data, remember message, but continue trying + lasterr = "Mismatch in request data " + err.Error() + continue + } + } + } + // all matches + return ff, nil + } + return TestDataEntryInternal{}, errors.New("Could not find matching entry for URL, " + lasterr) +} + +func requestHandlerIntern(w http.ResponseWriter, r *http.Request, method, body, basedir string) error { + mockURL := r.URL.Path + entry, err := findFileForMockURL(mockURL, method, r.URL.RawQuery, body) + if err != nil { + return err + } + // read and return response + b, err := ioutil.ReadFile(basedir + "/" + entry.Filename) + if err != nil { + return errors.New("Could not read data file for request") + } + fmt.Fprint(w, string(b)) + return nil +} + +func requestHandler(w http.ResponseWriter, r *http.Request, basedir string) { + // read body + body := "" + if r.Method == "POST" { + bodyByte, err := ioutil.ReadAll(r.Body) + if err == nil { + body = string(bodyByte) + } + } + err := requestHandlerIntern(w, r, r.Method, body, basedir) + if err == nil { + log.Println("Request ok", r.Method, r.URL.Path, r.URL.RawQuery, body) + return + } + // error + errorMsg := err.Error() + log.Println("ERROR for request:", errorMsg, r.Method, r.URL.Path, r.URL.RawQuery, body) + fmt.Fprintf(w, "{\"error\": \""+errorMsg+"\", \"url\": \""+r.URL.Path+"\"") +} + +func main() { + basedir := "." + if err := readFileList(basedir + "/mock"); err != nil { + log.Fatalf("Could not read data file list, err %v", err.Error()) + return + } + + http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) { + requestHandler(w, r, basedir) + }) + + port := 3347 + log.Printf("About to listen on port %v", port) + err := http.ListenAndServe(":"+strconv.Itoa(port), nil) + if err != nil { + log.Fatalf("Could not listen on port %v", port) + } +} diff --git a/mock/mockserver/mockserver_test.go b/mock/mockserver/mockserver_test.go new file mode 100644 index 000000000..93ab22ac0 --- /dev/null +++ b/mock/mockserver/mockserver_test.go @@ -0,0 +1,67 @@ +package main + +import ( + "testing" +) + +func TestMatchQueryParams(t *testing.T) { + tests := [][]string{ + { + "a=1&b=20", + "a=1&b=20", + "true", + }, + { + "a=1&b=20", + "a=1&b=20&c=3", + "true", + }, + { + "a=1&b=20", + "b=20&a=1", + "true", + }, + { + "a=1&b=20", + "a=1&b=500", + "false", + }, + { + "a=1&b=20", + "a=123&b=20", + "false", + }, + { + "a=1&b=20", + "a=1", + "false", + }, + { + "a=1&b=20", + "b=20", + "false", + }, + { + "", + "c=500", + "true", + }, + { + "", + "", + "true", + }, + } + for _, tt := range tests { + inputExpected := tt[0] + inputActual := tt[1] + expectedResult := true + if tt[2] == "false" { + expectedResult = false + } + result := matchQueryParams(inputExpected, inputActual) + if result != expectedResult { + t.Errorf("Did not match, inputExpected %v inputActual %v expectedResult %v", inputExpected, inputActual, expectedResult) + } + } +} diff --git a/observer/dispatcher.go b/observer/dispatcher.go deleted file mode 100644 index 7cb7b5ce2..000000000 --- a/observer/dispatcher.go +++ /dev/null @@ -1,54 +0,0 @@ -package observer - -import ( - "bytes" - "encoding/json" - "github.com/trustwallet/blockatlas/pkg/blockatlas" - "github.com/trustwallet/blockatlas/pkg/errors" - "github.com/trustwallet/blockatlas/pkg/logger" - "net/http" -) - -type Dispatcher struct { - Client http.Client -} - -type DispatchEvent struct { - Action blockatlas.TransactionType `json:"action"` - Result *blockatlas.Tx `json:"result"` -} - -func (d *Dispatcher) Run(events <-chan Event) { - for event := range events { - d.dispatch(event) - } -} - -func (d *Dispatcher) dispatch(event Event) { - action := DispatchEvent{ - Action: event.Tx.Type, - Result: event.Tx, - } - txJson, err := json.Marshal(action) - if err != nil { - logger.Panic(err) - } - - webhook := event.Subscription.Webhook - logParams := logger.Params{ - "webhook": webhook, - "coin": event.Subscription.Coin, - "txID": event.Tx.ID, - } - go d.postWebhook(webhook, txJson, logParams) - logger.Info("Dispatching webhooks...", logger.Params{"webhook": webhook}, logParams) -} - -func (d *Dispatcher) postWebhook(hook string, data []byte, logParams logger.Params) { - _, err := d.Client.Post(hook, "application/json", bytes.NewReader(data)) - if err != nil { - err = errors.E(err, errors.Params{"hook": hook}).PushToSentry() - logger.Error(err, "Failed to dispatch event", logger.Params{"webhook": hook}, logParams) - } - logger.Info("Webhook dispatched", logger.Params{"webhook": hook}, logParams) -} diff --git a/observer/observer.go b/observer/observer.go deleted file mode 100644 index 4c6956d86..000000000 --- a/observer/observer.go +++ /dev/null @@ -1,108 +0,0 @@ -package observer - -import ( - mapset "github.com/deckarep/golang-set" - "github.com/trustwallet/blockatlas/coin" - "github.com/trustwallet/blockatlas/pkg/blockatlas" - "github.com/trustwallet/blockatlas/platform/bitcoin" - "github.com/trustwallet/blockatlas/storage" -) - -type Event struct { - Subscription blockatlas.Subscription - Tx *blockatlas.Tx -} - -type Observer struct { - Storage storage.Addresses - Coin uint -} - -func (o *Observer) Execute(blocks <-chan *blockatlas.Block) <-chan Event { - events := make(chan Event) - go o.run(events, blocks) - return events -} - -func (o *Observer) run(events chan<- Event, blocks <-chan *blockatlas.Block) { - for block := range blocks { - o.processBlock(events, block) - } -} - -func (o *Observer) processBlock(events chan<- Event, block *blockatlas.Block) { - txMap := GetTxs(block) - if len(txMap) == 0 { - return - } - - // Build list of unique addresses - var addresses []string - for address := range txMap { - if len(address) == 0 { - continue - } - addresses = append(addresses, address) - } - - // Lookup subscriptions - subs, err := o.Storage.Lookup(o.Coin, addresses) - if err != nil || len(subs) == 0 { - return - } - for _, sub := range subs { - tx, ok := txMap[sub.Address] - if !ok { - continue - } - for _, tx := range tx.Txs() { - tx.Direction = getDirection(tx, sub.Address) - inferUtxoValue(&tx, sub.Address, o.Coin) - events <- Event{ - Subscription: sub, - Tx: &tx, - } - } - } -} - -func GetTxs(block *blockatlas.Block) map[string]*blockatlas.TxSet { - txMap := make(map[string]*blockatlas.TxSet) - for i := 0; i < len(block.Txs); i++ { - addresses := block.Txs[i].GetAddresses() - addresses = append(addresses, block.Txs[i].GetUtxoAddresses()...) - for _, address := range addresses { - if txMap[address] == nil { - txMap[address] = new(blockatlas.TxSet) - } - txMap[address].Add(&block.Txs[i]) - } - } - return txMap -} - -func getDirection(tx blockatlas.Tx, address string) blockatlas.Direction { - if len(tx.Inputs) > 0 && len(tx.Outputs) > 0 { - addressSet := mapset.NewSet(address) - return bitcoin.InferDirection(&tx, addressSet) - } - if address == tx.To { - if tx.From == tx.To { - return blockatlas.DirectionSelf - } - return blockatlas.DirectionIncoming - } - return blockatlas.DirectionOutgoing -} - -func inferUtxoValue(tx *blockatlas.Tx, address string, coinIndex uint) { - if len(tx.Inputs) > 0 && len(tx.Outputs) > 0 { - addressSet := mapset.NewSet(address) - value := bitcoin.InferValue(tx, tx.Direction, addressSet) - tx.Meta = blockatlas.Transfer{ - Value: value, - Symbol: coin.Coins[coinIndex].Symbol, - Decimals: coin.Coins[coinIndex].Decimals, - } - } -} diff --git a/observer/observer_test.go b/observer/observer_test.go deleted file mode 100644 index ce7b0055f..000000000 --- a/observer/observer_test.go +++ /dev/null @@ -1,154 +0,0 @@ -package observer - -import ( - "github.com/trustwallet/blockatlas/coin" - "github.com/trustwallet/blockatlas/pkg/blockatlas" - "testing" -) - -func Test_getDirection(t *testing.T) { - type args struct { - tx blockatlas.Tx - address string - } - tests := []struct { - name string - args args - want blockatlas.Direction - }{ - {"Test Direction Self", - args{ - blockatlas.Tx{ - From: "0xfc10cab6a50a1ab10c56983c80cc82afc6559cf1", To: "0xfc10cab6a50a1ab10c56983c80cc82afc6559cf1"}, - "0xfc10cab6a50a1ab10c56983c80cc82afc6559cf1"}, blockatlas.DirectionSelf, - }, - {"Test Direction Outgoing", - args{ - blockatlas.Tx{ - From: "0x5574Cd97432cEd0D7Caf58ac3c4fEDB2061C98fB", To: "0x74c8199372c584DAB8b14c519bc8BC8C622F37b7"}, - "0x5574Cd97432cEd0D7Caf58ac3c4fEDB2061C98fB"}, blockatlas.DirectionOutgoing, - }, - {"Test Direction Incoming", - args{ - blockatlas.Tx{ - From: "0x74c8199372c584DAB8b14c519bc8BC8C622F37b7", To: "0xfc10cab6a50a1ab10c56983c80cc82afc6559cf1"}, - "0xfc10cab6a50a1ab10c56983c80cc82afc6559cf1"}, blockatlas.DirectionIncoming, - }, - {"Test UTXO Direction Self", - args{ - blockatlas.Tx{ - Outputs: []blockatlas.TxOutput{ - {"DAzruJfMBhd1vcQ13gVVyqb2g1vSEo2d5S", "72934112534"}, - {"DAzruJfMBhd1vcQ13gVVyqb2g1vSEo2d5S", "500000000"}, - }, - Inputs: []blockatlas.TxOutput{ - {"DAzruJfMBhd1vcQ13gVVyqb2g1vSEo2d5S", "73196112534"}, - }, - }, "DAzruJfMBhd1vcQ13gVVyqb2g1vSEo2d5S", - }, blockatlas.DirectionSelf, - }, - {"Test UTXO Direction Outgoing", - args{ - blockatlas.Tx{ - Outputs: []blockatlas.TxOutput{ - {"3BMEXVshYmWqc8qcQLyBQPgRgAPfogWdJ4", "4471835"}, - {"324Wmkkbr9uT9xnLUqFvCA3ntqqpqEZQDp", "1600000"}, - {"32yRH5tNnFtAXE844wNrHN7Bf3SBcb3Uhd", "1262899630"}, - }, - Inputs: []blockatlas.TxOutput{ - {"32yRH5tNnFtAXE844wNrHN7Bf3SBcb3Uhd", "1268998877"}, - }, - }, "32yRH5tNnFtAXE844wNrHN7Bf3SBcb3Uhd", - }, blockatlas.DirectionOutgoing, - }, - {"Test UTXO Direction Incoming", - args{ - blockatlas.Tx{ - Outputs: []blockatlas.TxOutput{ - {"3BMEXVshYmWqc8qcQLyBQPgRgAPfogWdJ4", "4471835"}, - {"324Wmkkbr9uT9xnLUqFvCA3ntqqpqEZQDp", "1600000"}, - {"32yRH5tNnFtAXE844wNrHN7Bf3SBcb3Uhd", "1262899630"}, - }, - Inputs: []blockatlas.TxOutput{ - {"32yRH5tNnFtAXE844wNrHN7Bf3SBcb3Uhd", "1268998877"}, - }, - }, "3BMEXVshYmWqc8qcQLyBQPgRgAPfogWdJ4", - }, blockatlas.DirectionIncoming, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - if got := getDirection(tt.args.tx, tt.args.address); got != tt.want { - t.Errorf("getDirection() = %v, want %v", got, tt.want) - } - }) - } -} - -func Test_inferUtxoValue(t *testing.T) { - type args struct { - tx blockatlas.Tx - address string - coinIndex uint - } - tests := []struct { - name string - args args - wantAmount blockatlas.Amount - }{ - {"Test UTXO Direction Self", - args{ - blockatlas.Tx{ - Outputs: []blockatlas.TxOutput{ - {"DAzruJfMBhd1vcQ13gVVyqb2g1vSEo2d5S", "72934112534"}, - {"DAzruJfMBhd1vcQ13gVVyqb2g1vSEo2d5S", "500000000"}, - }, - Inputs: []blockatlas.TxOutput{ - {"DAzruJfMBhd1vcQ13gVVyqb2g1vSEo2d5S", "73196112534"}, - }, - }, "DAzruJfMBhd1vcQ13gVVyqb2g1vSEo2d5S", 3, - }, blockatlas.Amount("72934112534"), - }, - {"Test UTXO Direction Outgoing", - args{ - blockatlas.Tx{ - Outputs: []blockatlas.TxOutput{ - {"3BMEXVshYmWqc8qcQLyBQPgRgAPfogWdJ4", "4471835"}, - {"324Wmkkbr9uT9xnLUqFvCA3ntqqpqEZQDp", "1600000"}, - {"32yRH5tNnFtAXE844wNrHN7Bf3SBcb3Uhd", "1262899630"}, - }, - Inputs: []blockatlas.TxOutput{ - {"32yRH5tNnFtAXE844wNrHN7Bf3SBcb3Uhd", "1268998877"}, - }, - }, "32yRH5tNnFtAXE844wNrHN7Bf3SBcb3Uhd", 0, - }, blockatlas.Amount("4471835"), - }, - {"Test UTXO Direction Incoming", - args{ - blockatlas.Tx{ - Outputs: []blockatlas.TxOutput{ - {"3BMEXVshYmWqc8qcQLyBQPgRgAPfogWdJ4", "4471835"}, - {"324Wmkkbr9uT9xnLUqFvCA3ntqqpqEZQDp", "1600000"}, - {"32yRH5tNnFtAXE844wNrHN7Bf3SBcb3Uhd", "1262899630"}, - }, - Inputs: []blockatlas.TxOutput{ - {"32yRH5tNnFtAXE844wNrHN7Bf3SBcb3Uhd", "1268998877"}, - }, - }, "3BMEXVshYmWqc8qcQLyBQPgRgAPfogWdJ4", 0, - }, blockatlas.Amount("4471835"), - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - expect := blockatlas.Transfer{ - Value: tt.wantAmount, - Symbol: coin.Coins[tt.args.coinIndex].Symbol, - Decimals: coin.Coins[tt.args.coinIndex].Decimals, - } - tt.args.tx.Direction = getDirection(tt.args.tx, tt.args.address) - if inferUtxoValue(&tt.args.tx, tt.args.address, tt.args.coinIndex); tt.args.tx.Meta != expect { - t.Errorf("inferUtxoValue() = %v, want %v", tt.args.tx.Meta, expect) - } - }) - } -} diff --git a/observer/retry.go b/observer/retry.go deleted file mode 100644 index 7d3b685a8..000000000 --- a/observer/retry.go +++ /dev/null @@ -1,40 +0,0 @@ -package observer - -import ( - "github.com/trustwallet/blockatlas/pkg/blockatlas" - "github.com/trustwallet/blockatlas/pkg/logger" - "math/rand" - "time" -) - -type GetBlockByNumber func(num int64) (*blockatlas.Block, error) - -type stop struct { - error -} - -func retry(attempts int, sleep time.Duration, f GetBlockByNumber, n int64) (*blockatlas.Block, error) { - r, err := f(n) - if err != nil { - if s, ok := err.(stop); ok { - return nil, s.error - } - if attempts--; attempts > 0 { - // Add some randomness to prevent creating a Thundering Herd - jitter := time.Duration(rand.Int63n(int64(sleep))) - sleep = sleep + jitter/2 - - logger.Info("GetBlockByNumber retry", - logger.Params{ - "number": n, - "attempts": attempts, - "sleep": sleep.String(), - }, - ) - - time.Sleep(sleep) - return retry(attempts, sleep*2, f, n) - } - } - return r, err -} diff --git a/observer/retry_test.go b/observer/retry_test.go deleted file mode 100644 index 7b4333230..000000000 --- a/observer/retry_test.go +++ /dev/null @@ -1,43 +0,0 @@ -package observer - -import ( - "errors" - "github.com/trustwallet/blockatlas/pkg/blockatlas" - "testing" - "time" -) - -func getBlock(num int64) (*blockatlas.Block, error) { - if num == 0 { - return nil, errors.New("teste") - } - return &blockatlas.Block{}, nil -} - -func TestRetry(t *testing.T) { - block, err := retry(3, time.Second*1, getBlock, 1) - if err != nil { - t.Error(err) - } - - if block == nil { - t.Error("block is nil") - } -} - -func TestRetryError(t *testing.T) { - now := time.Now() - block, err := retry(3, time.Second*1, getBlock, 0) - elapsed := time.Since(now) - if err == nil { - t.Error("retry method need fail") - } - - if block != nil { - t.Error("block object need be nil") - } - - if elapsed > time.Second*6 { - t.Error("Thundering Herd prevent doesn't work") - } -} diff --git a/observer/stream.go b/observer/stream.go deleted file mode 100644 index b86c95af5..000000000 --- a/observer/stream.go +++ /dev/null @@ -1,107 +0,0 @@ -package observer - -import ( - "context" - "github.com/spf13/viper" - "github.com/trustwallet/blockatlas/pkg/blockatlas" - "github.com/trustwallet/blockatlas/pkg/logger" - "github.com/trustwallet/blockatlas/pkg/semaphore" - "github.com/trustwallet/blockatlas/storage" - "sync" - "sync/atomic" - "time" -) - -type Stream struct { - BlockAPI blockatlas.BlockAPI - Tracker storage.Tracker - PollInterval time.Duration - BacklogCount int - coin uint - logParams logger.Params - - // Concurrency - blockNumber int64 - semaphore *semaphore.Semaphore - wg sync.WaitGroup -} - -func (s *Stream) Execute(ctx context.Context) <-chan *blockatlas.Block { - cn := s.BlockAPI.Coin() - s.coin = cn.ID - s.logParams = logger.Params{"platform": cn.Handle} - conns := viper.GetInt("observer.stream_conns") - if conns == 0 { - logger.Fatal("observer.stream_conns is 0") - } - s.semaphore = semaphore.NewSemaphore(conns) - c := make(chan *blockatlas.Block) - go s.run(ctx, c) - return c -} - -func (s *Stream) run(ctx context.Context, c chan<- *blockatlas.Block) { - ticker := time.NewTicker(s.PollInterval) - for { - select { - case <-ctx.Done(): - ticker.Stop() - close(c) - return - case <-ticker.C: - s.load(c) - } - } -} - -func (s *Stream) load(c chan<- *blockatlas.Block) { - lastHeight, err := s.Tracker.GetBlockNumber(s.coin) - if err != nil { - logger.Error(err, "Polling failed: tracker didn't return last known block number", s.logParams) - return - } - - height, err := s.BlockAPI.CurrentBlockNumber() - height -= s.BlockAPI.Coin().MinConfirmations - if err != nil { - logger.Error(err, "Polling failed: source didn't return chain head number", s.logParams) - return - } - - if height-lastHeight > int64(s.BacklogCount) { - lastHeight = height - int64(s.BacklogCount) - } - backLogMax := viper.GetInt64("observer.backlog_max_blocks") - if height-lastHeight > backLogMax { - lastHeight = height - backLogMax - } - - atomic.StoreInt64(&s.blockNumber, lastHeight) - for i := lastHeight + 1; i <= height; i++ { - s.wg.Add(1) - go s.loadBlock(c, i) - } - s.wg.Wait() -} - -func (s *Stream) loadBlock(c chan<- *blockatlas.Block, num int64) { - defer s.wg.Done() - s.semaphore.Acquire() - defer s.semaphore.Release() - - block, err := retry(5, time.Second*5, s.BlockAPI.GetBlockByNumber, num) - if err != nil { - logger.Error(err, "Polling failed: could not get block", s.logParams, logger.Params{"block": num}) - return - } - c <- block - logger.Info(err, "Got new block", s.logParams, logger.Params{"block": num, "txs": len(block.Txs)}) - - // Not strictly correct nor avoids race conditions - // But good enough - newNum := atomic.AddInt64(&s.blockNumber, 1) - err = s.Tracker.SetBlockNumber(s.coin, newNum) - if err != nil { - logger.Error(err, "SetBlockNumber failed", s.logParams, logger.Params{"block": num, "coin": s.coin}) - } -} diff --git a/pkg/address/address.go b/pkg/address/address.go deleted file mode 100644 index 05c3260bc..000000000 --- a/pkg/address/address.go +++ /dev/null @@ -1,39 +0,0 @@ -package address - -import ( - "golang.org/x/crypto/sha3" - "strings" -) - -const ethereumAddressLength = 40 - -// Decode decodes a hex string with 0x prefix. -func Remove0x(input string) string { - if strings.HasPrefix(input, "0x") { - return input[2:] - } - return input -} - -// Hex returns an EIP55-compliant hex string representation of the address. -func EIP55Checksum(unchecksummed string) string { - v := []byte(Remove0x(strings.ToLower(unchecksummed))) - sha := sha3.NewLegacyKeccak256() - sha.Write(v) - hash := sha.Sum(nil) - - result := v - for i := 0; i < len(result); i++ { - hashByte := hash[i/2] - if i%2 == 0 { - hashByte = hashByte >> 4 - } else { - hashByte &= 0xf - } - if result[i] > '9' && hashByte > 7 { - result[i] -= 32 - } - } - val := string(result) - return "0x" + val -} diff --git a/pkg/address/address_test.go b/pkg/address/address_test.go deleted file mode 100644 index cdbbd41e9..000000000 --- a/pkg/address/address_test.go +++ /dev/null @@ -1,49 +0,0 @@ -package address - -import ( - "testing" -) - -func TestChecksum(t *testing.T) { - tests := []struct { - name string - unchecksummed string - want string - }{ - {"test checksum 1", "checktest", "0xChecKTeSt"}, - {"test checksum 2", "trustwallet", "0xtrUstWaLlET"}, - {"test checksum number", "16345785d8a0000", "0x16345785d8A0000"}, - {"test checksum hex", "fffdefefed", "0xFfFDEfeFeD"}, - {"test checksum 3", "0x0000000000000000003731342d4f4e452d354639", "0x0000000000000000003731342d4f4E452d354639"}, - {"test checksum 4", "0000000000000000003731342d4f4e452d354639", "0x0000000000000000003731342d4f4E452d354639"}, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - if got := EIP55Checksum(tt.unchecksummed); got != tt.want { - t.Errorf("EIP55Checksum() = %v, want %v", got, tt.want) - } - }) - } -} - -func TestRemove0x(t *testing.T) { - tests := []struct { - name string - input string - want string - }{ - {"remove 0x from addres", "0x158079ee67fce2f58472a96584a73c7ab9ac95c1", "158079ee67fce2f58472a96584a73c7ab9ac95c1"}, - {"remove 0x from hash", "0x230798fe22abff459b004675bf827a4089326a296fa4165d0c2ad27688e03e0c", "230798fe22abff459b004675bf827a4089326a296fa4165d0c2ad27688e03e0c"}, - {"remove 0x hex value", "0xfffdefefed", "fffdefefed"}, - {"remove 0x hex number", "0x16345785d8a0000", "16345785d8a0000"}, - {"remove hex without 0x", "trustwallet", "trustwallet"}, - {"remove hex number without 0x", "16345785d8a0000", "16345785d8a0000"}, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - if got := Remove0x(tt.input); got != tt.want { - t.Errorf("Remove0x() = %v, want %v", got, tt.want) - } - }) - } -} diff --git a/pkg/blockatlas/api.go b/pkg/blockatlas/api.go deleted file mode 100644 index f1ae1cf21..000000000 --- a/pkg/blockatlas/api.go +++ /dev/null @@ -1,78 +0,0 @@ -package blockatlas - -import ( - "github.com/gin-gonic/gin" - "github.com/trustwallet/blockatlas/coin" -) - -// Initer is a service that can be initialized once -type Initer interface { - Init() error -} - -// Platform can be used to access a crypto service -type Platform interface { - Initer - Coin() coin.Coin -} - -// TxAPI provides transaction lookups -type TxAPI interface { - Platform - GetTxsByAddress(address string) (TxPage, error) -} - -// TokenTxAPI provides token transaction lookups -type TokenTxAPI interface { - Platform - GetTokenTxsByAddress(address, token string) (TxPage, error) -} - -// TokenAPI provides token lookups -type TokenAPI interface { - Platform - GetTokenListByAddress(address string) (TokenPage, error) -} - -// BlockAPI provides block information and lookups -type BlockAPI interface { - Platform - CurrentBlockNumber() (int64, error) - GetBlockByNumber(num int64) (*Block, error) -} - -// AddressAPI provides address information -type AddressAPI interface { - Platform - GetAddressesFromXpub(xpub string) ([]string, error) -} - -// StakingAPI provides staking information -type StakeAPI interface { - Platform - UndelegatedBalance(address string) (string, error) - GetDetails() StakingDetails - GetValidators() (ValidatorPage, error) - GetDelegations(address string) (DelegationsPage, error) -} - -type CollectionAPI interface { - Platform - GetCollections(owner string) (CollectionPage, error) - GetCollectibles(owner, collectibleID string) (CollectiblePage, error) - - //TODO: remove once most of the clients will be updated (deadline: March 17th) - OldGetCollections(owner string) (CollectionPage, error) - OldGetCollectibles(owner, collectibleID string) (CollectiblePage, error) -} - -// CustomAPI provides custom HTTP routes -type CustomAPI interface { - Platform - RegisterRoutes(router gin.IRouter) -} - -type NamingServiceAPI interface { - Platform - Lookup(coins []uint64, name string) ([]Resolved, error) -} diff --git a/pkg/blockatlas/block.go b/pkg/blockatlas/block.go deleted file mode 100644 index e11e8e2d3..000000000 --- a/pkg/blockatlas/block.go +++ /dev/null @@ -1,13 +0,0 @@ -package blockatlas - -type Block struct { - Number int64 `json:"number"` - ID string `json:"id,omitempty"` - Txs []Tx `json:"txs"` -} - -type Subscription struct { - Coin uint `json:"coin"` - Address string `json:"address"` - Webhook string `json:"webhook"` -} diff --git a/pkg/blockatlas/client.go b/pkg/blockatlas/client.go deleted file mode 100644 index 8de11cfca..000000000 --- a/pkg/blockatlas/client.go +++ /dev/null @@ -1,105 +0,0 @@ -package blockatlas - -import ( - "bytes" - "encoding/json" - "fmt" - "github.com/trustwallet/blockatlas/pkg/errors" - "github.com/trustwallet/blockatlas/pkg/metrics" - "io" - "io/ioutil" - "net/http" - "net/url" - "strings" - "time" -) - -type Request struct { - BaseUrl string - Headers map[string]string - HttpClient *http.Client - ErrorHandler func(res *http.Response, uri string) error -} - -func InitClient(baseUrl string) Request { - return Request{ - Headers: make(map[string]string), - HttpClient: DefaultClient, - ErrorHandler: DefaultErrorHandler, - BaseUrl: baseUrl, - } -} - -var DefaultClient = &http.Client{ - Timeout: time.Second * 15, -} - -var DefaultErrorHandler = func(res *http.Response, uri string) error { - return nil -} - -func (r *Request) Get(result interface{}, path string, query url.Values) error { - var queryStr = "" - if query != nil { - queryStr = query.Encode() - } - uri := strings.Join([]string{r.GetBase(path), queryStr}, "?") - return r.Execute("GET", uri, nil, result) -} - -func (r *Request) Post(result interface{}, path string, body interface{}) error { - buf, err := GetBody(body) - if err != nil { - return err - } - uri := r.GetBase(path) - return r.Execute("POST", uri, buf, result) -} - -func (r *Request) Execute(method string, url string, body io.Reader, result interface{}) error { - start := time.Now() - req, err := http.NewRequest(method, url, body) - if err != nil { - return errors.E(err, errors.TypePlatformRequest, errors.Params{"url": url, "method": method}).PushToSentry() - } - - for key, value := range r.Headers { - req.Header.Set(key, value) - } - - res, err := r.HttpClient.Do(req) - if err != nil { - return errors.E(err, errors.TypePlatformRequest, errors.Params{"url": url, "method": method}).PushToSentry() - } - go metrics.GetMetrics(res.Status, url, method, start) - - err = r.ErrorHandler(res, url) - if err != nil { - return errors.E(err, errors.TypePlatformError, errors.Params{"url": url, "method": method}).PushToSentry() - } - defer res.Body.Close() - b, err := ioutil.ReadAll(res.Body) - if err != nil { - return errors.E(err, errors.TypePlatformUnmarshal, errors.Params{"url": url, "method": method}).PushToSentry() - } - err = json.Unmarshal(b, result) - if err != nil { - return errors.E(err, errors.TypePlatformUnmarshal, errors.Params{"url": url, "method": method}).PushToSentry() - } - return err -} - -func (r *Request) GetBase(path string) string { - if path == "" { - return fmt.Sprintf("%s", r.BaseUrl) - } - return fmt.Sprintf("%s/%s", r.BaseUrl, path) -} - -func GetBody(body interface{}) (buf io.ReadWriter, err error) { - if body != nil { - buf = new(bytes.Buffer) - err = json.NewEncoder(buf).Encode(body) - } - return -} diff --git a/pkg/blockatlas/clientcache.go b/pkg/blockatlas/clientcache.go deleted file mode 100644 index bd6f7555a..000000000 --- a/pkg/blockatlas/clientcache.go +++ /dev/null @@ -1,90 +0,0 @@ -package blockatlas - -import ( - "crypto/sha1" - "encoding/base64" - "encoding/json" - "github.com/patrickmn/go-cache" - "github.com/trustwallet/blockatlas/pkg/errors" - "github.com/trustwallet/blockatlas/pkg/logger" - "github.com/trustwallet/blockatlas/pkg/storage/util" - "net/url" - "strings" - "time" -) - -var ( - memoryCache *cache.Cache -) - -func init() { - memoryCache = cache.New(5*time.Minute, 5*time.Minute) -} - -func (r *Request) PostWithCache(result interface{}, path string, body interface{}, cache time.Duration) error { - key := r.generateKey(path, nil, body) - err := getCache(key, result) - if err == nil { - return nil - } - - err = r.Post(result, path, body) - if err != nil { - return err - } - setCache(key, result, cache) - return err -} - -func (r *Request) GetWithCache(result interface{}, path string, query url.Values, cache time.Duration) error { - key := r.generateKey(path, query, nil) - err := getCache(key, result) - if err == nil { - return nil - } - - err = r.Get(result, path, query) - if err != nil { - return err - } - setCache(key, result, cache) - return err -} - -func getCache(key string, value interface{}) error { - cache, ok := memoryCache.Get(key) - if !ok { - return errors.E("validator cache: invalid cache key") - } - r, ok := cache.([]byte) - if !ok { - return errors.E("validator cache: failed to cast cache to bytes") - } - err := json.Unmarshal(r, value) - if err != nil { - return errors.E(err, util.ErrNotFound).PushToSentry() - } - return nil -} - -func setCache(key string, value interface{}, duration time.Duration) { - b, err := json.Marshal(value) - if err != nil { - logger.Error(errors.E(err, "client cache cannot marshal cache object").PushToSentry()) - } - memoryCache.Set(key, b, duration) -} - -func (r *Request) generateKey(path string, query url.Values, body interface{}) string { - var queryStr = "" - if query != nil { - queryStr = query.Encode() - } - url := strings.Join([]string{r.GetBase(path), queryStr}, "?") - var b []byte - if body != nil { - b, _ = json.Marshal(body) - } - hash := sha1.Sum(append([]byte(url), b...)) - return base64.URLEncoding.EncodeToString(hash[:]) -} diff --git a/pkg/blockatlas/clientcache_test.go b/pkg/blockatlas/clientcache_test.go deleted file mode 100644 index 8cf455cd7..000000000 --- a/pkg/blockatlas/clientcache_test.go +++ /dev/null @@ -1,75 +0,0 @@ -package blockatlas - -import ( - "net/url" - "testing" -) - -func TestRequest_generateKey(t *testing.T) { - type args struct { - baseUrl string - path string - query url.Values - body interface{} - } - tests := []struct { - name string - args args - want string - }{ - { - name: "test cosmos key without params", - args: args{ - baseUrl: "https://raw.githubusercontent.com/trustwallet/assets/master/blockchains/cosmos", - path: "validators/list.json", - }, - want: "ukpgy7t9m_vLHvyQL82smBoTov4=", - }, - { - name: "test cosmos key with params", - args: args{ - baseUrl: "https://raw.githubusercontent.com/trustwallet/assets/master/blockchains/cosmos", - path: "validators/list.json", - query: url.Values{"address": {"TQZskDJJRGAHifeKoQ7wLey42iGvwp3"}, "visible": {"false"}}, - }, - want: "jkkaXhzkelj5l3WE_B57Q1IY0Qo=", - }, - {name: "test tron key without params ", - args: args{ - baseUrl: "https://api.trongrid.io", - path: "wallet/getaccount", - }, - want: "PIoOx2azFYta4KMAtt0lttrqquM=", - }, - {name: "test tron key with params 1", - args: args{ - baseUrl: "https://api.trongrid.io", - path: "wallet/getaccount", - body: struct { - Address string `json:"address"` - Visible bool `json:"visible"` - }{Address: "TQZskDJJRGAHifeKoQ7wLC4QDyB2iGvwp2", Visible: true}, - }, - want: "h0noiR5a4M_RGQBH7805sgGl_HE=", - }, - {name: "test tron key with params 2", - args: args{ - baseUrl: "https://api.trongrid.io", - path: "wallet/getaccount", - body: struct { - Address string `json:"address"` - Visible bool `json:"visible"` - }{Address: "TQZskDJJRGAHifeKoQ7wLey42iGvwp3", Visible: false}, - }, - want: "Admv3wAXHkirPi4SaIXimDgLbow=", - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - r := &Request{BaseUrl: tt.args.baseUrl} - if got := r.generateKey(tt.args.path, tt.args.query, tt.args.body); got != tt.want { - t.Errorf("generateKey() = %v, want %v", got, tt.want) - } - }) - } -} diff --git a/pkg/blockatlas/collectible.go b/pkg/blockatlas/collectible.go new file mode 100644 index 000000000..4d478a4c4 --- /dev/null +++ b/pkg/blockatlas/collectible.go @@ -0,0 +1,7 @@ +package blockatlas + +import "fmt" + +func GenCollectibleId(contract, tokenId string) string { + return fmt.Sprintf("%s-%s", contract, tokenId) +} diff --git a/pkg/blockatlas/collectibles.go b/pkg/blockatlas/collectibles.go deleted file mode 100644 index ac8cacb9c..000000000 --- a/pkg/blockatlas/collectibles.go +++ /dev/null @@ -1,38 +0,0 @@ -package blockatlas - -type Collection struct { - Id string `json:"id"` - Name string `json:"name"` - Symbol string `json:"symbol"` - Slug string `json:"slug"` - ImageUrl string `json:"image_url"` - Description string `json:"description"` - ExternalLink string `json:"external_link"` - Total int `json:"total"` - CategoryAddress string `json:"category_address"` - Address string `json:"address"` - Version string `json:"nft_version"` - Coin uint `json:"coin"` - Type string `json:"type"` -} - -type CollectionPage []Collection - -type Collectible struct { - ID string `json:"id"` - CollectionID string `json:"collection_id"` - TokenID string `json:"token_id"` - CategoryContract string `json:"category_contract"` - // Deprecated: for support old client, ContractAddress eq CollectionID - ContractAddress string `json:"contract_address"` - Category string `json:"category"` - ImageUrl string `json:"image_url"` - ExternalLink string `json:"external_link"` - ProviderLink string `json:"provider_link"` - Type string `json:"type"` - Description string `json:"description"` - Coin uint `json:"coin"` - Name string `json:"name"` -} - -type CollectiblePage []Collectible diff --git a/pkg/blockatlas/errors.go b/pkg/blockatlas/errors.go index 6eafa7d3b..46dd6d354 100644 --- a/pkg/blockatlas/errors.go +++ b/pkg/blockatlas/errors.go @@ -2,11 +2,16 @@ package blockatlas import "errors" -// ErrSourceConn signals that the connection to the source API failed -var ErrSourceConn = errors.New("connection to servers failed") +var ( + // ErrSourceConn signals that the connection to the source API failed + ErrSourceConn = errors.New("connection to servers failed") -// ErrInvalidAddr signals that the requested address is invalid -var ErrInvalidAddr = errors.New("invalid address") + // ErrInvalidAddr signals that the requested address is invalid + ErrInvalidAddr = errors.New("invalid address") -// ErrNotFound signals that the resource has not been found -var ErrNotFound = errors.New("not found") + // ErrNotFound signals that the resource has not been found + ErrNotFound = errors.New("not found") + + // ErrInvalidKey signals that the requested key is invalid + ErrInvalidKey = errors.New("invalid key") +) diff --git a/pkg/blockatlas/jsonrpc.go b/pkg/blockatlas/jsonrpc.go deleted file mode 100644 index 81f5e0618..000000000 --- a/pkg/blockatlas/jsonrpc.go +++ /dev/null @@ -1,58 +0,0 @@ -package blockatlas - -import ( - "encoding/json" - "github.com/trustwallet/blockatlas/pkg/errors" -) - -const ( - JsonRpcVersion = "2.0" -) - -type RpcRequest struct { - JsonRpc string `json:"jsonrpc"` - Method string `json:"method"` - Params interface{} `json:"params,omitempty"` - Id string `json:"id,omitempty"` -} - -type RpcResponse struct { - JsonRpc string `json:"jsonrpc"` - Error *RpcError `json:"error,omitempty"` - Result interface{} `json:"result,omitempty"` - Id string `json:"id,omitempty"` -} - -type RpcError struct { - Code int `json:"code"` - Message string `json:"message"` -} - -func (r *RpcResponse) GetObject(toType interface{}) error { - js, err := json.Marshal(r.Result) - if err != nil { - return errors.E(err, "json-rpc GetObject Marshal error", errors.Params{"obj": toType}).PushToSentry() - } - - err = json.Unmarshal(js, toType) - if err != nil { - return errors.E(err, "json-rpc GetObject Unmarshal error", errors.Params{"obj": toType, "string": string(js)}).PushToSentry() - } - return nil -} - -func (r *Request) RpcCall(result interface{}, method string, params interface{}) error { - req := &RpcRequest{JsonRpc: JsonRpcVersion, Method: method, Params: params, Id: method} - var resp *RpcResponse - err := r.Post(&resp, "", req) - if err != nil { - return err - } - if resp.Error != nil { - return errors.E("RPC Call error", errors.Params{ - "method": method, - "error_code": resp.Error.Code, - "error_message": resp.Error.Message}).PushToSentry() - } - return resp.GetObject(result) -} diff --git a/pkg/blockatlas/marketdata.go b/pkg/blockatlas/marketdata.go deleted file mode 100644 index 7f68b2f41..000000000 --- a/pkg/blockatlas/marketdata.go +++ /dev/null @@ -1,91 +0,0 @@ -package blockatlas - -import ( - "math/big" - "time" -) - -const ( - TypeCoin CoinType = "coin" - TypeToken CoinType = "token" - - DefaultCurrency = "USD" -) - -type CoinType string - -type TickerResponse struct { - Currency string `json:"currency"` - Docs Tickers `json:"docs"` -} - -type Ticker struct { - Coin uint `json:"coin"` - CoinName string `json:"coin_name,omitempty"` - TokenId string `json:"token_id,omitempty"` - CoinType CoinType `json:"type,omitempty"` - Price TickerPrice `json:"price,omitempty"` - LastUpdate time.Time `json:"last_update,omitempty"` - Error string `json:"error,omitempty"` -} - -type ChartData struct { - Prices []ChartPrice `json:"prices,omitempty"` - Error string `json:"error,omitempty"` -} - -type ChartCoinInfo struct { - Vol24 float64 `json:"volume_24"` - MarketCap float64 `json:"market_cap"` - CirculatingSupply float64 `json:"circulating_supply"` - TotalSupply float64 `json:"total_supply"` -} - -type ChartPrice struct { - Price float64 `json:"price"` - Date int64 `json:"date"` -} - -func (t *Ticker) SetCoinId(coinId uint) { - t.Coin = coinId - t.CoinName = "" - t.Price.Provider = "" - t.Price.Currency = "" -} - -type TickerPrice struct { - Value float64 `json:"value"` - Change24h float64 `json:"change_24h"` - Currency string `json:"currency,omitempty"` - Provider string `json:"provider,omitempty"` -} - -type Rate struct { - Currency string `json:"currency"` - Rate float64 `json:"rate"` - Timestamp int64 `json:"timestamp"` - PercentChange24h *big.Float `json:"percent_change_24h,omitempty"` - Provider string `json:"provider,omitempty"` -} - -type Rates []Rate -type Tickers []*Ticker - -func (ts Tickers) ApplyRate(currency string, rate float64, percentChange24h *big.Float) { - for _, t := range ts { - t.ApplyRate(currency, rate, percentChange24h) - } -} - -func (t *Ticker) ApplyRate(currency string, rate float64, percentChange24h *big.Float) { - if t.Price.Currency == currency { - return - } - t.Price.Value *= rate - t.Price.Currency = currency - - if percentChange24h != nil { - change24h, _ := percentChange24h.Float64() - t.Price.Change24h -= change24h - } -} diff --git a/pkg/blockatlas/marketdata_test.go b/pkg/blockatlas/marketdata_test.go deleted file mode 100644 index f2bd81a43..000000000 --- a/pkg/blockatlas/marketdata_test.go +++ /dev/null @@ -1,70 +0,0 @@ -package blockatlas - -import ( - "github.com/stretchr/testify/assert" - "math/big" - "testing" -) - -func TestTicker_ApplyRate(t *testing.T) { - type args struct { - price float64 - percentChange24h float64 - rate float64 - rateChange24h float64 - currency string - } - type want struct { - price float64 - percentChange24h float64 - } - tests := []struct { - name string - args args - want want - }{ - { - "apply rate 1", - args{443, -0.44, 344, -0.33, "BTC"}, - want{152392, -0.10999999999999999}, - }, { - "apply rate 2", - args{1111.22, 3.04, 0.88, -2.12, "BTC"}, - want{977.8736, 5.16}, - }, { - "apply rate 3", - args{3.33, -1.02, 22.3, 1.02, "BTC"}, - want{74.259, -2.04}, - }, { - "apply rate 4", - args{9.3332, -2, 22, -0.555, "BTC"}, - want{205.3304, -1.4449999999999998}, - }, { - "apply rate 5", - args{0.00000001, 0, 0.2, 1.333, "BTC"}, - want{0.000000002, -1.333}, - }, { - "apply rate 6", - args{0.00000001, -0.0003, 10, -0.0003, "BTC"}, - want{0.0000001, 0}, - }, { - "apply for same currency", - args{0.33333, -0.0003, 10, -0.0003, "USD"}, - want{0.33333, -0.0003}, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t1 *testing.T) { - ticker := &Ticker{ - Price: TickerPrice{ - Value: tt.args.price, - Change24h: tt.args.percentChange24h, - Currency: DefaultCurrency, - }, - } - ticker.ApplyRate(tt.args.currency, tt.args.rate, big.NewFloat(tt.args.rateChange24h)) - assert.Equal(t, tt.want.price, ticker.Price.Value) - assert.Equal(t, tt.want.percentChange24h, ticker.Price.Change24h) - }) - } -} diff --git a/pkg/blockatlas/marshal.go b/pkg/blockatlas/marshal.go deleted file mode 100644 index 17fae4e66..000000000 --- a/pkg/blockatlas/marshal.go +++ /dev/null @@ -1,171 +0,0 @@ -package blockatlas - -import ( - "encoding/json" - "github.com/spf13/cast" - "github.com/trustwallet/blockatlas/pkg/errors" - "github.com/trustwallet/blockatlas/pkg/numbers" - "regexp" - "sort" - "strings" -) - -var matchNumber = regexp.MustCompile(`^\d+(\.\d+)?$`) - -// Tx, but with default JSON marshalling methods -type wrappedTx Tx - -// UnmarshalJSON creates a transaction along with metadata from a JSON object. -// Fails if the meta object can't be read. -func (t *Tx) UnmarshalJSON(data []byte) error { - // Wrap the Tx type to avoid infinite recursion - var wrapped wrappedTx - - var raw json.RawMessage - wrapped.Meta = &raw - if err := json.Unmarshal(data, &wrapped); err != nil { - return err - } - - *t = Tx(wrapped) - - switch t.Type { - case TxTransfer: - t.Meta = new(Transfer) - case TxMultiCurrencyTransfer: - t.Meta = new(MultiCurrencyTransfer) - case TxNativeTokenTransfer: - t.Meta = new(NativeTokenTransfer) - case TxTokenTransfer: - t.Meta = new(TokenTransfer) - case TxCollectibleTransfer: - t.Meta = new(CollectibleTransfer) - case TxTokenSwap: - t.Meta = new(TokenSwap) - case TxContractCall: - t.Meta = new(ContractCall) - case TxAnyAction: - t.Meta = new(AnyAction) - default: - return errors.E("unsupported tx type", errors.Params{"type": t.Type}).PushToSentry() - } - if err := json.Unmarshal(raw, t.Meta); err != nil { - return err - } - return nil -} - -// MarshalJSON creates a JSON object from a transaction. -// Sets the Type field to the currect value based on the Meta type. -func (t *Tx) MarshalJSON() ([]byte, error) { - // Set type from metadata content - switch t.Meta.(type) { - case Transfer, *Transfer: - t.Type = TxTransfer - case MultiCurrencyTransfer, *MultiCurrencyTransfer: - t.Type = TxMultiCurrencyTransfer - case NativeTokenTransfer, *NativeTokenTransfer: - t.Type = TxNativeTokenTransfer - case TokenTransfer, *TokenTransfer: - t.Type = TxTokenTransfer - case CollectibleTransfer, *CollectibleTransfer: - t.Type = TxCollectibleTransfer - case TokenSwap, *TokenSwap: - t.Type = TxTokenSwap - case ContractCall, *ContractCall: - t.Type = TxContractCall - case AnyAction, *AnyAction: - t.Type = TxAnyAction - default: - return nil, errors.E("unsupported tx metadata", errors.Params{"meta": t.Meta}).PushToSentry() - } - - // Set status to completed by default - if t.Status == "" { - t.Status = StatusCompleted - } - - // Wrap the Tx type to avoid infinite recursion - return json.Marshal(wrappedTx(*t)) -} - -// UnmarshalJSON reads an amount from a JSON string or number. -// Comma separators get dropped with address.DecimalToSatoshis. -func (a *Amount) UnmarshalJSON(data []byte) error { - var n json.Number - err := json.Unmarshal(data, &n) - if err != nil { - return err - } - str := string(n) - if !matchNumber.MatchString(str) { - return errors.E("not a regular decimal number", errors.Params{"str": str}).PushToSentry() - } - if strings.ContainsRune(str, '.') { - str, _ = numbers.DecimalToSatoshis(str) - } - *a = Amount(str) - return nil -} - -// MarshalJSON returns a JSON string representing the amount -func (a *Amount) MarshalJSON() ([]byte, error) { - return json.Marshal(string(*a)) -} - -// Sort sorts the response by date, descending -func (r *TxPage) Sort() { - sort.Slice(*r, func(i, j int) bool { - ti := cast.ToUint64((*r)[i].Date) - tj := cast.ToUint64((*r)[j].Date) - return ti >= tj - }) -} - -// MarshalJSON returns a wrapped list of transactions in JSON -func (r *TxPage) MarshalJSON() ([]byte, error) { - var page struct { - Total int `json:"total"` - Docs []Tx `json:"docs"` - Status bool `json:"status"` - } - page.Docs = []Tx(*r) - if page.Docs == nil { - page.Docs = make([]Tx, 0) - } - page.Total = len(page.Docs) - page.Status = true - return json.Marshal(page) -} - -// MarshalJSON returns a wrapped list of collections in JSON -func (r CollectionPage) MarshalJSON() ([]byte, error) { - var page struct { - Total int `json:"total"` - Docs []Collection `json:"docs"` - Status bool `json:"status"` - } - page.Docs = []Collection(r) - if page.Docs == nil { - page.Docs = make([]Collection, 0) - } - page.Total = len(page.Docs) - page.Status = true - return json.Marshal(page) -} - -// MarshalJSON returns a wrapped list of collectibles in JSON -func (r CollectiblePage) MarshalJSON() ([]byte, error) { - var page struct { - Total int `json:"total"` - Docs []Collectible `json:"docs"` - Status bool `json:"status"` - } - page.Docs = []Collectible(r) - if page.Docs == nil { - page.Docs = make([]Collectible, 0) - } - page.Total = len(page.Docs) - page.Status = true - return json.Marshal(page) -} diff --git a/pkg/blockatlas/marshal_test.go b/pkg/blockatlas/marshal_test.go deleted file mode 100644 index 1cfdfb220..000000000 --- a/pkg/blockatlas/marshal_test.go +++ /dev/null @@ -1,78 +0,0 @@ -package blockatlas - -import ( - "bytes" - "encoding/json" - "reflect" - "testing" - - "github.com/trustwallet/blockatlas/coin" -) - -var txJSON = []byte(`{ - "id": "14beb212aaefd06d7c6c0b25fc5ec242a2de2725af0a2827c105e743222cacd6", - "coin": 242, - "from": "NQ11 P00L 2HYP TUK8 VY6L 2N22 MMBU MHHR BSAA", - "to": "NQ86 2H8F YGU5 RM77 QSN9 LYLH C56A CYYR 0MLA", - "fee": "138", - "date": 1548954343, - "block": 419040, - "status": "completed", - "type": "transfer", - "metadata": { - "value": "5004160" - } -}`) - -var txModel = Tx{ - ID: "14beb212aaefd06d7c6c0b25fc5ec242a2de2725af0a2827c105e743222cacd6", - Coin: coin.NIM, - From: "NQ11 P00L 2HYP TUK8 VY6L 2N22 MMBU MHHR BSAA", - To: "NQ86 2H8F YGU5 RM77 QSN9 LYLH C56A CYYR 0MLA", - Fee: "138", - Date: 1548954343, - Block: 419040, - Status: StatusCompleted, - Meta: &Transfer{ - Value: "5004160", - }, -} - -func TestTx_UnmarshalJSON(t *testing.T) { - // Expect to get txModel, but with type set - expected := txModel - expected.Type = TxTransfer - - // Unmarshal source - var got Tx - err := json.Unmarshal(txJSON, &got) - if err != nil { - t.Fatal(err) - } - - // Compare got and expected - if !reflect.DeepEqual(expected, got) { - t.Error("txs not equal") - } -} - -func TestTx_MarshalJSON(t *testing.T) { - // Input is txModel without type - input := txModel - - // Marshal transaction - got, err := json.MarshalIndent(&input, "", "\t") - if err != nil { - t.Fatal(err) - } - - // After marshal, the type should be set - if input.Type == "" { - t.Fatal("type was not set") - } else if input.Type != TxTransfer { - t.Fatal("wrong type set") - } - - // Compare expected and output JSON - bytes.Equal(got, txJSON) -} diff --git a/pkg/blockatlas/models.go b/pkg/blockatlas/models.go index da366ed3b..6ae14fc0d 100644 --- a/pkg/blockatlas/models.go +++ b/pkg/blockatlas/models.go @@ -1,10 +1,17 @@ package blockatlas -type DocsResponse struct { - Docs interface{} `json:"docs"` -} +import "encoding/json" + +type ( + ResultsResponse struct { + Results interface{} `json:"docs"` + } +) -type ResultsResponse struct { - Total int `json:"total"` - Results interface{} `json:"docs"` +func MapJsonObject(from interface{}, to interface{}) error { + bytes, err := json.Marshal(from) + if err != nil { + return err + } + return json.Unmarshal(bytes, to) } diff --git a/pkg/blockatlas/naming_service.go b/pkg/blockatlas/naming_service.go deleted file mode 100644 index ca44b4479..000000000 --- a/pkg/blockatlas/naming_service.go +++ /dev/null @@ -1,6 +0,0 @@ -package blockatlas - -type Resolved struct { - Result string `json:"result"` - Coin uint64 `json:"coin"` -} diff --git a/pkg/blockatlas/observer.go b/pkg/blockatlas/observer.go deleted file mode 100644 index 588861633..000000000 --- a/pkg/blockatlas/observer.go +++ /dev/null @@ -1,16 +0,0 @@ -package blockatlas - -type Webhook struct { - Subscriptions map[string][]string `json:"subscriptions"` - Webhook string `json:"webhook"` -} - -type CoinStatus struct { - Height int64 `json:"height"` - Error string `json:"error,omitempty"` -} - -type Observer struct { - Status bool `json:"status"` - Message string `json:"message"` -} diff --git a/pkg/blockatlas/platform.go b/pkg/blockatlas/platform.go new file mode 100644 index 000000000..60d825f57 --- /dev/null +++ b/pkg/blockatlas/platform.go @@ -0,0 +1,73 @@ +package blockatlas + +import ( + "github.com/trustwallet/golibs/coin" + "github.com/trustwallet/golibs/types" +) + +type ( + // Platform can be used to access a crypto service + Platform interface { + Coin() coin.Coin + } + + // BlockAPI provides block information and lookups + BlockAPI interface { + Platform + CurrentBlockNumber() (int64, error) + GetBlockByNumber(num int64) (*types.Block, error) + } + + // TxAPI provides transaction lookups based on address + TxAPI interface { + Platform + GetTxsByAddress(address string) (types.Txs, error) + } + + // TokenTxAPI provides token transaction lookups + TokenTxAPI interface { + Platform + GetTokenTxsByAddress(address, token string) (types.Txs, error) + } + + // TxUtxoAPI provides transaction lookup based on address and XPUB (Bitcoin-style) + TxUtxoAPI interface { + TxAPI + GetTxsByXpub(xpub string) (types.Txs, error) + } + + // TokensAPI provides token lookups + TokensAPI interface { + Platform + GetTokenListByAddress(address string) ([]types.Token, error) + GetTokenListIdsByAddress(address string) ([]string, error) + } + + // StakingAPI provides staking information + StakeAPI interface { + Platform + UndelegatedBalance(address string) (string, error) + GetDetails() StakingDetails + GetValidators() (ValidatorPage, error) + GetDelegations(address string) (DelegationsPage, error) + GetActiveValidators() (StakeValidators, error) + } + + CollectionsAPI interface { + Platform + GetCollections(owner string) (types.CollectionPage, error) + GetCollectibles(owner, collectibleID string) (types.CollectiblePage, error) + } + + Platforms map[string]Platform + + CollectionsAPIs map[uint]CollectionsAPI +) + +func (ps Platforms) GetPlatformList() []Platform { + platforms := make([]Platform, 0) + for _, p := range ps { + platforms = append(platforms, p) + } + return platforms +} diff --git a/pkg/blockatlas/platform_test.go b/pkg/blockatlas/platform_test.go new file mode 100644 index 000000000..5cafdb6c6 --- /dev/null +++ b/pkg/blockatlas/platform_test.go @@ -0,0 +1,45 @@ +package blockatlas + +import ( + "reflect" + "testing" +) + +func TestPlatforms_GetPlatformList(t *testing.T) { + var p Platform + tests := []struct { + name string + ps Platforms + want []Platform + }{ + { + "test 1", + Platforms{ + "test1": p, + "test2": p, + "test3": p, + }, + []Platform{p, p, p}, + }, { + "test 2", + Platforms{ + "test1": p, + "test2": p, + }, + []Platform{p, p}, + }, { + "test 3", + Platforms{ + "test1": p, + }, + []Platform{p}, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + if got := tt.ps.GetPlatformList(); !reflect.DeepEqual(got, tt.want) { + t.Errorf("GetPlatformList() = %v, want %v", got, tt.want) + } + }) + } +} diff --git a/pkg/blockatlas/staking.go b/pkg/blockatlas/staking.go index 8d34edf4f..452eb1598 100644 --- a/pkg/blockatlas/staking.go +++ b/pkg/blockatlas/staking.go @@ -1,16 +1,9 @@ package blockatlas -import "github.com/trustwallet/blockatlas/coin" - -type ValidatorPage []Validator -type DelegationsPage []Delegation -type DelegationsBatchPage []DelegationResponse -type StakingBatchPage []StakingResponse - -type DelegationStatus string -type DelegationType string - -type ValidatorMap map[string]StakeValidator +import ( + "github.com/trustwallet/golibs/coin" + "github.com/trustwallet/golibs/types" +) const ( DelegationStatusActive DelegationStatus = "active" @@ -18,58 +11,91 @@ const ( DelegationTypeAuto DelegationType = "auto" DelegationTypeDelegate DelegationType = "delegate" + + DefaultAnnualReward = 0.0 ) -type StakingReward struct { - Annual float64 `json:"annual"` -} +type ( + ValidatorPage []Validator + DelegationsPage []Delegation + DelegationsBatchPage []DelegationResponse + StakingBatchPage []StakingResponse + StakeValidators []StakeValidator -type StakingDetails struct { - Reward StakingReward `json:"reward"` - LockTime int `json:"locktime"` - MinimumAmount Amount `json:"minimum_amount"` - Type DelegationType `json:"type"` -} + DelegationStatus string + DelegationType string -type Validator struct { - ID string `json:"id"` - Status bool `json:"status"` - Details StakingDetails `json:"details"` -} + ValidatorMap map[string]StakeValidator -type Delegation struct { - Delegator StakeValidator `json:"delegator"` - Value string `json:"value"` - Status DelegationStatus `json:"status"` - Metadata interface{} `json:"metadata,omitempty"` -} + StakingReward struct { + Annual float64 `json:"annual"` + } -type DelegationMetaDataPending struct { - AvailableDate uint `json:"available_date"` -} + StakingDetails struct { + Reward StakingReward `json:"reward"` + LockTime int `json:"locktime"` + MinimumAmount types.Amount `json:"minimum_amount"` + Type DelegationType `json:"type"` + } -type StakeValidatorInfo struct { - Name string `json:"name"` - Description string `json:"description"` - Image string `json:"image"` - Website string `json:"website"` -} + Validator struct { + ID string `json:"id"` + Status bool `json:"status"` + Details StakingDetails `json:"details"` + } -type StakeValidator struct { - ID string `json:"id"` - Status bool `json:"status,omitempty"` - Info StakeValidatorInfo `json:"info,omitempty"` - Details StakingDetails `json:"details,omitempty"` -} + Delegation struct { + Delegator StakeValidator `json:"delegator"` + Value string `json:"value"` + Status DelegationStatus `json:"status"` + Metadata interface{} `json:"metadata,omitempty"` + } + + DelegationMetaDataPending struct { + AvailableDate uint `json:"available_date"` + } + + StakeValidatorInfo struct { + Name string `json:"name"` + Description string `json:"description"` + Image string `json:"image"` + Website string `json:"website"` + } + + StakeValidator struct { + ID string `json:"id"` + Status bool `json:"status"` + Info StakeValidatorInfo `json:"info,omitempty"` + Details StakingDetails `json:"details,omitempty"` + } + + DelegationResponse struct { + Delegations DelegationsPage `json:"delegations"` + Balance string `json:"balance"` + Address string `json:"address"` + StakingResponse + } + + StakingResponse struct { + Coin *coin.ExternalCoin `json:"coin"` + Details StakingDetails `json:"details"` + } +) -type DelegationResponse struct { - Delegations DelegationsPage `json:"delegations"` - Balance string `json:"balance"` - Address string `json:"address"` - StakingResponse +func (s StakeValidators) ToMap() ValidatorMap { + validators := make(ValidatorMap) + for _, v := range s { + validators[v.ID] = v + } + return validators } -type StakingResponse struct { - Coin *coin.ExternalCoin `json:"coin"` - Details StakingDetails `json:"details"` +func FindHightestAPR(validators []Validator) float64 { + var apr = 0.0 + for _, v := range validators { + if apr < v.Details.Reward.Annual { + apr = v.Details.Reward.Annual + } + } + return apr } diff --git a/pkg/blockatlas/staking_test.go b/pkg/blockatlas/staking_test.go new file mode 100644 index 000000000..4abb2b919 --- /dev/null +++ b/pkg/blockatlas/staking_test.go @@ -0,0 +1,25 @@ +package blockatlas + +import ( + "reflect" + "testing" +) + +func TestStakeValidators_ToMap(t *testing.T) { + tests := []struct { + name string + sv StakeValidators + want ValidatorMap + }{ + {"test 1 validator", StakeValidators{{ID: "test1"}}, ValidatorMap{"test1": {ID: "test1"}}}, + {"test 2 validators", StakeValidators{{ID: "test1"}, {ID: "test2"}}, ValidatorMap{"test1": {ID: "test1"}, "test2": {ID: "test2"}}}, + {"test 3 validators", StakeValidators{{ID: "test1"}, {ID: "test2"}, {ID: "test3"}}, ValidatorMap{"test1": {ID: "test1"}, "test2": {ID: "test2"}, "test3": {ID: "test3"}}}, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + if got := tt.sv.ToMap(); !reflect.DeepEqual(got, tt.want) { + t.Errorf("ToMap() = %v, want %v", got, tt.want) + } + }) + } +} diff --git a/pkg/blockatlas/string_test.go b/pkg/blockatlas/string_test.go index 77d3f5b1f..babf707a6 100644 --- a/pkg/blockatlas/string_test.go +++ b/pkg/blockatlas/string_test.go @@ -6,7 +6,7 @@ import ( ) func TestGetValidParameter(t *testing.T) { - var tests = []struct { + tests := []struct { first string second string result string diff --git a/pkg/blockatlas/tx.go b/pkg/blockatlas/tx.go deleted file mode 100644 index 6e40b645e..000000000 --- a/pkg/blockatlas/tx.go +++ /dev/null @@ -1,234 +0,0 @@ -package blockatlas - -type Direction string -type Status string -type TokenType string -type TransactionType string -type KeyType string -type KeyTitle string - -// Types of transaction statuses -const ( - StatusCompleted Status = "completed" - StatusPending Status = "pending" - StatusFailed Status = "failed" - - DirectionOutgoing Direction = "outgoing" - DirectionIncoming Direction = "incoming" - DirectionSelf Direction = "yourself" - - TokenTypeERC20 TokenType = "ERC20" - TokenTypeBEP2 TokenType = "BEP2" - TokenTypeTRC10 TokenType = "TRC10" - TokenTypeETC20 TokenType = "ETC20" - TokenTypePOA20 TokenType = "POA20" - TokenTypeTRC20 TokenType = "TRC20" - TokenTypeCLO20 TokenType = "CLO20" - TokenTypeGO20 TokenType = "G020" - TokenTypeWAN20 TokenType = "WAN20" - TokenTypeTT20 TokenType = "TT20" - - TxTransfer TransactionType = "transfer" - TxNativeTokenTransfer TransactionType = "native_token_transfer" - TxTokenTransfer TransactionType = "token_transfer" - TxCollectibleTransfer TransactionType = "collectible_transfer" - TxTokenSwap TransactionType = "token_swap" - TxContractCall TransactionType = "contract_call" - TxAnyAction TransactionType = "any_action" - TxMultiCurrencyTransfer TransactionType = "multi_currency_transfer" - - KeyPlaceOrder KeyType = "place_order" - KeyCancelOrder KeyType = "cancel_order" - KeyIssueToken KeyType = "issue_token" - KeyBurnToken KeyType = "burn_token" - KeyMintToken KeyType = "mint_token" - KeyApproveToken KeyType = "approve_token" - KeyStakeDelegate KeyType = "stake_delegate" - KeyStakeClaimRewards KeyType = "stake_claim_rewards" - - KeyTitlePlaceOrder KeyTitle = "Place Order" - KeyTitleCancelOrder KeyTitle = "Cancel Order" - AnyActionDelegation KeyTitle = "Delegation" - AnyActionUndelegation KeyTitle = "Undelegation" - AnyActionClaimRewards KeyTitle = "Claim Rewards" -) - -// TxPerPage says how many transactions to return per page -const TxPerPage = 25 - -// TxPage is a page of transactions -type TxPage []Tx - -// Amount is a positive decimal integer string. -// It is written in the smallest possible unit (e.g. Wei, Satoshis) -type Amount string - -// Tx describes an on-chain transaction generically -type Tx struct { - // Unique identifier - ID string `json:"id"` - // SLIP-44 coin index of the platform - Coin uint `json:"coin"` - // Address of the transaction sender - From string `json:"from"` - // Address of the transaction recipient - To string `json:"to"` - // Transaction fee (native currency) - Fee Amount `json:"fee"` - // Unix timestamp of the block the transaction was included in - Date int64 `json:"date"` - // Height of the block the transaction was included in - Block uint64 `json:"block"` - // Status of the transaction - Status Status `json:"status"` - // Empty if the transaction was successful, - // else error explaining why the transaction failed (optional) - Error string `json:"error,omitempty"` - // Transaction nonce or sequence - Sequence uint64 `json:"sequence,omitempty"` - // Type of metadata - Type TransactionType `json:"type"` - // Input addresses - Inputs []TxOutput `json:"inputs,omitempty"` - // Output addresses - Outputs []TxOutput `json:"outputs,omitempty"` - // Transaction Direction - Direction Direction `json:"direction,omitempty"` - // Meta data object - Memo string `json:"memo"` - Meta interface{} `json:"metadata"` -} - -type TxOutput struct { - Address string `json:"address"` - Value Amount `json:"value"` -} - -// Transfer describes the transfer of currency native to the platform -type Transfer struct { - Value Amount `json:"value"` - Symbol string `json:"symbol"` - Decimals uint `json:"decimals"` -} - -// NativeTokenTransfer describes the transfer of native tokens. -// Example: Stellar Tokens, TRC10 -type NativeTokenTransfer struct { - Name string `json:"name"` - Symbol string `json:"symbol"` - TokenID string `json:"token_id"` - Decimals uint `json:"decimals"` - Value Amount `json:"value"` - From string `json:"from"` - To string `json:"to"` -} - -// TokenTransfer describes the transfer of non-native tokens. -// Examples: ERC-20, TRC20 -type TokenTransfer struct { - Name string `json:"name"` - Symbol string `json:"symbol"` - TokenID string `json:"token_id"` - Decimals uint `json:"decimals"` - Value Amount `json:"value"` - From string `json:"from"` - To string `json:"to"` -} - -// CollectibleTransfer describes the transfer of a -// "collectible", unique token. -type CollectibleTransfer struct { - Name string `json:"name"` - Contract string `json:"contract"` - ImageURL string `json:"image_url"` -} - -// TokenSwap describes the exchange of two different tokens -type TokenSwap struct { - Input TokenTransfer `json:"input"` - Output TokenTransfer `json:"output"` -} - -// ContractCall describes a -type ContractCall struct { - Input string `json:"input"` - Value string `json:"value"` -} - -// Currency describes currency information with its amount -type Currency struct { - Token Token `json:"token"` - Value Amount `json:"value"` -} - -// MultiCurrencyTransfer describes the transfer of multiple currency native to the platform -type MultiCurrencyTransfer struct { - Currencies []Currency `json:"currencies"` - Fees []Currency `json:"fees"` -} - -// AnyAction describes all other types -type AnyAction struct { - Coin uint `json:"coin"` - Title KeyTitle `json:"title"` - Key KeyType `json:"key"` - TokenID string `json:"token_id"` - Name string `json:"name"` - Symbol string `json:"symbol"` - Decimals uint `json:"decimals"` - Value Amount `json:"value"` -} - -// TokenPage is a page of transactions. -type TokenPage []Token - -// Token describes the non-native tokens. -// Examples: ERC-20, TRC-20, BEP-2 -type Token struct { - Name string `json:"name"` - Symbol string `json:"symbol"` - Decimals uint `json:"decimals"` - TokenID string `json:"token_id"` - Coin uint `json:"coin"` - Type TokenType `json:"type"` -} - -func (t *Tx) GetUtxoAddresses() (addresses []string) { - for _, input := range t.Inputs { - addresses = append(addresses, input.Address) - } - - for _, output := range t.Outputs { - addresses = append(addresses, output.Address) - } - - return addresses -} - -func (t *Tx) GetAddresses() []string { - addresses := make([]string, 0) - switch t.Meta.(type) { - case Transfer, *Transfer, CollectibleTransfer, *CollectibleTransfer, ContractCall, *ContractCall, AnyAction, *AnyAction, MultiCurrencyTransfer, *MultiCurrencyTransfer: - return append(addresses, t.From, t.To) - case NativeTokenTransfer: - return append(addresses, t.Meta.(NativeTokenTransfer).From, t.Meta.(NativeTokenTransfer).To) - case *NativeTokenTransfer: - return append(addresses, t.Meta.(*NativeTokenTransfer).From, t.Meta.(*NativeTokenTransfer).To) - case TokenTransfer: - return append(addresses, t.Meta.(TokenTransfer).From, t.Meta.(TokenTransfer).To) - case *TokenTransfer: - return append(addresses, t.Meta.(*TokenTransfer).From, t.Meta.(*TokenTransfer).To) - case TokenSwap: - { - m := t.Meta.(TokenSwap) - return append(addresses, m.Input.From, m.Input.To, m.Output.From, m.Output.To) - } - case *TokenSwap: - { - m := t.Meta.(*TokenSwap) - return append(addresses, m.Input.From, m.Input.To, m.Output.From, m.Output.To) - } - default: - return addresses - } -} diff --git a/pkg/blockatlas/txset.go b/pkg/blockatlas/txset.go deleted file mode 100644 index a3a27ac81..000000000 --- a/pkg/blockatlas/txset.go +++ /dev/null @@ -1,38 +0,0 @@ -package blockatlas - -import "sync" - -type TxSet struct { - items map[*Tx]bool - lock sync.RWMutex -} - -// Add adds a new element to the Set. Returns a pointer to the Set. -func (s *TxSet) Add(t *Tx) *TxSet { - s.lock.Lock() - defer s.lock.Unlock() - if s.items == nil { - s.items = make(map[*Tx]bool) - } - _, ok := s.items[t] - if !ok { - s.items[t] = true - } - return s -} - -func (s *TxSet) Txs() []Tx { - s.lock.RLock() - defer s.lock.RUnlock() - items := []Tx{} - for i := range s.items { - items = append(items, *i) - } - return items -} - -func (s *TxSet) Size() int { - s.lock.RLock() - defer s.lock.RUnlock() - return len(s.items) -} diff --git a/pkg/errors/errorType.go b/pkg/errors/errorType.go deleted file mode 100644 index f7f74fef1..000000000 --- a/pkg/errors/errorType.go +++ /dev/null @@ -1,44 +0,0 @@ -package errors - -import ( - "fmt" -) - -type Type uint16 - -const ( - TypeNone Type = iota - TypePlatformUnmarshal - TypePlatformNormalize - TypePlatformUnknown - TypePlatformRequest - TypePlatformClient - TypePlatformError - TypePlatformApi - TypeUnknown -) - -func (e Type) String() string { - switch e { - case TypeNone: - return "" - case TypePlatformRequest: - return "Platform Request Error" - case TypePlatformUnmarshal: - return "Platform Unmarshal Error" - case TypePlatformClient: - return "Platform Client Generic Error" - case TypePlatformApi: - return "Platform API Error" - case TypePlatformNormalize: - return "Platform Normalize Error" - case TypePlatformUnknown: - return "Platform Unknown Error" - case TypePlatformError: - return "Custom Platform Error" - case TypeUnknown: - return "Unknown Error" - default: - return fmt.Sprintf("Error: %d", int(e)) - } -} diff --git a/pkg/errors/errors.go b/pkg/errors/errors.go deleted file mode 100644 index 5a9019cba..000000000 --- a/pkg/errors/errors.go +++ /dev/null @@ -1,135 +0,0 @@ -package errors - -import ( - "encoding/json" - "errors" - "fmt" - "runtime" - "strings" -) - -type Params map[string]interface{} - -// Error represents a error's specification. -type Error struct { - Err error - Type Type - meta map[string]interface{} - stack []string -} - -var ( - _ error = (*Error)(nil) -) - -func (e *Error) isEmpty() bool { - return e.meta == nil && e.Type == TypeNone && e.Err == nil -} - -func (e *Error) Error() string { - r, err := e.MarshalJSON() - if err != nil { - return e.Err.Error() - } - return string(r) -} - -func (e *Error) String() string { - msg := e.Err.Error() - if e.Type != TypeNone { - msg = fmt.Sprintf("%s | Type: %s", msg, e.Type.String()) - } - if len(e.Meta()) > 0 { - msg = fmt.Sprintf("%s | Meta: %s", msg, e.Meta()) - } - if len(e.stack) > 0 { - msg = fmt.Sprintf("%s | Stack: %s", msg, e.stack) - } - return msg -} - -// SetMeta sets the error's meta data. -func (e *Error) SetMeta(data Params) *Error { - e.meta = data - return e -} - -func (e *Error) Meta() string { - r, err := json.Marshal(e.meta) - if err != nil { - return "" - } - return string(r) -} - -// JSON creates a properly formatted JSON -func (e *Error) JSON() interface{} { - p := Params{} - if e.meta != nil { - p["meta"] = e.meta - } - if e.Err != nil { - p["error"] = e.Err.Error() - } - if e.Type != TypeNone { - p["type"] = e.Type.String() - } - if len(e.stack) > 0 { - p["stack"] = e.stack - } - return p -} - -// MarshalJSON implements the json.Marshaller interface. -func (e *Error) MarshalJSON() ([]byte, error) { - return json.Marshal(e.JSON()) -} - -func (e *Error) PushToSentry() *Error { - SendError(e) - return e -} - -// T create a new error with runtime stack trace. -func T(args ...interface{}) *Error { - e := E(args...) - for i := 1; i <= 5; i++ { - _, fn, line, ok := runtime.Caller(i) - if ok { - e.stack = append(e.stack, fmt.Sprintf("%s:%d", fn, line)) - } - } - return e -} - -// E create a new error. -func E(args ...interface{}) *Error { - e := &Error{Type: TypeNone, meta: make(Params)} - var message []string - for _, arg := range args { - switch arg := arg.(type) { - case nil: - continue - case string: - message = append(message, arg) - case *Error: - message = append([]string{arg.Err.Error()}, message...) - appendMap(e.meta, arg.meta) - case error: - message = append([]string{arg.Error()}, message...) - case Type: - e.Type = arg - case Params: - appendMap(e.meta, arg) - case map[string]interface{}: - appendMap(e.meta, arg) - default: - continue - } - } - if len(message) > 0 { - msg := strings.Join(message[:], ": ") - e.Err = errors.New(msg) - } - return e -} diff --git a/pkg/errors/helper_test.go b/pkg/errors/helper_test.go deleted file mode 100644 index 0be276b72..000000000 --- a/pkg/errors/helper_test.go +++ /dev/null @@ -1,47 +0,0 @@ -package errors - -import ( - "fmt" - "testing" -) - -func TestIsType(t *testing.T) { - var tests = []struct { - error error - errorType Type - result bool - }{ - {fmt.Errorf("test"), TypePlatformRequest, false}, - {&Error{Type: TypePlatformRequest}, TypePlatformRequest, true}, - {&Error{Type: TypePlatformUnmarshal}, TypePlatformRequest, false}, - } - for i, tt := range tests { - t.Run(fmt.Sprintf("TestIsType %d", i), func(t *testing.T) { - s := Is(tt.error, tt.errorType) - if s != tt.result { - t.Errorf("got %t, want %t", s, tt.result) - } - }) - } -} - -func TestEqual(t *testing.T) { - var tests = []struct { - err1 error - err2 error - result bool - }{ - {fmt.Errorf("test"), &Error{Type: TypePlatformRequest}, false}, - {&Error{Type: TypePlatformNormalize}, &Error{Type: TypePlatformRequest}, false}, - {&Error{Type: TypePlatformRequest}, &Error{Type: TypePlatformRequest}, true}, - {fmt.Errorf("err1"), fmt.Errorf("err2"), false}, - } - for i, tt := range tests { - t.Run(fmt.Sprintf("TestEqual %d", i), func(t *testing.T) { - s := Equal(tt.err1, tt.err2) - if s != tt.result { - t.Errorf("got %t, want %t", s, tt.result) - } - }) - } -} diff --git a/pkg/errors/helpers.go b/pkg/errors/helpers.go deleted file mode 100644 index 1cafcce81..000000000 --- a/pkg/errors/helpers.go +++ /dev/null @@ -1,49 +0,0 @@ -package errors - -// Is reports whether err is an *Error of the given Type. -// If err is nil then Is returns false. -func Is(err error, t Type) bool { - e, ok := err.(*Error) - if !ok { - return false - } - if e.Type != TypeNone { - return e.Type == t - } - if e.Err != nil { - return Is(e.Err, t) - } - return false -} - -func Equal(err1, err2 error) bool { - e1, ok := err1.(*Error) - if !ok { - return false - } - e2, ok := err2.(*Error) - if !ok { - return false - } - if e1.Err != nil && e2.Err != e1.Err { - return false - } - if e1.Type != TypeNone && e2.Type != e1.Type { - return false - } - if e1.Err != nil { - if _, ok := e1.Err.(*Error); ok { - return Equal(e1.Err, e2.Err) - } - if e2.Err == nil || e2.Err.Error() != e1.Err.Error() { - return false - } - } - return true -} - -func appendMap(root map[string]interface{}, tmp map[string]interface{}) { - for k, v := range tmp { - root[k] = v - } -} diff --git a/pkg/errors/sentry.go b/pkg/errors/sentry.go deleted file mode 100755 index b11c84865..000000000 --- a/pkg/errors/sentry.go +++ /dev/null @@ -1,31 +0,0 @@ -package errors - -import ( - "github.com/getsentry/sentry-go" - "github.com/spf13/viper" - "time" -) - -func InitSentry() error { - err := sentry.Init(sentry.ClientOptions{ - Dsn: viper.GetString("sentry.dsn"), - AttachStacktrace: true, - }) - if err != nil { - return E(err, "InitSentry failed") - } - return nil -} - -func SendError(err error) { - sentry.CaptureException(err) -} - -func SendFatal(err error) { - sentry.CaptureException(err) - sentry.Flush(time.Second * 5) -} - -func SendMessage(msg string) { - sentry.CaptureMessage(msg) -} diff --git a/pkg/ginutils/gincache/cache.go b/pkg/ginutils/gincache/cache.go deleted file mode 100644 index 3714c681c..000000000 --- a/pkg/ginutils/gincache/cache.go +++ /dev/null @@ -1,139 +0,0 @@ -package gincache - -import ( - "bytes" - "crypto/sha1" - "encoding/base64" - "fmt" - "github.com/gin-gonic/gin" - "github.com/patrickmn/go-cache" - "github.com/trustwallet/blockatlas/pkg/logger" - "io/ioutil" - "net/http" - "time" -) - -var ( - memoryCache *cache.Cache -) - -func init() { - memoryCache = cache.New(5*time.Minute, 5*time.Minute) -} - -type cacheResponse struct { - Status int - Header http.Header - Data []byte -} - -type cachedWriter struct { - gin.ResponseWriter - status int - written bool - expire time.Duration - key string -} - -var _ gin.ResponseWriter = &cachedWriter{} - -func newCachedWriter(expire time.Duration, writer gin.ResponseWriter, key string) *cachedWriter { - return &cachedWriter{writer, 0, false, expire, key} -} - -func (w *cachedWriter) WriteHeader(code int) { - w.status = code - w.written = true - w.ResponseWriter.WriteHeader(code) -} - -func (w *cachedWriter) Status() int { - return w.ResponseWriter.Status() -} - -func (w *cachedWriter) Written() bool { - return w.ResponseWriter.Written() -} - -func getCacheResponse(key string) (*cacheResponse, error) { - mc, ok := memoryCache.Get(key) - if !ok { - return nil, fmt.Errorf("gin-cache: invalid cache key %s", key) - } - - tempCache, ok := mc.(cacheResponse) - if !ok { - return nil, fmt.Errorf("gin-cache: invalid cache object %s", key) - } - return &tempCache, nil -} - -func (w *cachedWriter) Write(data []byte) (int, error) { - ret, err := w.ResponseWriter.Write(data) - if err != nil { - return 0, err - } - if w.Status() < 300 { - val := cacheResponse{ - w.Status(), - w.Header(), - data, - } - memoryCache.Set(w.key, val, w.expire) - } - return ret, nil -} - -func (w *cachedWriter) WriteString(data string) (n int, err error) { - ret, err := w.ResponseWriter.WriteString(data) - if err == nil && w.Status() < 300 { - val := cacheResponse{ - w.Status(), - w.Header(), - []byte(data), - } - memoryCache.Set(w.key, val, w.expire) - } - return ret, err -} - -func generateKey(c *gin.Context) string { - url := c.Request.URL.String() - var b []byte - if c.Request.Body != nil { - b, _ = ioutil.ReadAll(c.Request.Body) - // Restore the io.ReadCloser to its original state - c.Request.Body = ioutil.NopCloser(bytes.NewBuffer(b)) - } - hash := sha1.Sum(append([]byte(url), b...)) - return base64.URLEncoding.EncodeToString(hash[:]) -} - -// CacheMiddleware encapsulates a gin handler function and caches the response with an expiration time. -func CacheMiddleware(expiration time.Duration, handle gin.HandlerFunc) gin.HandlerFunc { - return func(c *gin.Context) { - key := generateKey(c) - mc, err := getCacheResponse(key) - if err != nil || mc.Data == nil { - writer := newCachedWriter(expiration, c.Writer, key) - c.Writer = writer - handle(c) - - if c.IsAborted() { - memoryCache.Delete(key) - } - return - } - - c.Writer.WriteHeader(mc.Status) - for k, vals := range mc.Header { - for _, v := range vals { - c.Writer.Header().Set(k, v) - } - } - _, err = c.Writer.Write(mc.Data) - if err != nil { - logger.Error(err, "cannot write data", mc) - } - } -} diff --git a/pkg/ginutils/gincache/cache_test.go b/pkg/ginutils/gincache/cache_test.go deleted file mode 100644 index 820c5fd4d..000000000 --- a/pkg/ginutils/gincache/cache_test.go +++ /dev/null @@ -1,65 +0,0 @@ -package gincache - -import ( - "fmt" - "github.com/gin-gonic/gin" - "github.com/stretchr/testify/assert" - "net/http/httptest" - "testing" - "time" -) - -func init() { - gin.SetMode(gin.TestMode) -} - -func performRequest(method, target string, router *gin.Engine) *httptest.ResponseRecorder { - r := httptest.NewRequest(method, target, nil) - w := httptest.NewRecorder() - router.ServeHTTP(w, r) - return w -} - -func TestWrite(t *testing.T) { - w := httptest.NewRecorder() - c, _ := gin.CreateTestContext(w) - - writer := newCachedWriter(time.Second*3, c.Writer, "mykey") - c.Writer = writer - - c.Writer.WriteHeader(204) - c.Writer.WriteHeaderNow() - c.Writer.Write([]byte("foo")) - assert.Equal(t, 204, c.Writer.Status()) - assert.Equal(t, "foo", w.Body.String()) - assert.True(t, c.Writer.Written()) -} - -func TestCachePage(t *testing.T) { - router := gin.New() - router.GET("/cache_ping", CacheMiddleware(time.Second*3, func(c *gin.Context) { - c.String(200, "pong "+fmt.Sprint(time.Now().UnixNano())) - })) - - w1 := performRequest("GET", "/cache_ping", router) - w2 := performRequest("GET", "/cache_ping", router) - - assert.Equal(t, 200, w1.Code) - assert.Equal(t, 200, w2.Code) - assert.Equal(t, w1.Body.String(), w2.Body.String()) -} - -func TestCachePageExpire(t *testing.T) { - router := gin.New() - router.GET("/cache_ping", CacheMiddleware(time.Second, func(c *gin.Context) { - c.String(200, "pong "+fmt.Sprint(time.Now().UnixNano())) - })) - - w1 := performRequest("GET", "/cache_ping", router) - time.Sleep(time.Second * 3) - w2 := performRequest("GET", "/cache_ping", router) - - assert.Equal(t, 200, w1.Code) - assert.Equal(t, 200, w2.Code) - assert.NotEqual(t, w1.Body.String(), w2.Body.String()) -} diff --git a/pkg/ginutils/middleware.go b/pkg/ginutils/middleware.go deleted file mode 100644 index 0cc162377..000000000 --- a/pkg/ginutils/middleware.go +++ /dev/null @@ -1,46 +0,0 @@ -package ginutils - -import ( - "github.com/gin-gonic/gin" - "net/http" - "strings" -) - -var DefaultMiddleware = func(c *gin.Context) { - c.Next() -} - -func TokenAuthMiddleware(requiredToken string) gin.HandlerFunc { - if requiredToken == "" { - return DefaultMiddleware - } - - return func(c *gin.Context) { - token := c.Request.Header.Get("Authorization") - token = strings.Replace(token, "Bearer ", "", 1) - if token == "" { - RenderError(c, http.StatusUnauthorized, "API token required") - return - } - - if token != requiredToken { - RenderError(c, http.StatusUnauthorized, "Invalid API token") - return - } - c.Next() - } -} - -func CORSMiddleware() gin.HandlerFunc { - return func(c *gin.Context) { - c.Writer.Header().Set("Access-Control-Allow-Origin", "*") - c.Writer.Header().Set("Access-Control-Allow-Credentials", "true") - c.Writer.Header().Set("Access-Control-Allow-Headers", "Content-Type, Content-Length, Accept-Encoding, X-CSRF-Token, Authorization, accept, origin, Cache-Control, X-Requested-With") - c.Writer.Header().Set("Access-Control-Allow-Methods", "GET,HEAD,PUT,PATCH,POST,DELETE") - if c.Request.Method == "OPTIONS" { - c.AbortWithStatus(204) - return - } - c.Next() - } -} diff --git a/pkg/ginutils/response.go b/pkg/ginutils/response.go deleted file mode 100644 index 83efac655..000000000 --- a/pkg/ginutils/response.go +++ /dev/null @@ -1,66 +0,0 @@ -package ginutils - -import ( - "encoding/json" - "github.com/gin-gonic/gin" - "net/http" -) - -type ApiError struct { - *gin.Context `json:"-"` - StatusCode int `json:"status_code"` - StatusMessage string `json:"status_message"` -} - -func RenderSuccess(c *gin.Context, result interface{}) { - c.JSON(http.StatusOK, result) -} - -func RenderError(c *gin.Context, code int, msg string) { - err := &ApiError{ - StatusCode: code, - StatusMessage: msg, - Context: c, - } - err.Render() -} - -func ErrorResponse(c *gin.Context) *ApiError { - return &ApiError{ - StatusCode: http.StatusInternalServerError, - StatusMessage: "Internal server error", - Context: c, - } -} - -func (e *ApiError) Code(code int) *ApiError { - e.StatusCode = code - return e -} - -func (e *ApiError) Message(msg string) *ApiError { - e.StatusMessage = msg - return e -} - -func (e *ApiError) Params(code int, msg string) *ApiError { - e.StatusCode = code - e.StatusMessage = msg - return e -} - -func (e *ApiError) Render() { - var msg map[string]interface{} - err := json.Unmarshal([]byte(e.StatusMessage), &msg) - if err == nil { - e.AbortWithStatusJSON(e.StatusCode, map[string]interface{}{ - "error": msg, - "code": e.StatusCode, - }) - return - } - e.AbortWithStatusJSON(e.StatusCode, map[string]interface{}{ - "error": e.StatusMessage, - "code": e.StatusCode, - }) -} diff --git a/pkg/ginutils/reverse_proxy.go b/pkg/ginutils/reverse_proxy.go deleted file mode 100644 index c828956ed..000000000 --- a/pkg/ginutils/reverse_proxy.go +++ /dev/null @@ -1,17 +0,0 @@ -package ginutils - -import ( - "github.com/gin-gonic/gin" - "github.com/spf13/viper" -) - -// CheckReverseProxy removes untrusted forwarded HTTP headers -// if gin.reverse_proxy is defined -func CheckReverseProxy(c *gin.Context) { - if !viper.GetBool("gin.reverse_proxy") { - c.Request.Header.Del("Forwarded") - c.Request.Header.Del("X-Forwarded-Proto") - c.Request.Header.Del("X-Forwarded-Host") - c.Request.Header.Del("X-Forwarded-For") - } -} diff --git a/pkg/integration/fixtures.go b/pkg/integration/fixtures.go deleted file mode 100644 index f9da2955d..000000000 --- a/pkg/integration/fixtures.go +++ /dev/null @@ -1,111 +0,0 @@ -// +build integration - -package integration - -import ( - "encoding/json" - "fmt" - "github.com/trustwallet/blockatlas/coin" - "github.com/trustwallet/blockatlas/pkg/logger" - "io/ioutil" - "path/filepath" - "strings" -) - -const ( - fixturesFolder = "testdata" // Folder contains the JSON fixtures - bodyFixturesFile = "body_fixtures.json" // Body fixtures for POST requests - coinFixturesFile = "coin_fixtures.json" // Coin fixtures for path parameters - queryFixturesFile = "query_fixtures.json" // Query string for GET requests - excludeApisFile = "exclude.json" // API's need to be excluded from integration tests -) - -type BodyFixture map[string][]interface{} -type CoinFixture map[string]map[string]string -type QueryFixture map[string][]string -type ExcludeApis []string - -var bodyFixture BodyFixture -var coinFixture CoinFixture -var queryFixture QueryFixture -var excludeApis ExcludeApis - -func init() { - geFixtures(bodyFixturesFile, &bodyFixture) - geFixtures(coinFixturesFile, &coinFixture) - geFixtures(queryFixturesFile, &queryFixture) - geFixtures(excludeApisFile, &excludeApis) -} - -func geFixtures(f string, r interface{}) { - b, err := getFile(f) - if err != nil { - logger.Panic(err) - } - err = json.Unmarshal(b[:], &r) - if err != nil { - logger.Panic(err) - } -} - -func isExcluded(path string) bool { - return contains(excludeApis, path) -} - -func getFile(file string) ([]byte, error) { - golden := filepath.Join(fixturesFolder, file) - return ioutil.ReadFile(golden) -} - -func getCoin(path string) coin.Coin { - for _, c := range coin.Coins { - if strings.Contains(path, fmt.Sprintf("/%s/", c.Handle)) { - return c - } - } - return coin.Coin{} -} - -func getBodyTests(path string) []interface{} { - fix, ok := bodyFixture[path] - if !ok { - return []interface{}{nil} - } - return fix -} - -func getQueryTests(path string) []string { - fix, ok := queryFixture[path] - if !ok { - return []string{""} - } - return fix -} - -func addCoinFixtures(path string) string { - c := getCoin(path) - if (c == coin.Coin{}) { - return path - } - fix, ok := coinFixture[c.Handle] - if !ok { - return strings.Replace(path, ":address", c.SampleAddr, -1) - } - if _, ok := fix["address"]; !ok { - return strings.Replace(path, ":address", c.SampleAddr, -1) - } - result := path - for key, value := range fix { - result = strings.Replace(result, ":"+key, value, -1) - } - return result -} - -func contains(s []string, e string) bool { - for _, a := range s { - if a == e { - return true - } - } - return false -} diff --git a/pkg/integration/http.go b/pkg/integration/http.go deleted file mode 100644 index e81264dac..000000000 --- a/pkg/integration/http.go +++ /dev/null @@ -1,101 +0,0 @@ -// +build integration - -package integration - -import ( - "encoding/json" - "fmt" - "github.com/Pantani/httpexpect" - "github.com/trustwallet/blockatlas/pkg/logger" - "net/http" - "sync" - "testing" - "time" -) - -const ( - baseUrl = "http://localhost%s" - schema = `{ - "docs": "array" - }` -) - -type Client struct { - baseUrl string - e *httpexpect.Expect - t *testing.T -} - -func newClient(t *testing.T, port string) *Client { - client := httpexpect.WithConfig(httpexpect.Config{ - BaseURL: getBaseUrl(port), - Client: &http.Client{ - Jar: httpexpect.NewJar(), - Timeout: time.Second * 30, - }, - // use fatal failures - Reporter: httpexpect.NewAssertReporter(t), - // use verbose logging - Printers: []httpexpect.Printer{}, - }) - return &Client{ - baseUrl: getBaseUrl(port), - e: client, - t: t, - } -} - -func (c *Client) testGet(route string, query string) { - request := c.e.GET(route).WithURL(c.baseUrl) - request.WithQueryString(query) - response := request.Expect() - - //TODO create a logic to validate schemas - //response.JSON().Schema(schema) - if response.Raw().StatusCode != http.StatusOK { - logger.Error("Invalid status code", logger.Params{"code": response.Raw().Status, "route": route, "query": query}) - } - response.Status(http.StatusOK) -} - -func (c *Client) testPost(route string, body interface{}) { - request := c.e.POST(route).WithURL(c.baseUrl) - if body == nil { - request.WithText("[]") - } else { - b, err := json.Marshal(body) - if err == nil && b != nil { - request.WithText(string(b)) - } - } - response := request.Expect() - if response.Raw().StatusCode != http.StatusOK { - bodyJson, _ := json.Marshal(body) - logger.Error("Invalid status code", logger.Params{"code": response.Raw().Status, "route": route, "body": bodyJson}) - } - response.Status(http.StatusOK) -} - -func (c *Client) doTests(method, path string, wg *sync.WaitGroup) { - defer wg.Done() - if isExcluded(path) { - return - } - url := addCoinFixtures(path) - switch method { - case "GET": - tests := getQueryTests(path) - for _, query := range tests { - c.testGet(url, query) - } - case "POST": - tests := getBodyTests(path) - for _, body := range tests { - c.testPost(url, body) - } - } -} - -func getBaseUrl(port string) string { - return fmt.Sprintf(baseUrl, port) -} diff --git a/pkg/integration/integration_test.go b/pkg/integration/integration_test.go deleted file mode 100755 index 7dcb07b49..000000000 --- a/pkg/integration/integration_test.go +++ /dev/null @@ -1,41 +0,0 @@ -// +build integration - -package integration - -import ( - "github.com/gin-gonic/gin" - "github.com/trustwallet/blockatlas/cmd" - "github.com/trustwallet/blockatlas/config" - "github.com/trustwallet/blockatlas/pkg/logger" - "github.com/trustwallet/blockatlas/platform" - "os" - "sync" - "testing" - "time" -) - -func TestApis(t *testing.T) { - os.Setenv("ATLAS_GIN_MODE", "debug") - config.LoadConfig(os.Getenv("TEST_CONFIG")) - - logger.InitLogger() - platform.Init() - - p := ":8080" - c := make(chan *gin.Engine) - go func() { - cmd.RunApi(p, c) - }() - e := <-c - time.Sleep(time.Second * 2) - - var wg sync.WaitGroup - cl := newClient(t, p) - for _, r := range e.Routes() { - wg.Add(1) - t.Run(r.Path, func(t *testing.T) { - go cl.doTests(r.Method, r.Path, &wg) - }) - } - wg.Wait() -} diff --git a/pkg/integration/testdata/body_fixtures.json b/pkg/integration/testdata/body_fixtures.json deleted file mode 100644 index d054da461..000000000 --- a/pkg/integration/testdata/body_fixtures.json +++ /dev/null @@ -1,35 +0,0 @@ -{ - "/v2/staking/delegations": [ - [ - { - "coin": 1729, - "address": "tz1eDhCa5PCkomAabH6PG4xdMoNTWKGyBpo1" - } - ] - ], - "/v2/collectibles/categories": [ - { - "60": [ - "0xb3624367b1ab37daef42e1a3a2ced012359659b0" - ] - }, - { - "60": [ - "0x7d8bf18C7cE84b3E175b339c4Ca93aEd1dD166F1" - ] - } - ], - "/v3/collectibles/categories": [ - { - "60": [ - "0xb3624367b1ab37daef42e1a3a2ced012359659b0" - ] - }, - { - "60": [ - "0x7d8bf18C7cE84b3E175b339c4Ca93aEd1dD166F1" - ] - } - ] -} - diff --git a/pkg/integration/testdata/coin_fixtures.json b/pkg/integration/testdata/coin_fixtures.json deleted file mode 100644 index 7d6fe53b2..000000000 --- a/pkg/integration/testdata/coin_fixtures.json +++ /dev/null @@ -1,162 +0,0 @@ -{ - "bitcoin": { - "address": "bc1quvuarfksewfeuevuc6tn0kfyptgjvwsvrprk9d", - "key": "xpub6CUGRUonZSQ4TWtTMmzXdrXDtypWKiKrhko4egpiMZbpiaQL2jkwSB1icqYh2cfDfVxdx4df189oLKnC5fSwqPfgyP3hooxujYzAu3fDVmz" - }, - "litecoin": { - "address": "ltc1qhd8fxxp2dx3vsmpac43z6ev0kllm4n53t5sk0u", - "key": "xprv9s21ZrQH143K277qXR6NRni1DS7qmSNBs96NmnF5VGdcejgrJtBHzRJYZxqDJZKX1pF5i6gmmDmWDbBCs4DcQ9T1bH65UttBRw2uMaNJnNQ" - }, - "bitcoincash": { - "address": "bitcoincash:qq07l6rr5lsdm3m80qxw80ku2ex0tj76vvsxpvmgme", - "key": "xprv9s21ZrQH143K277qXR6NRni1DS7qmSNBs96NmnF5VGdcejgrJtBHzRJYZxqDJZKX1pF5i6gmmDmWDbBCs4DcQ9T1bH65UttBRw2uMaNJnNQ" - }, - "viacoin": { - "address": "via1qnmsgjd6cvfprnszdgmyg9kewtjfgqflz67wwhc", - "key": "xprv9s21ZrQH143K277qXR6NRni1DS7qmSNBs96NmnF5VGdcejgrJtBHzRJYZxqDJZKX1pF5i6gmmDmWDbBCs4DcQ9T1bH65UttBRw2uMaNJnNQ" - }, - "zcash": { - "address": "t1YYnByMzdGhQv3W3rnjHMrJs6HH4Y231gy", - "key": "xprv9s21ZrQH143K277qXR6NRni1DS7qmSNBs96NmnF5VGdcejgrJtBHzRJYZxqDJZKX1pF5i6gmmDmWDbBCs4DcQ9T1bH65UttBRw2uMaNJnNQ" - }, - "zelcash": { - "address": "t1UKbRPzL4WN8Rs8aZ8RNiWoD2ftCMHKGUf", - "key": "xprv9s21ZrQH143K277qXR6NRni1DS7qmSNBs96NmnF5VGdcejgrJtBHzRJYZxqDJZKX1pF5i6gmmDmWDbBCs4DcQ9T1bH65UttBRw2uMaNJnNQ" - }, - "zilliqa": { - "address": "zil1anrjcsj2ntklaa3arq4w3s6gw4l4hqrycs9egy", - "key": "xprv9s21ZrQH143K277qXR6NRni1DS7qmSNBs96NmnF5VGdcejgrJtBHzRJYZxqDJZKX1pF5i6gmmDmWDbBCs4DcQ9T1bH65UttBRw2uMaNJnNQ" - }, - "dash": { - "address": "XqHiz8EXYbTAtBEYs4pWTHh7ipEDQcNQeT", - "key": "xprv9s21ZrQH143K277qXR6NRni1DS7qmSNBs96NmnF5VGdcejgrJtBHzRJYZxqDJZKX1pF5i6gmmDmWDbBCs4DcQ9T1bH65UttBRw2uMaNJnNQ" - }, - "decred": { - "address": "DsTxPUVFxXeNgu5fzozr4mTR4tqqMaKcvpY", - "key": "xprv9s21ZrQH143K277qXR6NRni1DS7qmSNBs96NmnF5VGdcejgrJtBHzRJYZxqDJZKX1pF5i6gmmDmWDbBCs4DcQ9T1bH65UttBRw2uMaNJnNQ" - }, - "doge": { - "address": "DJRFZNg8jkUtjcpo2zJd92FUAzwRjitw6f", - "key": "xprv9s21ZrQH143K277qXR6NRni1DS7qmSNBs96NmnF5VGdcejgrJtBHzRJYZxqDJZKX1pF5i6gmmDmWDbBCs4DcQ9T1bH65UttBRw2uMaNJnNQ" - }, - "ravencoin": { - "address": "RHoCwPc2FCQqwToYnSiAb3SrCET4zEHsbS", - "key": "xprv9s21ZrQH143K277qXR6NRni1DS7qmSNBs96NmnF5VGdcejgrJtBHzRJYZxqDJZKX1pF5i6gmmDmWDbBCs4DcQ9T1bH65UttBRw2uMaNJnNQ" - }, - "zcoin": { - "address": "aEd5XFChyXobvEics2ppAqgK3Bgusjxtik", - "key": "xprv9s21ZrQH143K277qXR6NRni1DS7qmSNBs96NmnF5VGdcejgrJtBHzRJYZxqDJZKX1pF5i6gmmDmWDbBCs4DcQ9T1bH65UttBRw2uMaNJnNQ" - }, - "groestlcoin": { - "address": "grs1qexwmshts5pdpeqglkl39zyl6693tmfwp0cue4j", - "key": "xprv9s21ZrQH143K277qXR6NRni1DS7qmSNBs96NmnF5VGdcejgrJtBHzRJYZxqDJZKX1pF5i6gmmDmWDbBCs4DcQ9T1bH65UttBRw2uMaNJnNQ" - }, - "qtum": { - "address": "QhceuaTdeCZtcxmVc6yyEDEJ7Riu5gWFoF", - "key": "xprv9s21ZrQH143K277qXR6NRni1DS7qmSNBs96NmnF5VGdcejgrJtBHzRJYZxqDJZKX1pF5i6gmmDmWDbBCs4DcQ9T1bH65UttBRw2uMaNJnNQ" - }, - "digibyte": { - "address": "D8NBg12kfW8uLjzCv7LYnPYCNhqvVtHaMQ", - "key": "xprv9s21ZrQH143K277qXR6NRni1DS7qmSNBs96NmnF5VGdcejgrJtBHzRJYZxqDJZKX1pF5i6gmmDmWDbBCs4DcQ9T1bH65UttBRw2uMaNJnNQ" - }, - "tomochain": { - "address": "0x0875BCab22dE3d02402bc38aEe4104e1239374a7", - "owner": "0x0875BCab22dE3d02402bc38aEe4104e1239374a7", - "collections": "0x0875BCab22dE3d02402bc38aEe4104e1239374a7", - "collection_id": "0xfaafdc07907ff5120a76b34b731b278c38d6043c" - }, - "ethereum": { - "address": "0x0875BCab22dE3d02402bc38aEe4104e1239374a7", - "owner": "0x0875BCab22dE3d02402bc38aEe4104e1239374a7", - "collections": "0x0875BCab22dE3d02402bc38aEe4104e1239374a7", - "collection_id": "ens" - }, - "classic": { - "address": "0x0875BCab22dE3d02402bc38aEe4104e1239374a7", - "owner": "0x0875BCab22dE3d02402bc38aEe4104e1239374a7", - "collections": "0x0875BCab22dE3d02402bc38aEe4104e1239374a7", - "collection_id": "0xfaafdc07907ff5120a76b34b731b278c38d6043c" - }, - "poa": { - "address": "0x0875BCab22dE3d02402bc38aEe4104e1239374a7", - "owner": "0x0875BCab22dE3d02402bc38aEe4104e1239374a7", - "collections": "0x0875BCab22dE3d02402bc38aEe4104e1239374a7", - "collection_id": "0xfaafdc07907ff5120a76b34b731b278c38d6043c" - }, - "thundertoken": { - "address": "0x0875BCab22dE3d02402bc38aEe4104e1239374a7", - "owner": "0x0875BCab22dE3d02402bc38aEe4104e1239374a7", - "collections": "0x0875BCab22dE3d02402bc38aEe4104e1239374a7", - "collection_id": "0xfaafdc07907ff5120a76b34b731b278c38d6043c" - }, - "callisto": { - "address": "0x0875BCab22dE3d02402bc38aEe4104e1239374a7", - "owner": "0x0875BCab22dE3d02402bc38aEe4104e1239374a7", - "collections": "0x0875BCab22dE3d02402bc38aEe4104e1239374a7", - "collection_id": "0xfaafdc07907ff5120a76b34b731b278c38d6043c" - }, - "gochain": { - "address": "0x0875BCab22dE3d02402bc38aEe4104e1239374a7", - "owner": "0x0875BCab22dE3d02402bc38aEe4104e1239374a7", - "collections": "0x0875BCab22dE3d02402bc38aEe4104e1239374a7", - "collection_id": "0xfaafdc07907ff5120a76b34b731b278c38d6043c" - }, - "theta": { - "address": "0xac0eeb6ee3e32e2c74e14ac74155063e4f4f981f" - }, - "binance": { - "address": "bnb1jxfh2g85q3v0tdq56fnevx6xcxtcnhtsmcu64m" - }, - "tezos": { - "address": "tz1WCd2jm4uSt4vntk4vSuUWoZQGhLcDuR9q" - }, - "tron": { - "address": "TQZskDJJRGAHifeKoQ7wLC4QDyB2iGvwp2" - }, - "vechain": { - "address": "0xB5e883349e68aB59307d1604555AC890fAC47128" - }, - "ripple": { - "address": "rMQ98K56yXJbDGv49ZSmW51sLn94Xe1mu1" - }, - "cosmos": { - "address": "cosmos1rw62phusuv9vzraezr55k0vsqssvz6ed52zyrl" - }, - "iotex": { - "address": "io154mvzs09vkgn0hw6gg3ayzw5w39jzp47f8py9v" - }, - "icon": { - "address": "hxee691e7bccc4eb11fee922896e9f51490e62b12e" - }, - "stellar": { - "address": "GDKIJJIKXLOM2NRMPNQZUUYK24ZPVFC6426GZAEP3KUK6KEJLACCWNMX" - }, - "semux": { - "address": "0x8197987c401a3466ad678b2080b24838ebd95b41" - }, - "nimiq": { - "address": "NQ94HC9AK9D83FSJM6PT8XGNNMXLR0E53Y07" - }, - "nebulas": { - "address": "n1RCYwrpLMpSpUCQ8QUDzGRg6B2PnY8R94a" - }, - "aeternity": { - "address": "ak_2p5878zbFhxnrm7meL7TmqwtvBaqcBddyp5eGzZbovZ5FeVfcw" - }, - "aion": { - "address": "0000000000000000000000000000000000000000000000000000000000000000" - }, - "fio": { - "address": "FIO5J2xdfWygeNdHZNZRzRws8YGbVxjUXtp4eP8KoGkGKoLFQ7CaU" - }, - "kin": { - "address": "GBHKUZ7C2SZ5N3X2S7O6TT6LNUWSEA2BXMSR5GTTSR6VZARSVAXIQNGH" - }, - "ontology": { - "address": "AUyL4TZ1zFEcSKDJrjFnD7vsq5iFZMZqT7" - }, - "waves": { - "address": "3P7wz6TXienpw3BHe8eHUEuZWb6WE58kgnQ" - } -} - diff --git a/pkg/integration/testdata/exclude.json b/pkg/integration/testdata/exclude.json deleted file mode 100644 index 3620e6450..000000000 --- a/pkg/integration/testdata/exclude.json +++ /dev/null @@ -1,29 +0,0 @@ -[ - "/swagger/*any", - "/v2/collectibles/categories", - "/v3/collectibles/categories", - "/v2/classic/collections/:owner", - "/v2/callisto/collections/:owner", - "/v2/poa/collections/:owner", - "/v2/thundertoken/collections/:owner", - "/v2/tomochain/collections/:owner", - "/v2/gochain/collections/:owner", - "/v2/classic/collections/:owner/collection/:collection_id", - "/v2/callisto/collections/:owner/collection/:collection_id", - "/v2/poa/collections/:owner/collection/:collection_id", - "/v2/thundertoken/collections/:owner/collection/:collection_id", - "/v2/tomochain/collections/:owner/collection/:collection_id", - "/v2/gochain/collections/:owner/collection/:collection_id", - "/v3/classic/collections/:owner", - "/v3/callisto/collections/:owner", - "/v3/poa/collections/:owner", - "/v3/thundertoken/collections/:owner", - "/v3/tomochain/collections/:owner", - "/v3/gochain/collections/:owner", - "/v3/classic/collections/:owner/collection/:collection_id", - "/v3/callisto/collections/:owner/collection/:collection_id", - "/v3/poa/collections/:owner/collection/:collection_id", - "/v3/thundertoken/collections/:owner/collection/:collection_id", - "/v3/tomochain/collections/:owner/collection/:collection_id", - "/v3/gochain/collections/:owner/collection/:collection_id" -] diff --git a/pkg/integration/testdata/query_fixtures.json b/pkg/integration/testdata/query_fixtures.json deleted file mode 100644 index 0e73c21d2..000000000 --- a/pkg/integration/testdata/query_fixtures.json +++ /dev/null @@ -1,28 +0,0 @@ -{ - "/ns/lookup": [ - "name=vitalik.eth&coin=60", - "name=vitalik.luxe&coin=60", - "name=ourxyzwallet.xyz&coin=60", - "name=btc.zil&coin=313", - "name=btc.crypto&coin=313" - ], - "/v2/ns/lookup": [ - "name=vitalik.eth&coins=60", - "name=vitalik.luxe&coins=60", - "name=ourxyzwallet.xyz&coins=60", - "name=btc.zil&coins=313", - "name=btc.crypto&coins=313" - ], - "/v1/market/charts": [ - "currency=USD&time_start=1574483028&coin=60&token=0xdAC17F958D2ee523a2206206994597C13D831ec7", - "currency=EUR&time_start=1574483028&coin=60&token=0xdAC17F958D2ee523a2206206994597C13D831ec7", - "currency=USD&time_start=1574483028&coin=0", - "currency=USD&time_start=1574483028&coin=60" - ], - "/v1/market/info": [ - "currency=USD&coin=60&token=0xdAC17F958D2ee523a2206206994597C13D831ec7", - "currency=EUR&coin=60&token=0xdAC17F958D2ee523a2206206994597C13D831ec7", - "currency=USD&coin=0", - "currency=USD&coin=60" - ] -} diff --git a/pkg/logger/error.go b/pkg/logger/error.go deleted file mode 100755 index 5e7a37bf8..000000000 --- a/pkg/logger/error.go +++ /dev/null @@ -1,58 +0,0 @@ -package logger - -import ( - log "github.com/sirupsen/logrus" - "github.com/trustwallet/blockatlas/pkg/errors" -) - -type errMessage struct { - *message - err error -} - -func Error(args ...interface{}) { - if len(args) == 0 { - Panic("call to logger.Error with no arguments") - } - e := getError(args...) - log.WithFields(e.params).Error(e.err) -} - -func Fatal(args ...interface{}) { - if len(args) == 0 { - Panic("call to logger.Fatal with no arguments") - } - e := getError(args...) - errors.SendFatal(e.err) - log.WithFields(e.params).Fatal(e.err) -} - -func Panic(args ...interface{}) { - if len(args) == 0 { - Panic("call to logger.Panic with no arguments") - } - e := getError(args...) - errors.SendFatal(e.err) - log.WithFields(e.params).Panic(e.err) -} - -func getError(args ...interface{}) *errMessage { - msg := getMessage(args...) - err := &errMessage{message: msg} - for _, arg := range args { - switch arg := arg.(type) { - case *errors.Error: - err.err = arg - case error: - err.err = errors.E(arg) - case nil: - continue - default: - continue - } - } - if err.err == nil { - err.err = errors.E(msg.message, msg.params) - } - return err -} diff --git a/pkg/logger/logger.go b/pkg/logger/logger.go deleted file mode 100755 index 92e6130bd..000000000 --- a/pkg/logger/logger.go +++ /dev/null @@ -1,91 +0,0 @@ -package logger - -import ( - "fmt" - log "github.com/sirupsen/logrus" - "github.com/trustwallet/blockatlas/pkg/errors" - "os" - "strings" -) - -type Params map[string]interface{} - -func InitLogger() { - log.SetFormatter(&log.TextFormatter{}) - log.SetOutput(os.Stdout) - err := errors.InitSentry() - if err != nil { - Error(err) - } -} - -type message struct { - message string - params map[string]interface{} -} - -func (msg *message) String() string { - if len(msg.params) > 0 { - return fmt.Sprintf("%s - %v", msg.message, msg.params) - } - return fmt.Sprintf("%s", msg.message) -} - -func Info(args ...interface{}) { - if len(args) == 0 { - Panic("call to logger.Info with no arguments") - } - msg := getMessage(args...) - log.WithFields(msg.params).Info(msg.message) -} - -func Debug(args ...interface{}) { - if len(args) == 0 { - Panic("call to logger.Debug with no arguments") - } - msg := getMessage(args...) - log.WithFields(msg.params).Debug(msg.message) -} - -func Warn(args ...interface{}) { - if len(args) == 0 { - Panic("call to logger.Warn with no arguments") - } - msg := getMessage(args...) - log.WithFields(msg.params).Warn(msg.message) -} - -func getMessage(args ...interface{}) *message { - msg := &message{params: make(Params), message: ""} - var generic []string - var message []string - for _, arg := range args { - switch arg := arg.(type) { - case nil: - continue - case error: - continue - case string: - message = append(message, arg) - case Params: - appendMap(msg.params, arg) - case map[string]interface{}: - appendMap(msg.params, arg) - default: - generic = append(generic, fmt.Sprintf("%s", arg)) - } - } - if len(message) > 0 { - msg.message = strings.Join(message[:], ": ") - } - if len(generic) > 0 { - msg.params["objects"] = strings.Join(generic[:], " | ") - } - return msg -} - -func appendMap(root map[string]interface{}, tmp map[string]interface{}) { - for k, v := range tmp { - root[k] = v - } -} diff --git a/pkg/metrics/client.go b/pkg/metrics/client.go deleted file mode 100644 index e7c5a55fc..000000000 --- a/pkg/metrics/client.go +++ /dev/null @@ -1,35 +0,0 @@ -package metrics - -import ( - "github.com/prometheus/client_golang/prometheus" - "time" -) - -const ( - clientNamespace = "client" -) - -var ( - clientLabels = []string{"status", "endpoint", "method"} - clientReqCount = prometheus.NewCounterVec( - prometheus.CounterOpts{ - Namespace: clientNamespace, - Name: "http_request_count_total", - Help: "Total number of HTTP requests made.", - }, clientLabels, - ) - clientReqDuration = prometheus.NewHistogramVec( - prometheus.HistogramOpts{ - Namespace: clientNamespace, - Name: "http_request_duration_seconds", - Help: "HTTP request latencies in seconds.", - }, clientLabels, - ) -) - -func GetMetrics(status, url, method string, start time.Time) { - endpoint := removeSensitiveInfo(url) - lvs := []string{status, endpoint, method} - clientReqCount.WithLabelValues(lvs...).Inc() - clientReqDuration.WithLabelValues(lvs...).Observe(time.Since(start).Seconds()) -} diff --git a/pkg/metrics/metrics.go b/pkg/metrics/metrics.go deleted file mode 100644 index 4c7c2a534..000000000 --- a/pkg/metrics/metrics.go +++ /dev/null @@ -1,16 +0,0 @@ -package metrics - -import ( - "github.com/prometheus/client_golang/prometheus" - "regexp" -) - -// init registers the prometheus metrics -func init() { - prometheus.MustRegister(clientReqCount, clientReqDuration, serverReqCount, serverReqDuration, serverReqSizeBytes, serverRespSizeBytes) -} - -func removeSensitiveInfo(info string) string { - reg := regexp.MustCompile(`([a-zA-Z0-9\s]{30,})|([0-9]{4,})|(=(.*?)[^(&|$)]+)|(--[^$]+)|(&asset_contract_addresses)`) - return reg.ReplaceAllString(info, "") -} diff --git a/pkg/metrics/metrics_test.go b/pkg/metrics/metrics_test.go deleted file mode 100644 index debf02503..000000000 --- a/pkg/metrics/metrics_test.go +++ /dev/null @@ -1,24 +0,0 @@ -package metrics - -import "testing" - -func Test_removeSensitiveInfo(t *testing.T) { - tests := []struct { - name string - info string - want string - }{ - {"Remove Nimiq address", "/v1/nimiq/NQ43 J7G6 K6T8 H5KJ 5CXN Q5JK 2GJ4 6DSB 7PUH", "/v1/nimiq/"}, - {"Remove Tezos address", "/v1/tezos/tz1WCd2jm4uSt4vntk4vSuUWoZQGhLcDuR9q", "/v1/tezos/"}, - {"Remove Tron info", "https://api.trongrid.io/v1/accounts/TPJYCz8ppZNyvw7pTwmjajcx4Kk1MmEUhD/transactions?limit=200&only_confirmed=true&token_id=1000011", "https://api.trongrid.io/v1/accounts//transactions?limit&only_confirmed&token_id"}, - {"Remove asset id", "https://api.trongrid.io/v1/assets/1000570?", "https://api.trongrid.io/v1/assets/?"}, - {"Remove collection id", "/v2/ethereum/collections//collection/---enjin-old", "/v2/ethereum/collections//collection/"}, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - if got := removeSensitiveInfo(tt.info); got != tt.want { - t.Errorf("removeSensitiveInfo() = %v, want %v", got, tt.want) - } - }) - } -} diff --git a/pkg/metrics/server.go b/pkg/metrics/server.go deleted file mode 100644 index f95777e2c..000000000 --- a/pkg/metrics/server.go +++ /dev/null @@ -1,89 +0,0 @@ -package metrics - -import ( - "fmt" - "github.com/gin-gonic/gin" - "github.com/prometheus/client_golang/prometheus" - "net/http" - "time" -) - -const ( - serverNamespace = "server" -) - -var ( - serverLabels = []string{"status", "endpoint", "method"} - serverReqCount = prometheus.NewCounterVec( - prometheus.CounterOpts{ - Namespace: serverNamespace, - Name: "http_request_count_total", - Help: "Total number of HTTP requests made.", - }, serverLabels, - ) - serverReqDuration = prometheus.NewHistogramVec( - prometheus.HistogramOpts{ - Namespace: serverNamespace, - Name: "http_request_duration_seconds", - Help: "HTTP request latencies in seconds.", - }, serverLabels, - ) - - serverReqSizeBytes = prometheus.NewSummaryVec( - prometheus.SummaryOpts{ - Namespace: serverNamespace, - Name: "http_request_size_bytes", - Help: "HTTP request sizes in bytes.", - }, serverLabels, - ) - serverRespSizeBytes = prometheus.NewSummaryVec( - prometheus.SummaryOpts{ - Namespace: serverNamespace, - Name: "http_response_size_bytes", - Help: "HTTP request sizes in bytes.", - }, serverLabels, - ) -) - -func PromMiddleware() gin.HandlerFunc { - return func(c *gin.Context) { - start := time.Now() - c.Next() - - status := fmt.Sprintf("%d", c.Writer.Status()) - url := c.Request.URL.Path - method := c.Request.Method - - endpoint := removeSensitiveInfo(url) - lvs := []string{status, endpoint, method} - - serverReqCount.WithLabelValues(lvs...).Inc() - serverReqDuration.WithLabelValues(lvs...).Observe(time.Since(start).Seconds()) - serverReqSizeBytes.WithLabelValues(lvs...).Observe(calcRequestSize(c.Request)) - serverRespSizeBytes.WithLabelValues(lvs...).Observe(float64(c.Writer.Size())) - } -} - -func calcRequestSize(r *http.Request) float64 { - size := 0 - if r.URL != nil { - size = len(r.URL.String()) - } - - size += len(r.Method) - size += len(r.Proto) - - for name, values := range r.Header { - size += len(name) - for _, value := range values { - size += len(value) - } - } - size += len(r.Host) - - // r.Form and r.MultipartForm are assumed to be included in r.URL. - if r.ContentLength != -1 { - size += int(r.ContentLength) - } - return float64(size) -} diff --git a/pkg/numbers/amount.go b/pkg/numbers/amount.go deleted file mode 100644 index d5b202181..000000000 --- a/pkg/numbers/amount.go +++ /dev/null @@ -1,34 +0,0 @@ -package numbers - -import ( - "math" - "strconv" -) - -func GetAmountValue(amount string) string { - value := ParseAmount(amount) - return strconv.FormatInt(value, 10) -} - -func ParseAmount(amount string) int64 { - value, err := strconv.ParseInt(amount, 10, 64) - if err == nil { - return value - } - return ToSatoshi(amount) -} - -func ToSatoshi(amount string) int64 { - value, err := strconv.ParseFloat(amount, 64) - if err != nil { - return 0 - } - total := value * math.Pow10(8) - return int64(total) -} - -func AddAmount(left string, right string) (sum string) { - amount1 := ParseAmount(left) - amount2 := ParseAmount(right) - return strconv.FormatInt(amount1+amount2, 10) -} diff --git a/pkg/numbers/amount_test.go b/pkg/numbers/amount_test.go deleted file mode 100644 index 5b95462d5..000000000 --- a/pkg/numbers/amount_test.go +++ /dev/null @@ -1,94 +0,0 @@ -package numbers - -import ( - "testing" -) - -func Test_addAmount(t *testing.T) { - type args struct { - left string - right string - } - tests := []struct { - name string - args args - wantSum string - }{ - {"test zero + float", args{left: "0", right: "0.33333"}, "33333000"}, - {"test zero + int", args{left: "0", right: "333"}, "333"}, - {"test zero + zero", args{left: "0", right: "0"}, "0"}, - {"test int + float", args{left: "232", right: "0.222"}, "22200232"}, - {"test int + int", args{left: "661", right: "12"}, "673"}, - {"test int + zero", args{left: "131", right: "0"}, "131"}, - {"test float + float", args{left: "0.4141", right: "0.11211"}, "52621000"}, - {"test float + int", args{left: "3.111", right: "11"}, "311100011"}, - {"test float + zero", args{left: "0.455", right: "0"}, "45500000"}, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - if gotSum := AddAmount(tt.args.left, tt.args.right); gotSum != tt.wantSum { - t.Errorf("AddAmount() = %v, want %v", gotSum, tt.wantSum) - } - }) - } -} - -func Test_decimalToSatoshis(t *testing.T) { - tests := []struct { - name string - amount string - want int64 - }{ - {"test float", "0.33333", 33333000}, - {"test int", "3333", 333300000000}, - {"test zero", "0", 0}, - {"test error", "trust", 0}, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - if got := ToSatoshi(tt.amount); got != tt.want { - t.Errorf("decimalToSatoshis() = %v, want %v", got, tt.want) - } - }) - } -} - -func Test_getValue(t *testing.T) { - tests := []struct { - name string - amount string - want string - }{ - {"test float", "0.33333", "33333000"}, - {"test int", "3333", "3333"}, - {"test zero", "0", "0"}, - {"test error", "trust", "0"}, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - if got := GetAmountValue(tt.amount); got != tt.want { - t.Errorf("GetAmountValue() = %v, want %v", got, tt.want) - } - }) - } -} - -func Test_parseAmount(t *testing.T) { - tests := []struct { - name string - amount string - want int64 - }{ - {"test float", "0.33333", 33333000}, - {"test int", "3333", 3333}, - {"test zero", "0", 0}, - {"test error", "trust", 0}, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - if got := ParseAmount(tt.amount); got != tt.want { - t.Errorf("ParseAmount() = %v, want %v", got, tt.want) - } - }) - } -} diff --git a/pkg/numbers/decimal.go b/pkg/numbers/decimal.go deleted file mode 100644 index 51ce48a94..000000000 --- a/pkg/numbers/decimal.go +++ /dev/null @@ -1,94 +0,0 @@ -package numbers - -import ( - "github.com/trustwallet/blockatlas/pkg/errors" - "math/big" - "strings" - "unicode" -) - -// DecimalToSatoshis removes the comma in a decimal string -// "12.345" => "12345" -// "0.0230" => "230" -func DecimalToSatoshis(dec string) (string, error) { - out := strings.Replace(dec, ".", "", 1) - out = strings.TrimLeft(out, "0") - for _, c := range out { - if !unicode.IsNumber(c) { - return "", errors.E("not a number", errors.Params{"dec": dec, "c": c}).PushToSentry() - } - } - return out, nil -} - -// DecimalExp calculates dec * 10^exp in decimal string representation -func DecimalExp(dec string, exp int) string { - // 0 * n = 0 - if dec == "0" { - return "0" - } - // Get comma position - i := strings.IndexRune(dec, '.') - if i == -1 { - // Virtual comma at the end of the string - i = len(dec) - } else { - // Remove comma from underlying number - dec = strings.Replace(dec, ".", "", 1) - } - // Shift comma by exponent - i += exp - // Remove leading zeros - origSize := len(dec) - dec = strings.TrimLeft(dec, "0") - i -= origSize - len(dec) - // Fix bounds - if i <= 0 { - zeros := "" - for ; i < 0; i++ { - zeros += "0" - } - return "0." + zeros + dec - } else if i >= len(dec) { - for i > len(dec) { - dec += "0" - } - return dec - } - // No bound fix needed - return dec[:i] + "." + dec[i:] -} - -// HexToDecimal converts a hexadecimal integer to a base-10 integer -// "0x1fbad5f2e25570000" => "36582000000000000000" -func HexToDecimal(hex string) (string, error) { - var i big.Int - if _, ok := i.SetString(hex, 0); !ok { - return "", errors.E("invalid hex", errors.Params{"hex": hex}).PushToSentry() - } - return i.String(), nil -} - -// CutZeroFractional cuts off a decimal separator and zeros to the right. -// Fails if the fractional part contains contains other digits than zeros. -// - CutZeroFractional("123.00000") => ("123", true) -// - CutZeroFractional("123.456") => ("", false) -func CutZeroFractional(dec string) (integer string, ok bool) { - // Get comma position - comma := strings.IndexRune(dec, '.') - if comma == -1 { - return dec, true - } - - for i := len(dec) - 1; i > comma; i-- { - if dec[i] != '0' { - return "", false - } - } - - if comma == 0 { - return "0", true - } else { - return dec[:comma], true - } -} diff --git a/pkg/numbers/decimal_test.go b/pkg/numbers/decimal_test.go deleted file mode 100644 index b32ed8977..000000000 --- a/pkg/numbers/decimal_test.go +++ /dev/null @@ -1,92 +0,0 @@ -package numbers - -import "testing" - -func TestDecimalToSatoshis(t *testing.T) { - assertSatEquals := func(expected string, input string) { - actual, err := DecimalToSatoshis(input) - if err != nil { - t.Error(err) - } - if expected != actual { - t.Errorf("expected: %s, got %s", expected, actual) - } - } - - assertSatEquals("10", "1.0") - assertSatEquals("1", "0.1") - assertSatEquals("13602", "136.02") - assertSatEquals("1500000", "0.01500000") -} - -func TestDecimalExp(t *testing.T) { - assertEquals := func(inputDec string, inputExp int, expected string) { - actual := DecimalExp(inputDec, inputExp) - if expected != actual { - t.Errorf("expected: %s * (10^%d) = %s, got %s", - inputDec, inputExp, expected, actual) - } - } - - // No-Op - assertEquals("0", 300, "0") - assertEquals("123", 0, "123") - assertEquals("0.456", 0, "0.456") - assertEquals("123.456", 0, "123.456") - - // In-Bounds, comma - assertEquals("12.34", -1, "1.234") - assertEquals("12.34", 1, "123.4") - - // 1 past bounds, comma - assertEquals("12.34", -2, "0.1234") - assertEquals("12.34", 2, "1234") - - // n past bounds, comma - assertEquals("12.34", -4, "0.001234") - assertEquals("12.34", 4, "123400") - - // Integer - assertEquals("1234", -1, "123.4") - assertEquals("1234", 1, "12340") - - // Denormalized - assertEquals("0.1234", -1, "0.01234") - assertEquals("0.1234", 1, "1.234") - - // Tiny - assertEquals("0.001234", -1, "0.0001234") - assertEquals("0.001234", 1, "0.01234") -} - -func TestCutZeroFractional(t *testing.T) { - assertEquals := func(inputDec string, expected string, expOk bool) { - actual, ok := CutZeroFractional(inputDec) - if expected != actual || ok != expOk { - t.Errorf("expected: %s => (%s, %v), actual: (%s, %v)", - inputDec, expected, expOk, actual, ok) - } - } - - // No comma - assertEquals("", "", true) - assertEquals("eee", "eee", true) - - // Length 1 - assertEquals(".", "0", true) - assertEquals(".3", "", false) - assertEquals(".0", "0", true) - assertEquals("0.", "0", true) - assertEquals("1.0", "1", true) - assertEquals("1.1", "", false) - assertEquals("1.0.0", "", false) - - // Arbitrary content left to comma - assertEquals("eee.000", "eee", true) - assertEquals("eee.001", "", false) - assertEquals("eee.100", "", false) - - // Long strings - assertEquals("163056848705309039018274728757999527956626319283048085297785610.238523", "", false) - assertEquals("11434397695550368380599182733571088333799363173941798154.0000000000000", "11434397695550368380599182733571088333799363173941798154", true) -} diff --git a/pkg/numbers/number.go b/pkg/numbers/number.go deleted file mode 100644 index 916f219af..000000000 --- a/pkg/numbers/number.go +++ /dev/null @@ -1,71 +0,0 @@ -package numbers - -import ( - "github.com/shopspring/decimal" - "github.com/trustwallet/blockatlas/pkg/errors" - "math" - "math/big" - "strconv" - "strings" -) - -func Min(x, y int) int { - if x < y { - return x - } - return y -} - -func Max(x, y int64) int64 { - if x > y { - return x - } - return y -} - -func Round(num float64) int { - return int(num + math.Copysign(0.5, num)) -} - -func Float64toPrecision(num float64, precision int) float64 { - output := math.Pow(10, float64(precision)) - return float64(Round(num*output)) / output -} - -func FromDecimal(dec string) string { - v, err := DecimalToSatoshis(dec) - if err != nil { - return "0" - } - return v -} - -func ToDecimal(value string, exp int) string { - num, ok := new(big.Int).SetString(value, 10) - if !ok { - return "0" - } - denom := new(big.Int).Exp(big.NewInt(10), big.NewInt(int64(exp)), nil) - rat := new(big.Rat).SetFrac(num, denom) - f, err := decimal.NewFromString(rat.FloatString(10)) - if err != nil { - return "0" - } - return f.String() -} - -func FromDecimalExp(dec string, exp int) string { - return strings.Split(DecimalExp(dec, exp), ".")[0] -} - -func SliceAtoi(sa []string) ([]int, error) { - si := make([]int, 0, len(sa)) - for _, a := range sa { - i, err := strconv.Atoi(a) - if err != nil { - return si, errors.E(err, "SliceAtoi error", errors.Params{"sa": sa}) - } - si = append(si, i) - } - return si, nil -} diff --git a/pkg/numbers/number_test.go b/pkg/numbers/number_test.go deleted file mode 100644 index 522f39f17..000000000 --- a/pkg/numbers/number_test.go +++ /dev/null @@ -1,56 +0,0 @@ -package numbers - -import ( - "github.com/stretchr/testify/assert" - "testing" -) - -func TestMin(t *testing.T) { - assert.Equal(t, Min(1, 5), 1) - assert.Equal(t, Min(22, 5), 5) -} - -func TestMax(t *testing.T) { - assert.Equal(t, Max(1, 5), int64(5)) - assert.Equal(t, Max(22, 5), int64(22)) -} - -func TestToDecimal(t *testing.T) { - assert.Equal(t, ToDecimal("0", 18), "0") - assert.Equal(t, ToDecimal("100", 1), "10") - assert.Equal(t, ToDecimal("123123", 3), "123.123") - assert.Equal(t, ToDecimal("10012000000000000", 12), "10012") - assert.Equal(t, ToDecimal("123456789012345678901", 18), "123.4567890123") - assert.Equal(t, ToDecimal("4618", 6), "0.004618") - assert.Equal(t, ToDecimal("218218", 8), "0.00218218") - assert.Equal(t, ToDecimal("212880628", 9), "0.212880628") - assert.Equal(t, ToDecimal("4634460765323682", 18), "0.0046344608") -} - -func TestFromDecimal(t *testing.T) { - assert.Equal(t, FromDecimal("100.12"), "10012") -} - -func TestToDecimalExp(t *testing.T) { - assert.Equal(t, FromDecimalExp("10", 1), "100") - assert.Equal(t, FromDecimalExp("100", 1), "1000") - assert.Equal(t, FromDecimalExp("10012", 12), "10012000000000000") - assert.Equal(t, FromDecimalExp("123.123", 3), "123123") - //assert.Equal(t, FromDecimalExp("0.005170630816959669", 2), "") Need fix - assert.Equal(t, FromDecimalExp("0.000180508184692364", 4), "1") - assert.Equal(t, FromDecimalExp("0.004618071835862274", 6), "4618") - assert.Equal(t, FromDecimalExp("0.00216013705800604", 8), "216013") - assert.Equal(t, FromDecimalExp("0.002182187913804679", 8), "218218") - assert.Equal(t, FromDecimalExp("0.21288062808828456", 9), "212880628") - assert.Equal(t, FromDecimalExp("0.004634460765323682", 18), "4634460765323682") - assert.Equal(t, FromDecimalExp("0.00000001", 8), "1") - assert.Equal(t, FromDecimalExp("10.00000000", 8), "1000000000") -} - -func TestFloat64toPrecision(t *testing.T) { - assert.Equal(t, Float64toPrecision(3.643005, 4), 3.6430) - assert.Equal(t, Float64toPrecision(9.8233168e-5, 4), 0.0001) - assert.Equal(t, Float64toPrecision(0.8010, 4), 0.8010) - assert.Equal(t, Float64toPrecision(26.5, 4), 26.5) - assert.Equal(t, Float64toPrecision(3374, 4), 3374.0) -} diff --git a/pkg/semaphore/semaphore.go b/pkg/semaphore/semaphore.go deleted file mode 100644 index e46e33262..000000000 --- a/pkg/semaphore/semaphore.go +++ /dev/null @@ -1,17 +0,0 @@ -package semaphore - -type Semaphore struct { - c chan bool -} - -func NewSemaphore(n int) *Semaphore { - return &Semaphore{make(chan bool, n)} -} - -func (s *Semaphore) Acquire() { - s.c <- true -} - -func (s *Semaphore) Release() { - <-s.c -} diff --git a/pkg/storage/redis/hmap.go b/pkg/storage/redis/hmap.go deleted file mode 100644 index d7637921a..000000000 --- a/pkg/storage/redis/hmap.go +++ /dev/null @@ -1,51 +0,0 @@ -package redis - -import ( - "encoding/json" - "github.com/trustwallet/blockatlas/pkg/errors" - "github.com/trustwallet/blockatlas/pkg/storage/util" -) - -func (db *Redis) GetAllHM(entity string) (map[string]string, error) { - cmd := db.client.HGetAll(entity) - if cmd.Err() != nil { - return nil, errors.E(cmd.Err(), util.ErrNotFound).PushToSentry() - } - return cmd.Val(), nil -} - -func (db *Redis) GetHMValue(entity, key string, value interface{}) error { - cmd := db.client.HMGet(entity, key) - if cmd.Err() != nil { - return errors.E(cmd.Err(), util.ErrNotFound).PushToSentry() - } - val, ok := cmd.Val()[0].(string) - if !ok { - return errors.E(util.ErrNotFound).PushToSentry() - } - err := json.Unmarshal([]byte(val), value) - if err != nil { - return errors.E(err, util.ErrNotFound).PushToSentry() - } - return nil -} - -func (db *Redis) AddHM(entity, key string, value interface{}) error { - j, err := json.Marshal(value) - if err != nil { - return errors.E(err, errors.Params{"value": value}).PushToSentry() - } - cmd := db.client.HMSet(entity, map[string]interface{}{key: j}) - if cmd.Err() != nil { - return errors.E(cmd.Err(), util.ErrNotStored).PushToSentry().PushToSentry() - } - return nil -} - -func (db *Redis) DeleteHM(entity, key string) error { - cmd := db.client.HDel(entity, key) - if cmd.Err() != nil { - return errors.E(cmd.Err(), util.ErrNotDeleted).PushToSentry() - } - return nil -} diff --git a/pkg/storage/redis/redis.go b/pkg/storage/redis/redis.go deleted file mode 100644 index 61d51b6c1..000000000 --- a/pkg/storage/redis/redis.go +++ /dev/null @@ -1,64 +0,0 @@ -package redis - -import ( - "encoding/json" - "github.com/go-redis/redis" - "github.com/trustwallet/blockatlas/pkg/errors" - "github.com/trustwallet/blockatlas/pkg/storage/util" -) - -type Redis struct { - client *redis.Client -} - -func (db *Redis) Init(host string) error { - options, err := redis.ParseURL(host) - if err != nil { - return errors.E(err, "Cannot connect to Redis") - } - client := redis.NewClient(options) - if err := client.Ping().Err(); err != nil { - return errors.E(err, "Redis connection test failed") - } - db.client = client - return nil -} - -func (db *Redis) GetValue(key string, value interface{}) error { - cmd := db.client.Get(key) - if cmd.Err() != nil { - return errors.E(cmd.Err(), util.ErrNotFound) - } - err := json.Unmarshal([]byte(cmd.Val()), value) - if err != nil { - return errors.E(err, util.ErrNotFound) - } - return nil -} - -func (db *Redis) Add(key string, value interface{}) error { - j, err := json.Marshal(value) - if err != nil { - return errors.E(err, errors.Params{"value": value}) - } - cmd := db.client.Set(key, j, 0) - if cmd.Err() != nil { - return errors.E(cmd.Err(), util.ErrNotStored) - } - return nil -} - -func (db *Redis) Delete(key string) error { - cmd := db.client.Del(key) - if cmd.Err() != nil { - return errors.E(cmd.Err(), util.ErrNotDeleted) - } - return nil -} - -func (db *Redis) IsReady() bool { - if db.client == nil { - return false - } - return db.client.Ping().Err() == nil -} diff --git a/pkg/storage/sql/postgres.go b/pkg/storage/sql/postgres.go deleted file mode 100644 index 51b903703..000000000 --- a/pkg/storage/sql/postgres.go +++ /dev/null @@ -1,32 +0,0 @@ -package sql - -import ( - "github.com/jinzhu/gorm" - _ "github.com/jinzhu/gorm/dialects/postgres" - "github.com/trustwallet/blockatlas/pkg/logger" - "time" -) - -type PgSql struct { - sql -} - -func (db *PgSql) Init(host string) { - client, err := gorm.Open("postgres", host) - if err != nil { - logger.Fatal(err, "postgress connection failed") - } - client.DB().SetMaxIdleConns(20) - client.DB().SetMaxOpenConns(100) - client.DB().SetConnMaxLifetime(time.Minute) - client.LogMode(true) - db.Client = client -} - -func (db *PgSql) IsReady() bool { - return db.Client != nil -} - -func (db *PgSql) Close() error { - return db.Client.Close() -} diff --git a/pkg/storage/sql/sql.go b/pkg/storage/sql/sql.go deleted file mode 100644 index 899ee643f..000000000 --- a/pkg/storage/sql/sql.go +++ /dev/null @@ -1,87 +0,0 @@ -package sql - -import ( - "github.com/jinzhu/gorm" - "github.com/trustwallet/blockatlas/pkg/errors" - "github.com/trustwallet/blockatlas/pkg/storage/util" -) - -type sql struct { - Client *gorm.DB -} - -type Handler func(db *gorm.DB, value interface{}) error - -func Get(db *gorm.DB, value interface{}) error { - err := db.Where(value).Take(value).Error - if err != nil { - return errors.E(err, util.ErrNotFound, errors.Params{"method": "Get", "value": value}) - } - return nil -} - -func Find(db *gorm.DB, out interface{}, where ...interface{}) error { - err := db.Find(out, where...).Error - if err != nil { - return errors.E(err, util.ErrNotFound, errors.Params{"method": "Find", "out": out, "where": where}) - } - return nil -} - -func Save(db *gorm.DB, value interface{}) error { - err := db.Save(value).Error - if err != nil { - return errors.E(err, util.ErrNotUpdated, errors.Params{"method": "Save", "value": value}) - } - return nil -} - -func Add(db *gorm.DB, value interface{}) error { - err := db.Where(value).FirstOrCreate(value).Error - if err != nil { - return errors.E(err, util.ErrNotStored, errors.Params{"method": "Add", "value": value}) - } - return nil -} - -func (db *sql) AddMany(values ...interface{}) error { - return db.Batch(true, Add, values...) -} - -func (db *sql) MustAddMany(values ...interface{}) error { - return db.Batch(false, Add, values...) -} - -func Delete(db *gorm.DB, value interface{}) error { - err := Get(db, value) - if err != nil { - return err - } - err = db.Delete(value).Error - if err != nil { - return errors.E(err, util.ErrNotDeleted) - } - return nil -} - -func (db *sql) DeleteMany(values ...interface{}) error { - return db.Batch(true, Delete, values...) -} - -func (db *sql) MustDeleteMany(values ...interface{}) error { - return db.Batch(false, Delete, values...) -} - -func (db *sql) Batch(rollback bool, handler Handler, values ...interface{}) error { - tx := db.Client.Begin() - for _, value := range values { - err := handler(tx, value) - if err != nil { - if rollback { - tx.Rollback() - return err - } - } - } - return tx.Commit().Error -} diff --git a/pkg/storage/util/errors.go b/pkg/storage/util/errors.go deleted file mode 100644 index 162401f98..000000000 --- a/pkg/storage/util/errors.go +++ /dev/null @@ -1,14 +0,0 @@ -package util - -import ( - "github.com/trustwallet/blockatlas/pkg/errors" -) - -var ( - ErrNotFound = errors.E("storage: obj not found") - ErrNotStored = errors.E("storage: not stored") - ErrNotUpdated = errors.E("storage: not updated") - ErrNotDeleted = errors.E("storage: not deleted") - ErrInvalidType = errors.E("storage: invalid type") - ErrAlreadyExist = errors.E("storage: object already exist") -) diff --git a/platform/aeternity/api.go b/platform/aeternity/api.go deleted file mode 100644 index 9b5d5e456..000000000 --- a/platform/aeternity/api.go +++ /dev/null @@ -1,73 +0,0 @@ -package aeternity - -import ( - "encoding/base64" - "github.com/trustwallet/blockatlas/coin" - "github.com/trustwallet/blockatlas/pkg/blockatlas" - "strings" - - "github.com/spf13/viper" -) - -type Platform struct { - client Client -} - -func (p *Platform) Init() error { - p.client = Client{blockatlas.InitClient(viper.GetString("aeternity.api"))} - return nil -} - -func (p *Platform) Coin() coin.Coin { - return coin.Coins[coin.AE] -} - -func (p *Platform) GetTxsByAddress(address string) (blockatlas.TxPage, error) { - addressTxs, err := p.client.GetTxs(address, blockatlas.TxPerPage) - if err != nil { - return nil, err - } - - var txs []blockatlas.Tx - for _, srcTx := range addressTxs { - txs = append(txs, NormalizeTx(&srcTx)) - } - return txs, nil -} - -func NormalizeTx(srcTx *Transaction) blockatlas.Tx { - txValue := srcTx.TxValue - return blockatlas.Tx{ - ID: srcTx.Hash, - Coin: coin.AE, - From: txValue.Sender, - To: txValue.Recipient, - Fee: blockatlas.Amount(txValue.Fee), - Date: int64(srcTx.Timestamp) / 1000, - Block: srcTx.BlockHeight, - Memo: getPayload(txValue.Payload), - Status: blockatlas.StatusCompleted, - Sequence: txValue.Nonce, - Meta: blockatlas.Transfer{ - Value: blockatlas.Amount(txValue.Amount), - Symbol: coin.Coins[coin.AE].Symbol, - Decimals: coin.Coins[coin.AE].Decimals, - }, - } -} - -func getPayload(encodedPayload string) string { - payload := []byte(strings.Replace(encodedPayload, "ba_", "", 1)) - if len(payload) <= 8 { - return "" - } else { - payload = payload[:len(payload)-8] - data, err := base64.StdEncoding.DecodeString(string(payload)) - if err != nil || len(data) <= 4 { - payload = []byte("") - } else { - payload = data - } - return string(payload) - } -} diff --git a/platform/aeternity/api_test.go b/platform/aeternity/api_test.go deleted file mode 100644 index fec5dbbae..000000000 --- a/platform/aeternity/api_test.go +++ /dev/null @@ -1,95 +0,0 @@ -package aeternity - -import ( - "encoding/json" - "github.com/stretchr/testify/assert" - "github.com/trustwallet/blockatlas/coin" - "github.com/trustwallet/blockatlas/pkg/blockatlas" - "testing" -) - -const transferTransaction = ` -{ - "block_hash": "mh_sJqfsWuuhA7vXDJLYFVtpagCSTmfmhzdqKWFR4pU5LK4D8W8T", - "block_height": 113579, - "hash": "th_oJfBC6KZKaKsL4WXTq1ZtFiSE8Wp2PQYEnwyZqtudyHcU3Qg6", - "signatures": [ - "sg_F3Ecfu5g6FcPyHrgZue96hVHthnXW7CbuDUEoKwWqWvbE84xb3ifB57AGTaH1WzDr4x1cnv4biLqTorjq9ZqhzCFVJC5c" - ], - "time": 1563848658206, - "tx": { - "amount": 252550000000000000000, - "fee": 20500000000000, - "nonce": 251291, - "payload": "ba_SGVsbG8sIE1pbmVyISAvWW91cnMgQmVlcG9vbC4vKXcQag==", - "recipient_id": "ak_ZWrS6xGhzxBasKmMbVSACfRioWqPyM5jNqMpBQ5ngP75RS6pS", - "sender_id": "ak_nv5B93FPzRHrGNmMdTDfGdd5xGZvep3MVSpJqzcQmMp59bBCv", - "type": "SpendTx", - "version": 1 - } - } -` - -var transferDst = blockatlas.Tx{ - ID: "th_oJfBC6KZKaKsL4WXTq1ZtFiSE8Wp2PQYEnwyZqtudyHcU3Qg6", - Coin: coin.AE, - From: "ak_nv5B93FPzRHrGNmMdTDfGdd5xGZvep3MVSpJqzcQmMp59bBCv", - To: "ak_ZWrS6xGhzxBasKmMbVSACfRioWqPyM5jNqMpBQ5ngP75RS6pS", - Fee: "20500000000000", - Date: 1563848658, - Block: 113579, - Status: blockatlas.StatusCompleted, - Memo: "Hello, Miner! /Yours Beepool./", - Sequence: 251291, - Meta: blockatlas.Transfer{ - Value: "252550000000000000000", - Symbol: "AE", - Decimals: 18, - }, -} - -type test struct { - name string - apiResponse string - expected *blockatlas.Tx - token string -} - -func testNormalize(t *testing.T, _test *test) { - var srcTx Transaction - err := json.Unmarshal([]byte(_test.apiResponse), &srcTx) - if err != nil { - t.Error(err) - return - } - - tx := NormalizeTx(&srcTx) - - resJSON, err := json.Marshal(&tx) - if err != nil { - t.Fatal(err) - } - - dstJSON, err := json.Marshal(_test.expected) - if err != nil { - println(string(resJSON)) - println(string(dstJSON)) - t.Fatal(err) - } - assert.Equal(t, resJSON, dstJSON) -} - -func TestNormalize(t *testing.T) { - testNormalize(t, &test{ - name: "transfer", - apiResponse: transferTransaction, - expected: &transferDst, - token: "", - }) -} - -func TestPayloadEncoding(t *testing.T) { - assert.Equal(t, getPayload("ba_SGVsbG8sIE1pbmVyISAvWW91cnMgQmVlcG9vbC4vKXcQag=="), "Hello, Miner! /Yours Beepool./") - assert.Equal(t, getPayload("xvass-///BadEncoding///Test"), "") - assert.Equal(t, getPayload(""), "") -} diff --git a/platform/aeternity/base.go b/platform/aeternity/base.go new file mode 100644 index 000000000..9b17b6168 --- /dev/null +++ b/platform/aeternity/base.go @@ -0,0 +1,21 @@ +package aeternity + +import ( + "github.com/trustwallet/golibs/client" + "github.com/trustwallet/golibs/coin" + "github.com/trustwallet/golibs/network/middleware" +) + +type Platform struct { + client Client +} + +func Init(api string) *Platform { + return &Platform{ + client: Client{client.InitClient(api, middleware.SentryErrorHandler)}, + } +} + +func (p *Platform) Coin() coin.Coin { + return coin.Aeternity() +} diff --git a/platform/aeternity/client.go b/platform/aeternity/client.go index 71a5f48e5..a6fe45276 100644 --- a/platform/aeternity/client.go +++ b/platform/aeternity/client.go @@ -2,24 +2,24 @@ package aeternity import ( "fmt" - "github.com/trustwallet/blockatlas/pkg/blockatlas" "net/url" "strconv" + + "github.com/trustwallet/golibs/client" ) type Client struct { - blockatlas.Request + client.Request } -func (c *Client) GetTxs(address string, limit int) (transactions []Transaction, err error) { +func (c *Client) GetTxs(address string, limit int) ([]Transaction, error) { query := url.Values{ "limit": {strconv.Itoa(limit)}, } uri := fmt.Sprintf("middleware/transactions/account/%s", address) - - err = c.Get(&transactions, uri, query) - if err != nil { - return + var transactions []Transaction + if err := c.Get(&transactions, uri, query); err != nil { + return nil, err } var result []Transaction @@ -28,5 +28,5 @@ func (c *Client) GetTxs(address string, limit int) (transactions []Transaction, result = append(result, tx) } } - return + return result, nil } diff --git a/platform/aeternity/mocks/transfer.json b/platform/aeternity/mocks/transfer.json new file mode 100644 index 000000000..f060dfe8f --- /dev/null +++ b/platform/aeternity/mocks/transfer.json @@ -0,0 +1,19 @@ +{ + "block_hash": "mh_sJqfsWuuhA7vXDJLYFVtpagCSTmfmhzdqKWFR4pU5LK4D8W8T", + "block_height": 113579, + "hash": "th_oJfBC6KZKaKsL4WXTq1ZtFiSE8Wp2PQYEnwyZqtudyHcU3Qg6", + "signatures": [ + "sg_F3Ecfu5g6FcPyHrgZue96hVHthnXW7CbuDUEoKwWqWvbE84xb3ifB57AGTaH1WzDr4x1cnv4biLqTorjq9ZqhzCFVJC5c" + ], + "time": 1563848658206, + "tx": { + "amount": 252550000000000000000, + "fee": 20500000000000, + "nonce": 251291, + "payload": "ba_SGVsbG8sIE1pbmVyISAvWW91cnMgQmVlcG9vbC4vKXcQag==", + "recipient_id": "ak_ZWrS6xGhzxBasKmMbVSACfRioWqPyM5jNqMpBQ5ngP75RS6pS", + "sender_id": "ak_nv5B93FPzRHrGNmMdTDfGdd5xGZvep3MVSpJqzcQmMp59bBCv", + "type": "SpendTx", + "version": 1 + } +} diff --git a/platform/aeternity/transaction.go b/platform/aeternity/transaction.go new file mode 100644 index 000000000..7bc7e9125 --- /dev/null +++ b/platform/aeternity/transaction.go @@ -0,0 +1,70 @@ +package aeternity + +import ( + "encoding/base64" + "strings" + + "github.com/trustwallet/golibs/coin" + "github.com/trustwallet/golibs/numbers" + "github.com/trustwallet/golibs/types" +) + +func (p *Platform) GetTxsByAddress(address string) (types.Txs, error) { + addressTxs, err := p.client.GetTxs(address, types.TxPerPage) + if err != nil { + return nil, err + } + + var txs types.Txs + for _, srcTx := range addressTxs { + tx, err := NormalizeTx(&srcTx) + if err != nil { + continue + } + txs = append(txs, tx) + } + return txs, nil +} + +func NormalizeTx(srcTx *Transaction) (types.Tx, error) { + txValue := srcTx.TxValue + decimals := coin.Aeternity().Decimals + amountFloat, err := txValue.Amount.Float64() + if err != nil { + return types.Tx{}, err + } + amount := numbers.Float64toString(amountFloat) + return types.Tx{ + ID: srcTx.Hash, + Coin: coin.AETERNITY, + From: txValue.Sender, + To: txValue.Recipient, + Fee: types.Amount(txValue.Fee), + Date: srcTx.Timestamp / 1000, + Block: srcTx.BlockHeight, + Memo: getPayload(txValue.Payload), + Status: types.StatusCompleted, + Sequence: txValue.Nonce, + Meta: types.Transfer{ + Value: types.Amount(amount), + Symbol: coin.Aeternity().Symbol, + Decimals: decimals, + }, + }, nil +} + +func getPayload(encodedPayload string) string { + payload := []byte(strings.Replace(encodedPayload, "ba_", "", 1)) + if len(payload) <= 8 { + return "" + } else { + payload = payload[:len(payload)-8] + data, err := base64.StdEncoding.DecodeString(string(payload)) + if err != nil || len(data) <= 4 { + payload = []byte("") + } else { + payload = data + } + return string(payload) + } +} diff --git a/platform/aeternity/transaction_test.go b/platform/aeternity/transaction_test.go new file mode 100644 index 000000000..4d42e2f18 --- /dev/null +++ b/platform/aeternity/transaction_test.go @@ -0,0 +1,68 @@ +package aeternity + +import ( + "reflect" + "testing" + + "github.com/stretchr/testify/assert" + "github.com/trustwallet/golibs/coin" + "github.com/trustwallet/golibs/mock" + "github.com/trustwallet/golibs/types" +) + +func TestNormalizeTx(t *testing.T) { + type args struct { + filename string + } + tests := []struct { + name string + args args + wantTx types.Tx + wantErr bool + }{ + { + name: "Test normalize transaction", + args: args{ + filename: "transfer.json", + }, + wantTx: types.Tx{ + ID: "th_oJfBC6KZKaKsL4WXTq1ZtFiSE8Wp2PQYEnwyZqtudyHcU3Qg6", + Coin: coin.AETERNITY, + From: "ak_nv5B93FPzRHrGNmMdTDfGdd5xGZvep3MVSpJqzcQmMp59bBCv", + To: "ak_ZWrS6xGhzxBasKmMbVSACfRioWqPyM5jNqMpBQ5ngP75RS6pS", + Fee: "20500000000000", + Date: 1563848658, + Block: 113579, + Status: types.StatusCompleted, + Memo: "Hello, Miner! /Yours Beepool./", + Sequence: 251291, + Meta: types.Transfer{ + Value: "252550000000000000000", + Symbol: "AE", + Decimals: 18, + }, + }, + wantErr: false, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + var srcTx Transaction + _ = mock.JsonModelFromFilePath("mocks/"+tt.args.filename, &srcTx) + gotTx, err := NormalizeTx(&srcTx) + if (err != nil) != tt.wantErr { + t.Errorf("NormalizeTx() error = %v, wantErr %v", err, tt.wantErr) + return + } + if !reflect.DeepEqual(gotTx, tt.wantTx) { + t.Errorf("NormalizeTx() gotTx = %v, want %v", gotTx, tt.wantTx) + } + }) + } +} + +func TestPayloadEncoding(t *testing.T) { + assert.Equal(t, getPayload("ba_SGVsbG8sIE1pbmVyISAvWW91cnMgQmVlcG9vbC4vKXcQag=="), "Hello, Miner! /Yours Beepool./") + assert.Equal(t, getPayload("xvass-///BadEncoding///Test"), "") + assert.Equal(t, getPayload(""), "") +} diff --git a/platform/aion/api.go b/platform/aion/api.go deleted file mode 100644 index 8287980d3..000000000 --- a/platform/aion/api.go +++ /dev/null @@ -1,67 +0,0 @@ -package aion - -import ( - "github.com/spf13/viper" - "github.com/trustwallet/blockatlas/coin" - "github.com/trustwallet/blockatlas/pkg/blockatlas" - "github.com/trustwallet/blockatlas/pkg/numbers" - "strconv" -) - -type Platform struct { - client Client -} - -func (p *Platform) Init() error { - p.client = Client{blockatlas.InitClient(viper.GetString("aion.api"))} - return nil -} - -func (p *Platform) Coin() coin.Coin { - return coin.Coins[coin.AION] -} - -func (p *Platform) GetTxsByAddress(address string) (blockatlas.TxPage, error) { - if srcTxs, err := p.client.GetTxsOfAddress(address, blockatlas.TxPerPage); err == nil { - return NormalizeTxs(srcTxs.Content), err - } else { - return nil, err - } -} - -// NormalizeTx converts an Aion transaction into the generic model -func NormalizeTx(srcTx *Tx) (tx blockatlas.Tx, ok bool) { - fee := strconv.Itoa(srcTx.NrgConsumed) - value := numbers.DecimalExp(string(srcTx.Value), 18) - value, ok = numbers.CutZeroFractional(value) - if !ok { - return tx, false - } - - return blockatlas.Tx{ - ID: "0x" + srcTx.TransactionHash, - Coin: coin.AION, - Date: srcTx.BlockTimestamp, - From: "0x" + srcTx.FromAddr, - To: "0x" + srcTx.ToAddr, - Fee: blockatlas.Amount(fee), - Block: srcTx.BlockNumber, - Meta: blockatlas.Transfer{ - Value: blockatlas.Amount(value), - Symbol: coin.Coins[coin.AION].Symbol, - Decimals: coin.Coins[coin.AION].Decimals, - }, - }, true -} - -// NormalizeTxs converts multiple Aion transactions -func NormalizeTxs(srcTxs []Tx) []blockatlas.Tx { - var txs []blockatlas.Tx - for _, srcTx := range srcTxs { - tx, ok := NormalizeTx(&srcTx) - if ok { - txs = append(txs, tx) - } - } - return txs -} diff --git a/platform/aion/api_test.go b/platform/aion/api_test.go deleted file mode 100644 index dbaff0539..000000000 --- a/platform/aion/api_test.go +++ /dev/null @@ -1,78 +0,0 @@ -package aion - -import ( - "bytes" - "encoding/json" - "github.com/trustwallet/blockatlas/coin" - "github.com/trustwallet/blockatlas/pkg/blockatlas" - "testing" -) - -const transferSrc = ` -{ - "blockHash": "68364cfa1873c42f3c2ef659349ca101c4c691a0385fd1c1677f92a96f7332ca", - "nrgPrice": 10000000000, - "toAddr": "a09b8c4c40bd7a81e969b8f6f291074206196a99948b03c6a469892931a3c258", - "contractAddr": "", - "data": "", - "year": 2019, - "transactionIndex": 7, - "nonce": "170c", - "transactionHash": "af3c2f5087fc3332154dc9d11c27e312f30ff829dbc5436aec8cc4342c7dc384", - "transactionTimestamp": 1554862205533375, - "nrgConsumed": 21000, - "month": 4, - "blockNumber": 2880919, - "blockTimestamp": 1554862228, - "transactionLog": "[]", - "fromAddr": "a07981da70ce919e1db5f051c3c386eb526e6ce8b9e2bfd56e3f3d754b0a17f3", - "day": 10, - "value": 11.903810405853733, - "txError": "" -}` - -var transferDst = blockatlas.Tx{ - ID: "0xaf3c2f5087fc3332154dc9d11c27e312f30ff829dbc5436aec8cc4342c7dc384", - Coin: coin.AION, - From: "0xa07981da70ce919e1db5f051c3c386eb526e6ce8b9e2bfd56e3f3d754b0a17f3", - To: "0xa09b8c4c40bd7a81e969b8f6f291074206196a99948b03c6a469892931a3c258", - Fee: "21000", - Date: 1554862228, - Block: 2880919, - Status: blockatlas.StatusCompleted, - Meta: blockatlas.Transfer{ - Value: "11903810405853733000", - Symbol: "AION", - Decimals: 18, - }, -} - -func TestNormalize(t *testing.T) { - var srcTx Tx - err := json.Unmarshal([]byte(transferSrc), &srcTx) - if err != nil { - t.Error(err) - return - } - - resTx, ok := NormalizeTx(&srcTx) - if !ok { - t.Fatal("Can't normalize transaction") - } - - resJSON, err := json.Marshal(&resTx) - if err != nil { - t.Fatal(err) - } - - dstJSON, err := json.Marshal(&transferDst) - if err != nil { - t.Fatal(err) - } - - if !bytes.Equal(resJSON, dstJSON) { - println(string(resJSON)) - println(string(dstJSON)) - t.Error("tx don't equal") - } -} diff --git a/platform/aion/base.go b/platform/aion/base.go new file mode 100644 index 000000000..e110731dd --- /dev/null +++ b/platform/aion/base.go @@ -0,0 +1,21 @@ +package aion + +import ( + "github.com/trustwallet/golibs/client" + "github.com/trustwallet/golibs/coin" + "github.com/trustwallet/golibs/network/middleware" +) + +type Platform struct { + client Client +} + +func Init(api string) *Platform { + return &Platform{ + client: Client{client.InitClient(api, middleware.SentryErrorHandler)}, + } +} + +func (p *Platform) Coin() coin.Coin { + return coin.Coins[coin.AION] +} diff --git a/platform/aion/client.go b/platform/aion/client.go index b82e8445f..68bf4dbee 100644 --- a/platform/aion/client.go +++ b/platform/aion/client.go @@ -1,13 +1,14 @@ package aion import ( - "github.com/trustwallet/blockatlas/pkg/blockatlas" "net/url" "strconv" + + "github.com/trustwallet/golibs/client" ) type Client struct { - blockatlas.Request + client.Request } func (c *Client) GetTxsOfAddress(address string, num int) (txPage *TxPage, err error) { diff --git a/platform/aion/mocks/transfer.json b/platform/aion/mocks/transfer.json new file mode 100644 index 000000000..dc300b603 --- /dev/null +++ b/platform/aion/mocks/transfer.json @@ -0,0 +1,21 @@ +{ + "blockHash": "68364cfa1873c42f3c2ef659349ca101c4c691a0385fd1c1677f92a96f7332ca", + "nrgPrice": 10000000000, + "toAddr": "a09b8c4c40bd7a81e969b8f6f291074206196a99948b03c6a469892931a3c258", + "contractAddr": "", + "data": "", + "year": 2019, + "transactionIndex": 7, + "nonce": "170c", + "transactionHash": "af3c2f5087fc3332154dc9d11c27e312f30ff829dbc5436aec8cc4342c7dc384", + "transactionTimestamp": 1554862205533375, + "nrgConsumed": 21000, + "month": 4, + "blockNumber": 2880919, + "blockTimestamp": 1554862228, + "transactionLog": "[]", + "fromAddr": "a07981da70ce919e1db5f051c3c386eb526e6ce8b9e2bfd56e3f3d754b0a17f3", + "day": 10, + "value": 11.903810405853733, + "txError": "" +} diff --git a/platform/aion/transaction.go b/platform/aion/transaction.go new file mode 100644 index 000000000..bf108ce0a --- /dev/null +++ b/platform/aion/transaction.go @@ -0,0 +1,55 @@ +package aion + +import ( + "strconv" + + "github.com/trustwallet/golibs/coin" + "github.com/trustwallet/golibs/numbers" + "github.com/trustwallet/golibs/types" +) + +func (p *Platform) GetTxsByAddress(address string) (types.Txs, error) { + if srcTxs, err := p.client.GetTxsOfAddress(address, types.TxPerPage); err == nil { + return NormalizeTxs(srcTxs.Content), err + } else { + return nil, err + } +} + +// NormalizeTx converts an Aion transaction into the generic model +func NormalizeTx(srcTx *Tx) (tx types.Tx, ok bool) { + fee := strconv.Itoa(srcTx.NrgConsumed) + value := numbers.DecimalExp(string(srcTx.Value), 18) + value, ok = numbers.CutZeroFractional(value) + if !ok { + return tx, false + } + + return types.Tx{ + ID: "0x" + srcTx.TransactionHash, + Coin: coin.AION, + Date: srcTx.BlockTimestamp, + From: "0x" + srcTx.FromAddr, + To: "0x" + srcTx.ToAddr, + Fee: types.Amount(fee), + Block: srcTx.BlockNumber, + Status: types.StatusCompleted, + Meta: types.Transfer{ + Value: types.Amount(value), + Symbol: coin.Coins[coin.AION].Symbol, + Decimals: coin.Coins[coin.AION].Decimals, + }, + }, true +} + +// NormalizeTxs converts multiple Aion transactions +func NormalizeTxs(srcTxs []Tx) types.Txs { + var txs types.Txs + for _, srcTx := range srcTxs { + tx, ok := NormalizeTx(&srcTx) + if ok { + txs = append(txs, tx) + } + } + return txs +} diff --git a/platform/aion/transaction_test.go b/platform/aion/transaction_test.go new file mode 100644 index 000000000..3b2855058 --- /dev/null +++ b/platform/aion/transaction_test.go @@ -0,0 +1,58 @@ +package aion + +import ( + "reflect" + "testing" + + "github.com/trustwallet/golibs/coin" + "github.com/trustwallet/golibs/mock" + "github.com/trustwallet/golibs/types" +) + +func TestNormalizeTx(t *testing.T) { + type args struct { + srcTx string + } + tests := []struct { + name string + args args + wantTx types.Tx + wantOk bool + }{ + { + name: "Test normalize transfer", + args: args{ + srcTx: "transfer.json", + }, + wantTx: types.Tx{ + ID: "0xaf3c2f5087fc3332154dc9d11c27e312f30ff829dbc5436aec8cc4342c7dc384", + Coin: coin.AION, + From: "0xa07981da70ce919e1db5f051c3c386eb526e6ce8b9e2bfd56e3f3d754b0a17f3", + To: "0xa09b8c4c40bd7a81e969b8f6f291074206196a99948b03c6a469892931a3c258", + Fee: "21000", + Date: 1554862228, + Block: 2880919, + Status: types.StatusCompleted, + Meta: types.Transfer{ + Value: "11903810405853733000", + Symbol: "AION", + Decimals: 18, + }, + }, + wantOk: true, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + var srcTx Tx + _ = mock.JsonModelFromFilePath("mocks/"+tt.args.srcTx, &srcTx) + gotTx, gotOk := NormalizeTx(&srcTx) + if !reflect.DeepEqual(gotTx, tt.wantTx) { + t.Errorf("NormalizeTx() gotTx = %v, want %v", gotTx, tt.wantTx) + } + if gotOk != tt.wantOk { + t.Errorf("NormalizeTx() gotOk = %v, want %v", gotOk, tt.wantOk) + } + }) + } +} diff --git a/platform/algorand/api.go b/platform/algorand/api.go deleted file mode 100644 index ed6ef66b9..000000000 --- a/platform/algorand/api.go +++ /dev/null @@ -1,110 +0,0 @@ -package algorand - -import ( - "github.com/spf13/viper" - - "strconv" - - "github.com/trustwallet/blockatlas/coin" - "github.com/trustwallet/blockatlas/pkg/blockatlas" -) - -type Platform struct { - client Client -} - -func (p *Platform) Init() error { - p.client = Client{blockatlas.InitClient(viper.GetString("algorand.api"))} - p.client.Headers["x-api-key"] = viper.GetString("algorand.key") - return nil -} - -func (p *Platform) Coin() coin.Coin { - return coin.Coins[coin.ALGO] -} - -func (p *Platform) CurrentBlockNumber() (int64, error) { - return p.client.GetLatestBlock() -} - -func (p *Platform) GetBlockByNumber(num int64) (*blockatlas.Block, error) { - txs, err := p.client.GetTxsInBlock(num) - if err != nil { - return nil, err - } - - return &blockatlas.Block{ - Number: num, - Txs: NormalizeTxs(txs), - }, nil -} - -func (p *Platform) GetTxsByAddress(address string) (blockatlas.TxPage, error) { - txs, err := p.client.GetTxsOfAddress(address) - if err != nil { - return nil, err - } - return NormalizeTxs(txs), nil -} - -func (p *Platform) GetDetails() blockatlas.StakingDetails { - //TODO: Find a way to have a dynamic - return blockatlas.StakingDetails{ - Reward: blockatlas.StakingReward{Annual: 6.1}, - MinimumAmount: blockatlas.Amount("0"), - LockTime: 0, - Type: blockatlas.DelegationTypeAuto, - } -} - -func (p *Platform) UndelegatedBalance(address string) (string, error) { - acc, err := p.client.GetAccount(address) - if err != nil { - return "0", err - } - return strconv.FormatUint(acc.Amount, 10), nil -} - -func (p *Platform) GetValidators() (blockatlas.ValidatorPage, error) { - return make(blockatlas.ValidatorPage, 0), nil -} - -func (p *Platform) GetDelegations(address string) (blockatlas.DelegationsPage, error) { - return make(blockatlas.DelegationsPage, 0), nil -} - -func NormalizeTxs(txs []Transaction) []blockatlas.Tx { - result := make([]blockatlas.Tx, 0) - - for _, tx := range txs { - if normalized, ok := Normalize(tx); ok { - result = append(result, normalized) - } - } - - return result -} - -func Normalize(tx Transaction) (result blockatlas.Tx, ok bool) { - - if tx.Type != TransactionTypePay { - return result, false - } - - return blockatlas.Tx{ - ID: tx.Hash, - Coin: coin.ALGO, - From: tx.From, - To: tx.Payment.To, - Fee: blockatlas.Amount(strconv.Itoa(int(tx.Fee))), - Date: int64(tx.Timestamp), - Block: tx.Round, - Status: blockatlas.StatusCompleted, - Type: blockatlas.TxTransfer, - Meta: blockatlas.Transfer{ - Value: blockatlas.Amount(strconv.Itoa(int(tx.Payment.Amount))), - Symbol: coin.Coins[coin.ALGO].Symbol, - Decimals: coin.Coins[coin.ALGO].Decimals, - }, - }, true -} diff --git a/platform/algorand/api_test.go b/platform/algorand/api_test.go deleted file mode 100644 index bddec1400..000000000 --- a/platform/algorand/api_test.go +++ /dev/null @@ -1,74 +0,0 @@ -package algorand - -import ( - "encoding/json" - "github.com/stretchr/testify/assert" - "github.com/trustwallet/blockatlas/coin" - "github.com/trustwallet/blockatlas/pkg/blockatlas" - "testing" -) - -const ( - transfer = ` -{ - "transactions":[ - { - "type":"pay", - "tx":"C2LK3CGBPIGERLPFUXE6INSBJGHOXU7YZMEGELWMVSBASFJYOOQQ", - "from":"5TSQNIL54GB545B3WLC6OVH653SHAELMHU6MSVNGTUNMOEHAMWG7EC3AA4", - "fee":1000, - "first-round":2031300, - "last-round":2031749, - "noteb64":"6OZ0TFd0HPw=", - "round":2031351, - "poolerror":"", - "payment":{ - "to":"4EZFQABCVQTHQCK3HQBIYGC4NV2VM42FZHEFTVH77ROG4ZGREC6Y7V5T2U", - "close":"", - "closeamount":0, - "amount":1, - "torewards":3237690, - "closerewards":0 - }, - "fromrewards":0, - "genesisID":"mainnet-v1.0", - "genesishashb64":"wGHE2Pwdvd7S12BL5FaOP20EGYesN73ktiC1qzkkit8=", - "group":"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=" - } - ] -} -` -) - -var expected = []*blockatlas.Tx{ - { - ID: "C2LK3CGBPIGERLPFUXE6INSBJGHOXU7YZMEGELWMVSBASFJYOOQQ", - Coin: coin.ALGO, - From: "5TSQNIL54GB545B3WLC6OVH653SHAELMHU6MSVNGTUNMOEHAMWG7EC3AA4", - To: "4EZFQABCVQTHQCK3HQBIYGC4NV2VM42FZHEFTVH77ROG4ZGREC6Y7V5T2U", - Fee: blockatlas.Amount("1000"), - Date: 0, - Block: 2031351, - Status: blockatlas.StatusCompleted, - Type: blockatlas.TxTransfer, - Meta: blockatlas.Transfer{ - Value: blockatlas.Amount("1"), - Symbol: "ALGO", - Decimals: 6, - }, - }, - nil, - nil, -} - -func TestNormalize(t *testing.T) { - var act TransactionsResponse - assert.NoError(t, json.Unmarshal([]byte(transfer), &act)) - assert.Equal(t, 1, len(act.Transactions)) - - for i, v := range act.Transactions { - tx, ok := Normalize(v) - assert.True(t, ok) - assert.Equal(t, expected[i], &tx) - } -} diff --git a/platform/algorand/base.go b/platform/algorand/base.go new file mode 100644 index 000000000..24bb60857 --- /dev/null +++ b/platform/algorand/base.go @@ -0,0 +1,19 @@ +package algorand + +import ( + "github.com/trustwallet/golibs/coin" +) + +type Platform struct { + client Client +} + +func Init(api, apiKey string) *Platform { + return &Platform{ + client: InitClient(api, apiKey), + } +} + +func (p *Platform) Coin() coin.Coin { + return coin.Algorand() +} diff --git a/platform/algorand/block.go b/platform/algorand/block.go new file mode 100644 index 000000000..9294fa291 --- /dev/null +++ b/platform/algorand/block.go @@ -0,0 +1,19 @@ +package algorand + +import "github.com/trustwallet/golibs/types" + +func (p *Platform) CurrentBlockNumber() (int64, error) { + return p.client.GetLatestBlock() +} + +func (p *Platform) GetBlockByNumber(num int64) (*types.Block, error) { + txs, err := p.client.GetTxsInBlock(num) + if err != nil { + return nil, err + } + + return &types.Block{ + Number: num, + Txs: NormalizeTxs(txs), + }, nil +} diff --git a/platform/algorand/client.go b/platform/algorand/client.go index 913a3311e..427ce7468 100644 --- a/platform/algorand/client.go +++ b/platform/algorand/client.go @@ -2,90 +2,63 @@ package algorand import ( "fmt" + "strconv" + + "github.com/trustwallet/golibs/network/middleware" + "github.com/trustwallet/blockatlas/pkg/blockatlas" - "github.com/trustwallet/blockatlas/pkg/numbers" + "github.com/trustwallet/golibs/client" ) type Client struct { - blockatlas.Request + client.Request } -func InitClient(baseUrl string) Client { - return Client{ - Request: blockatlas.Request{ - HttpClient: blockatlas.DefaultClient, - ErrorHandler: blockatlas.DefaultErrorHandler, - BaseUrl: baseUrl, - }, - } +func InitClient(url, apiKey string) Client { + request := client.InitClient(url, middleware.SentryErrorHandler) + request.Headers = map[string]string{"X-Indexer-API-Token": apiKey} + return Client{request} } func (c *Client) GetLatestBlock() (int64, error) { var status Status - err := c.Get(&status, "v1/status", nil) + err := c.Get(&status, "health", nil) if err != nil { return 0, err } - return status.LastRound, nil -} - -func (c *Client) GetBlock(number int64) (BlockResponse, error) { - path := fmt.Sprintf("v1/block/%d", number) - var resp BlockResponse - err := c.Get(&resp, path, nil) + block, err := strconv.Atoi(status.Block) if err != nil { - return resp, err - } - - normalizedTxs := make([]Transaction, 0) - //TODO: Read GetTxsOfAddress explanation - for _, t := range resp.Transactions.Transactions { - normalized := normalizeTx(&t, resp) - normalizedTxs = append(normalizedTxs, *normalized) + return 0, err } - resp.Transactions.Transactions = normalizedTxs - return resp, nil + return int64(block), nil } func (c *Client) GetTxsInBlock(number int64) ([]Transaction, error) { - block, err := c.GetBlock(number) - return block.Transactions.Transactions, err + path := fmt.Sprintf("v2/blocks/%d", number) + var resp BlockResponse + err := c.Get(&resp, path, nil) + if err != nil { + return []Transaction{}, err + } + return resp.Transactions, err } +//deprecated, no longer need to support staking func (c *Client) GetAccount(address string) (account *Account, err error) { - path := fmt.Sprintf("v1/account/%s", address) + path := fmt.Sprintf("v2/accounts/%s", address) err = c.Get(&account, path, nil) return } func (c *Client) GetTxsOfAddress(address string) ([]Transaction, error) { var response TransactionsResponse - path := fmt.Sprintf("v1/account/%s/transactions", address) + path := fmt.Sprintf("v2/accounts/%s/transactions", address) err := c.Get(&response, path, nil) if err != nil { return nil, blockatlas.ErrSourceConn } - results := make([]Transaction, 0) - - //FIXME. Currently fetching the last 6 transactions and get 6 blocks for each to retrieve timestamp. - //Algorand team promised to provide endpoint soon that will contain timestamp value inside TransactionsResponse response - //Get latest 6 transactions, which is enough until new endpoint fixes it. - txs := response.Transactions[:numbers.Min(6, len(response.Transactions))] - - for _, t := range txs { - block, err := c.GetBlock(int64(t.Round)) - if err == nil { - normalizeTx(&t, block) - results = append(results, t) - } - } - - return results, err -} -func normalizeTx(transaction *Transaction, block BlockResponse) *Transaction { - transaction.Timestamp = block.Timestamp - return transaction + return response.Transactions, err } diff --git a/platform/algorand/mocks/transfer.json b/platform/algorand/mocks/transfer.json new file mode 100644 index 000000000..09fd0dda7 --- /dev/null +++ b/platform/algorand/mocks/transfer.json @@ -0,0 +1,30 @@ +{ + "transactions": [ + { + "close-rewards": 0, + "closing-amount": 0, + "confirmed-round": 2031351, + "fee": 1000, + "first-valid": 2031300, + "genesis-hash": "wGHE2Pwdvd7S12BL5FaOP20EGYesN73ktiC1qzkkit8=", + "genesis-id": "mainnet-v1.0", + "id": "C2LK3CGBPIGERLPFUXE6INSBJGHOXU7YZMEGELWMVSBASFJYOOQQ", + "intra-round-offset": 57, + "last-valid": 2031749, + "note": "6OZ0TFd0HPw=", + "payment-transaction": { + "amount": 1, + "close-amount": 0, + "receiver": "4EZFQABCVQTHQCK3HQBIYGC4NV2VM42FZHEFTVH77ROG4ZGREC6Y7V5T2U" + }, + "receiver-rewards": 3237690, + "round-time": 1569123058, + "sender": "5TSQNIL54GB545B3WLC6OVH653SHAELMHU6MSVNGTUNMOEHAMWG7EC3AA4", + "sender-rewards": 0, + "signature": { + "sig": "J1G/vapWXJJjuFcsUPut9ffHrFnXsg1GRQlLyqhTOC0V78zCw3OIAYgeg6k/xiX5NDLLrgy4aYF1hhsEXGZ2Dg==" + }, + "tx-type": "pay" + } + ] +} diff --git a/platform/algorand/model.go b/platform/algorand/model.go index 7915b17a9..87e66c544 100644 --- a/platform/algorand/model.go +++ b/platform/algorand/model.go @@ -21,29 +21,25 @@ type TransactionsResponse struct { } type BlockResponse struct { - Timestamp uint64 `json:"timestamp"` - Transactions BlockTransactions `json:"txns"` -} - -type BlockTransactions struct { + Timestamp uint64 `json:"timestamp"` Transactions []Transaction `json:"transactions"` } type Transaction struct { - Type TransactionType `json:"type"` - Hash string `json:"tx"` - From string `json:"from"` + Type TransactionType `json:"tx-type"` + Hash string `json:"id"` + From string `json:"sender"` Fee uint64 `json:"fee"` - Round uint64 `json:"round"` - Payment TransactionPayment `json:"payment"` - Timestamp uint64 `json:"timestamp,omitempty"` + Round uint64 `json:"confirmed-round"` + Payment TransactionPayment `json:"payment-transaction"` + Timestamp uint64 `json:"round-time"` } type TransactionPayment struct { - To string `json:"to"` - Amount uint64 `json:"amount"` + Receiver string `json:"receiver"` + Amount uint64 `json:"amount"` } type Status struct { - LastRound int64 `json:"lastRound"` + Block string `json:"message"` } diff --git a/platform/algorand/stake.go b/platform/algorand/stake.go new file mode 100644 index 000000000..910aa9aed --- /dev/null +++ b/platform/algorand/stake.go @@ -0,0 +1,45 @@ +package algorand + +import ( + "github.com/trustwallet/blockatlas/services/assets" + "strconv" + + "github.com/trustwallet/blockatlas/pkg/blockatlas" +) + +func (p *Platform) GetActiveValidators() (blockatlas.StakeValidators, error) { + validators, err := assets.GetValidatorsMap(p) + if err != nil { + return nil, err + } + result := make(blockatlas.StakeValidators, 0, len(validators)) + for _, v := range validators { + result = append(result, v) + } + return result, nil +} + +func (p *Platform) GetDetails() blockatlas.StakingDetails { + return blockatlas.StakingDetails{ + Reward: blockatlas.StakingReward{Annual: 6.1}, + MinimumAmount: "0", + LockTime: 0, + Type: blockatlas.DelegationTypeAuto, + } +} + +func (p *Platform) UndelegatedBalance(address string) (string, error) { + acc, err := p.client.GetAccount(address) + if err != nil { + return "0", err + } + return strconv.FormatUint(acc.Amount, 10), nil +} + +func (p *Platform) GetValidators() (blockatlas.ValidatorPage, error) { + return blockatlas.ValidatorPage{}, nil +} + +func (p *Platform) GetDelegations(address string) (blockatlas.DelegationsPage, error) { + return blockatlas.DelegationsPage{}, nil +} diff --git a/platform/algorand/transaction.go b/platform/algorand/transaction.go new file mode 100644 index 000000000..d5776f009 --- /dev/null +++ b/platform/algorand/transaction.go @@ -0,0 +1,52 @@ +package algorand + +import ( + "strconv" + + "github.com/trustwallet/golibs/coin" + "github.com/trustwallet/golibs/types" +) + +func (p *Platform) GetTxsByAddress(address string) (types.Txs, error) { + txs, err := p.client.GetTxsOfAddress(address) + if err != nil { + return nil, err + } + return NormalizeTxs(txs), nil +} + +func NormalizeTxs(txs []Transaction) types.Txs { + result := make(types.Txs, 0) + + for _, tx := range txs { + if normalized, ok := Normalize(tx); ok { + result = append(result, normalized) + } + } + + return result +} + +func Normalize(tx Transaction) (result types.Tx, ok bool) { + + if tx.Type != TransactionTypePay { + return result, false + } + + return types.Tx{ + ID: tx.Hash, + Coin: coin.ALGORAND, + From: tx.From, + To: tx.Payment.Receiver, + Fee: types.Amount(strconv.Itoa(int(tx.Fee))), + Date: int64(tx.Timestamp), + Block: tx.Round, + Status: types.StatusCompleted, + Type: types.TxTransfer, + Meta: types.Transfer{ + Value: types.Amount(strconv.Itoa(int(tx.Payment.Amount))), + Symbol: coin.Algorand().Symbol, + Decimals: coin.Algorand().Decimals, + }, + }, true +} diff --git a/platform/algorand/transaction_test.go b/platform/algorand/transaction_test.go new file mode 100644 index 000000000..d9db60a3c --- /dev/null +++ b/platform/algorand/transaction_test.go @@ -0,0 +1,60 @@ +package algorand + +import ( + "reflect" + "testing" + + "github.com/trustwallet/golibs/coin" + "github.com/trustwallet/golibs/mock" + "github.com/trustwallet/golibs/types" +) + +func TestNormalizeTx(t *testing.T) { + type args struct { + filename string + } + tests := []struct { + name string + args args + wantTx types.Tx + ok bool + }{ + { + name: "Test normalize transaction", + args: args{ + filename: "transfer.json", + }, + wantTx: types.Tx{ + ID: "C2LK3CGBPIGERLPFUXE6INSBJGHOXU7YZMEGELWMVSBASFJYOOQQ", + Coin: coin.ALGORAND, + From: "5TSQNIL54GB545B3WLC6OVH653SHAELMHU6MSVNGTUNMOEHAMWG7EC3AA4", + To: "4EZFQABCVQTHQCK3HQBIYGC4NV2VM42FZHEFTVH77ROG4ZGREC6Y7V5T2U", + Fee: types.Amount("1000"), + Date: 1569123058, + Block: 2031351, + Status: types.StatusCompleted, + Type: types.TxTransfer, + Meta: types.Transfer{ + Value: types.Amount("1"), + Symbol: "ALGO", + Decimals: 6, + }, + }, + ok: true, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + var response TransactionsResponse + _ = mock.JsonModelFromFilePath("mocks/"+tt.args.filename, &response) + gotTx, ok := Normalize(response.Transactions[0]) + if ok != tt.ok { + t.Errorf("Normalize() ok = %v, wantOk %v", ok, tt.ok) + return + } + if !reflect.DeepEqual(gotTx, tt.wantTx) { + t.Errorf("Normalize() gotTx = %v, want %v", gotTx, tt.wantTx) + } + }) + } +} diff --git a/platform/binance/api.go b/platform/binance/api.go deleted file mode 100644 index 544550b00..000000000 --- a/platform/binance/api.go +++ /dev/null @@ -1,236 +0,0 @@ -package binance - -import ( - "github.com/trustwallet/blockatlas/pkg/blockatlas" - "github.com/trustwallet/blockatlas/pkg/errors" - "github.com/trustwallet/blockatlas/pkg/numbers" - "strings" - - "github.com/spf13/viper" - "github.com/trustwallet/blockatlas/coin" -) - -type Platform struct { - client Client - dexClient DexClient -} - -func (p *Platform) Init() error { - p.client = Client{blockatlas.InitClient(viper.GetString("binance.api"))} - p.client.ErrorHandler = getHTTPError - - p.dexClient = DexClient{blockatlas.InitClient(viper.GetString("binance.dex"))} - p.dexClient.ErrorHandler = getHTTPError - return nil -} - -func (p *Platform) Coin() coin.Coin { - return coin.Coins[coin.BNB] -} - -func (p *Platform) CurrentBlockNumber() (int64, error) { - // No native function to get height in explorer API - // Workaround: Request list of blocks - // and return number of the newest one - list, err := p.client.GetBlockList(1) - if err != nil { - return 0, err - } - if len(list.BlockArray) == 0 { - return 0, errors.E("no block descriptor found", errors.TypePlatformApi).PushToSentry() - } - return list.BlockArray[0].BlockHeight, nil -} - -func (p *Platform) GetBlockByNumber(num int64) (*blockatlas.Block, error) { - srcTxs, err := p.client.GetBlockByNumber(num) - if err != nil { - return nil, err - } - txs := NormalizeTxs(srcTxs.Txs, "") - return &blockatlas.Block{ - Number: num, - Txs: txs, - }, nil -} - -func (p *Platform) GetTxsByAddress(address string) (blockatlas.TxPage, error) { - // Endpoint supports queries without token query parameter - return p.GetTokenTxsByAddress(address, p.Coin().Symbol) -} - -func (p *Platform) GetTokenTxsByAddress(address string, token string) (blockatlas.TxPage, error) { - srcTxs, err := p.client.GetTxsOfAddress(address, token) - if err != nil { - return nil, err - } - return NormalizeTxs(srcTxs.Txs, token), nil -} - -// NormalizeTx converts a Binance transaction into the generic model -func NormalizeTx(srcTx *Tx, token string) (blockatlas.Tx, bool) { - var tx blockatlas.Tx - bnbCoin := coin.Coins[coin.BNB] - value := numbers.DecimalExp(string(srcTx.Value), 8) - - fee := "0" - feeNumber, err := srcTx.Fee.Float64() - if err == nil && feeNumber > 0 { - fee = numbers.DecimalExp(string(srcTx.Fee), 8) - } - - tx = blockatlas.Tx{ - ID: srcTx.Hash, - Coin: coin.BNB, - From: srcTx.FromAddr, - To: srcTx.ToAddr, - Fee: blockatlas.Amount(fee), - Date: srcTx.Timestamp / 1000, - Block: srcTx.BlockHeight, - Status: blockatlas.StatusCompleted, - Memo: srcTx.Memo, - } - - switch srcTx.Type { - case TxTransfer: - if len(token) > 0 && srcTx.Asset != token { - return tx, false - } - - if srcTx.Asset == bnbCoin.Symbol { - // Condition for native transfer (BNB) - tx.Meta = blockatlas.Transfer{ - Value: blockatlas.Amount(value), - Symbol: bnbCoin.Symbol, - Decimals: bnbCoin.Decimals, - } - return tx, true - } //else if len(srcTx.FromAddr) > 0 && len(srcTx.ToAddr) > 0 { - // Condition for native token transfer - tx.Meta = blockatlas.NativeTokenTransfer{ - TokenID: srcTx.Asset, - Symbol: TokenSymbol(srcTx.Asset), - Value: blockatlas.Amount(value), - Decimals: bnbCoin.Decimals, - From: srcTx.FromAddr, - To: srcTx.ToAddr, - } - //} - //case TxCancelOrder, TxNewOrder: - // return tx, false - //case "invalid": - // return tx, false - // dt, err := srcTx.getData() - // if err != nil { - // return tx, false - // } - // - // symbol := dt.OrderData.Quote - // if len(token) > 0 && symbol != token { - // return tx, false - // } - // - // key := blockatlas.KeyPlaceOrder - // title := blockatlas.KeyTitlePlaceOrder - // if srcTx.Type == TxCancelOrder { - // key = blockatlas.KeyCancelOrder - // title = blockatlas.KeyTitleCancelOrder - // } - // volume, ok := dt.OrderData.GetVolume() - // if ok { - // value = strconv.Itoa(int(volume)) - // } - // - // tx.Meta = blockatlas.AnyAction{ - // Coin: coin.BNB, - // TokenID: dt.OrderData.Symbol, - // Symbol: TokenSymbol(symbol), - // Name: symbol, - // Value: blockatlas.Amount(value), - // Decimals: coin.Coins[coin.BNB].Decimals, - // Title: title, - // Key: key, - // } - - default: - return tx, false - } - - return tx, true -} - -func TokenSymbol(asset string) string { - s := strings.Split(asset, "-") - if len(s) > 1 { - return s[0] - } - return asset -} - -// NormalizeTxs converts multiple Binance transactions -func NormalizeTxs(srcTxs []Tx, token string) (txs []blockatlas.Tx) { - for _, srcTx := range srcTxs { - tx, ok := NormalizeTx(&srcTx, token) - if !ok { - continue - } - txs = append(txs, tx) - } - return -} - -func (p *Platform) GetTokenListByAddress(address string) (blockatlas.TokenPage, error) { - account, err := p.dexClient.GetAccountMetadata(address) - if err != nil || len(account.Balances) == 0 { - return []blockatlas.Token{}, nil - } - tokens, err := p.dexClient.GetTokens() - if err != nil { - return nil, err - } - return NormalizeTokens(account.Balances, tokens), nil -} - -// NormalizeToken converts a Binance token into the generic model -func NormalizeToken(srcToken *Balance, tokens *TokenPage) (t blockatlas.Token, ok bool) { - if srcToken.isAllZeroBalance() { - return t, false - } - - tk := tokens.findToken(srcToken.Symbol) - if tk == nil { - return t, false - } - - t = blockatlas.Token{ - Name: tk.Name, - Symbol: tk.OriginalSymbol, - TokenID: tk.Symbol, - Coin: coin.BNB, - Decimals: uint(decimalPlaces(tk.TotalSupply)), - Type: blockatlas.TokenTypeBEP2, - } - - return t, true -} - -// NormalizeTxs converts multiple Binance tokens -func NormalizeTokens(srcBalance []Balance, tokens *TokenPage) (tokenPage []blockatlas.Token) { - for _, srcToken := range srcBalance { - token, ok := NormalizeToken(&srcToken, tokens) - if !ok { - continue - } - tokenPage = append(tokenPage, token) - } - return -} - -// decimalPlaces count the decimals places. -func decimalPlaces(v string) int { - s := strings.Split(v, ".") - if len(s) < 2 { - return 0 - } - return len(s[1]) -} diff --git a/platform/binance/api_test.go b/platform/binance/api_test.go deleted file mode 100644 index 0a48da341..000000000 --- a/platform/binance/api_test.go +++ /dev/null @@ -1,541 +0,0 @@ -package binance - -import ( - "encoding/json" - "github.com/stretchr/testify/assert" - "github.com/trustwallet/blockatlas/coin" - "github.com/trustwallet/blockatlas/pkg/blockatlas" - "testing" -) - -const ( - transferTransaction = ` -{ - "blockHeight": 7761368, - "code": 0, - "confirmBlocks": 2089441, - "fromAddr": "tbnb1fhr04azuhcj0dulm7ka40y0cqjlafwae9k9gk2", - "hasChildren": 0, - "log": "Msg 0: ", - "timeStamp": 1555049867552, - "toAddr": "tbnb1sylyjw032eajr9cyllp26n04300qzzre38qyv5", - "txAge": 836729, - "txAsset": "BNB", - "txFee": 0.00125, - "txHash": "1681EE543FB4B5A628EF21D746E031F018E226D127044A4F9BA5EE2542A44555", - "txType": "TRANSFER", - "value": 100000, - "memo": "test" -}` - tokenTransferTransaction = ` -{ - "blockHeight": 7928667, - "code": 0, - "confirmBlocks": 1922024, - "fromAddr": "tbnb1ttyn4csghfgyxreu7lmdu3lcplhqhxtzced45a", - "hasChildren": 0, - "log": "Msg 0: ", - "timeStamp": 1555117625829, - "toAddr": "tbnb12hlquylu78cjylk5zshxpdj6hf3t0tahwjt3ex", - "txAge": 768924, - "txAsset": "YLC-D8B", - "txFee": 0.00125, - "txHash": "95CF63FAA27579A9B6AF84EF8B2DFEAC29627479E9C98E7F5AE4535E213FA4C9", - "txType": "TRANSFER", - "value": 2.10572645, - "memo": "test" -}` - newOrderTransaction = ` -{ - "txHash": "B0677F3436C1B1661E94D192B84B98AA42AC2485D9808357796EE501CBF794F7", - "blockHeight": 10815565, - "txType": "NEW_ORDER", - "timeStamp": 1559689901929, - "fromAddr": "bnb16ya67j7kvw8682kka09qujlw5u7lf4geqef0ku", - "value": 0.00649878, - "txAsset": "BNB", - "txQuoteAsset": "AWC-986", - "txFee": 0, - "txAge": 14346340, - "orderId": "D13BAF4BD6638FA3AAD6EBCA0E4BEEA73DF4D519-30", - "data": "{\"orderData\":{\"symbol\":\"BNB_AWC-986\",\"orderType\":\"limit\",\"side\":\"buy\",\"price\":0.00324939,\"quantity\":2.00000000,\"timeInForce\":\"GTE\",\"orderId\":\"D13BAF4BD6638FA3AAD6EBCA0E4BEEA73DF4D519-30\"}}", - "code": 0, - "log": "Msg 0: ", - "confirmBlocks": 0, - "memo": "", - "source": 0, - "hasChildren": 0 -}` - cancelOrderTransaction = ` -{ - "txHash": "F48DE755170C10F4A4C0E6836A708C33EEF9A7144800F25187D5F2349FD15A34", - "blockHeight": 10815539, - "txType": "CANCEL_ORDER", - "timeStamp": 1559689892180, - "fromAddr": "bnb16ya67j7kvw8682kka09qujlw5u7lf4geqef0ku", - "txFee": 0, - "txAge": 14346349, - "data": "{\"orderData\":{\"symbol\":\"BNB_GTO-908\",\"orderType\":\"limit\",\"side\":\"buy\",\"price\":0.00104716,\"quantity\":1.00000000,\"timeInForce\":\"GTE\",\"orderId\":\"D13BAF4BD6638FA3AAD6EBCA0E4BEEA73DF4D519-28\"}}", - "code": 0, - "log": "Msg 0: ", - "confirmBlocks": 0, - "memo": "", - "source": 0, - "hasChildren": 0 -}` -) - -var ( - transferDst = blockatlas.Tx{ - ID: "1681EE543FB4B5A628EF21D746E031F018E226D127044A4F9BA5EE2542A44555", - Coin: coin.BNB, - From: "tbnb1fhr04azuhcj0dulm7ka40y0cqjlafwae9k9gk2", - To: "tbnb1sylyjw032eajr9cyllp26n04300qzzre38qyv5", - Fee: "125000", - Date: 1555049867, - Block: 7761368, - Status: blockatlas.StatusCompleted, - Memo: "test", - Meta: blockatlas.Transfer{ - Value: "10000000000000", - Decimals: 8, - Symbol: "BNB", - }, - } - tokenTransferDst = blockatlas.Tx{ - ID: "95CF63FAA27579A9B6AF84EF8B2DFEAC29627479E9C98E7F5AE4535E213FA4C9", - Coin: coin.BNB, - From: "tbnb1ttyn4csghfgyxreu7lmdu3lcplhqhxtzced45a", - To: "tbnb12hlquylu78cjylk5zshxpdj6hf3t0tahwjt3ex", - Fee: "125000", - Date: 1555117625, - Block: 7928667, - Status: blockatlas.StatusCompleted, - Memo: "test", - Meta: blockatlas.NativeTokenTransfer{ - TokenID: "YLC-D8B", - Symbol: "YLC", - Value: "210572645", - Decimals: 8, - From: "tbnb1ttyn4csghfgyxreu7lmdu3lcplhqhxtzced45a", - To: "tbnb12hlquylu78cjylk5zshxpdj6hf3t0tahwjt3ex", - }, - } - newOrderTransferDst = blockatlas.Tx{ - ID: "B0677F3436C1B1661E94D192B84B98AA42AC2485D9808357796EE501CBF794F7", - Coin: coin.BNB, - From: "bnb16ya67j7kvw8682kka09qujlw5u7lf4geqef0ku", - Fee: "0", - Date: 1559689901, - Block: 10815565, - Status: blockatlas.StatusCompleted, - Meta: blockatlas.AnyAction{ - Coin: coin.BNB, - Title: blockatlas.KeyTitlePlaceOrder, - Key: blockatlas.KeyPlaceOrder, - TokenID: "BNB_AWC-986", - Name: "AWC-986", - Symbol: "AWC", - Value: "649878", - Decimals: 8, - }, - } - //TODO: temp test dst - metaFreeNewOrderTransferDst = blockatlas.Tx{ - ID: "B0677F3436C1B1661E94D192B84B98AA42AC2485D9808357796EE501CBF794F7", - Coin: coin.BNB, - From: "bnb16ya67j7kvw8682kka09qujlw5u7lf4geqef0ku", - Fee: "0", - Date: 1559689901, - Block: 10815565, - Status: blockatlas.StatusCompleted, - Meta: nil, - } - cancelOrdeTransferDst = blockatlas.Tx{ - ID: "F48DE755170C10F4A4C0E6836A708C33EEF9A7144800F25187D5F2349FD15A34", - Coin: coin.BNB, - From: "bnb16ya67j7kvw8682kka09qujlw5u7lf4geqef0ku", - Fee: "0", - Date: 1559689892, - Block: 10815539, - Status: blockatlas.StatusCompleted, - Meta: blockatlas.AnyAction{ - Coin: coin.BNB, - Title: blockatlas.KeyTitleCancelOrder, - Key: blockatlas.KeyCancelOrder, - TokenID: "BNB_GTO-908", - Name: "GTO-908", - Symbol: "GTO", - Value: "104716", - Decimals: 8, - }, - } - //TODO: temp test dst - metaFreeCancelOrdeTransferDst = blockatlas.Tx{ - ID: "F48DE755170C10F4A4C0E6836A708C33EEF9A7144800F25187D5F2349FD15A34", - Coin: coin.BNB, - From: "bnb16ya67j7kvw8682kka09qujlw5u7lf4geqef0ku", - Fee: "0", - Date: 1559689892, - Block: 10815539, - Status: blockatlas.StatusCompleted, - Meta: nil, - } -) - -type testTx struct { - name string - apiResponse string - expected blockatlas.Tx - token string - wantError bool -} - -func TestNormalizeTx(t *testing.T) { - testTxList := []testTx{ - { - name: "bnb transfer", - apiResponse: transferTransaction, - expected: transferDst, - token: "BNB", - wantError: false, - }, - { - name: "native token transfer", - apiResponse: tokenTransferTransaction, - expected: tokenTransferDst, - token: "YLC-D8B", - wantError: false, - }, - { - name: "new order transfer", - apiResponse: newOrderTransaction, - expected: newOrderTransferDst, - token: "AWC-986", - wantError: true, - }, - { - name: "cancel order transfer", - apiResponse: cancelOrderTransaction, - expected: cancelOrdeTransferDst, - token: "GTO-908", - wantError: true, - }, - { - name: "new order transfer", - apiResponse: newOrderTransaction, - expected: metaFreeNewOrderTransferDst, - token: "AWC-986", - wantError: true, - }, - { - name: "cancel order transfer", - apiResponse: cancelOrderTransaction, - expected: metaFreeCancelOrdeTransferDst, - token: "GTO-908", - wantError: true, - }, - { - name: "normalize error transfer", - apiResponse: tokenTransferTransaction, - token: "GTO-908", - wantError: true, - }, - } - - for _, testTxInstance := range testTxList { - t.Run(testTxInstance.name, func(t *testing.T) { - var srcTx Tx - err := json.Unmarshal([]byte(testTxInstance.apiResponse), &srcTx) - assert.Nil(t, err) - tx, ok := NormalizeTx(&srcTx, testTxInstance.token) - if testTxInstance.wantError { - assert.False(t, ok, "transfer: tx could be normalized") - return - } - assert.True(t, ok, "transfer: tx could not be normalized") - assert.Equal(t, testTxInstance.expected, tx, "transfer: tx don't equal") - }) - } -} - -const AllTransfersType = ` -[ - { - "blockHeight": 7761368, - "code": 0, - "confirmBlocks": 2089441, - "fromAddr": "tbnb1fhr04azuhcj0dulm7ka40y0cqjlafwae9k9gk2", - "hasChildren": 0, - "log": "Msg 0: ", - "timeStamp": 1555049867552, - "toAddr": "tbnb1sylyjw032eajr9cyllp26n04300qzzre38qyv5", - "txAge": 836729, - "txAsset": "BNB", - "txFee": 0.00125, - "txHash": "1681EE543FB4B5A628EF21D746E031F018E226D127044A4F9BA5EE2542A44555", - "txType": "TRANSFER", - "value": 100000, - "memo": "test" - }, - { - "blockHeight": 7928667, - "code": 0, - "confirmBlocks": 1922024, - "fromAddr": "tbnb1ttyn4csghfgyxreu7lmdu3lcplhqhxtzced45a", - "hasChildren": 0, - "log": "Msg 0: ", - "timeStamp": 1555117625829, - "toAddr": "tbnb12hlquylu78cjylk5zshxpdj6hf3t0tahwjt3ex", - "txAge": 768924, - "txAsset": "YLC-D8B", - "txFee": 0.00125, - "txHash": "95CF63FAA27579A9B6AF84EF8B2DFEAC29627479E9C98E7F5AE4535E213FA4C9", - "txType": "TRANSFER", - "value": 2.10572645, - "memo": "test" - }, - { - "txHash": "B0677F3436C1B1661E94D192B84B98AA42AC2485D9808357796EE501CBF794F7", - "blockHeight": 10815565, - "txType": "NEW_ORDER", - "timeStamp": 1559689901929, - "fromAddr": "bnb16ya67j7kvw8682kka09qujlw5u7lf4geqef0ku", - "value": 0.00649878, - "txAsset": "BNB", - "txQuoteAsset": "AWC-986", - "txFee": 0, - "txAge": 14346340, - "orderId": "D13BAF4BD6638FA3AAD6EBCA0E4BEEA73DF4D519-30", - "data": "{\"orderData\":{\"symbol\":\"BNB_AWC-986\",\"orderType\":\"limit\",\"side\":\"buy\",\"price\":0.00324939,\"quantity\":2.00000000,\"timeInForce\":\"GTE\",\"orderId\":\"D13BAF4BD6638FA3AAD6EBCA0E4BEEA73DF4D519-30\"}}", - "code": 0, - "log": "Msg 0: ", - "confirmBlocks": 0, - "memo": "", - "source": 0, - "hasChildren": 0 - }, - { - "txHash": "F48DE755170C10F4A4C0E6836A708C33EEF9A7144800F25187D5F2349FD15A34", - "blockHeight": 10815539, - "txType": "CANCEL_ORDER", - "timeStamp": 1559689892180, - "fromAddr": "bnb16ya67j7kvw8682kka09qujlw5u7lf4geqef0ku", - "txFee": 0, - "txAge": 14346349, - "data": "{\"orderData\":{\"symbol\":\"BNB_GTO-908\",\"orderType\":\"limit\",\"side\":\"buy\",\"price\":0.00104716,\"quantity\":1.00000000,\"timeInForce\":\"GTE\",\"orderId\":\"D13BAF4BD6638FA3AAD6EBCA0E4BEEA73DF4D519-28\"}}", - "code": 0, - "log": "Msg 0: ", - "confirmBlocks": 0, - "memo": "", - "source": 0, - "hasChildren": 0 - } -] -` - -type testTxs struct { - name string - apiResponse string - expected []blockatlas.Tx - token string -} - -func convertJsonToArray(jsonString string) string { - return "[" + jsonString + "]" -} - -func TestNormalizeTxs(t *testing.T) { - testTxsList := []testTxs{ - { - name: "bnb transfer", - apiResponse: convertJsonToArray(transferTransaction), - expected: []blockatlas.Tx{transferDst}, - token: "BNB", - }, - { - name: "native token transfer", - apiResponse: convertJsonToArray(tokenTransferTransaction), - expected: []blockatlas.Tx{tokenTransferDst}, - token: "YLC-D8B", - }, - //{ - // name: "all transfers", - // apiResponse: AllTransfersType, - // expected: []blockatlas.Tx{transferDst, tokenTransferDst, newOrderTransferDst, cancelOrdeTransferDst}, - // token: "", - //}, - //{ - // name: "new order transfer", - // apiResponse: convertJsonToArray(newOrderTransaction), - // expected: []blockatlas.Tx{newOrderTransferDst}, - // token: "AWC-986", - //}, - //{ - // name: "cancel order transfer", - // apiResponse: convertJsonToArray(cancelOrderTransaction), - // expected: []blockatlas.Tx{cancelOrdeTransferDst}, - // token: "GTO-908", - //} - } - - for _, testTxsInstance := range testTxsList { - t.Run(testTxsInstance.name, func(t *testing.T) { - var srcTxs []Tx - err := json.Unmarshal([]byte(testTxsInstance.apiResponse), &srcTxs) - assert.Nil(t, err) - txs := NormalizeTxs(srcTxs, testTxsInstance.token) - assert.Equal(t, testTxsInstance.expected, txs, "transfer: tx don't equal") - }) - } -} - -const ( - myToken = ` -{ - "free": "17199.38841739", - "frozen": "0.00000000", - "locked": "0.00000000", - "symbol": "ARN-71B" -} -` - myTokenAllZero = ` -{ - "free": "0.00000000", - "frozen": "0.00000000", - "locked": "0.00000000", - "symbol": "ARN-71B" -} -` - myTokenFreeZero = ` -{ - "free": "0.00000000", - "frozen": "1.00000000", - "locked": "0.00000000", - "symbol": "ARN-71B" -} -` - myTokenFrozenAndFreeZero = ` -{ - "free": "0.00000000", - "frozen": "0.00000000", - "locked": "0.00000001", - "symbol": "ARN-71B" -} -` - tokenList = ` -[ - { - "mintable": false, - "name": "Aeron", - "original_symbol": "ARN", - "owner": "bnb1dq8ae0ayztqp99peggq5sygzf3n7u2ze4t0jne", - "symbol": "ARN-71B", - "total_supply": "20000000.00000000" - }, - { - "mintable": false, - "name": "BOLT Token", - "original_symbol": "BOLT", - "owner": "bnb177ujwmshxu8r9za4vy9ztqn65tmr54ddw958rt", - "symbol": "BOLT-4C6", - "total_supply": "995000000.00000000" - } -] -` -) - -var ( - tokenDst = blockatlas.Token{ - Name: "Aeron", - Symbol: "ARN", - Decimals: 8, - TokenID: "ARN-71B", - Coin: coin.BNB, - Type: blockatlas.TokenTypeBEP2, - } - emptyTokenDst = blockatlas.Token{} -) - -type testToken struct { - name string - apiResponse string - expected blockatlas.Token - tokens string - ok bool -} - -func TestNormalizeToken(t *testing.T) { - testingTokens := []testToken{ - { - name: "Test with not zero balance", - apiResponse: myToken, - tokens: tokenList, - expected: tokenDst, - ok: true, - }, - { - name: "Test with all zero balance", - apiResponse: myTokenAllZero, - tokens: tokenList, - expected: emptyTokenDst, - ok: false, - }, - { - name: "Test with only free zero balance", - apiResponse: myTokenFreeZero, - tokens: tokenList, - expected: tokenDst, - ok: true, - }, - { - name: "Test with free and frozen zero balances", - apiResponse: myTokenFrozenAndFreeZero, - tokens: tokenList, - expected: tokenDst, - ok: true, - }, - } - for _, testToken := range testingTokens { - t.Run(testToken.name, func(t *testing.T) { - var srcToken Balance - err := json.Unmarshal([]byte(testToken.apiResponse), &srcToken) - assert.Nil(t, err) - - var srcTokens TokenPage - err = json.Unmarshal([]byte(testToken.tokens), &srcTokens) - assert.Nil(t, err) - - tk, ok := NormalizeToken(&srcToken, &srcTokens) - assert.Equal(t, testToken.ok, ok, "token: token could not be normalized") - assert.Equal(t, testToken.expected, tk, "token: token don't equal") - }) - } -} - -func TestDecimalPlaces(t *testing.T) { - tests := []struct { - name string - value string - want int - }{ - {"Test text value with dot", "decimal.places", 6}, - {"Test float value", "1234.543212222", 9}, - {"Test float value", "5.33333333", 8}, - {"Test text value", "decimal", 0}, - {"Test integer value", "4", 0}, - {"Test empty value", "", 0}, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - if got := decimalPlaces(tt.value); got != tt.want { - t.Errorf("decimalPlaces() = %v, want %v", got, tt.want) - } - }) - } -} - -func TestTokenSymbol(t *testing.T) { - assert.Equal(t, "UGAS", TokenSymbol("UGAS")) - assert.Equal(t, "UGAS", TokenSymbol("UGAS-B0C")) -} diff --git a/platform/binance/base.go b/platform/binance/base.go new file mode 100644 index 000000000..c6042f691 --- /dev/null +++ b/platform/binance/base.go @@ -0,0 +1,23 @@ +package binance + +import ( + "github.com/trustwallet/blockatlas/platform/binance/staking" + "github.com/trustwallet/golibs/coin" +) + +type Platform struct { + client Client + stakingClient staking.Client +} + +func Init(api, apiKey, stakingApi string) *Platform { + p := Platform{ + client: InitClient(api, apiKey), + stakingClient: staking.InitClient(stakingApi), + } + return &p +} + +func (p *Platform) Coin() coin.Coin { + return coin.Binance() +} diff --git a/platform/binance/base_test.go b/platform/binance/base_test.go new file mode 100644 index 000000000..5241df002 --- /dev/null +++ b/platform/binance/base_test.go @@ -0,0 +1,86 @@ +package binance + +import ( + "fmt" + "net/http" + + "github.com/trustwallet/golibs/mock" +) + +var ( + wantedBlockNoOrders, _ = mock.JsonStringFromFilePath("mocks/block_no_orders.json") + wantedTxs, _ = mock.JsonStringFromFilePath("mocks/txs.json") + wantedTokens, _ = mock.JsonStringFromFilePath("mocks/tokens.json") + wantedBlockMultiNoOrders, _ = mock.JsonStringFromFilePath("mocks/block_multi_no_orders.json") + wantedTxsResponse, _ = mock.JsonStringFromFilePath("mocks/txs_response.json") + wantedAccountMetaResponse, _ = mock.JsonStringFromFilePath("mocks/account_meta_response.json") + wantedTokensResponse, _ = mock.JsonStringFromFilePath("mocks/tokens_response.json") + wantedTxsResponseAva, _ = mock.JsonStringFromFilePath("mocks/txs_ava_response.json") + wantedBlockResponseMulti, _ = mock.JsonStringFromFilePath("mocks/block_multi_response.json") + mockedBlockResponse, _ = mock.JsonStringFromFilePath("mocks/block_response.json") + mockedNodeInfo, _ = mock.JsonStringFromFilePath("mocks/node_info.json") +) + +func createMockedAPI() http.Handler { + r := http.NewServeMux() + + r.HandleFunc("/api/v1/node-info", func(w http.ResponseWriter, r *http.Request) { + w.WriteHeader(http.StatusOK) + if _, err := fmt.Fprint(w, mockedNodeInfo); err != nil { + panic(err) + } + }) + + r.HandleFunc("/api/v2/transactions-in-block/104867508", func(w http.ResponseWriter, r *http.Request) { + w.WriteHeader(http.StatusOK) + if _, err := fmt.Fprint(w, mockedBlockResponse); err != nil { + panic(err) + } + }) + + r.HandleFunc("/api/v2/transactions-in-block/105529271", func(w http.ResponseWriter, r *http.Request) { + w.WriteHeader(http.StatusOK) + if _, err := fmt.Fprint(w, wantedBlockResponseMulti); err != nil { + panic(err) + } + }) + + r.HandleFunc("/api/v1/tokens", func(w http.ResponseWriter, r *http.Request) { + w.WriteHeader(http.StatusOK) + if _, err := fmt.Fprint(w, wantedTokensResponse); err != nil { + panic(err) + } + }) + + r.HandleFunc("/api/v1/account/bnb1w7puzjxu05ktc5zvpnzkndt6tyl720nsutzvpg", func(w http.ResponseWriter, r *http.Request) { + w.WriteHeader(http.StatusOK) + if _, err := fmt.Fprint(w, wantedAccountMetaResponse); err != nil { + panic(err) + } + }) + + r.HandleFunc("/api/v1/transactions", func(w http.ResponseWriter, r *http.Request) { + w.WriteHeader(http.StatusOK) + var ( + address = r.URL.Query().Get("address") + txAsset = r.URL.Query().Get("txAsset") + + response string + ) + + switch { + case address == "bnb136ns6lfw4zs5hg4n85vdthaad7hq5m4gtkgf23" && txAsset == "BNB": + response = wantedTxsResponse + case address == "bnb1w7puzjxu05ktc5zvpnzkndt6tyl720nsutzvpg" && txAsset == "AVA-645": + response = wantedTxsResponseAva + default: + response = "" + } + + if _, err := fmt.Fprint(w, response); err != nil { + panic(err) + } + }) + + return r +} diff --git a/platform/binance/block.go b/platform/binance/block.go new file mode 100644 index 000000000..92831e042 --- /dev/null +++ b/platform/binance/block.go @@ -0,0 +1,20 @@ +package binance + +import "github.com/trustwallet/golibs/types" + +func (p *Platform) CurrentBlockNumber() (int64, error) { + block, err := p.client.FetchLatestBlockNumber() + if err != nil { + return 0, err + } + return block, nil +} + +func (p *Platform) GetBlockByNumber(num int64) (*types.Block, error) { + transactionInBlockResponse, err := p.client.FetchTransactionsInBlock(num) + if err != nil { + return nil, err + } + block := normalizeBlock(transactionInBlockResponse) + return &block, nil +} diff --git a/platform/binance/block_test.go b/platform/binance/block_test.go new file mode 100644 index 000000000..c6f40dd33 --- /dev/null +++ b/platform/binance/block_test.go @@ -0,0 +1,35 @@ +package binance + +import ( + "encoding/json" + "net/http/httptest" + "testing" + + "github.com/stretchr/testify/assert" +) + +func TestPlatform_CurrentBlockNumber(t *testing.T) { + server := httptest.NewServer(createMockedAPI()) + defer server.Close() + p := Init(server.URL, "", "") + number, err := p.CurrentBlockNumber() + assert.Nil(t, err) + assert.Equal(t, int64(104867535), number) +} + +func TestPlatform_GetBlockByNumber(t *testing.T) { + server := httptest.NewServer(createMockedAPI()) + defer server.Close() + p := Init(server.URL, "", "") + block, err := p.GetBlockByNumber(104867508) + assert.Nil(t, err) + res, err := json.Marshal(block) + assert.Nil(t, err) + assert.JSONEq(t, wantedBlockNoOrders, string(res)) + + blockMulti, err := p.GetBlockByNumber(105529271) + assert.Nil(t, err) + resMulti, err := json.Marshal(blockMulti) + assert.Nil(t, err) + assert.JSONEq(t, wantedBlockMultiNoOrders, string(resMulti)) +} diff --git a/platform/binance/client.go b/platform/binance/client.go index a7bac1d2c..64549b6aa 100644 --- a/platform/binance/client.go +++ b/platform/binance/client.go @@ -1,79 +1,72 @@ package binance import ( - "encoding/json" - "github.com/trustwallet/blockatlas/pkg/blockatlas" - "github.com/trustwallet/blockatlas/pkg/errors" - "github.com/trustwallet/blockatlas/pkg/logger" - "net/http" + "fmt" "net/url" "strconv" -) + "time" + + "github.com/trustwallet/golibs/network/middleware" -// TODO Headers + rate limiting + "github.com/trustwallet/golibs/client" + "github.com/trustwallet/golibs/types" +) type Client struct { - blockatlas.Request + client.Request } -func (c *Client) GetBlockList(count int) (*BlockList, error) { - result := new(BlockList) - query := url.Values{"rows": {strconv.Itoa(count)}, "page": {"1"}} - err := c.Get(result, "blocks", query) - return result, err +func InitClient(url, apiKey string) Client { + c := Client{client.InitClient(url, middleware.SentryErrorHandler)} + c.Headers["apikey"] = apiKey + return c } -func (c *Client) GetBlockByNumber(num int64) (*TxPage, error) { - stx := new(TxPage) - query := url.Values{ - "blockHeight": {strconv.FormatInt(num, 10)}, - // Only first 100 transactions of block returned - // Shouldn't be a problem at the current transaction rate - "rows": {"100"}, - "page": {"1"}, +func (c Client) FetchLatestBlockNumber() (int64, error) { + var result NodeInfoResponse + err := c.Get(&result, "api/v1/node-info", nil) + if err != nil { + return 0, err } - err := c.Get(stx, "txs", query) - return stx, err + return int64(result.SyncInfo.LatestBlockHeight), nil } -func (c *Client) GetTxsOfAddress(address string, token string) (*TxPage, error) { - stx := new(TxPage) - query := url.Values{"address": {address}, "rows": {"20"}, "page": {"1"}, "txAsset": {token}, "txType": {"TRANSFER"}} - err := c.Get(stx, "txs", query) - return stx, err +func (c Client) FetchTransactionsInBlock(blockNumber int64) (TransactionsInBlockResponse, error) { + var result TransactionsInBlockResponse + err := c.Get(&result, fmt.Sprintf("api/v2/transactions-in-block/%d", blockNumber), nil) + if err != nil { + return TransactionsInBlockResponse{}, err + } + return result, nil } -func getHTTPError(res *http.Response, desc string) error { - switch res.StatusCode { - case http.StatusBadRequest: - return getAPIError(res, desc) - case http.StatusNotFound: - return blockatlas.ErrNotFound - case http.StatusOK: - return nil - default: - return errors.E("getHTTPError error", errors.Params{"status": res.Status}).PushToSentry() +func (c Client) FetchTransactionsByAddressAndTokenID(address, tokenID string) ([]Tx, error) { + var result TransactionsInBlockResponse + startTime := strconv.Itoa(int(time.Now().AddDate(0, -3, 0).Unix() * 1000)) + limit := strconv.Itoa(types.TxPerPage) + params := url.Values{"address": {address}, "txAsset": {tokenID}, "startTime": {startTime}, "limit": {limit}} + err := c.Get(&result, "api/v1/transactions", params) + if err != nil { + return nil, err } + return result.Tx, nil } -func getAPIError(res *http.Response, desc string) error { - var sErr Error - err := json.NewDecoder(res.Body).Decode(&sErr) +func (c Client) FetchAccountMeta(address string) (AccountMeta, error) { + var result AccountMeta + err := c.Get(&result, fmt.Sprintf("api/v1/account/%s", address), nil) if err != nil { - err = errors.E(err, errors.TypePlatformUnmarshal, errors.Params{"desc": desc}).PushToSentry() - logger.Error(err, "Binance: Failed to decode error response") - return blockatlas.ErrSourceConn + return AccountMeta{}, err } + return result, nil +} - switch sErr.Message { - case "address is not valid": - return blockatlas.ErrInvalidAddr +func (c Client) FetchTokens() (Tokens, error) { + var result Tokens + query := url.Values{"limit": {tokensLimit}} + err := c.GetWithCache(&result, "api/v1/tokens", query, 5*time.Minute) + if err != nil { + return nil, err } - - logger.Error("Binance: Failed", desc, err, logger.Params{ - "status": res.StatusCode, - "code": sErr.Code, - "message": sErr.Message, - }) - return blockatlas.ErrSourceConn + return result, nil } diff --git a/platform/binance/dex_client.go b/platform/binance/dex_client.go deleted file mode 100644 index 4de3efa61..000000000 --- a/platform/binance/dex_client.go +++ /dev/null @@ -1,26 +0,0 @@ -package binance - -import ( - "fmt" - "github.com/trustwallet/blockatlas/pkg/blockatlas" - "net/url" -) - -// TODO Headers + rate limiting - -type DexClient struct { - blockatlas.Request -} - -func (c *DexClient) GetAccountMetadata(address string) (account *Account, err error) { - path := fmt.Sprintf("v1/account/%s", address) - err = c.Get(&account, path, nil) - return account, err -} - -func (c *DexClient) GetTokens() (*TokenPage, error) { - stp := new(TokenPage) - query := url.Values{"limit": {"1000"}, "offset": {"0"}} - err := c.Get(stp, "v1/tokens", query) - return stp, err -} diff --git a/platform/binance/mocks/account_meta_response.json b/platform/binance/mocks/account_meta_response.json new file mode 100644 index 000000000..774123a1c --- /dev/null +++ b/platform/binance/mocks/account_meta_response.json @@ -0,0 +1,61 @@ +{ + "account_number": 398176, + "address": "bnb1w7puzjxu05ktc5zvpnzkndt6tyl720nsutzvpg", + "balances": [ + { + "free": "366.87270502", + "frozen": "0.00000000", + "locked": "2226.00000000", + "symbol": "AVA-645" + }, + { + "free": "6.51198688", + "frozen": "0.00000000", + "locked": "0.00000000", + "symbol": "BNB" + }, + { + "free": "850.41375978", + "frozen": "0.00000000", + "locked": "3220.00483000", + "symbol": "BUSD-BD1" + } + ], + "flags": 0, + "public_key": [ + 2, + 241, + 253, + 162, + 68, + 84, + 67, + 180, + 235, + 15, + 238, + 212, + 39, + 75, + 236, + 33, + 202, + 249, + 109, + 68, + 247, + 56, + 104, + 66, + 240, + 219, + 8, + 22, + 245, + 187, + 84, + 46, + 54 + ], + "sequence": 1595533 +} diff --git a/platform/binance/mocks/block_multi_no_orders.json b/platform/binance/mocks/block_multi_no_orders.json new file mode 100644 index 000000000..a1e3cfcb7 --- /dev/null +++ b/platform/binance/mocks/block_multi_no_orders.json @@ -0,0 +1,33 @@ +{ + "number": 105529271, + "txs": [ + { + "id": "CC7C3EF1407373FDA74B005E64683AB5865126DE93A5FAF755FF5CC948992067", + "coin": 714, + "from": "bnb15qced76xere38hmmpe644u5kd8v4lzl9gsex9w", + "to": "bnb15qced76xere38hmmpe644u5kd8v4lzl9gsex9w", + "fee": "60000", + "date": 1596746326, + "block": 105529271, + "status": "completed", + "sequence": 2300, + "type": "transfer", + "memo": "0", + "metadata": { "value": "1", "symbol": "BNB", "decimals": 8 } + }, + { + "id": "CC7C3EF1407373FDA74B005E64683AB5865126DE93A5FAF755FF5CC948992067", + "coin": 714, + "from": "bnb1t38ccns9var4ac4yj2ylmu99r9ecmggr8ye5e5", + "to": "bnb136ns6lfw4zs5hg4n85vdthaad7hq5m4gtkgf23", + "fee": "0", + "date": 1596746326, + "block": 105529271, + "status": "completed", + "sequence": 2300, + "type": "transfer", + "memo": "0", + "metadata": { "value": "39421249", "symbol": "BNB", "decimals": 8 } + } + ] +} diff --git a/platform/binance/mocks/block_multi_response.json b/platform/binance/mocks/block_multi_response.json new file mode 100644 index 000000000..661c0a852 --- /dev/null +++ b/platform/binance/mocks/block_multi_response.json @@ -0,0 +1,59 @@ +{ + "blockHeight": 105529271, + "tx": [ + { + "txHash": "432FF828B1DC1C4DAF13A51B6AE7ADD9932B7FC6526C28F7FE9C905F95472820", + "blockHeight": 105529271, + "txType": "CANCEL_ORDER", + "timeStamp": "2020-08-06T20:38:46.583Z", + "fromAddr": "bnb1z35wusfv8twfele77vddclka9z84ugywug48gn", + "toAddr": null, + "value": null, + "txAsset": null, + "txFee": null, + "code": 0, + "data": "{\"orderData\":{\"orderId\":\"1468EE412C3ADC9CFF3EF31ADC7EDD288F5E208E-11315084\"}}", + "memo": "", + "source": 0, + "sequence": 11317170 + }, + { + "txHash": "CC7C3EF1407373FDA74B005E64683AB5865126DE93A5FAF755FF5CC948992067", + "blockHeight": 105529271, + "txType": "TRANSFER", + "timeStamp": "2020-08-06T20:38:46.583Z", + "fromAddr": null, + "toAddr": null, + "value": null, + "txAsset": null, + "txFee": null, + "code": 0, + "data": null, + "memo": "0", + "source": 1, + "sequence": 2300, + "subTransactions": [ + { + "txHash": "CC7C3EF1407373FDA74B005E64683AB5865126DE93A5FAF755FF5CC948992067", + "blockHeight": 105529271, + "txType": "TRANSFER", + "fromAddr": "bnb15qced76xere38hmmpe644u5kd8v4lzl9gsex9w", + "toAddr": "bnb15qced76xere38hmmpe644u5kd8v4lzl9gsex9w", + "txAsset": "BNB", + "txFee": "0.00060000", + "value": "0.00000001" + }, + { + "txHash": "CC7C3EF1407373FDA74B005E64683AB5865126DE93A5FAF755FF5CC948992067", + "blockHeight": 105529271, + "txType": "TRANSFER", + "fromAddr": "bnb1t38ccns9var4ac4yj2ylmu99r9ecmggr8ye5e5", + "toAddr": "bnb136ns6lfw4zs5hg4n85vdthaad7hq5m4gtkgf23", + "txAsset": "BNB", + "txFee": null, + "value": "0.39421249" + } + ] + } + ] +} diff --git a/platform/binance/mocks/block_no_orders.json b/platform/binance/mocks/block_no_orders.json new file mode 100644 index 000000000..304f546f6 --- /dev/null +++ b/platform/binance/mocks/block_no_orders.json @@ -0,0 +1,19 @@ +{ + "number": 104867508, + "txs": [ + { + "id": "9B87D17581F2AC73D2999EDE56535E50D9D4DB75150A92A90122190F77D47755", + "coin": 714, + "from": "bnb1c4czpzvn0ttdcpnv3cy2858l2m9frxdfgk4jr0", + "to": "bnb1g2ukzn702napq3levm54m2z3p2gam7upern9aq", + "fee": "37500", + "date": 1596472337, + "block": 104867508, + "status": "completed", + "sequence": 6, + "type": "transfer", + "memo": "", + "metadata": { "value": "24481570", "symbol": "BNB", "decimals": 8 } + } + ] +} diff --git a/platform/binance/mocks/block_response.json b/platform/binance/mocks/block_response.json new file mode 100644 index 000000000..5e9d58638 --- /dev/null +++ b/platform/binance/mocks/block_response.json @@ -0,0 +1,54 @@ +{ + "blockHeight": 104867508, + "tx": [ + { + "txHash": "4CD5BAA433BABA63D862141A4A2F9235B0BA5CBAB8114C93A0556ECA4EC7A68A", + "blockHeight": 104867508, + "txType": "CANCEL_ORDER", + "timeStamp": "2020-08-03T16:32:17.963Z", + "fromAddr": "bnb1l83kstts7lt9dpgawzechnrgjq54dql36dyspc", + "toAddr": null, + "value": null, + "txAsset": null, + "txFee": null, + "code": 0, + "data": "{\"orderData\":{\"symbol\":\"AVA-645_BUSD-BD1\",\"orderType\":\"LIMIT\",\"side\":\"SELL\",\"price\":\"1.94064\",\"quantity\":\"40\",\"timeInForce\":\"GTE\",\"orderId\":\"F9E3682D70F7D656851D70B38BCC6890295683F1-1023254\"}}", + "memo": "", + "source": 0, + "sequence": 1023322 + }, + { + "txHash": "9B87D17581F2AC73D2999EDE56535E50D9D4DB75150A92A90122190F77D47755", + "blockHeight": 104867508, + "txType": "TRANSFER", + "timeStamp": "2020-08-03T16:32:17.963Z", + "fromAddr": "bnb1c4czpzvn0ttdcpnv3cy2858l2m9frxdfgk4jr0", + "toAddr": "bnb1g2ukzn702napq3levm54m2z3p2gam7upern9aq", + "value": "0.24481570", + "txAsset": "BNB", + "txFee": "0.00037500", + "code": 0, + "data": null, + "memo": "", + "source": 0, + "sequence": 6 + }, + { + "txHash": "5C0580AC983C1CF36F1656D9E8B062CD0578839BEFC839EFD6720FF315B45EEB", + "blockHeight": 104867508, + "txType": "NEW_ORDER", + "timeStamp": "2020-08-03T16:32:17.963Z", + "fromAddr": "bnb1w7puzjxu05ktc5zvpnzkndt6tyl720nsutzvpg", + "toAddr": null, + "value": "169.20330000", + "txAsset": "AVA-645", + "txFee": "0.00000000", + "orderId": "7783C148DC7D2CBC504C0CC569B57A593FE53E70-1509155", + "code": 0, + "data": "{\"orderData\":{\"symbol\":\"AVA-645_BUSD-BD1\",\"orderType\":\"LIMIT\",\"side\":\"BUY\",\"price\":\"1.61146\",\"quantity\":\"105\",\"timeInForce\":\"GTE\",\"orderId\":\"7783C148DC7D2CBC504C0CC569B57A593FE53E70-1509155\"}}", + "memo": "", + "source": 0, + "sequence": 1509154 + } + ] +} diff --git a/platform/binance/mocks/node_info.json b/platform/binance/mocks/node_info.json new file mode 100644 index 000000000..5b059912b --- /dev/null +++ b/platform/binance/mocks/node_info.json @@ -0,0 +1,57 @@ +{ + "node_info": { + "protocol_version": { "p2p": 7, "block": 10, "app": 0 }, + "id": "46ba46d5b6fcb61b7839881a75b081123297f7cf", + "listen_addr": "10.212.32.84:27146", + "network": "Binance-Chain-Tigris", + "version": "0.32.3", + "channels": "3640202122233038", + "moniker": "Ararat", + "other": { "tx_index": "on", "rpc_address": "tcp://0.0.0.0:27147" } + }, + "sync_info": { + "latest_block_hash": "507BB016F306906569F12883617A4231AB51DAF5FA5004C8F70B17CDF73A8B40", + "latest_app_hash": "A96FA3DB1FAC12D325845FFEE679EC52CB944BE4B343BC016CE4707FA63EE2BE", + "latest_block_height": 104867535, + "latest_block_time": "2020-08-03T16:32:29.834625465Z", + "catching_up": false + }, + "validator_info": { + "address": "B7707D9F593C62E85BB9E1A2366D12A97CD5DFF2", + "pub_key": [ + 113, + 242, + 215, + 184, + 236, + 28, + 139, + 153, + 166, + 83, + 66, + 155, + 1, + 24, + 205, + 32, + 31, + 121, + 79, + 64, + 157, + 15, + 234, + 77, + 101, + 177, + 182, + 98, + 242, + 176, + 0, + 99 + ], + "voting_power": 1000000000000 + } +} diff --git a/platform/binance/mocks/tokens.json b/platform/binance/mocks/tokens.json new file mode 100644 index 000000000..8f8d1bcae --- /dev/null +++ b/platform/binance/mocks/tokens.json @@ -0,0 +1,26 @@ +[ + { + "name": "Travala.com Token", + "symbol": "AVA", + "decimals": 8, + "token_id": "AVA-645", + "coin": 714, + "type": "BEP2" + }, + { + "name": "Binance Chain Native Token", + "symbol": "BNB", + "decimals": 8, + "token_id": "BNB", + "coin": 714, + "type": "BEP2" + }, + { + "name": "Binance USD", + "symbol": "BUSD", + "decimals": 8, + "token_id": "BUSD-BD1", + "coin": 714, + "type": "BEP2" + } +] diff --git a/platform/binance/mocks/tokens_response.json b/platform/binance/mocks/tokens_response.json new file mode 100644 index 000000000..26e9613cf --- /dev/null +++ b/platform/binance/mocks/tokens_response.json @@ -0,0 +1,802 @@ +[ + { + "mintable": true, + "name": "Africa Stable-Coin", + "original_symbol": "ABCD", + "owner": "bnb1ujvzeuft0ezf9fu4u0mk52t8mc7t8geyfkevms", + "symbol": "ABCD-5D8", + "total_supply": "3000000.00000000" + }, + { + "mintable": false, + "name": "Aditus", + "original_symbol": "ADI", + "owner": "bnb1djdymfgzknmcsu9dzm9s0uavdszn0cl82z4hps", + "symbol": "ADI-6BB", + "total_supply": "750000000.00000000" + }, + { + "mintable": false, + "name": "Aergo", + "original_symbol": "AERGO", + "owner": "bnb1llqhwwwmh878844tm3g8v47k0t7xtnhl4hggjl", + "symbol": "AERGO-46B", + "total_supply": "500000000.00000000" + }, + { + "mintable": false, + "name": "Alaris", + "original_symbol": "ALA", + "owner": "bnb1pmdkvw6cquwylr46wcrl82xzmul0y2jpj5cwx7", + "symbol": "ALA-DCD", + "total_supply": "60000000.00000000" + }, + { + "mintable": false, + "name": "ANKR", + "original_symbol": "ANKR", + "owner": "bnb1hvg059mkwleum35j6y2qjn4fvmgl7zxtlah4tn", + "symbol": "ANKR-E97", + "total_supply": "10000000000.00000000" + }, + { + "mintable": false, + "name": "Aeron", + "original_symbol": "ARN", + "owner": "bnb1dq8ae0ayztqp99peggq5sygzf3n7u2ze4t0jne", + "symbol": "ARN-71B", + "total_supply": "20000000.00000000" + }, + { + "mintable": true, + "name": "ARPA", + "original_symbol": "ARPA", + "owner": "bnb1mecnt25u3j9ne7th5av7hqvnmzvyrr7ny8hg8c", + "symbol": "ARPA-575", + "total_supply": "12000000.00000000" + }, + { + "mintable": false, + "name": "Maecenas ART Token", + "original_symbol": "ART", + "owner": "bnb13plj9kycvcew5v0achpatnd5l5pacys9h0gu8l", + "symbol": "ART-3C9", + "total_supply": "100000000.00000000" + }, + { + "mintable": true, + "name": "Atlas Protocol", + "original_symbol": "ATP", + "owner": "bnb1msw3avv894nlpeu0vn4qlkl0r65a3rp7gtz5hf", + "symbol": "ATP-38C", + "total_supply": "40000000.00000000" + }, + { + "mintable": false, + "name": "Travala.com Token", + "original_symbol": "AVA", + "owner": "bnb1dm9c7gccgd07td5r69m50u8fg8danfgqvlhj6c", + "symbol": "AVA-645", + "total_supply": "61228716.00000000" + }, + { + "mintable": true, + "name": "“Atomic", + "original_symbol": "AWC", + "owner": "bnb1g5xj69c0s0x646hug7j3vr6eamlkf7jw3cr3yw", + "symbol": "AWC-8B2", + "total_supply": "147.00000000" + }, + { + "mintable": false, + "name": "Atomic Wallet Token", + "original_symbol": "AWC", + "owner": "bnb1g5xj69c0s0x646hug7j3vr6eamlkf7jw3cr3yw", + "symbol": "AWC-986", + "total_supply": "50000000.00000000" + }, + { + "mintable": false, + "name": "AXPR.B", + "original_symbol": "AXPR", + "owner": "bnb1zpnmet0vhfupn9ysu26gukzj7a2xkkcry22n9t", + "symbol": "AXPR-777", + "total_supply": "347955111.02000000" + }, + { + "mintable": true, + "name": "BAWnetwork", + "original_symbol": "BAW", + "owner": "bnb1umdp5z4hugur26tcgf48fhr0548fv0q0fga84u", + "symbol": "BAW-DFB", + "total_supply": "25000000000.00000000" + }, + { + "mintable": true, + "name": "BCH BEP2", + "original_symbol": "BCH", + "owner": "bnb15tjhzw85wyywwp7zvc4l3ux3j0393rzp9exl0p", + "symbol": "BCH-1FD", + "total_supply": "5000.00000000" + }, + { + "mintable": false, + "name": "Blockmason Credit Protocol", + "original_symbol": "BCPT", + "owner": "bnb1ed7sfac04uzkg8lsxmgl7sxlj8pvyrpnyjm9ew", + "symbol": "BCPT-95A", + "total_supply": "116158667.00000000" + }, + { + "mintable": true, + "name": "3X Short Bitcoin Token", + "original_symbol": "BEAR", + "owner": "bnb1ff4r0t7j8ll8lf3gm2ltdu3hjy4w690j7vvees", + "symbol": "BEAR-14C", + "total_supply": "50301.00000000" + }, + { + "mintable": false, + "name": "EOSBet Token", + "original_symbol": "BET", + "owner": "bnb1rgylg0f3ka24a63rnq926quvet438fxrz3320c", + "symbol": "BET-844", + "total_supply": "88000000.00000000" + }, + { + "mintable": false, + "name": "BETX Token", + "original_symbol": "BETX", + "owner": "bnb15v9e3c4wy8vpex0c5fj702lexjesh30v2203f2", + "symbol": "BETX-A0C", + "total_supply": "200000000.00000000" + }, + { + "mintable": true, + "name": "Binance GBP Stable Coin", + "original_symbol": "BGBP", + "owner": "bnb1r4ag7kd90rptlhcuuc8trh60v4m4vvzrfyecta", + "symbol": "BGBP-CF3", + "total_supply": "200.00000000" + }, + { + "mintable": true, + "name": "Humanity First Token", + "original_symbol": "BHFT", + "owner": "bnb148t3u8zxa44vhydes5qa8xnxuzuq6zgyxmzt6d", + "symbol": "BHFT-BBE", + "total_supply": "636425000.00000000" + }, + { + "mintable": true, + "name": "BIDR BEP2", + "original_symbol": "BIDR", + "owner": "bnb1v7hlk89x4t6wtfx89wrvhxj5wcv7sxjrve6dav", + "symbol": "BIDR-0E9", + "total_supply": "13700000000.00000000" + }, + { + "mintable": false, + "name": "Bitwires Token", + "original_symbol": "BKBT", + "owner": "bnb104p50kz2uvep5s5u6j0lr6vkl6rp5g4653d7w4", + "symbol": "BKBT-3A6", + "total_supply": "10000000000.00000000" + }, + { + "mintable": true, + "name": "Binance KRW", + "original_symbol": "BKRW", + "owner": "bnb18kha55gvsxl7gkdh8y329hu3p6wndh6jkwqnxn", + "symbol": "BKRW-AB7", + "total_supply": "1571020711.00000000" + }, + { + "mintable": false, + "name": "Blockmason Link", + "original_symbol": "BLINK", + "owner": "bnb1ed7sfac04uzkg8lsxmgl7sxlj8pvyrpnyjm9ew", + "symbol": "BLINK-9C6", + "total_supply": "5000000000.00000000" + }, + { + "mintable": false, + "name": "Binance Chain Native Token", + "original_symbol": "BNB", + "owner": "bnb1ultyhpw2p2ktvr68swz56570lgj2rdsadq3ym2", + "symbol": "BNB", + "total_supply": "176406560.90000000" + }, + { + "mintable": false, + "name": "BOLT Token", + "original_symbol": "BOLT", + "owner": "bnb177ujwmshxu8r9za4vy9ztqn65tmr54ddw958rt", + "symbol": "BOLT-4C6", + "total_supply": "980230000.00000000" + }, + { + "mintable": false, + "name": "Bitcloud Pro", + "original_symbol": "BPRO", + "owner": "bnb1482svhhrffpga5wmqw8068af4c9u2q9dp3hg4m", + "symbol": "BPRO-5A6", + "total_supply": "5000000000.00000000" + }, + { + "mintable": true, + "name": "BQTX", + "original_symbol": "BQTX", + "owner": "bnb1j42h6j40htujnjmtp4ckw4zx27vp0f93cvmua8", + "symbol": "BQTX-235", + "total_supply": "1000000.00000000" + }, + { + "mintable": false, + "name": "BOOSTO", + "original_symbol": "BST2", + "owner": "bnb19k2av7cmdvp9f0qkeu5vfl59yp8ftqv2s55dzs", + "symbol": "BST2-2F2", + "total_supply": "500000000.00000000" + }, + { + "mintable": true, + "name": "Bitcoin BEP2", + "original_symbol": "BTCB", + "owner": "bnb1akey87kt0r8y3fmhu2l8eyzdjvt9ptl5cppz0v", + "symbol": "BTCB-1DE", + "total_supply": "9001.00000000" + }, + { + "mintable": true, + "name": "BTTB", + "original_symbol": "BTTB", + "owner": "bnb1srm577fgsjg363vsqt8td4tat5arzfvkjchqgq", + "symbol": "BTTB-D31", + "total_supply": "1000000000.00000000" + }, + { + "mintable": true, + "name": "3x Long Bitcoin Token", + "original_symbol": "BULL", + "owner": "bnb1ff4r0t7j8ll8lf3gm2ltdu3hjy4w690j7vvees", + "symbol": "BULL-BE4", + "total_supply": "604.80000000" + }, + { + "mintable": true, + "name": "Binance USD", + "original_symbol": "BUSD", + "owner": "bnb19v2ayq6k6e5x6ny3jdutdm6kpqn3n6mxheegvj", + "symbol": "BUSD-BD1", + "total_supply": "26000000.00000000" + }, + { + "mintable": false, + "name": "Bezant Token", + "original_symbol": "BZNT", + "owner": "bnb1w5a5jywe3cu20uq6n6x3vmzcq342s6st4cz73s", + "symbol": "BZNT-464", + "total_supply": "964511442.00000000" + }, + { + "mintable": false, + "name": "CanYaCoin", + "original_symbol": "CAN", + "owner": "bnb16w59lfh4y2cqvu8f7yr000ll37ldh4w6hnz7l0", + "symbol": "CAN-677", + "total_supply": "95827000.00000000" + }, + { + "mintable": false, + "name": "CASHAA", + "original_symbol": "CAS", + "owner": "bnb1xkw2sagpx6t0cmwzapxpv94tupvqk7tpgy72ku", + "symbol": "CAS-167", + "total_supply": "1000000000.00000000" + }, + { + "mintable": false, + "name": "Cubiex", + "original_symbol": "CBIX", + "owner": "bnb1jlm66w38gpfuqr4s2jcfwlcrlx46p05thdnv7g", + "symbol": "CBIX-3C9", + "total_supply": "150000000.00000000" + }, + { + "mintable": false, + "name": "CryptoBonusMiles", + "original_symbol": "CBM", + "owner": "bnb1dq8ae0ayztqp99peggq5sygzf3n7u2ze4t0jne", + "symbol": "CBM-4B2", + "total_supply": "5000000000.00000000" + }, + { + "mintable": false, + "name": "Clipper Coin", + "original_symbol": "CCCX", + "owner": "bnb1ry99rte8gfnn9c6at9mlmrrq6p2k4u7732j9h7", + "symbol": "CCCX-10D", + "total_supply": "5000000000.00000000" + }, + { + "mintable": false, + "name": "Chiliz", + "original_symbol": "CHZ", + "owner": "bnb1cghr4z8ag440tv4wnk3l6wzynytlpvfqltm9ph", + "symbol": "CHZ-ECD", + "total_supply": "8888888888.00000000" + }, + { + "mintable": false, + "name": "Crypto Neo-value Neural System", + "original_symbol": "CNNS", + "owner": "bnb193wdp4gdnm58urnsjf8nv57lxt58sckt2k50ss", + "symbol": "CNNS-E16", + "total_supply": "10000000000.00000000" + }, + { + "mintable": false, + "name": "Contentos", + "original_symbol": "COS", + "owner": "bnb1u9j9hkst6gf09dkdvxlj7puk8c7vh68a0kkmht", + "symbol": "COS-2E4", + "total_supply": "9400000000.00000000" + }, + { + "mintable": true, + "name": "COTI", + "original_symbol": "COTI", + "owner": "bnb1kn733gkku9xsqkuk6wcz86gftqtl4qvthvrj5m", + "symbol": "COTI-CBB", + "total_supply": "80000000.00000000" + }, + { + "mintable": false, + "name": "Covalent Token", + "original_symbol": "COVA", + "owner": "bnb1pucvxaf3l9rslupza75r9fca9h5892ntumszfm", + "symbol": "COVA-218", + "total_supply": "6500000000.00000000" + }, + { + "mintable": false, + "name": "CPChain", + "original_symbol": "CPC", + "owner": "bnb1wq4rlwrmvvltlarvypql8wrr4vlh0dczd8uksg", + "symbol": "CPC-FED", + "total_supply": "150000000.00000000" + }, + { + "mintable": false, + "name": "Crypterium Token", + "original_symbol": "CRPT", + "owner": "bnb17fk3uvagucxzpvmdvd373fapqsahxvzevdard9", + "symbol": "CRPT-8C9", + "total_supply": "99968575.14285720" + }, + { + "mintable": false, + "name": "“Consentium”", + "original_symbol": "CSM", + "owner": "bnb1gguz7vcrlf7a87et8u5gt40f0890qvkpkn9y79", + "symbol": "CSM-734", + "total_supply": "84000000.00000000" + }, + { + "mintable": true, + "name": "Carbon Dollar", + "original_symbol": "CUSD", + "owner": "bnb1y9797dtklkm3haajsfnevm9ruuxs5fyf5rpj67", + "symbol": "CUSD-24B", + "total_supply": "9999999999.00000000" + }, + { + "mintable": false, + "name": "Konstellation Network", + "original_symbol": "DARC", + "owner": "bnb1gyhnhdns4vf63nfzfq7g25czj8swjgrz3rhah8", + "symbol": "DARC-24B", + "total_supply": "1000000000.00000000" + }, + { + "mintable": true, + "name": "DeepCloud", + "original_symbol": "DEEP", + "owner": "bnb1t0ws9gvnjm7j7qssk8te7m2dt5hmm8s3amqk2d", + "symbol": "DEEP-9D3", + "total_supply": "200000000.00000000" + }, + { + "mintable": false, + "name": "DeFi Token", + "original_symbol": "DEFI", + "owner": "bnb1q5xefr07503pqtfrl5sfyyhlghxwc80d4vpas2", + "symbol": "DEFI-FA5", + "total_supply": "2500000000.00000000" + }, + { + "mintable": true, + "name": "DOS Network Token", + "original_symbol": "DOS", + "owner": "bnb13gse9n7mvrjg5w2cymnt4nmxkgj200k9k2l2nh", + "symbol": "DOS-120", + "total_supply": "1000000000.00000000" + }, + { + "mintable": false, + "name": "DREP", + "original_symbol": "DREP", + "owner": "bnb1ez5s9v4rcgsmhwr4fkrnlv6zwsukjnh4y754kn", + "symbol": "DREP-7D2", + "total_supply": "10000000000.00000000" + }, + { + "mintable": true, + "name": "Dusk Network", + "original_symbol": "DUSK", + "owner": "bnb1dfls6c8y39l7qq4gj2479wkehg85pt5m07y94g", + "symbol": "DUSK-45E", + "total_supply": "50000000.00000000" + }, + { + "mintable": false, + "name": "eBoost", + "original_symbol": "EBST", + "owner": "bnb1pmdkvw6cquwylr46wcrl82xzmul0y2jpj5cwx7", + "symbol": "EBST-783", + "total_supply": "80838159.07000000" + }, + { + "mintable": true, + "name": "Ormeus Ecosystem", + "original_symbol": "ECO", + "owner": "bnb1tr49nv08k828n2lqfw0vrgvwj7xtep5kg8wr4c", + "symbol": "ECO-083", + "total_supply": "5000000000.00000000" + }, + { + "mintable": false, + "name": "Energy Eco Token", + "original_symbol": "EET", + "owner": "bnb1pt353m8ygvvgy4f2ud9xx85tl7fqewkrksh6r5", + "symbol": "EET-45C", + "total_supply": "600000000.00000000" + }, + { + "mintable": false, + "name": "Hut34 Entropy", + "original_symbol": "ENTRP", + "owner": "bnb1wu0hu9pelx3yvplysx0je7d93htcandpj86aev", + "symbol": "ENTRP-C8D", + "total_supply": "100000000.00000000" + }, + { + "mintable": true, + "name": "EOS BEP2", + "original_symbol": "EOS", + "owner": "bnb1la8alalwjzkchd67wza3r75lj5rm7m9e85ffqr", + "symbol": "EOS-CDD", + "total_supply": "500000.00000000" + }, + { + "mintable": true, + "name": "3X Short EOS Token", + "original_symbol": "EOSBEAR", + "owner": "bnb1ff4r0t7j8ll8lf3gm2ltdu3hjy4w690j7vvees", + "symbol": "EOSBEAR-721", + "total_supply": "32301.00000000" + }, + { + "mintable": true, + "name": "3X Long EOS Token", + "original_symbol": "EOSBULL", + "owner": "bnb1ff4r0t7j8ll8lf3gm2ltdu3hjy4w690j7vvees", + "symbol": "EOSBULL-F0D", + "total_supply": "456191.00000000" + }, + { + "mintable": false, + "name": "EQUAL", + "original_symbol": "EQL", + "owner": "bnb1uz0s54rzv022dh66l7atwk83wqcet9qstgg358", + "symbol": "EQL-586", + "total_supply": "675259060.00000000" + }, + { + "mintable": true, + "name": "Elrond", + "original_symbol": "ERD", + "owner": "bnb1m5uzzfxs7x05sl28gg96zyecn9jwgtkpyeftyn", + "symbol": "ERD-D06", + "total_supply": "13000000000.00000000" + }, + { + "mintable": true, + "name": "ETH BEP2", + "original_symbol": "ETH", + "owner": "bnb1yss2345dphss8c823dh2jzje2w8k8x4jguuxhf", + "symbol": "ETH-1C9", + "total_supply": "10000.00000000" + }, + { + "mintable": true, + "name": "3X Short Ethereum Token", + "original_symbol": "ETHBEAR", + "owner": "bnb1ff4r0t7j8ll8lf3gm2ltdu3hjy4w690j7vvees", + "symbol": "ETHBEAR-B2B", + "total_supply": "61821.00000000" + }, + { + "mintable": true, + "name": "3X Long Ethereum Token", + "original_symbol": "ETHBULL", + "owner": "bnb1ff4r0t7j8ll8lf3gm2ltdu3hjy4w690j7vvees", + "symbol": "ETHBULL-D33", + "total_supply": "33684.00000000" + }, + { + "mintable": true, + "name": "everiToken", + "original_symbol": "EVT", + "owner": "bnb1v3fl4kuwuhzf3g7ghscsq7uzmu5dw50waseptd", + "symbol": "EVT-49B", + "total_supply": "1000000000.00000000" + }, + { + "mintable": true, + "name": "The Force Token", + "original_symbol": "FOR", + "owner": "bnb1c46nhwdwm3u2mlfhx6t07fls25shnvktpr9w9m", + "symbol": "FOR-997", + "total_supply": "100000000.00000000" + }, + { + "mintable": false, + "name": "Ferrum Network Token", + "original_symbol": "FRM", + "owner": "bnb1um8ntkgwle8yrdk0yn5hwdf7hckjpyjjg29k2p", + "symbol": "FRM-DE7", + "total_supply": "164609374.50000000" + }, + { + "mintable": false, + "name": "Fusion", + "original_symbol": "FSN", + "owner": "bnb17mnutyduat9fe02r2dawp3kn4rnaqamp5kpg0c", + "symbol": "FSN-E14", + "total_supply": "57344000.00000000" + }, + { + "mintable": true, + "name": "Fantom", + "original_symbol": "FTM", + "owner": "bnb1f6sxnf3nhn9fcfwkuccrzvl2pgu3sq0m8pyjhw", + "symbol": "FTM-A64", + "total_supply": "952500000.00000000" + }, + { + "mintable": true, + "name": "FTX Token", + "original_symbol": "FTT", + "owner": "bnb1msxdh7e7smpg68gxxhs0p3fhuj9tzhrxa4c2x2", + "symbol": "FTT-F11", + "total_supply": "10000000.00000000" + }, + { + "mintable": true, + "name": "Givly Coin", + "original_symbol": "GIV", + "owner": "bnb13jzr6sqz72fl0edg2tpqp8tddyzvyt4su2490m", + "symbol": "GIV-94E", + "total_supply": "1000000000.00000000" + }, + { + "mintable": false, + "name": "GoWithMi", + "original_symbol": "GMAT", + "owner": "bnb1yltla9mnk8999ygmjjn3kwmmz2zs94a9v20sca", + "symbol": "GMAT-FC8", + "total_supply": "14900000000.00000000" + }, + { + "mintable": false, + "name": "Global Gaming", + "original_symbol": "GMNG", + "owner": "bnb1qe6zxqptfxw0kh38t8pg6c3qa527n2x2a87qvm", + "symbol": "GMNG-F3E", + "total_supply": "5000000000.00000000" + }, + { + "mintable": false, + "name": "GTEX", + "original_symbol": "GTEX", + "owner": "bnb1nksrzfl24he9xtvdvpypsl6r5jnh5x2uf9s82z", + "symbol": "GTEX-71B", + "total_supply": "4000000000.00000000" + }, + { + "mintable": false, + "name": "Gifto", + "original_symbol": "GTO", + "owner": "bnb1lvp8k3zenlfp2pl2nyaf428xjgh385m258gzvq", + "symbol": "GTO-908", + "total_supply": "1000000000.00000000" + }, + { + "mintable": true, + "name": "“Hermes", + "original_symbol": "HEC", + "owner": "bnb1dfyydqkmsv5m0rs0pa4uut2gwrcsahppktns2t", + "symbol": "HEC-1A9", + "total_supply": "100000000.00000000" + }, + { + "mintable": false, + "name": "Honest", + "original_symbol": "HNST", + "owner": "bnb1k9fv2hz0w3l9v9z4g9samg3gtc7nc2xgyqw5u0", + "symbol": "HNST-3C9", + "total_supply": "400000000.00000000" + }, + { + "mintable": true, + "name": "Hyperion Token", + "original_symbol": "HYN", + "owner": "bnb1q5cqecuy2g7syl8fssp9a7v2sjamtrzlr3pa0n", + "symbol": "HYN-F21", + "total_supply": "10000000000.00000000" + }, + { + "mintable": true, + "name": "Rupiah Token", + "original_symbol": "IDRTB", + "owner": "bnb1wc44duax6pygh23psx0u945skvs3eh7w59e4sp", + "symbol": "IDRTB-178", + "total_supply": "90000000000.00000000" + }, + { + "mintable": false, + "name": "IKU", + "original_symbol": "IKU", + "owner": "bnb1f52tc9l0qg337qtgu4n024ayllc78wxpc5xhvd", + "symbol": "IKU-416", + "total_supply": "300000000.00000000" + }, + { + "mintable": true, + "name": "IRIS Network", + "original_symbol": "IRIS", + "owner": "bnb1dcpm0jjj8el8g6ekr3mvjxa8kptgu4e5xzvqv8", + "symbol": "IRIS-D88", + "total_supply": "2000000000.00000000" + }, + { + "mintable": false, + "name": "JDXUCoin", + "original_symbol": "JDXU", + "owner": "bnb1dwcsg0t86g7935zpxc054n97styzgdtnu2kzg6", + "symbol": "JDXU-706", + "total_supply": "1000000000.00000000" + }, + { + "mintable": false, + "name": "Kambria Token", + "original_symbol": "KAT", + "owner": "bnb1l68n6equtr925lhnentyq54zfrzqyj45lg8uwj", + "symbol": "KAT-7BB", + "total_supply": "3700000000.00000000" + }, + { + "mintable": true, + "name": "Kava BEP2 Token", + "original_symbol": "KAVA", + "owner": "bnb1uyekdn62yur9zuctzqyd9ckasfvqttjz9c33me", + "symbol": "KAVA-10C", + "total_supply": "271190.72181900" + }, + { + "mintable": false, + "name": "Sessia Kicks", + "original_symbol": "KICKS", + "owner": "bnb130tmwjd3fc79eh6f5ezl2326ur8rqpsxeeq30x", + "symbol": "KICKS-162", + "total_supply": "5000000.00000000" + }, + { + "mintable": true, + "name": "Lambda", + "original_symbol": "LAMB", + "owner": "bnb19vnwdjwthm9unxe9hxdxmgm6qw0d42d2lmcesw", + "symbol": "LAMB-46C", + "total_supply": "5000000.00000000" + }, + { + "mintable": false, + "name": "Lend-Borrow-Asset", + "original_symbol": "LBA", + "owner": "bnb1m8r74hr532lfwtaf5e88cxeakd36ut0ufpd4yu", + "symbol": "LBA-340", + "total_supply": "1000000000.00000000" + }, + { + "mintable": true, + "name": "LITION", + "original_symbol": "LIT", + "owner": "bnb1fhlxwqlwd7cm5fmurg0wmsaalshnp7lwu46nk9", + "symbol": "LIT-099", + "total_supply": "145061313.45061312" + }, + { + "mintable": true, + "name": "Loki", + "original_symbol": "LOKI", + "owner": "bnb1j5sft8wp7tktjwauy30x79f3tqa53fycmgxxs0", + "symbol": "LOKI-6A9", + "total_supply": "3000000.00000000" + }, + { + "mintable": true, + "name": "LTC BEP2", + "original_symbol": "LTC", + "owner": "bnb1cn4sqm79wqmr8rey923r34cp2wrtyhlr9easpg", + "symbol": "LTC-F07", + "total_supply": "18500.00000000" + }, + { + "mintable": false, + "name": "LTO Network", + "original_symbol": "LTO", + "owner": "bnb1ac6p45m00pv36y9mu48e5xr73fyxke3zv2rhmq", + "symbol": "LTO-BDF", + "total_supply": "500000000.00000000" + }, + { + "mintable": false, + "name": "LYFE", + "original_symbol": "LYFE", + "owner": "bnb1k0779dltjkl6a05v5uq06zym62hcufzcqu6gq7", + "symbol": "LYFE-6AB", + "total_supply": "231250000.00000000" + }, + { + "mintable": false, + "name": "Matic Token", + "original_symbol": "MATIC", + "owner": "bnb1a6nkf3g7c2z0jcrqhp8c9upcwmme0y49qx58nz", + "symbol": "MATIC-84A", + "total_supply": "10000000000.00000000" + }, + { + "mintable": false, + "name": "Moviebloc", + "original_symbol": "MBL", + "owner": "bnb17p8rc0z5vlysff2wc7xehff464dm0v7nhl27xq", + "symbol": "MBL-2D2", + "total_supply": "30000000000.00000000" + }, + { + "mintable": true, + "name": "Mcashchain", + "original_symbol": "MCASH", + "owner": "bnb1q420q7qpyv7tghfp6aac7vnjq74dhkeutdhqsg", + "symbol": "MCASH-869", + "total_supply": "200000000.00000000" + }, + { + "mintable": false, + "name": "Magic Cube Token", + "original_symbol": "MCC", + "owner": "bnb14nt79d6hzhjefkys2cgrc9nrzugdjwwtggfmu4", + "symbol": "MCC-33B", + "total_supply": "20000000000.00000000" + }, + { + "mintable": false, + "name": "MDAB", + "original_symbol": "MDAB", + "owner": "bnb1m3edd4q4nd3wxg9vm3xe8pnfnetu5yjmhtnrqz", + "symbol": "MDAB-D42", + "total_supply": "1000000000.00000000" + } +] diff --git a/platform/binance/mocks/txs.json b/platform/binance/mocks/txs.json new file mode 100644 index 000000000..7491ddcab --- /dev/null +++ b/platform/binance/mocks/txs.json @@ -0,0 +1,352 @@ +[ + { + "id": "771B07C8D921B5995524C163E9D4504C31A9E07EC858263A53EA007484009C90", + "coin": 714, + "from": "bnb1d83u9afqw296ejw9jdfhc22f0ljr23nn7pradx", + "to": "bnb136ns6lfw4zs5hg4n85vdthaad7hq5m4gtkgf23", + "fee": "37500", + "date": 1596826106, + "block": 105722032, + "status": "completed", + "sequence": 33, + "type": "transfer", + "memo": "106890151", + "metadata": { "value": "120740436", "symbol": "BNB", "decimals": 8 } + }, + { + "id": "1C5682716D2D34DD01428AD8D4200081FBDA06CE886B77499F755E9D93B0FF20", + "coin": 714, + "from": "bnb1k9ktd79psysucucyxqcd5r9ahuuygk8gh3ly8q", + "to": "bnb136ns6lfw4zs5hg4n85vdthaad7hq5m4gtkgf23", + "fee": "37500", + "date": 1596826069, + "block": 105721942, + "status": "completed", + "sequence": 64, + "type": "transfer", + "memo": "103215089", + "metadata": { "value": "229350524", "symbol": "BNB", "decimals": 8 } + }, + { + "id": "C728F7C13977649FCDF9B8E983A9E3AA257EB5596DBCA2A2580584312B5AA535", + "coin": 714, + "from": "bnb155svs6sgxe55rnvs6ghprtqu0mh69kehphsppd", + "to": "bnb136ns6lfw4zs5hg4n85vdthaad7hq5m4gtkgf23", + "fee": "37500", + "date": 1596826063, + "block": 105721925, + "status": "completed", + "sequence": 23121, + "type": "transfer", + "memo": "101045880", + "metadata": { "value": "11964120000", "symbol": "BNB", "decimals": 8 } + }, + { + "id": "794302F9C6562358581A3A8432AF82CD70DF0DA345C917BDE21DDF9A9D4B9DE7", + "coin": 714, + "from": "bnb14gk6m77tswyks9nnadm92mdy3066wj42t60z0l", + "to": "bnb136ns6lfw4zs5hg4n85vdthaad7hq5m4gtkgf23", + "fee": "37500", + "date": 1596826058, + "block": 105721913, + "status": "completed", + "sequence": 11228, + "type": "transfer", + "memo": "100341541", + "metadata": { "value": "456000000", "symbol": "BNB", "decimals": 8 } + }, + { + "id": "2827377A04E3B22DD654A02AD4BA50B3CB83973B6B9BA1A423ABD5045873850C", + "coin": 714, + "from": "bnb132gvg9gdthtaf6xgkk9jkmsep56fv62vg95unv", + "to": "bnb136ns6lfw4zs5hg4n85vdthaad7hq5m4gtkgf23", + "fee": "37500", + "date": 1596826024, + "block": 105721828, + "status": "completed", + "sequence": 4, + "type": "transfer", + "memo": "105772095", + "metadata": { "value": "1045498916", "symbol": "BNB", "decimals": 8 } + }, + { + "id": "AACC80FDA9C45DCD7F6DBAA40A2EB600FF6EBB24A5A840578D4AB306C3427385", + "coin": 714, + "from": "bnb10y4hu5psc7hztlczrhzgghfjzufnqyfrrml3yn", + "to": "bnb136ns6lfw4zs5hg4n85vdthaad7hq5m4gtkgf23", + "fee": "37500", + "date": 1596826006, + "block": 105721785, + "status": "completed", + "sequence": 65, + "type": "transfer", + "memo": "109027392", + "metadata": { "value": "8750000000", "symbol": "BNB", "decimals": 8 } + }, + { + "id": "66CF0F65442FD35A3B91CC2655CE60E565D13EEFC6BDB1C5AF9F9E484C8B6295", + "coin": 714, + "from": "bnb17g92armmr926kd88umh7u90vglq4ghjtku6ssc", + "to": "bnb136ns6lfw4zs5hg4n85vdthaad7hq5m4gtkgf23", + "fee": "37500", + "date": 1596825967, + "block": 105721686, + "status": "completed", + "sequence": 896, + "type": "transfer", + "memo": "107780643", + "metadata": { "value": "878900000", "symbol": "BNB", "decimals": 8 } + }, + { + "id": "81EA185BE754809E40FCBF1B07A0C389F39DECD38D56302D980534850996B144", + "coin": 714, + "from": "bnb12nq7fhh3t8q0m9s2n5gqwd9gcx0j85yn0h5zcu", + "to": "bnb136ns6lfw4zs5hg4n85vdthaad7hq5m4gtkgf23", + "fee": "37500", + "date": 1596825888, + "block": 105721490, + "status": "completed", + "sequence": 0, + "type": "transfer", + "memo": "101210049", + "metadata": { "value": "4498159221", "symbol": "BNB", "decimals": 8 } + }, + { + "id": "24ED2153427ABACD7F6DB53A1339D9C2573D720FDE6EC45B0047CB146227FF9A", + "coin": 714, + "from": "bnb1s5qucugaxv7gkzyg4kacf225s6mhj0ysejn8jq", + "to": "bnb136ns6lfw4zs5hg4n85vdthaad7hq5m4gtkgf23", + "fee": "37500", + "date": 1596825847, + "block": 105721385, + "status": "completed", + "sequence": 40, + "type": "transfer", + "memo": "104298046", + "metadata": { "value": "34300000000", "symbol": "BNB", "decimals": 8 } + }, + { + "id": "411A27CE85D0928BC5908DA5BA288CB52E152C1E54FA35042147A90FCEBAB29C", + "coin": 714, + "from": "bnb1erj09eqrnz06jv2acxhhy7s3k0q6w4hfmj9rey", + "to": "bnb136ns6lfw4zs5hg4n85vdthaad7hq5m4gtkgf23", + "fee": "37500", + "date": 1596825789, + "block": 105721238, + "status": "completed", + "sequence": 12, + "type": "transfer", + "memo": "107303874", + "metadata": { "value": "6319074", "symbol": "BNB", "decimals": 8 } + }, + { + "id": "25359F7277760004BBD42557B3E50F86F06B096478840E057C6F394BF63F6081", + "coin": 714, + "from": "bnb10y4hu5psc7hztlczrhzgghfjzufnqyfrrml3yn", + "to": "bnb136ns6lfw4zs5hg4n85vdthaad7hq5m4gtkgf23", + "fee": "37500", + "date": 1596825692, + "block": 105720997, + "status": "completed", + "sequence": 57, + "type": "transfer", + "memo": "109027392", + "metadata": { "value": "1090000000", "symbol": "BNB", "decimals": 8 } + }, + { + "id": "1DB710AF4983D9CAFB24AC3DD7C2C6EBC7752F347E5A7599840AB3EFBD436C5D", + "coin": 714, + "from": "bnb10y4hu5psc7hztlczrhzgghfjzufnqyfrrml3yn", + "to": "bnb136ns6lfw4zs5hg4n85vdthaad7hq5m4gtkgf23", + "fee": "37500", + "date": 1596825639, + "block": 105720867, + "status": "completed", + "sequence": 56, + "type": "transfer", + "memo": "109027392", + "metadata": { "value": "2000000000", "symbol": "BNB", "decimals": 8 } + }, + { + "id": "B7C799B9853ECA41F02241B67E294E2642AE88BBF551DE188A73C48D1A0E821D", + "coin": 714, + "from": "bnb1q2994t0djzsy0q2fc62jruxr22nxq6y8l4503l", + "to": "bnb136ns6lfw4zs5hg4n85vdthaad7hq5m4gtkgf23", + "fee": "37500", + "date": 1596825619, + "block": 105720816, + "status": "completed", + "sequence": 1, + "type": "transfer", + "memo": "108202494", + "metadata": { "value": "295957149", "symbol": "BNB", "decimals": 8 } + }, + { + "id": "865C098D021CC649FC83B2442092E4D6F0777488163E5797DA9D264C87F1F4F4", + "coin": 714, + "from": "bnb16xqcchlutsm8g6gk7wvlzukeu2sy9xt2u77056", + "to": "bnb136ns6lfw4zs5hg4n85vdthaad7hq5m4gtkgf23", + "fee": "37500", + "date": 1596825548, + "block": 105720641, + "status": "completed", + "sequence": 33, + "type": "transfer", + "memo": "102080722", + "metadata": { "value": "1373501799", "symbol": "BNB", "decimals": 8 } + }, + { + "id": "1D4F777D1D227D57E4D4BAC3E83FB203147E7B0E7429E60A48A9053372359174", + "coin": 714, + "from": "bnb1t6tk66zncqqt7twnfyxx22fn9t3wz3nac5hkck", + "to": "bnb136ns6lfw4zs5hg4n85vdthaad7hq5m4gtkgf23", + "fee": "37500", + "date": 1596825500, + "block": 105720519, + "status": "completed", + "sequence": 14, + "type": "transfer", + "memo": "106456805", + "metadata": { "value": "1490609", "symbol": "BNB", "decimals": 8 } + }, + { + "id": "9A818687D52B4E9E0C5F962E6E464ECC6348D6A41AE2C5DD051A5EF71E15B1AC", + "coin": 714, + "from": "bnb1v47qw5acc72c34uwt7t9wm9ztqtg6678dmrssa", + "to": "bnb136ns6lfw4zs5hg4n85vdthaad7hq5m4gtkgf23", + "fee": "37500", + "date": 1596825415, + "block": 105720307, + "status": "completed", + "sequence": 6273, + "type": "transfer", + "memo": "104471384", + "metadata": { "value": "356700000", "symbol": "BNB", "decimals": 8 } + }, + { + "id": "6C7D4469525E44501ED03BA38A6D54A04DFD6AD2D13328761DA4602A3D777332", + "coin": 714, + "from": "bnb1tzet704pc6zjsl3xcwdexn6xlu0zc092y0n4ay", + "to": "bnb136ns6lfw4zs5hg4n85vdthaad7hq5m4gtkgf23", + "fee": "37500", + "date": 1596825348, + "block": 105720136, + "status": "completed", + "sequence": 721, + "type": "transfer", + "memo": "101245732", + "metadata": { "value": "93900000", "symbol": "BNB", "decimals": 8 } + }, + { + "id": "8C47875F09371B45C0A29D7C6EF308A1C499D1BBECD5A56E0561B40675AF2D26", + "coin": 714, + "from": "bnb1t7hpl286qgvsg08lvx6ac9ul0msy4k2ud8dukp", + "to": "bnb136ns6lfw4zs5hg4n85vdthaad7hq5m4gtkgf23", + "fee": "37500", + "date": 1596825311, + "block": 105720042, + "status": "completed", + "sequence": 1912, + "type": "transfer", + "memo": "101186586", + "metadata": { "value": "95193451", "symbol": "BNB", "decimals": 8 } + }, + { + "id": "39A48766F8ACC33B3BB1B4F442ABFDFBC695F440D72795794A01E8E446CE8EAE", + "coin": 714, + "from": "bnb10y4hu5psc7hztlczrhzgghfjzufnqyfrrml3yn", + "to": "bnb136ns6lfw4zs5hg4n85vdthaad7hq5m4gtkgf23", + "fee": "37500", + "date": 1596825298, + "block": 105720010, + "status": "completed", + "sequence": 47, + "type": "transfer", + "memo": "109027392", + "metadata": { "value": "480000000", "symbol": "BNB", "decimals": 8 } + }, + { + "id": "54248E3C09713E3870F661749A8690DAD46A8078C7346C497EB4E166564420F4", + "coin": 714, + "from": "bnb1hc304lytvp9jnumnjmppq97erm70r7muzv6y98", + "to": "bnb136ns6lfw4zs5hg4n85vdthaad7hq5m4gtkgf23", + "fee": "37500", + "date": 1596825237, + "block": 105719860, + "status": "completed", + "sequence": 1, + "type": "transfer", + "memo": "105261446", + "metadata": { "value": "10210962500", "symbol": "BNB", "decimals": 8 } + }, + { + "id": "ADDDB705AB8C2B1AF58D7EDCAEC00C893A6CD87281D7A7146689E9FE1A846EAE", + "coin": 714, + "from": "bnb17g92armmr926kd88umh7u90vglq4ghjtku6ssc", + "to": "bnb136ns6lfw4zs5hg4n85vdthaad7hq5m4gtkgf23", + "fee": "37500", + "date": 1596825173, + "block": 105719705, + "status": "completed", + "sequence": 895, + "type": "transfer", + "memo": "103617121", + "metadata": { "value": "297900000", "symbol": "BNB", "decimals": 8 } + }, + { + "id": "7C338C78BBBCD998628CCAF85211883AACB159201755501139F56E0D2A7941A4", + "coin": 714, + "from": "bnb1pys084nlc8gqm7lvjje4kt39dn84vd2xsvnwqa", + "to": "bnb136ns6lfw4zs5hg4n85vdthaad7hq5m4gtkgf23", + "fee": "37500", + "date": 1596825147, + "block": 105719641, + "status": "completed", + "sequence": 18, + "type": "transfer", + "memo": "108802310", + "metadata": { "value": "200000000", "symbol": "BNB", "decimals": 8 } + }, + { + "id": "6DD7120E43CD5031E2DD6C7977D141B74CA41C8E476D8AE972A9DA2D2EFD2D84", + "coin": 714, + "from": "bnb17g92armmr926kd88umh7u90vglq4ghjtku6ssc", + "to": "bnb136ns6lfw4zs5hg4n85vdthaad7hq5m4gtkgf23", + "fee": "37500", + "date": 1596825061, + "block": 105719428, + "status": "completed", + "sequence": 894, + "type": "transfer", + "memo": "102393444", + "metadata": { "value": "677900000", "symbol": "BNB", "decimals": 8 } + }, + { + "id": "86FB14C637D7B0A4AA123FFF76C5C541C70568B67E3F5BC63EB0FDEDEF30301F", + "coin": 714, + "from": "bnb17nak8gnucl6lcze0d04def4de77a33qh29f6ur", + "to": "bnb136ns6lfw4zs5hg4n85vdthaad7hq5m4gtkgf23", + "fee": "37500", + "date": 1596825051, + "block": 105719403, + "status": "completed", + "sequence": 3, + "type": "transfer", + "memo": "109823910", + "metadata": { "value": "900000", "symbol": "BNB", "decimals": 8 } + }, + { + "id": "1DEEFC0A838F80704574951DF15969CCE34654BE2007BF77F9521A1B4686BE33", + "coin": 714, + "from": "bnb1yjlk7f47qf0z97ph6pxc00s2s0yw048edmtjtw", + "to": "bnb136ns6lfw4zs5hg4n85vdthaad7hq5m4gtkgf23", + "fee": "37500", + "date": 1596825014, + "block": 105719312, + "status": "completed", + "sequence": 1431, + "type": "transfer", + "memo": "103268674", + "metadata": { "value": "315739000", "symbol": "BNB", "decimals": 8 } + } +] diff --git a/platform/binance/mocks/txs_ava_response.json b/platform/binance/mocks/txs_ava_response.json new file mode 100644 index 000000000..92fc48811 --- /dev/null +++ b/platform/binance/mocks/txs_ava_response.json @@ -0,0 +1,505 @@ +{ + "tx": [ + { + "txHash": "2BF49DF1D10D9A20438376E760352734DAEBD5D92D6CAA14735EE095A3F65FD3", + "blockHeight": 105725696, + "txType": "NEW_ORDER", + "timeStamp": "2020-08-07T19:13:41.390Z", + "fromAddr": "bnb1w7puzjxu05ktc5zvpnzkndt6tyl720nsutzvpg", + "toAddr": null, + "value": "47.98467000", + "txAsset": "AVA-645", + "txFee": "0.00000000", + "proposalId": null, + "txAge": 5, + "orderId": "7783C148DC7D2CBC504C0CC569B57A593FE53E70-1594674", + "code": 0, + "data": "{\"orderData\":{\"symbol\":\"AVA-645_BUSD-BD1\",\"orderType\":\"LIMIT\",\"side\":\"BUY\",\"price\":\"1.77721\",\"quantity\":\"27\",\"timeInForce\":\"GTE\",\"orderId\":\"7783C148DC7D2CBC504C0CC569B57A593FE53E70-1594674\"}}", + "confirmBlocks": 0, + "memo": "", + "source": 0, + "sequence": 1594673 + }, + { + "txHash": "C858D15E2745A61D0D3D354750E4462792160FFBB9927739587FFAAEDEFA00FF", + "blockHeight": 105725676, + "txType": "NEW_ORDER", + "timeStamp": "2020-08-07T19:13:32.989Z", + "fromAddr": "bnb1w7puzjxu05ktc5zvpnzkndt6tyl720nsutzvpg", + "toAddr": null, + "value": "250.85976000", + "txAsset": "AVA-645", + "txFee": "0.00000000", + "proposalId": null, + "txAge": 13, + "orderId": "7783C148DC7D2CBC504C0CC569B57A593FE53E70-1594671", + "code": 0, + "data": "{\"orderData\":{\"symbol\":\"AVA-645_BUSD-BD1\",\"orderType\":\"LIMIT\",\"side\":\"SELL\",\"price\":\"1.91496\",\"quantity\":\"131\",\"timeInForce\":\"GTE\",\"orderId\":\"7783C148DC7D2CBC504C0CC569B57A593FE53E70-1594671\"}}", + "confirmBlocks": 0, + "memo": "", + "source": 0, + "sequence": 1594670 + }, + { + "txHash": "9BDCF416622AA4E8F11162747614585FD840F5721D7163A68BC03EC94E855DEE", + "blockHeight": 105725673, + "txType": "NEW_ORDER", + "timeStamp": "2020-08-07T19:13:31.760Z", + "fromAddr": "bnb1w7puzjxu05ktc5zvpnzkndt6tyl720nsutzvpg", + "toAddr": null, + "value": "30.17126000", + "txAsset": "AVA-645", + "txFee": "0.00000000", + "proposalId": null, + "txAge": 14, + "orderId": "7783C148DC7D2CBC504C0CC569B57A593FE53E70-1594670", + "code": 0, + "data": "{\"orderData\":{\"symbol\":\"AVA-645_BUSD-BD1\",\"orderType\":\"LIMIT\",\"side\":\"BUY\",\"price\":\"1.77478\",\"quantity\":\"17\",\"timeInForce\":\"GTE\",\"orderId\":\"7783C148DC7D2CBC504C0CC569B57A593FE53E70-1594670\"}}", + "confirmBlocks": 0, + "memo": "", + "source": 0, + "sequence": 1594669 + }, + { + "txHash": "52512D9498D4CF51997A5A62C0A55252776B00C888D2D01502C68B56E892F42E", + "blockHeight": 105725652, + "txType": "NEW_ORDER", + "timeStamp": "2020-08-07T19:13:23.040Z", + "fromAddr": "bnb1w7puzjxu05ktc5zvpnzkndt6tyl720nsutzvpg", + "toAddr": null, + "value": "41.48298000", + "txAsset": "AVA-645", + "txFee": "0.00000000", + "proposalId": null, + "txAge": 23, + "orderId": "7783C148DC7D2CBC504C0CC569B57A593FE53E70-1594667", + "code": 0, + "data": "{\"orderData\":{\"symbol\":\"AVA-645_BUSD-BD1\",\"orderType\":\"LIMIT\",\"side\":\"SELL\",\"price\":\"1.88559\",\"quantity\":\"22\",\"timeInForce\":\"GTE\",\"orderId\":\"7783C148DC7D2CBC504C0CC569B57A593FE53E70-1594667\"}}", + "confirmBlocks": 0, + "memo": "", + "source": 0, + "sequence": 1594666 + }, + { + "txHash": "1BAF96AB01E7AB5A7746CA7E76B293CD636D55713C7CCE71FD0E0ED8ACE05C92", + "blockHeight": 105725646, + "txType": "NEW_ORDER", + "timeStamp": "2020-08-07T19:13:20.614Z", + "fromAddr": "bnb1w7puzjxu05ktc5zvpnzkndt6tyl720nsutzvpg", + "toAddr": null, + "value": "26.59905000", + "txAsset": "AVA-645", + "txFee": "0.00000000", + "proposalId": null, + "txAge": 26, + "orderId": "7783C148DC7D2CBC504C0CC569B57A593FE53E70-1594666", + "code": 0, + "data": "{\"orderData\":{\"symbol\":\"AVA-645_BUSD-BD1\",\"orderType\":\"LIMIT\",\"side\":\"BUY\",\"price\":\"1.77327\",\"quantity\":\"15\",\"timeInForce\":\"GTE\",\"orderId\":\"7783C148DC7D2CBC504C0CC569B57A593FE53E70-1594666\"}}", + "confirmBlocks": 0, + "memo": "", + "source": 0, + "sequence": 1594665 + }, + { + "txHash": "9990419EFE1B327966EBAAFFC2771046E1AC2E4DDFAD8A93C55DE105A2948A8D", + "blockHeight": 105725624, + "txType": "NEW_ORDER", + "timeStamp": "2020-08-07T19:13:11.499Z", + "fromAddr": "bnb1w7puzjxu05ktc5zvpnzkndt6tyl720nsutzvpg", + "toAddr": null, + "value": "206.81568000", + "txAsset": "AVA-645", + "txFee": "0.00000000", + "proposalId": null, + "txAge": 35, + "orderId": "7783C148DC7D2CBC504C0CC569B57A593FE53E70-1594663", + "code": 0, + "data": "{\"orderData\":{\"symbol\":\"AVA-645_BUSD-BD1\",\"orderType\":\"LIMIT\",\"side\":\"SELL\",\"price\":\"1.91496\",\"quantity\":\"108\",\"timeInForce\":\"GTE\",\"orderId\":\"7783C148DC7D2CBC504C0CC569B57A593FE53E70-1594663\"}}", + "confirmBlocks": 0, + "memo": "", + "source": 0, + "sequence": 1594662 + }, + { + "txHash": "922F86E110E897233A7B43C0D31397923298C176EBE6F33D98B70ACB911A497A", + "blockHeight": 105725620, + "txType": "NEW_ORDER", + "timeStamp": "2020-08-07T19:13:09.679Z", + "fromAddr": "bnb1w7puzjxu05ktc5zvpnzkndt6tyl720nsutzvpg", + "toAddr": null, + "value": "31.95630000", + "txAsset": "AVA-645", + "txFee": "0.00000000", + "proposalId": null, + "txAge": 36, + "orderId": "7783C148DC7D2CBC504C0CC569B57A593FE53E70-1594662", + "code": 0, + "data": "{\"orderData\":{\"symbol\":\"AVA-645_BUSD-BD1\",\"orderType\":\"LIMIT\",\"side\":\"BUY\",\"price\":\"1.77535\",\"quantity\":\"18\",\"timeInForce\":\"GTE\",\"orderId\":\"7783C148DC7D2CBC504C0CC569B57A593FE53E70-1594662\"}}", + "confirmBlocks": 0, + "memo": "", + "source": 0, + "sequence": 1594661 + }, + { + "txHash": "925A208AFDCD718F8383F7559C7BBA5AE616B693A6029F57BFB67AEBB1CE5F3C", + "blockHeight": 105725597, + "txType": "NEW_ORDER", + "timeStamp": "2020-08-07T19:13:00.237Z", + "fromAddr": "bnb1w7puzjxu05ktc5zvpnzkndt6tyl720nsutzvpg", + "toAddr": null, + "value": "135.99044000", + "txAsset": "AVA-645", + "txFee": "0.00000000", + "proposalId": null, + "txAge": 46, + "orderId": "7783C148DC7D2CBC504C0CC569B57A593FE53E70-1594659", + "code": 0, + "data": "{\"orderData\":{\"symbol\":\"AVA-645_BUSD-BD1\",\"orderType\":\"LIMIT\",\"side\":\"BUY\",\"price\":\"1.65842\",\"quantity\":\"82\",\"timeInForce\":\"GTE\",\"orderId\":\"7783C148DC7D2CBC504C0CC569B57A593FE53E70-1594659\"}}", + "confirmBlocks": 0, + "memo": "", + "source": 0, + "sequence": 1594658 + }, + { + "txHash": "2B69327D6C0C7B9061AAD962BF4838E3B630A844439013E0EBEFC5B722205774", + "blockHeight": 105725575, + "txType": "NEW_ORDER", + "timeStamp": "2020-08-07T19:12:51.165Z", + "fromAddr": "bnb1w7puzjxu05ktc5zvpnzkndt6tyl720nsutzvpg", + "toAddr": null, + "value": "26.39040000", + "txAsset": "AVA-645", + "txFee": "0.00000000", + "proposalId": null, + "txAge": 55, + "orderId": "7783C148DC7D2CBC504C0CC569B57A593FE53E70-1594656", + "code": 0, + "data": "{\"orderData\":{\"symbol\":\"AVA-645_BUSD-BD1\",\"orderType\":\"LIMIT\",\"side\":\"BUY\",\"price\":\"1.75936\",\"quantity\":\"15\",\"timeInForce\":\"GTE\",\"orderId\":\"7783C148DC7D2CBC504C0CC569B57A593FE53E70-1594656\"}}", + "confirmBlocks": 0, + "memo": "", + "source": 0, + "sequence": 1594655 + }, + { + "txHash": "BB6FD86C9738C2991F587996ABBAC1151DF1F9DE57FDCC977BB0D8FBAD31188A", + "blockHeight": 105725529, + "txType": "NEW_ORDER", + "timeStamp": "2020-08-07T19:12:32.108Z", + "fromAddr": "bnb1w7puzjxu05ktc5zvpnzkndt6tyl720nsutzvpg", + "toAddr": null, + "value": "44.90475000", + "txAsset": "AVA-645", + "txFee": "0.00000000", + "proposalId": null, + "txAge": 74, + "orderId": "7783C148DC7D2CBC504C0CC569B57A593FE53E70-1594654", + "code": 0, + "data": "{\"orderData\":{\"symbol\":\"AVA-645_BUSD-BD1\",\"orderType\":\"LIMIT\",\"side\":\"SELL\",\"price\":\"1.79619\",\"quantity\":\"25\",\"timeInForce\":\"GTE\",\"orderId\":\"7783C148DC7D2CBC504C0CC569B57A593FE53E70-1594654\"}}", + "confirmBlocks": 0, + "memo": "", + "source": 0, + "sequence": 1594653 + }, + { + "txHash": "97856635BDBA4B0B3EAAA76EA46D848A2DFE3AAE554A33D308CFC4474C769290", + "blockHeight": 105725526, + "txType": "NEW_ORDER", + "timeStamp": "2020-08-07T19:12:30.917Z", + "fromAddr": "bnb1w7puzjxu05ktc5zvpnzkndt6tyl720nsutzvpg", + "toAddr": null, + "value": "94.10225000", + "txAsset": "AVA-645", + "txFee": "0.00000000", + "proposalId": null, + "txAge": 75, + "orderId": "7783C148DC7D2CBC504C0CC569B57A593FE53E70-1594653", + "code": 0, + "data": "{\"orderData\":{\"symbol\":\"AVA-645_BUSD-BD1\",\"orderType\":\"LIMIT\",\"side\":\"BUY\",\"price\":\"1.71095\",\"quantity\":\"55\",\"timeInForce\":\"GTE\",\"orderId\":\"7783C148DC7D2CBC504C0CC569B57A593FE53E70-1594653\"}}", + "confirmBlocks": 0, + "memo": "", + "source": 0, + "sequence": 1594652 + }, + { + "txHash": "4B4EC65A5972CC15C4B410339ED0081C4BB57F4E08F2A35744845F5A71531B59", + "blockHeight": 105725493, + "txType": "NEW_ORDER", + "timeStamp": "2020-08-07T19:12:17.373Z", + "fromAddr": "bnb1w7puzjxu05ktc5zvpnzkndt6tyl720nsutzvpg", + "toAddr": null, + "value": "30.49341000", + "txAsset": "AVA-645", + "txFee": "0.00000000", + "proposalId": null, + "txAge": 89, + "orderId": "7783C148DC7D2CBC504C0CC569B57A593FE53E70-1594649", + "code": 0, + "data": "{\"orderData\":{\"symbol\":\"AVA-645_BUSD-BD1\",\"orderType\":\"LIMIT\",\"side\":\"SELL\",\"price\":\"1.79373\",\"quantity\":\"17\",\"timeInForce\":\"GTE\",\"orderId\":\"7783C148DC7D2CBC504C0CC569B57A593FE53E70-1594649\"}}", + "confirmBlocks": 0, + "memo": "", + "source": 0, + "sequence": 1594648 + }, + { + "txHash": "86B5FFDDB06E0973A05434DDB858868A45EDA8B07E0D75125FEAEBA1093D4EA5", + "blockHeight": 105725489, + "txType": "NEW_ORDER", + "timeStamp": "2020-08-07T19:12:15.680Z", + "fromAddr": "bnb1w7puzjxu05ktc5zvpnzkndt6tyl720nsutzvpg", + "toAddr": null, + "value": "195.81982000", + "txAsset": "AVA-645", + "txFee": "0.00000000", + "proposalId": null, + "txAge": 90, + "orderId": "7783C148DC7D2CBC504C0CC569B57A593FE53E70-1594648", + "code": 0, + "data": "{\"orderData\":{\"symbol\":\"AVA-645_BUSD-BD1\",\"orderType\":\"LIMIT\",\"side\":\"BUY\",\"price\":\"1.65949\",\"quantity\":\"118\",\"timeInForce\":\"GTE\",\"orderId\":\"7783C148DC7D2CBC504C0CC569B57A593FE53E70-1594648\"}}", + "confirmBlocks": 0, + "memo": "", + "source": 0, + "sequence": 1594647 + }, + { + "txHash": "D20757EB130E8146D1A12E869BE69EC2CB03193D8E62467327B09A5D73BBC6F8", + "blockHeight": 105725473, + "txType": "NEW_ORDER", + "timeStamp": "2020-08-07T19:12:09.086Z", + "fromAddr": "bnb1w7puzjxu05ktc5zvpnzkndt6tyl720nsutzvpg", + "toAddr": null, + "value": "59.27427000", + "txAsset": "AVA-645", + "txFee": "0.00000000", + "proposalId": null, + "txAge": 97, + "orderId": "7783C148DC7D2CBC504C0CC569B57A593FE53E70-1594646", + "code": 0, + "data": "{\"orderData\":{\"symbol\":\"AVA-645_BUSD-BD1\",\"orderType\":\"LIMIT\",\"side\":\"SELL\",\"price\":\"1.79619\",\"quantity\":\"33\",\"timeInForce\":\"GTE\",\"orderId\":\"7783C148DC7D2CBC504C0CC569B57A593FE53E70-1594646\"}}", + "confirmBlocks": 0, + "memo": "", + "source": 0, + "sequence": 1594645 + }, + { + "txHash": "04291A7AE08A78C5E5AE216C67D17B6A4260950FFAB6FD3D1C1B991E3B7BB935", + "blockHeight": 105725470, + "txType": "NEW_ORDER", + "timeStamp": "2020-08-07T19:12:07.990Z", + "fromAddr": "bnb1w7puzjxu05ktc5zvpnzkndt6tyl720nsutzvpg", + "toAddr": null, + "value": "242.28554000", + "txAsset": "AVA-645", + "txFee": "0.00000000", + "proposalId": null, + "txAge": 98, + "orderId": "7783C148DC7D2CBC504C0CC569B57A593FE53E70-1594645", + "code": 0, + "data": "{\"orderData\":{\"symbol\":\"AVA-645_BUSD-BD1\",\"orderType\":\"LIMIT\",\"side\":\"BUY\",\"price\":\"1.65949\",\"quantity\":\"146\",\"timeInForce\":\"GTE\",\"orderId\":\"7783C148DC7D2CBC504C0CC569B57A593FE53E70-1594645\"}}", + "confirmBlocks": 0, + "memo": "", + "source": 0, + "sequence": 1594644 + }, + { + "txHash": "31E16E3F53DD476475256C8D872AF3FD86DC44F3085EF87DDE3643E20C0CE624", + "blockHeight": 105725448, + "txType": "NEW_ORDER", + "timeStamp": "2020-08-07T19:11:58.857Z", + "fromAddr": "bnb1w7puzjxu05ktc5zvpnzkndt6tyl720nsutzvpg", + "toAddr": null, + "value": "32.30208000", + "txAsset": "AVA-645", + "txFee": "0.00000000", + "proposalId": null, + "txAge": 107, + "orderId": "7783C148DC7D2CBC504C0CC569B57A593FE53E70-1594642", + "code": 0, + "data": "{\"orderData\":{\"symbol\":\"AVA-645_BUSD-BD1\",\"orderType\":\"LIMIT\",\"side\":\"SELL\",\"price\":\"1.79456\",\"quantity\":\"18\",\"timeInForce\":\"GTE\",\"orderId\":\"7783C148DC7D2CBC504C0CC569B57A593FE53E70-1594642\"}}", + "confirmBlocks": 0, + "memo": "", + "source": 0, + "sequence": 1594641 + }, + { + "txHash": "1D61A9E35893BB51DE4AE63FA6898FCAE14B6D48F7A2EFD0B51DCCACF6E36B88", + "blockHeight": 105725446, + "txType": "NEW_ORDER", + "timeStamp": "2020-08-07T19:11:57.974Z", + "fromAddr": "bnb1w7puzjxu05ktc5zvpnzkndt6tyl720nsutzvpg", + "toAddr": null, + "value": "227.35013000", + "txAsset": "AVA-645", + "txFee": "0.00000000", + "proposalId": null, + "txAge": 108, + "orderId": "7783C148DC7D2CBC504C0CC569B57A593FE53E70-1594641", + "code": 0, + "data": "{\"orderData\":{\"symbol\":\"AVA-645_BUSD-BD1\",\"orderType\":\"LIMIT\",\"side\":\"BUY\",\"price\":\"1.65949\",\"quantity\":\"137\",\"timeInForce\":\"GTE\",\"orderId\":\"7783C148DC7D2CBC504C0CC569B57A593FE53E70-1594641\"}}", + "confirmBlocks": 0, + "memo": "", + "source": 0, + "sequence": 1594640 + }, + { + "txHash": "AB9E29B110844BD76F58B058CC20F1E13B37A1AAC4F09978BDE159F1B09B585E", + "blockHeight": 105725425, + "txType": "NEW_ORDER", + "timeStamp": "2020-08-07T19:11:49.358Z", + "fromAddr": "bnb1w7puzjxu05ktc5zvpnzkndt6tyl720nsutzvpg", + "toAddr": null, + "value": "26.88420000", + "txAsset": "AVA-645", + "txFee": "0.00000000", + "proposalId": null, + "txAge": 117, + "orderId": "7783C148DC7D2CBC504C0CC569B57A593FE53E70-1594638", + "code": 0, + "data": "{\"orderData\":{\"symbol\":\"AVA-645_BUSD-BD1\",\"orderType\":\"LIMIT\",\"side\":\"SELL\",\"price\":\"1.79228\",\"quantity\":\"15\",\"timeInForce\":\"GTE\",\"orderId\":\"7783C148DC7D2CBC504C0CC569B57A593FE53E70-1594638\"}}", + "confirmBlocks": 0, + "memo": "", + "source": 0, + "sequence": 1594637 + }, + { + "txHash": "F81649BAF3D888E3772C8708D255FE91E0CDB2818006A1FC96FFBDAC24BDE675", + "blockHeight": 105725422, + "txType": "NEW_ORDER", + "timeStamp": "2020-08-07T19:11:48.006Z", + "fromAddr": "bnb1w7puzjxu05ktc5zvpnzkndt6tyl720nsutzvpg", + "toAddr": null, + "value": "144.37563000", + "txAsset": "AVA-645", + "txFee": "0.00000000", + "proposalId": null, + "txAge": 118, + "orderId": "7783C148DC7D2CBC504C0CC569B57A593FE53E70-1594637", + "code": 0, + "data": "{\"orderData\":{\"symbol\":\"AVA-645_BUSD-BD1\",\"orderType\":\"LIMIT\",\"side\":\"BUY\",\"price\":\"1.65949\",\"quantity\":\"87\",\"timeInForce\":\"GTE\",\"orderId\":\"7783C148DC7D2CBC504C0CC569B57A593FE53E70-1594637\"}}", + "confirmBlocks": 0, + "memo": "", + "source": 0, + "sequence": 1594636 + }, + { + "txHash": "71B25BF61219BC87980EB67064C346801C01B00FFE52932799E28FB20DAF41D8", + "blockHeight": 105725401, + "txType": "NEW_ORDER", + "timeStamp": "2020-08-07T19:11:39.380Z", + "fromAddr": "bnb1w7puzjxu05ktc5zvpnzkndt6tyl720nsutzvpg", + "toAddr": null, + "value": "21.47556000", + "txAsset": "AVA-645", + "txFee": "0.00000000", + "proposalId": null, + "txAge": 127, + "orderId": "7783C148DC7D2CBC504C0CC569B57A593FE53E70-1594634", + "code": 0, + "data": "{\"orderData\":{\"symbol\":\"AVA-645_BUSD-BD1\",\"orderType\":\"LIMIT\",\"side\":\"SELL\",\"price\":\"1.78963\",\"quantity\":\"12\",\"timeInForce\":\"GTE\",\"orderId\":\"7783C148DC7D2CBC504C0CC569B57A593FE53E70-1594634\"}}", + "confirmBlocks": 0, + "memo": "", + "source": 0, + "sequence": 1594633 + }, + { + "txHash": "3424BFCA860A878FDCF304AD414EDE2AB3B0FF258CA940CD1269F469ED7C422C", + "blockHeight": 105725379, + "txType": "NEW_ORDER", + "timeStamp": "2020-08-07T19:11:30.336Z", + "fromAddr": "bnb1w7puzjxu05ktc5zvpnzkndt6tyl720nsutzvpg", + "toAddr": null, + "value": "144.92516000", + "txAsset": "AVA-645", + "txFee": "0.00000000", + "proposalId": null, + "txAge": 136, + "orderId": "7783C148DC7D2CBC504C0CC569B57A593FE53E70-1594631", + "code": 0, + "data": "{\"orderData\":{\"symbol\":\"AVA-645_BUSD-BD1\",\"orderType\":\"LIMIT\",\"side\":\"SELL\",\"price\":\"1.90691\",\"quantity\":\"76\",\"timeInForce\":\"GTE\",\"orderId\":\"7783C148DC7D2CBC504C0CC569B57A593FE53E70-1594631\"}}", + "confirmBlocks": 0, + "memo": "", + "source": 0, + "sequence": 1594630 + }, + { + "txHash": "46FFA039B955953D4F19BE7D56FA793B71F34BFB460D9B84A152B554E9219C44", + "blockHeight": 105725375, + "txType": "NEW_ORDER", + "timeStamp": "2020-08-07T19:11:28.671Z", + "fromAddr": "bnb1w7puzjxu05ktc5zvpnzkndt6tyl720nsutzvpg", + "toAddr": null, + "value": "231.90204000", + "txAsset": "AVA-645", + "txFee": "0.00000000", + "proposalId": null, + "txAge": 137, + "orderId": "7783C148DC7D2CBC504C0CC569B57A593FE53E70-1594630", + "code": 0, + "data": "{\"orderData\":{\"symbol\":\"AVA-645_BUSD-BD1\",\"orderType\":\"LIMIT\",\"side\":\"BUY\",\"price\":\"1.66836\",\"quantity\":\"139\",\"timeInForce\":\"GTE\",\"orderId\":\"7783C148DC7D2CBC504C0CC569B57A593FE53E70-1594630\"}}", + "confirmBlocks": 0, + "memo": "", + "source": 0, + "sequence": 1594629 + }, + { + "txHash": "701100D3783744D633FF34A6E211CEB923EA9BCE6D87A64211801E71F71AEE03", + "blockHeight": 105725327, + "txType": "NEW_ORDER", + "timeStamp": "2020-08-07T19:11:09.184Z", + "fromAddr": "bnb1w7puzjxu05ktc5zvpnzkndt6tyl720nsutzvpg", + "toAddr": null, + "value": "92.81678000", + "txAsset": "AVA-645", + "txFee": "0.00000000", + "proposalId": null, + "txAge": 157, + "orderId": "7783C148DC7D2CBC504C0CC569B57A593FE53E70-1594628", + "code": 0, + "data": "{\"orderData\":{\"symbol\":\"AVA-645_BUSD-BD1\",\"orderType\":\"LIMIT\",\"side\":\"SELL\",\"price\":\"1.89422\",\"quantity\":\"49\",\"timeInForce\":\"GTE\",\"orderId\":\"7783C148DC7D2CBC504C0CC569B57A593FE53E70-1594628\"}}", + "confirmBlocks": 0, + "memo": "", + "source": 0, + "sequence": 1594627 + }, + { + "txHash": "B12B30509B45CEFE526DAADDAC6399F902B30418859042D7A23F9A2FB311A6C8", + "blockHeight": 105725323, + "txType": "NEW_ORDER", + "timeStamp": "2020-08-07T19:11:07.404Z", + "fromAddr": "bnb1w7puzjxu05ktc5zvpnzkndt6tyl720nsutzvpg", + "toAddr": null, + "value": "47.87208000", + "txAsset": "AVA-645", + "txFee": "0.00000000", + "proposalId": null, + "txAge": 159, + "orderId": "7783C148DC7D2CBC504C0CC569B57A593FE53E70-1594627", + "code": 0, + "data": "{\"orderData\":{\"symbol\":\"AVA-645_BUSD-BD1\",\"orderType\":\"LIMIT\",\"side\":\"BUY\",\"price\":\"1.77304\",\"quantity\":\"27\",\"timeInForce\":\"GTE\",\"orderId\":\"7783C148DC7D2CBC504C0CC569B57A593FE53E70-1594627\"}}", + "confirmBlocks": 0, + "memo": "", + "source": 0, + "sequence": 1594626 + }, + { + "txHash": "933819F35F0F89FB2D58DC50CD15FABB3DA0B817BFCD39A8DDC99DFEC1663F7D", + "blockHeight": 105725301, + "txType": "NEW_ORDER", + "timeStamp": "2020-08-07T19:10:58.404Z", + "fromAddr": "bnb1w7puzjxu05ktc5zvpnzkndt6tyl720nsutzvpg", + "toAddr": null, + "value": "181.49465000", + "txAsset": "AVA-645", + "txFee": "0.00000000", + "proposalId": null, + "txAge": 168, + "orderId": "7783C148DC7D2CBC504C0CC569B57A593FE53E70-1594624", + "code": 0, + "data": "{\"orderData\":{\"symbol\":\"AVA-645_BUSD-BD1\",\"orderType\":\"LIMIT\",\"side\":\"SELL\",\"price\":\"1.91047\",\"quantity\":\"95\",\"timeInForce\":\"GTE\",\"orderId\":\"7783C148DC7D2CBC504C0CC569B57A593FE53E70-1594624\"}}", + "confirmBlocks": 0, + "memo": "", + "source": 0, + "sequence": 1594623 + } + ], + "total": 11603 +} diff --git a/platform/binance/mocks/txs_response.json b/platform/binance/mocks/txs_response.json new file mode 100644 index 000000000..9ed842e27 --- /dev/null +++ b/platform/binance/mocks/txs_response.json @@ -0,0 +1,505 @@ +{ + "tx": [ + { + "txHash": "771B07C8D921B5995524C163E9D4504C31A9E07EC858263A53EA007484009C90", + "blockHeight": 105722032, + "txType": "TRANSFER", + "timeStamp": "2020-08-07T18:48:26.284Z", + "fromAddr": "bnb1d83u9afqw296ejw9jdfhc22f0ljr23nn7pradx", + "toAddr": "bnb136ns6lfw4zs5hg4n85vdthaad7hq5m4gtkgf23", + "value": "1.20740436", + "txAsset": "BNB", + "txFee": "0.00037500", + "proposalId": null, + "txAge": 104, + "orderId": null, + "code": 0, + "data": null, + "confirmBlocks": 0, + "memo": "106890151", + "source": 1, + "sequence": 33 + }, + { + "txHash": "1C5682716D2D34DD01428AD8D4200081FBDA06CE886B77499F755E9D93B0FF20", + "blockHeight": 105721942, + "txType": "TRANSFER", + "timeStamp": "2020-08-07T18:47:49.895Z", + "fromAddr": "bnb1k9ktd79psysucucyxqcd5r9ahuuygk8gh3ly8q", + "toAddr": "bnb136ns6lfw4zs5hg4n85vdthaad7hq5m4gtkgf23", + "value": "2.29350524", + "txAsset": "BNB", + "txFee": "0.00037500", + "proposalId": null, + "txAge": 140, + "orderId": null, + "code": 0, + "data": null, + "confirmBlocks": 0, + "memo": "103215089", + "source": 2, + "sequence": 64 + }, + { + "txHash": "C728F7C13977649FCDF9B8E983A9E3AA257EB5596DBCA2A2580584312B5AA535", + "blockHeight": 105721925, + "txType": "TRANSFER", + "timeStamp": "2020-08-07T18:47:43.111Z", + "fromAddr": "bnb155svs6sgxe55rnvs6ghprtqu0mh69kehphsppd", + "toAddr": "bnb136ns6lfw4zs5hg4n85vdthaad7hq5m4gtkgf23", + "value": "119.64120000", + "txAsset": "BNB", + "txFee": "0.00037500", + "proposalId": null, + "txAge": 147, + "orderId": null, + "code": 0, + "data": null, + "confirmBlocks": 0, + "memo": "101045880", + "source": 1, + "sequence": 23121 + }, + { + "txHash": "794302F9C6562358581A3A8432AF82CD70DF0DA345C917BDE21DDF9A9D4B9DE7", + "blockHeight": 105721913, + "txType": "TRANSFER", + "timeStamp": "2020-08-07T18:47:38.279Z", + "fromAddr": "bnb14gk6m77tswyks9nnadm92mdy3066wj42t60z0l", + "toAddr": "bnb136ns6lfw4zs5hg4n85vdthaad7hq5m4gtkgf23", + "value": "4.56000000", + "txAsset": "BNB", + "txFee": "0.00037500", + "proposalId": null, + "txAge": 152, + "orderId": null, + "code": 0, + "data": null, + "confirmBlocks": 0, + "memo": "100341541", + "source": 1, + "sequence": 11228 + }, + { + "txHash": "2827377A04E3B22DD654A02AD4BA50B3CB83973B6B9BA1A423ABD5045873850C", + "blockHeight": 105721828, + "txType": "TRANSFER", + "timeStamp": "2020-08-07T18:47:04.205Z", + "fromAddr": "bnb132gvg9gdthtaf6xgkk9jkmsep56fv62vg95unv", + "toAddr": "bnb136ns6lfw4zs5hg4n85vdthaad7hq5m4gtkgf23", + "value": "10.45498916", + "txAsset": "BNB", + "txFee": "0.00037500", + "proposalId": null, + "txAge": 186, + "orderId": null, + "code": 0, + "data": null, + "confirmBlocks": 0, + "memo": "105772095", + "source": 2, + "sequence": 4 + }, + { + "txHash": "AACC80FDA9C45DCD7F6DBAA40A2EB600FF6EBB24A5A840578D4AB306C3427385", + "blockHeight": 105721785, + "txType": "TRANSFER", + "timeStamp": "2020-08-07T18:46:46.832Z", + "fromAddr": "bnb10y4hu5psc7hztlczrhzgghfjzufnqyfrrml3yn", + "toAddr": "bnb136ns6lfw4zs5hg4n85vdthaad7hq5m4gtkgf23", + "value": "87.50000000", + "txAsset": "BNB", + "txFee": "0.00037500", + "proposalId": null, + "txAge": 203, + "orderId": null, + "code": 0, + "data": null, + "confirmBlocks": 0, + "memo": "109027392", + "source": 1, + "sequence": 65 + }, + { + "txHash": "66CF0F65442FD35A3B91CC2655CE60E565D13EEFC6BDB1C5AF9F9E484C8B6295", + "blockHeight": 105721686, + "txType": "TRANSFER", + "timeStamp": "2020-08-07T18:46:07.122Z", + "fromAddr": "bnb17g92armmr926kd88umh7u90vglq4ghjtku6ssc", + "toAddr": "bnb136ns6lfw4zs5hg4n85vdthaad7hq5m4gtkgf23", + "value": "8.78900000", + "txAsset": "BNB", + "txFee": "0.00037500", + "proposalId": null, + "txAge": 243, + "orderId": null, + "code": 0, + "data": null, + "confirmBlocks": 0, + "memo": "107780643", + "source": 0, + "sequence": 896 + }, + { + "txHash": "81EA185BE754809E40FCBF1B07A0C389F39DECD38D56302D980534850996B144", + "blockHeight": 105721490, + "txType": "TRANSFER", + "timeStamp": "2020-08-07T18:44:48.958Z", + "fromAddr": "bnb12nq7fhh3t8q0m9s2n5gqwd9gcx0j85yn0h5zcu", + "toAddr": "bnb136ns6lfw4zs5hg4n85vdthaad7hq5m4gtkgf23", + "value": "44.98159221", + "txAsset": "BNB", + "txFee": "0.00037500", + "proposalId": null, + "txAge": 321, + "orderId": null, + "code": 0, + "data": null, + "confirmBlocks": 0, + "memo": "101210049", + "source": 0, + "sequence": 0 + }, + { + "txHash": "24ED2153427ABACD7F6DB53A1339D9C2573D720FDE6EC45B0047CB146227FF9A", + "blockHeight": 105721385, + "txType": "TRANSFER", + "timeStamp": "2020-08-07T18:44:07.201Z", + "fromAddr": "bnb1s5qucugaxv7gkzyg4kacf225s6mhj0ysejn8jq", + "toAddr": "bnb136ns6lfw4zs5hg4n85vdthaad7hq5m4gtkgf23", + "value": "343.00000000", + "txAsset": "BNB", + "txFee": "0.00037500", + "proposalId": null, + "txAge": 363, + "orderId": null, + "code": 0, + "data": null, + "confirmBlocks": 0, + "memo": "104298046", + "source": 2, + "sequence": 40 + }, + { + "txHash": "411A27CE85D0928BC5908DA5BA288CB52E152C1E54FA35042147A90FCEBAB29C", + "blockHeight": 105721238, + "txType": "TRANSFER", + "timeStamp": "2020-08-07T18:43:09.084Z", + "fromAddr": "bnb1erj09eqrnz06jv2acxhhy7s3k0q6w4hfmj9rey", + "toAddr": "bnb136ns6lfw4zs5hg4n85vdthaad7hq5m4gtkgf23", + "value": "0.06319074", + "txAsset": "BNB", + "txFee": "0.00037500", + "proposalId": null, + "txAge": 421, + "orderId": null, + "code": 0, + "data": null, + "confirmBlocks": 0, + "memo": "107303874", + "source": 2, + "sequence": 12 + }, + { + "txHash": "25359F7277760004BBD42557B3E50F86F06B096478840E057C6F394BF63F6081", + "blockHeight": 105720997, + "txType": "TRANSFER", + "timeStamp": "2020-08-07T18:41:32.193Z", + "fromAddr": "bnb10y4hu5psc7hztlczrhzgghfjzufnqyfrrml3yn", + "toAddr": "bnb136ns6lfw4zs5hg4n85vdthaad7hq5m4gtkgf23", + "value": "10.90000000", + "txAsset": "BNB", + "txFee": "0.00037500", + "proposalId": null, + "txAge": 518, + "orderId": null, + "code": 0, + "data": null, + "confirmBlocks": 0, + "memo": "109027392", + "source": 1, + "sequence": 57 + }, + { + "txHash": "1DB710AF4983D9CAFB24AC3DD7C2C6EBC7752F347E5A7599840AB3EFBD436C5D", + "blockHeight": 105720867, + "txType": "TRANSFER", + "timeStamp": "2020-08-07T18:40:39.623Z", + "fromAddr": "bnb10y4hu5psc7hztlczrhzgghfjzufnqyfrrml3yn", + "toAddr": "bnb136ns6lfw4zs5hg4n85vdthaad7hq5m4gtkgf23", + "value": "20.00000000", + "txAsset": "BNB", + "txFee": "0.00037500", + "proposalId": null, + "txAge": 570, + "orderId": null, + "code": 0, + "data": null, + "confirmBlocks": 0, + "memo": "109027392", + "source": 1, + "sequence": 56 + }, + { + "txHash": "B7C799B9853ECA41F02241B67E294E2642AE88BBF551DE188A73C48D1A0E821D", + "blockHeight": 105720816, + "txType": "TRANSFER", + "timeStamp": "2020-08-07T18:40:19.123Z", + "fromAddr": "bnb1q2994t0djzsy0q2fc62jruxr22nxq6y8l4503l", + "toAddr": "bnb136ns6lfw4zs5hg4n85vdthaad7hq5m4gtkgf23", + "value": "2.95957149", + "txAsset": "BNB", + "txFee": "0.00037500", + "proposalId": null, + "txAge": 591, + "orderId": null, + "code": 0, + "data": null, + "confirmBlocks": 0, + "memo": "108202494", + "source": 0, + "sequence": 1 + }, + { + "txHash": "865C098D021CC649FC83B2442092E4D6F0777488163E5797DA9D264C87F1F4F4", + "blockHeight": 105720641, + "txType": "TRANSFER", + "timeStamp": "2020-08-07T18:39:08.972Z", + "fromAddr": "bnb16xqcchlutsm8g6gk7wvlzukeu2sy9xt2u77056", + "toAddr": "bnb136ns6lfw4zs5hg4n85vdthaad7hq5m4gtkgf23", + "value": "13.73501799", + "txAsset": "BNB", + "txFee": "0.00037500", + "proposalId": null, + "txAge": 661, + "orderId": null, + "code": 0, + "data": null, + "confirmBlocks": 0, + "memo": "102080722", + "source": 1, + "sequence": 33 + }, + { + "txHash": "1D4F777D1D227D57E4D4BAC3E83FB203147E7B0E7429E60A48A9053372359174", + "blockHeight": 105720519, + "txType": "TRANSFER", + "timeStamp": "2020-08-07T18:38:20.149Z", + "fromAddr": "bnb1t6tk66zncqqt7twnfyxx22fn9t3wz3nac5hkck", + "toAddr": "bnb136ns6lfw4zs5hg4n85vdthaad7hq5m4gtkgf23", + "value": "0.01490609", + "txAsset": "BNB", + "txFee": "0.00037500", + "proposalId": null, + "txAge": 710, + "orderId": null, + "code": 0, + "data": null, + "confirmBlocks": 0, + "memo": "106456805", + "source": 2, + "sequence": 14 + }, + { + "txHash": "9A818687D52B4E9E0C5F962E6E464ECC6348D6A41AE2C5DD051A5EF71E15B1AC", + "blockHeight": 105720307, + "txType": "TRANSFER", + "timeStamp": "2020-08-07T18:36:55.571Z", + "fromAddr": "bnb1v47qw5acc72c34uwt7t9wm9ztqtg6678dmrssa", + "toAddr": "bnb136ns6lfw4zs5hg4n85vdthaad7hq5m4gtkgf23", + "value": "3.56700000", + "txAsset": "BNB", + "txFee": "0.00037500", + "proposalId": null, + "txAge": 794, + "orderId": null, + "code": 0, + "data": null, + "confirmBlocks": 0, + "memo": "104471384", + "source": 2, + "sequence": 6273 + }, + { + "txHash": "6C7D4469525E44501ED03BA38A6D54A04DFD6AD2D13328761DA4602A3D777332", + "blockHeight": 105720136, + "txType": "TRANSFER", + "timeStamp": "2020-08-07T18:35:48.142Z", + "fromAddr": "bnb1tzet704pc6zjsl3xcwdexn6xlu0zc092y0n4ay", + "toAddr": "bnb136ns6lfw4zs5hg4n85vdthaad7hq5m4gtkgf23", + "value": "0.93900000", + "txAsset": "BNB", + "txFee": "0.00037500", + "proposalId": null, + "txAge": 862, + "orderId": null, + "code": 0, + "data": null, + "confirmBlocks": 0, + "memo": "101245732", + "source": 0, + "sequence": 721 + }, + { + "txHash": "8C47875F09371B45C0A29D7C6EF308A1C499D1BBECD5A56E0561B40675AF2D26", + "blockHeight": 105720042, + "txType": "TRANSFER", + "timeStamp": "2020-08-07T18:35:11.247Z", + "fromAddr": "bnb1t7hpl286qgvsg08lvx6ac9ul0msy4k2ud8dukp", + "toAddr": "bnb136ns6lfw4zs5hg4n85vdthaad7hq5m4gtkgf23", + "value": "0.95193451", + "txAsset": "BNB", + "txFee": "0.00037500", + "proposalId": null, + "txAge": 899, + "orderId": null, + "code": 0, + "data": null, + "confirmBlocks": 0, + "memo": "101186586", + "source": 2, + "sequence": 1912 + }, + { + "txHash": "39A48766F8ACC33B3BB1B4F442ABFDFBC695F440D72795794A01E8E446CE8EAE", + "blockHeight": 105720010, + "txType": "TRANSFER", + "timeStamp": "2020-08-07T18:34:58.634Z", + "fromAddr": "bnb10y4hu5psc7hztlczrhzgghfjzufnqyfrrml3yn", + "toAddr": "bnb136ns6lfw4zs5hg4n85vdthaad7hq5m4gtkgf23", + "value": "4.80000000", + "txAsset": "BNB", + "txFee": "0.00037500", + "proposalId": null, + "txAge": 911, + "orderId": null, + "code": 0, + "data": null, + "confirmBlocks": 0, + "memo": "109027392", + "source": 1, + "sequence": 47 + }, + { + "txHash": "54248E3C09713E3870F661749A8690DAD46A8078C7346C497EB4E166564420F4", + "blockHeight": 105719860, + "txType": "TRANSFER", + "timeStamp": "2020-08-07T18:33:57.102Z", + "fromAddr": "bnb1hc304lytvp9jnumnjmppq97erm70r7muzv6y98", + "toAddr": "bnb136ns6lfw4zs5hg4n85vdthaad7hq5m4gtkgf23", + "value": "102.10962500", + "txAsset": "BNB", + "txFee": "0.00037500", + "proposalId": null, + "txAge": 973, + "orderId": null, + "code": 0, + "data": null, + "confirmBlocks": 0, + "memo": "105261446", + "source": 0, + "sequence": 1 + }, + { + "txHash": "ADDDB705AB8C2B1AF58D7EDCAEC00C893A6CD87281D7A7146689E9FE1A846EAE", + "blockHeight": 105719705, + "txType": "TRANSFER", + "timeStamp": "2020-08-07T18:32:53.527Z", + "fromAddr": "bnb17g92armmr926kd88umh7u90vglq4ghjtku6ssc", + "toAddr": "bnb136ns6lfw4zs5hg4n85vdthaad7hq5m4gtkgf23", + "value": "2.97900000", + "txAsset": "BNB", + "txFee": "0.00037500", + "proposalId": null, + "txAge": 1036, + "orderId": null, + "code": 0, + "data": null, + "confirmBlocks": 0, + "memo": "103617121", + "source": 0, + "sequence": 895 + }, + { + "txHash": "7C338C78BBBCD998628CCAF85211883AACB159201755501139F56E0D2A7941A4", + "blockHeight": 105719641, + "txType": "TRANSFER", + "timeStamp": "2020-08-07T18:32:27.476Z", + "fromAddr": "bnb1pys084nlc8gqm7lvjje4kt39dn84vd2xsvnwqa", + "toAddr": "bnb136ns6lfw4zs5hg4n85vdthaad7hq5m4gtkgf23", + "value": "2.00000000", + "txAsset": "BNB", + "txFee": "0.00037500", + "proposalId": null, + "txAge": 1062, + "orderId": null, + "code": 0, + "data": null, + "confirmBlocks": 0, + "memo": "108802310", + "source": 0, + "sequence": 18 + }, + { + "txHash": "6DD7120E43CD5031E2DD6C7977D141B74CA41C8E476D8AE972A9DA2D2EFD2D84", + "blockHeight": 105719428, + "txType": "TRANSFER", + "timeStamp": "2020-08-07T18:31:01.143Z", + "fromAddr": "bnb17g92armmr926kd88umh7u90vglq4ghjtku6ssc", + "toAddr": "bnb136ns6lfw4zs5hg4n85vdthaad7hq5m4gtkgf23", + "value": "6.77900000", + "txAsset": "BNB", + "txFee": "0.00037500", + "proposalId": null, + "txAge": 1149, + "orderId": null, + "code": 0, + "data": null, + "confirmBlocks": 0, + "memo": "102393444", + "source": 0, + "sequence": 894 + }, + { + "txHash": "86FB14C637D7B0A4AA123FFF76C5C541C70568B67E3F5BC63EB0FDEDEF30301F", + "blockHeight": 105719403, + "txType": "TRANSFER", + "timeStamp": "2020-08-07T18:30:51.089Z", + "fromAddr": "bnb17nak8gnucl6lcze0d04def4de77a33qh29f6ur", + "toAddr": "bnb136ns6lfw4zs5hg4n85vdthaad7hq5m4gtkgf23", + "value": "0.00900000", + "txAsset": "BNB", + "txFee": "0.00037500", + "proposalId": null, + "txAge": 1159, + "orderId": null, + "code": 0, + "data": null, + "confirmBlocks": 0, + "memo": "109823910", + "source": 2, + "sequence": 3 + }, + { + "txHash": "1DEEFC0A838F80704574951DF15969CCE34654BE2007BF77F9521A1B4686BE33", + "blockHeight": 105719312, + "txType": "TRANSFER", + "timeStamp": "2020-08-07T18:30:14.498Z", + "fromAddr": "bnb1yjlk7f47qf0z97ph6pxc00s2s0yw048edmtjtw", + "toAddr": "bnb136ns6lfw4zs5hg4n85vdthaad7hq5m4gtkgf23", + "value": "3.15739000", + "txAsset": "BNB", + "txFee": "0.00037500", + "proposalId": null, + "txAge": 1195, + "orderId": null, + "code": 0, + "data": null, + "confirmBlocks": 0, + "memo": "103268674", + "source": 2, + "sequence": 1431 + } + ], + "total": 1636 +} diff --git a/platform/binance/model.go b/platform/binance/model.go index 168a58f8d..d4ccaf05e 100644 --- a/platform/binance/model.go +++ b/platform/binance/model.go @@ -1,153 +1,276 @@ package binance import ( - "encoding/json" - "fmt" - "github.com/trustwallet/blockatlas/coin" - "github.com/trustwallet/blockatlas/pkg/errors" - "math" "strconv" "strings" + "time" + + "github.com/trustwallet/golibs/types" + + "github.com/trustwallet/golibs/coin" + "github.com/trustwallet/golibs/numbers" ) -type Account struct { - AccountNumber int `json:"account_number"` - Address string `json:"address"` - Balances []Balance `json:"balances"` - PublicKey []byte `json:"public_key"` - Sequence uint64 `json:"sequence"` -} +const ( + NewOrder TxType = "NEW_ORDER" + CancelOrder TxType = "CANCEL_ORDER" + Transfer TxType = "TRANSFER" +) -type Balance struct { - Free string `json:"free"` - Frozen string `json:"frozen"` - Locked string `json:"locked"` - Symbol string `json:"symbol"` -} +const ( + BNBAsset = "BNB" + tokensLimit = "1000" +) -type Error struct { - Code int64 `json:"code"` - Message string `json:"message"` -} +type ( + NodeInfoResponse struct { + SyncInfo struct { + LatestBlockHeight int `json:"latest_block_height"` + } `json:"sync_info"` + } -type BlockDescriptor struct { - BlockHeight int64 `json:"blockHeight"` - BlockHash string `json:"blockHash"` - TxNum int `json:"txNum"` -} + TxType string -type BlockList struct { - BlockArray []BlockDescriptor `json:"blockArray"` -} + TransactionsInBlockResponse struct { + BlockHeight int `json:"blockHeight"` + Tx []Tx `json:"tx"` + } -type TxType string + Tx struct { + TxHash string `json:"txHash"` + BlockHeight int `json:"blockHeight"` + TxType TxType `json:"txType"` + TimeStamp time.Time `json:"timeStamp"` + FromAddr interface{} `json:"fromAddr"` + ToAddr interface{} `json:"toAddr"` + Value string `json:"value"` + TxAsset string `json:"txAsset"` + TxFee string `json:"txFee"` + OrderID string `json:"orderId,omitempty"` + Code int `json:"code"` + Data string `json:"data"` + Memo string `json:"memo"` + Source int `json:"source"` + SubTransactions []SubTransactions `json:"subTransactions,omitempty"` + Sequence int `json:"sequence"` + } -const ( - TxTransfer TxType = "TRANSFER" - TxNewOrder TxType = "NEW_ORDER" - TxCancelOrder TxType = "CANCEL_ORDER" -) + TransactionData struct { + OrderData struct { + Symbol string `json:"symbol"` + OrderType string `json:"orderType"` + Side string `json:"side"` + Price string `json:"price"` + Quantity string `json:"quantity"` + TimeInForce string `json:"timeInForce"` + OrderID string `json:"orderId"` + } `json:"orderData"` + } -type Tx struct { - BlockHeight uint64 `json:"blockHeight"` - Type TxType `json:"txType"` - Code int `json:"code"` - ConfirmBlocks int `json:"confirmBlocks"` - Data string `json:"data"` - FromAddr string `json:"fromAddr"` - OrderID string `json:"orderId"` - Timestamp int64 `json:"timeStamp"` - ToAddr string `json:"toAddr"` - Age int64 `json:"txAge"` - Asset string `json:"txAsset"` - Fee json.Number `json:"txFee"` - Hash string `json:"txHash"` - Value json.Number `json:"value"` - Memo string `json:"memo"` -} + SubTransactions struct { + TxHash string `json:"txHash"` + BlockHeight int `json:"blockHeight"` + TxType string `json:"txType"` + FromAddr string `json:"fromAddr"` + ToAddr string `json:"toAddr"` + TxAsset string `json:"txAsset"` + TxFee string `json:"txFee"` + Value string `json:"value"` + } -func (tx *Tx) getData() (Data, error) { - rawIn := json.RawMessage(tx.Data) - b, err := rawIn.MarshalJSON() - if err != nil { - return Data{}, errors.E(err, "getData MarshalJSON", errors.Params{"data": tx.Data}) + TransactionsByAddressAndAssetResponse struct { + Txs []Tx `json:"tx"` } - var data Data - err = json.Unmarshal(b, &data) - if err != nil { - return Data{}, errors.E(err, "getData Unmarshal", errors.Params{"data": string(b)}) + AccountMeta struct { + Balances []TokenBalance `json:"balances"` } - symbols := strings.Split(data.OrderData.Symbol, "_") - if len(symbols) < 2 { - return data, nil + TokenBalance struct { + Free string `json:"free"` + Frozen string `json:"frozen"` + Locked string `json:"locked"` + Symbol string `json:"symbol"` } - data.OrderData.Base = symbols[0] - data.OrderData.Quote = symbols[1] - return data, nil -} + Tokens []Token + + Token struct { + Name string `json:"name"` + OriginalSymbol string `json:"original_symbol"` + Owner string `json:"owner"` + Symbol string `json:"symbol"` + TotalSupply string `json:"total_supply"` + } +) -type Data struct { - OrderData OrderData `json:"orderData"` +func normalizeBlock(response TransactionsInBlockResponse) types.Block { + result := types.Block{ + Number: int64(response.BlockHeight), + } + result.Txs = normalizeTransactions(response.Tx) + return result } -type OrderData struct { - Symbol string `json:"symbol"` - Base string `json:"-"` - Quote string `json:"-"` - Quantity interface{} `json:"quantity"` - Price interface{} `json:"price"` +func normalizeTransactions(txs []Tx) types.Txs { + totalTxs := make(types.Txs, 0, len(txs)) + for _, t := range txs { + var txs types.Txs + switch t.TxType { + case CancelOrder, NewOrder: + //txs = append(txs, normalizeOrderTransaction(t)) + continue + case Transfer: + if len(t.SubTransactions) > 0 { + txs = normalizeMultiTransferTransaction(t) + } else { + txs = append(txs, normalizeTransferTransaction(t)) + } + } + totalTxs = append(totalTxs, txs...) + } + return totalTxs } -func (od OrderData) GetVolume() (int64, bool) { - price, ok := od.GetPrice() - if !ok { - return 0, false +func normalizeTransferTransaction(t Tx) types.Tx { + tx := normalizeBaseOfTransaction(t) + tx.To = t.ToAddr.(string) + tx.From = t.FromAddr.(string) + switch { + case t.TxAsset == BNBAsset: + tx.Type = types.TxTransfer + tx.Meta = types.Transfer{ + Value: normalizeAmount(t.Value), + Symbol: coin.Binance().Symbol, + Decimals: coin.Binance().Decimals, + } + case t.TxAsset != "": + tx.Type = types.TxNativeTokenTransfer + tx.Meta = types.NativeTokenTransfer{ + Decimals: coin.Binance().Decimals, + From: t.FromAddr.(string), + Symbol: getTokenSymbolFromID(t.TxAsset), + Name: getTokenSymbolFromID(t.TxAsset), + To: t.ToAddr.(string), + TokenID: t.TxAsset, + Value: normalizeAmount(t.Value), + } } - quantity, ok := od.GetQuantity() - if !ok { - return 0, false + return tx +} + +func normalizeMultiTransferTransaction(t Tx) types.Txs { + txs := make(types.Txs, 0, len(t.SubTransactions)) + for _, subTx := range t.SubTransactions { + tx := types.Tx{ + ID: subTx.TxHash, + Coin: coin.Binance().ID, + From: subTx.FromAddr, + To: subTx.ToAddr, + Fee: normalizeFee(subTx.TxFee), + Date: t.TimeStamp.Unix(), + Block: uint64(t.BlockHeight), + Status: types.StatusCompleted, + Sequence: uint64(t.Sequence), + Memo: t.Memo, + } + switch { + case subTx.TxAsset == BNBAsset: + tx.Type = types.TxTransfer + tx.Meta = types.Transfer{ + Value: normalizeAmount(subTx.Value), + Symbol: coin.Binance().Symbol, + Decimals: coin.Binance().Decimals, + } + case subTx.TxAsset != "": + tx.Type = types.TxNativeTokenTransfer + tx.Meta = types.NativeTokenTransfer{ + Decimals: coin.Binance().Decimals, + Name: getTokenSymbolFromID(subTx.TxAsset), + From: subTx.FromAddr, + Symbol: getTokenSymbolFromID(subTx.TxAsset), + To: subTx.ToAddr, + TokenID: subTx.TxAsset, + Value: normalizeAmount(subTx.Value), + } + default: + continue + } + txs = append(txs, tx) } - return removeFloatPoint(price * quantity), true + return txs } -func (od OrderData) GetPrice() (float64, bool) { - return convertValue(od.Price) +func normalizeBaseOfTransaction(t Tx) types.Tx { + return types.Tx{ + ID: t.TxHash, + Coin: coin.Binance().ID, + From: t.FromAddr.(string), + Fee: normalizeFee(t.TxFee), + Date: t.TimeStamp.Unix(), + Block: uint64(t.BlockHeight), + Status: types.StatusCompleted, + Sequence: uint64(t.Sequence), + Memo: t.Memo, + } } -func (od OrderData) GetQuantity() (float64, bool) { - return convertValue(od.Quantity) +func normalizeTokens(srcBalance []TokenBalance, tokens Tokens) []types.Token { + assetIds := make([]types.Token, 0) + for _, srcToken := range srcBalance { + if token, ok := normalizeToken(srcToken, tokens); ok { + assetIds = append(assetIds, token) + } + } + return assetIds } -type TxPage struct { - Nums int `json:"txNums"` - Txs []Tx `json:"txArray"` +func normalizeToken(srcToken TokenBalance, tokens Tokens) (types.Token, bool) { + var result types.Token + if srcToken.isAllZeroBalance() { + return result, false + } + + token, ok := tokens.findTokenBySymbol(srcToken.Symbol) + if !ok { + return result, false + } + + result = types.Token{ + Name: token.Name, + Symbol: token.OriginalSymbol, + TokenID: token.Symbol, + Coin: coin.Binance().ID, + Decimals: coin.Binance().Decimals, + Type: types.BEP2, + } + + return result, true } -type Token struct { - Mintable bool `json:"mintable"` - Name string `json:"name"` - OriginalSymbol string `json:"original_symbol"` - Owner string `json:"owner"` - Symbol string `json:"symbol"` - TotalSupply string `json:"total_supply"` +func getTokenSymbolFromID(tokenID string) string { + s := strings.Split(tokenID, "-") + if len(s) > 1 { + return s[0] + } + return tokenID } -type TokenPage []Token +func normalizeAmount(amount string) types.Amount { + val := numbers.DecimalExp(amount, int(coin.Binance().Decimals)) + return types.Amount(val) +} -// findToken find a token into a token list -func (a TokenPage) findToken(symbol string) *Token { - for _, t := range a { - if t.Symbol == symbol { - return &t - } +func normalizeFee(amount string) types.Amount { + a, err := numbers.StringNumberToFloat64(amount) + if a != 0 && err == nil { + return types.Amount(numbers.DecimalExp(amount, int(coin.Binance().Decimals))) + } else { + return "0" } - return nil } -func (balance *Balance) isAllZeroBalance() bool { +func (balance TokenBalance) isAllZeroBalance() bool { balances := [3]string{balance.Frozen, balance.Free, balance.Locked} for _, value := range balances { value, err := strconv.ParseFloat(value, 64) @@ -156,33 +279,13 @@ func (balance *Balance) isAllZeroBalance() bool { } } return true - } -func (e *Error) Error() string { - return fmt.Sprintf("%d: %s", e.Code, e.Message) -} - -func removeFloatPoint(value float64) int64 { - bnbCoin := coin.Coins[coin.BNB] - pow := math.Pow(10, float64(bnbCoin.Decimals)) - return int64(value * pow) -} - -func convertValue(value interface{}) (float64, bool) { - result := 0.0 - switch v := value.(type) { - case float64: - result = v - case int: - result = float64(v) - case string: - f, err := strconv.ParseFloat(v, 64) - if err == nil { - result = f +func (page Tokens) findTokenBySymbol(symbol string) (Token, bool) { + for _, t := range page { + if t.Symbol == symbol { + return t, true } - default: - return result, false } - return result, true + return Token{}, false } diff --git a/platform/binance/model_test.go b/platform/binance/model_test.go index 3bba11e05..a6feecec6 100644 --- a/platform/binance/model_test.go +++ b/platform/binance/model_test.go @@ -1,193 +1,29 @@ package binance -import ( - "github.com/stretchr/testify/assert" - "testing" - "time" -) - -var newOrderDataDst = Data{OrderData: OrderData{ - Symbol: "AWC-986_BNB", - Base: "AWC-986", - Quote: "BNB", - Quantity: 2.0, - Price: 0.00324939, -}} - -var cancelOrderDataDst = Data{OrderData: OrderData{ - Symbol: "GTO-908_BNB", - Base: "GTO-908", - Quote: "BNB", - Quantity: 1.0, - Price: 0.00104716, -}} - -func TestTx_getData(t *testing.T) { - tests := []struct { - name string - Data string - want Data - }{ - { - "new order", - "{\"orderData\":{\"symbol\":\"AWC-986_BNB\",\"orderType\":\"limit\",\"side\":\"buy\",\"price\":0.00324939,\"quantity\":2.00000000,\"timeInForce\":\"GTE\",\"orderId\":\"D13BAF4BD6638FA3AAD6EBCA0E4BEEA73DF4D519-30\"}}", - newOrderDataDst, - }, - { - "cancel order", - "{\"orderData\":{\"symbol\":\"GTO-908_BNB\",\"orderType\":\"limit\",\"side\":\"buy\",\"price\":0.00104716,\"quantity\":1.00000000,\"timeInForce\":\"GTE\",\"orderId\":\"D13BAF4BD6638FA3AAD6EBCA0E4BEEA73DF4D519-28\"}}", - cancelOrderDataDst, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - tx := &Tx{Data: tt.Data} - got, _ := tx.getData() - assert.Equal(t, tt.want, got) - }) - } -} - -func TestConvertValue(t *testing.T) { - tests := []struct { - name string - value interface{} - wantResult float64 - wantError bool - }{ - {"test string 1", "9", 9, false}, - {"test number 1", 9, 9, false}, - {"test string 2", "9380938973", 9380938973, false}, - {"test number 2", 9380938973, 9380938973, false}, - {"test string 3", "0.0000003", 0.0000003, false}, - {"test number 3", 0.0000003, 0.0000003, false}, - {"test string 4", "0.44", 0.44, false}, - {"test number 4", 0.44, 0.44, false}, - {"test string 5", "3334", 3334, false}, - {"test number 5", 3334, 3334, false}, - {"test error", time.Time{}, 3334, true}, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - got, ok := convertValue(tt.value) - if tt.wantError { - assert.False(t, ok) - return - } - assert.True(t, ok) - assert.Equal(t, tt.wantResult, got) - }) - } -} - -func Test_removeFloatPoint(t *testing.T) { - tests := []struct { - name string - value float64 - want int64 - }{ - {"test float 1", 0.0034, 340000}, - {"test float 2", 0.00000013, 13}, - {"test float 3", 0.938984, 93898400}, - {"test float 4", 0.1, 10000000}, - {"test int 1", 12, 1200000000}, - {"test int 2", 2333333333, 233333333300000000}, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - if got := removeFloatPoint(tt.value); got != tt.want { - t.Errorf("removeFloatPoint() = %v, want %v", got, tt.want) - } - }) - } -} +import "testing" func Test_isZeroBalance(t *testing.T) { type testZeroStruct struct { name string - balance Balance + balance TokenBalance want bool } - // all combinations of 3 variables with 2 possible value 0 or 1 is 2^3 = 8 tests := []testZeroStruct{ - {"1", - Balance{"0.00000000", "0.00000000", "0.00000000", "BNB"}, - true, - }, - {"2", - Balance{"0.00000000", "0", "0.00000001", "BNB"}, - false, - }, - {"3", - Balance{"0.00000000", "0.00000001", "0.00000000", "BNB"}, - false, - }, - {"4", - Balance{"0.00000000", "0.00000001", "0.00000001", "BNB"}, - false, - }, - {"5", - Balance{"0.00000001", "0.00000000", "0.00000000", "BNB"}, - false, - }, - {"6", - Balance{"0.00000001", "0.00000000", "0.00000001", "BNB"}, - false, - }, - {"7", - Balance{"0.00000001", "0.00000001", "0.00000000", "BNB"}, - false, - }, - {"8", - Balance{"0.00000001", "0.00000001", "0.00000001", "BNB"}, - false, - }, - {"Negative", - Balance{"-0.00000001", "0.00000001", "0.00000001", "BNB"}, - false, - }, - {"Bad others are 0", - Balance{"f", - "0.0000000", "0.0000000", "BNB"}, - false, - }, - {"Bad others are not 0", - Balance{"f", - "0.0000001", "0.0000000", "BNB"}, - false, - }, - {"Empty others are not 0", - Balance{"", - "0.00000001", "0.00000001", "BNB"}, - false, - }, - {"Empty others are 0", - Balance{"", - "0.00000000", "0.00000000", "BNB"}, - false, - }, - {"Big", - Balance{"9999999999999999999999999999999999999999999999999999999999999999999999999999999999" + - "9999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999" + - "9999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999" + - "9999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999" + - "9999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999" + - "9999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999" + - "9999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999" + - "9999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999" + - "9999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999" + - "9999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999" + - "9999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999" + - "9999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999" + - "9999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999" + - "9999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999" + - "9999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999" + - "9999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999" + - "9999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999" + - "99999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999", - "0.00000000", "0.00000000", "BNB"}, - false, - }, + {"1", TokenBalance{"0.00000000", "0.00000000", "0.00000000", "BNB"}, true}, + {"2", TokenBalance{"0.00000000", "0", "0.00000001", "BNB"}, false}, + {"3", TokenBalance{"0.00000000", "0.00000001", "0.00000000", "BNB"}, false}, + {"4", TokenBalance{"0.00000000", "0.00000001", "0.00000001", "BNB"}, false}, + {"5", TokenBalance{"0.00000001", "0.00000000", "0.00000000", "BNB"}, false}, + {"6", TokenBalance{"0.00000001", "0.00000000", "0.00000001", "BNB"}, false}, + {"7", TokenBalance{"0.00000001", "0.00000001", "0.00000000", "BNB"}, false}, + {"8", TokenBalance{"0.00000001", "0.00000001", "0.00000001", "BNB"}, false}, + {"Negative", TokenBalance{"-0.00000001", "0.00000001", "0.00000001", "BNB"}, false}, + {"Bad others are 0", TokenBalance{"f", "0.0000000", "0.0000000", "BNB"}, false}, + {"Bad others are not 0", TokenBalance{"f", "0.0000001", "0.0000000", "BNB"}, false}, + {"Empty others are not 0", TokenBalance{"", "0.00000001", "0.00000001", "BNB"}, false}, + {"Empty others are 0", TokenBalance{"", "0.00000000", "0.00000000", "BNB"}, false}, + {"Big", TokenBalance{"9999999999999999999999999999999999999999999999999999999999999999999999999999999999" + + "9999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999", "0.00000000", "0.00000000", "BNB"}, false}, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { diff --git a/platform/binance/stake.go b/platform/binance/stake.go new file mode 100644 index 000000000..512066694 --- /dev/null +++ b/platform/binance/stake.go @@ -0,0 +1,79 @@ +package binance + +import ( + "github.com/trustwallet/blockatlas/pkg/blockatlas" + "github.com/trustwallet/blockatlas/platform/binance/staking" + "github.com/trustwallet/blockatlas/services/assets" +) + +const ( + lockTime = 604800 // 7 days + minimumAmount = "100000000" // 1 BNB +) + +func (p *Platform) GetActiveValidators() (blockatlas.StakeValidators, error) { + return blockatlas.StakeValidators{}, nil +} + +func (p *Platform) GetValidators() (blockatlas.ValidatorPage, error) { + validators, err := p.stakingClient.GetValidators() + if err != nil { + return nil, err + } + + assetsValidators, err := assets.GetValidatorsInfo(p.Coin()) + if err != nil { + return nil, err + } + + assetsMap := assetsValidators.ToMap() + result := make(blockatlas.ValidatorPage, 0) + + for _, validator := range validators.Validators { + // filter trusted + if _, ok := assetsMap[validator.Validator]; !ok { + continue + } + // filter inactive + if validator.Status != 0 { + continue + } + result = append(result, normalizeValidator(validator)) + } + return result, nil +} + +func (p *Platform) GetDetails() blockatlas.StakingDetails { + apr := blockatlas.DefaultAnnualReward + validators, err := p.GetValidators() + if err == nil { + apr = blockatlas.FindHightestAPR(validators) + } + return blockatlas.StakingDetails{ + Reward: blockatlas.StakingReward{Annual: apr * 100}, + MinimumAmount: minimumAmount, + LockTime: lockTime, + Type: blockatlas.DelegationTypeDelegate, + } +} + +func (p *Platform) UndelegatedBalance(address string) (string, error) { + return "0", nil +} + +func (p *Platform) GetDelegations(address string) (blockatlas.DelegationsPage, error) { + return blockatlas.DelegationsPage{}, nil +} + +func normalizeValidator(v staking.Validator) blockatlas.Validator { + return blockatlas.Validator{ + Status: v.Status == 0, + ID: v.Validator, + Details: blockatlas.StakingDetails{ + Reward: blockatlas.StakingReward{Annual: v.APR}, + MinimumAmount: minimumAmount, + LockTime: lockTime, + Type: blockatlas.DelegationTypeDelegate, + }, + } +} diff --git a/platform/binance/staking/client.go b/platform/binance/staking/client.go new file mode 100644 index 000000000..9ec27ea0e --- /dev/null +++ b/platform/binance/staking/client.go @@ -0,0 +1,26 @@ +package staking + +import ( + "net/url" + + "github.com/trustwallet/golibs/client" + "github.com/trustwallet/golibs/network/middleware" +) + +type Client struct { + client.Request +} + +func InitClient(url string) Client { + c := Client{client.InitClient(url, middleware.SentryErrorHandler)} + return c +} + +func (c *Client) GetValidators() (validators Validators, err error) { + params := url.Values{ + "limit": {"100"}, + "offset": {"0"}, + } + err = c.Get(&validators, "/v1/staking/chains/bsc/validators", params) + return +} diff --git a/platform/binance/staking/model.go b/platform/binance/staking/model.go new file mode 100644 index 000000000..9df34a956 --- /dev/null +++ b/platform/binance/staking/model.go @@ -0,0 +1,12 @@ +package staking + +type Validators struct { + Total int `json:"total"` + Validators []Validator `json:"validators"` +} + +type Validator struct { + Validator string `json:"validator"` + Status int `json:"status"` + APR float64 `json:"apr"` +} diff --git a/platform/binance/token.go b/platform/binance/token.go new file mode 100644 index 000000000..4ae4ac7f2 --- /dev/null +++ b/platform/binance/token.go @@ -0,0 +1,25 @@ +package binance + +import ( + "github.com/trustwallet/golibs/types" +) + +func (p *Platform) GetTokenListByAddress(address string) ([]types.Token, error) { + account, err := p.client.FetchAccountMeta(address) + if err != nil || len(account.Balances) == 0 { + return nil, nil + } + tokens, err := p.client.FetchTokens() + if err != nil { + return nil, err + } + return normalizeTokens(account.Balances, tokens), nil +} + +func (p *Platform) GetTokenListIdsByAddress(address string) ([]string, error) { + assets, err := p.GetTokenListByAddress(address) + if err != nil { + return []string{}, err + } + return types.GetAssetsIds(assets), nil +} diff --git a/platform/binance/token_test.go b/platform/binance/token_test.go new file mode 100644 index 000000000..005997b4b --- /dev/null +++ b/platform/binance/token_test.go @@ -0,0 +1,33 @@ +package binance + +import ( + "encoding/json" + "net/http/httptest" + "testing" + + "github.com/stretchr/testify/assert" +) + +func TestPlatform_GetTokenListByAddress(t *testing.T) { + server := httptest.NewServer(createMockedAPI()) + defer server.Close() + p := Init(server.URL, "", "") + + tokens, err := p.GetTokenListByAddress("bnb1w7puzjxu05ktc5zvpnzkndt6tyl720nsutzvpg") + assert.Nil(t, err) + res, err := json.Marshal(tokens) + assert.Nil(t, err) + assert.JSONEq(t, wantedTokens, string(res)) + + tokens, err = p.GetTokenListByAddress("bnb1w7puzjxu05ktc5zvpnzkndt6tyl720nsutzvpg") + assert.Nil(t, err) + res, err = json.Marshal(tokens) + assert.Nil(t, err) + assert.JSONEq(t, wantedTokens, string(res)) + + tokens, err = p.GetTokenListByAddress("bnb1w7puzjxu05ktc5zvpnzkndt6tyl720nsutzvpg") + assert.Nil(t, err) + res, err = json.Marshal(tokens) + assert.Nil(t, err) + assert.JSONEq(t, wantedTokens, string(res)) +} diff --git a/platform/binance/transaction.go b/platform/binance/transaction.go new file mode 100644 index 000000000..1f80983ca --- /dev/null +++ b/platform/binance/transaction.go @@ -0,0 +1,22 @@ +package binance + +import ( + "github.com/trustwallet/golibs/coin" + "github.com/trustwallet/golibs/types" +) + +func (p *Platform) GetTxsByAddress(address string) (types.Txs, error) { + txsFromClient, err := p.client.FetchTransactionsByAddressAndTokenID(address, coin.Binance().Symbol) + if err != nil { + return nil, err + } + return normalizeTransactions(txsFromClient), nil +} + +func (p *Platform) GetTokenTxsByAddress(address, token string) (types.Txs, error) { + txsFromClient, err := p.client.FetchTransactionsByAddressAndTokenID(address, token) + if err != nil { + return nil, err + } + return normalizeTransactions(txsFromClient), nil +} diff --git a/platform/binance/transaction_test.go b/platform/binance/transaction_test.go new file mode 100644 index 000000000..ffd81a49a --- /dev/null +++ b/platform/binance/transaction_test.go @@ -0,0 +1,31 @@ +package binance + +import ( + "encoding/json" + "net/http/httptest" + "testing" + + "github.com/stretchr/testify/assert" +) + +func TestPlatform_GetTxsByAddress(t *testing.T) { + server := httptest.NewServer(createMockedAPI()) + defer server.Close() + p := Init(server.URL, "", "") + txs, err := p.GetTxsByAddress("bnb136ns6lfw4zs5hg4n85vdthaad7hq5m4gtkgf23") + assert.Nil(t, err) + res, err := json.Marshal(txs) + assert.Nil(t, err) + assert.JSONEq(t, wantedTxs, string(res)) +} + +func TestPlatform_GetTokenTxsByAddress(t *testing.T) { + server := httptest.NewServer(createMockedAPI()) + defer server.Close() + p := Init(server.URL, "", "") + txs, err := p.GetTokenTxsByAddress("bnb1w7puzjxu05ktc5zvpnzkndt6tyl720nsutzvpg", "AVA-645") + assert.Nil(t, err) + res, err := json.Marshal(txs) + assert.Nil(t, err) + assert.Len(t, res, 2) +} diff --git a/platform/bitcoin/api.go b/platform/bitcoin/api.go deleted file mode 100644 index 5eb468b39..000000000 --- a/platform/bitcoin/api.go +++ /dev/null @@ -1,295 +0,0 @@ -package bitcoin - -import ( - "fmt" - mapset "github.com/deckarep/golang-set" - "github.com/gin-gonic/gin" - "github.com/spf13/viper" - "github.com/trustwallet/blockatlas/coin" - "github.com/trustwallet/blockatlas/pkg/blockatlas" - "github.com/trustwallet/blockatlas/pkg/logger" - "github.com/trustwallet/blockatlas/pkg/numbers" - "net/http" - "sync" -) - -type Platform struct { - client Client - CoinIndex uint -} - -func (p *Platform) Init() error { - p.client = Client{blockatlas.InitClient(viper.GetString(p.ConfigKey()))} - return nil -} - -func (p *Platform) Coin() coin.Coin { - return coin.Coins[p.CoinIndex] -} - -func (p *Platform) ConfigKey() string { - return fmt.Sprintf("%s.api", p.Coin().Handle) -} - -// @Summary Get xpub transactions -// @ID xpub -// @Description Get transactions from xpub address -// @Accept json -// @Produce json -// @Tags platform,tx -// @Param coin path string true "the coin name" default(bitcoin) -// @Param xpub path string true "the xpub address" default(zpub6ruK9k6YGm8BRHWvTiQcrEPnFkuRDJhR7mPYzV2LDvjpLa5CuGgrhCYVZjMGcLcFqv9b2WvsFtY2Gb3xq8NVq8qhk9veozrA2W9QaWtihrC) -// @Success 200 {object} blockatlas.TxPage -// @Router /v1/{coin}/xpub/{xpub} [get] -func (p *Platform) RegisterRoutes(router gin.IRouter) { - router.GET("/xpub/:key", func(c *gin.Context) { - p.handleXpubRoute(c) - }) - router.GET("/address/:address", func(c *gin.Context) { - p.handleAddressRoute(c) - }) -} - -func (p *Platform) handleAddressRoute(c *gin.Context) { - address := c.Param("address") - txs, ok := p.getTxsByAddress(address) - txPage := blockatlas.TxPage(txs) - txPage.Sort() - if ok != nil { - c.JSON(http.StatusInternalServerError, ok) - return - } - c.JSON(http.StatusOK, &txPage) -} - -func (p *Platform) handleXpubRoute(c *gin.Context) { - xpub := c.Param("key") - txs, ok := p.getTxsByXPub(xpub) - txPage := blockatlas.TxPage(txs) - txPage.Sort() - if ok != nil { - c.JSON(http.StatusInternalServerError, ok) - return - } - c.JSON(http.StatusOK, &txPage) -} - -func (p *Platform) getTxsByXPub(xpub string) ([]blockatlas.Tx, error) { - sourceTxs, err := p.client.GetTransactionsByXpub(xpub) - - if err != nil { - return []blockatlas.Tx{}, err - } - - addressSet := mapset.NewSet() - for _, token := range sourceTxs.Tokens { - addressSet.Add(token.Name) - } - - txs := normalizeTxs(sourceTxs, p.CoinIndex, addressSet) - return txs, nil -} - -func (p *Platform) getTxsByAddress(address string) ([]blockatlas.Tx, error) { - sourceTxs, err := p.client.GetTransactions(address) - if err != nil { - return []blockatlas.Tx{}, err - } - addressSet := mapset.NewSet() - addressSet.Add(address) - txs := normalizeTxs(sourceTxs, p.CoinIndex, addressSet) - return txs, nil -} - -func (p *Platform) GetAddressesFromXpub(xpub string) ([]string, error) { - tokens, err := p.client.GetAddressesFromXpub(xpub) - addresses := make([]string, 0) - for _, token := range tokens { - addresses = append(addresses, token.Name) - } - return addresses, err -} - -func (p *Platform) CurrentBlockNumber() (int64, error) { - status, err := p.client.GetBlockNumber() - return status.Backend.Blocks, err -} - -func (p *Platform) GetAllBlockPages(total, num int64) []Transaction { - start := int64(1) - var wg sync.WaitGroup - out := make(chan TransactionsList) - for start < total { - wg.Add(1) - start++ - go func(page, num int64, out chan TransactionsList) { - defer wg.Done() - block, err := p.client.GetTransactionsByBlock(num, page) - if err != nil { - logger.Error("GetTransactionsByBlockChan", err, logger.Params{"number": num, "page": page}) - return - } - out <- block - }(start, num, out) - } - go func() { - wg.Wait() - close(out) - }() - txs := make([]Transaction, 0) - for r := range out { - txs = append(txs, r.TransactionList()...) - } - return txs -} - -func (p *Platform) GetBlockByNumber(num int64) (*blockatlas.Block, error) { - page := int64(1) - block, err := p.client.GetTransactionsByBlock(num, page) - if err != nil { - return nil, err - } - txPages := p.GetAllBlockPages(block.TotalPages, num) - txs := append(txPages, block.TransactionList()...) - var normalized []blockatlas.Tx - for _, tx := range txs { - normalized = append(normalized, normalizeTransaction(tx, p.CoinIndex)) - } - return &blockatlas.Block{ - Number: num, - ID: block.Hash, - Txs: normalized, - }, nil -} - -func normalizeTxs(sourceTxs TransactionsList, coinIndex uint, addressSet mapset.Set) []blockatlas.Tx { - var txs []blockatlas.Tx - for _, transaction := range sourceTxs.TransactionList() { - if tx, ok := normalizeTransfer(transaction, coinIndex, addressSet); ok { - txs = append(txs, tx) - } - } - return txs -} - -func normalizeTransaction(tx Transaction, coinIndex uint) blockatlas.Tx { - inputs := parseOutputs(tx.Vin) - outputs := parseOutputs(tx.Vout) - from := "" - if len(inputs) > 0 { - from = inputs[0].Address - } - - to := "" - if len(outputs) > 0 { - to = outputs[0].Address - } - amount := blockatlas.Amount(tx.Amount()) - fees := blockatlas.Amount(numbers.GetAmountValue(tx.Fees)) - - return blockatlas.Tx{ - ID: tx.ID, - Coin: coinIndex, - From: from, - To: to, - Inputs: inputs, - Outputs: outputs, - Fee: fees, - Date: int64(tx.BlockTime), - Type: blockatlas.TxTransfer, - Block: tx.GetBlockHeight(), - Status: tx.getStatus(), - Sequence: 0, - Meta: blockatlas.Transfer{ - Value: amount, - Symbol: coin.Coins[coinIndex].Symbol, - Decimals: coin.Coins[coinIndex].Decimals, - }, - } -} - -func normalizeTransfer(transaction Transaction, coinIndex uint, addressSet mapset.Set) (tx blockatlas.Tx, ok bool) { - tx = normalizeTransaction(transaction, coinIndex) - direction := InferDirection(&tx, addressSet) - value := InferValue(&tx, direction, addressSet) - - tx.Direction = direction - tx.Meta = blockatlas.Transfer{ - Value: value, - Symbol: coin.Coins[coinIndex].Symbol, - Decimals: coin.Coins[coinIndex].Decimals, - } - - return tx, true -} - -func parseOutputs(outputs []Output) (addresses []blockatlas.TxOutput) { - set := make(map[string]blockatlas.TxOutput) - var ordered []string - for _, output := range outputs { - for _, address := range output.OutputAddress() { - if val, ok := set[address]; ok { - value := numbers.AddAmount(string(val.Value), output.Value) - val.Value = blockatlas.Amount(value) - } else { - amount := numbers.GetAmountValue(output.Value) - set[address] = blockatlas.TxOutput{ - Address: address, - Value: blockatlas.Amount(amount), - } - ordered = append(ordered, address) - } - } - } - for _, val := range ordered { - addresses = append(addresses, set[val]) - } - return addresses -} - -func InferDirection(tx *blockatlas.Tx, addressSet mapset.Set) blockatlas.Direction { - inputSet := mapset.NewSet() - for _, address := range tx.Inputs { - inputSet.Add(address.Address) - } - outputSet := mapset.NewSet() - for _, address := range tx.Outputs { - outputSet.Add(address.Address) - } - intersect := addressSet.Intersect(inputSet) - if intersect.Cardinality() == 0 { - return blockatlas.DirectionIncoming - } - if outputSet.IsProperSubset(addressSet) || outputSet.Equal(inputSet) { - return blockatlas.DirectionSelf - } - return blockatlas.DirectionOutgoing -} - -func InferValue(tx *blockatlas.Tx, direction blockatlas.Direction, addressSet mapset.Set) blockatlas.Amount { - value := blockatlas.Amount("0") - if len(tx.Outputs) == 0 { - return value - } - if direction == blockatlas.DirectionOutgoing || direction == blockatlas.DirectionSelf { - value = tx.Outputs[0].Value - } else if direction == blockatlas.DirectionIncoming { - amount := value - for _, output := range tx.Outputs { - if !addressSet.Contains(output.Address) { - continue - } - value := numbers.AddAmount(string(amount), string(output.Value)) - amount = blockatlas.Amount(value) - } - value = amount - } - return value -} - -func (transaction *Transaction) getStatus() blockatlas.Status { - if transaction.Confirmations == 0 { - return blockatlas.StatusPending - } - return blockatlas.StatusCompleted -} diff --git a/platform/bitcoin/api_test.go b/platform/bitcoin/api_test.go deleted file mode 100644 index a05badbe5..000000000 --- a/platform/bitcoin/api_test.go +++ /dev/null @@ -1,349 +0,0 @@ -package bitcoin - -import ( - "bytes" - "encoding/json" - "github.com/stretchr/testify/assert" - "github.com/trustwallet/blockatlas/pkg/blockatlas" - "testing" - - mapset "github.com/deckarep/golang-set" - "github.com/trustwallet/blockatlas/coin" -) - -const outgoingTx = `{ - "txid":"df63ddab7d4eed2fb6cb40d4d0519e7e5ac7cf5ad556b2edbd45963ea1a2931c", - "version":1, - "vin":[ - { - "txid":"bf19be44d7dc3e1e6771801a1d250c7207fa9b09d8df9b0ee1b028b6c153475e", - "sequence":4294967295, - "n":0, - "addresses":[ - "3QJmV3qfvL9SuYo34YihAf3sRCW3qSinyC" - ], - "value":"777200", - "hex":"00483045022100e9d0db3bb20a5828ab9dae7cd8373064ce087cc9c8e3def87034d5c2f6f3abb9022047d7c27b355c6487cff40bfbd45742d26d727f3135b2396d8f1abc371c51870c01473044022016280108af73079a69f378218ad4259f02c4e4b6f52c573729650cb3645bc9180220785973cb4e5c4ec6340dc77dc56cec3fb74ebd7296cf1d14344d4f3e157658bb014cc952410491bba2510912a5bd37da1fb5b1673010e43d2c6d812c514e91bfa9f2eb129e1c183329db55bd868e209aac2fbc02cb33d98fe74bf23f0c235d6126b1d8334f864104865c40293a680cb9c020e7b1e106d8c1916d3cef99aa431a56d253e69256dac09ef122b1a986818a7cb624532f062c1d1f8722084861c5c3291ccffef4ec687441048d2455d2403e08708fc1f556002f1b6cd83f992d085097f9974ab08a28838f07896fbab08f39495e15fa6fad6edbfb1e754e35fa1c7844c41f322a1863d4621353ae"} - ], - "vout":[ - { - "value":"677012", - "n":0, - "hex":"a91499fa965ad13a9580ed7a64ac24b2ecad30f1209a87", - "addresses":["3FjBW1KL9L8aYtdKzJ8FhCNxmXB7dXDRw4"] - } - ], - "blockHash":"00000000000000000011b58c01ede5a602eec61ebaf097aaa6e682ef2819536e", - "blockHeight":585094, - "confirmations":1997, - "blockTime":1562945790, - "value":"677012", - "valueIn":"777200", - "fees":"100188", - "hex":"01000000015e4753c1b628b0e10e9bdfd8099bfa07720c251d1a8071671e3edcd744be19bf00000000fd5d0100483045022100e9d0db3bb20a5828ab9dae7cd8373064ce087cc9c8e3def87034d5c2f6f3abb9022047d7c27b355c6487cff40bfbd45742d26d727f3135b2396d8f1abc371c51870c01473044022016280108af73079a69f378218ad4259f02c4e4b6f52c573729650cb3645bc9180220785973cb4e5c4ec6340dc77dc56cec3fb74ebd7296cf1d14344d4f3e157658bb014cc952410491bba2510912a5bd37da1fb5b1673010e43d2c6d812c514e91bfa9f2eb129e1c183329db55bd868e209aac2fbc02cb33d98fe74bf23f0c235d6126b1d8334f864104865c40293a680cb9c020e7b1e106d8c1916d3cef99aa431a56d253e69256dac09ef122b1a986818a7cb624532f062c1d1f8722084861c5c3291ccffef4ec687441048d2455d2403e08708fc1f556002f1b6cd83f992d085097f9974ab08a28838f07896fbab08f39495e15fa6fad6edbfb1e754e35fa1c7844c41f322a1863d4621353aeffffffff0194540a000000000017a91499fa965ad13a9580ed7a64ac24b2ecad30f1209a8700000000" -}` - -const incomingTx = `{ - "txid": "a2d70bee124510c476f159fa83cdb34d663fc6020c81aad19b238601d679fed7", - "version": 4, - "vin": [{ - "txid": "5a3664328ac4e1c0688729573296c2ec69dd9a7cf98d49967b41520be794229b", - "n": 0, - "addresses": ["t1T7cLkvDVScjw95WguoAZbbT8mrdqVtpiD"], - "isAddress": true, - "value": "387582", - "hex": "483045022100ec29a476dac49578339a92e6c20451aaf3ff6691efaf7d4d3113d07589771ca702203c0c173bdc356300edbd64cdfaa868b97c13ebc403026b283eb5e1fca398db8b012103729cc4211cf70f87c70c3cef90e0ca9b91e99b42364b8c600d5781277647de5f" - }], - "vout": [{ - "value": "200997", - "n": 0, - "spent": true, - "hex": "76a9146fd73e7c147d8ccc15fda31d8429e70f302b843988ac", - "addresses": ["t1U4xs3qMxc2TL8wwYufmBngA5mewLHRwhM"], - "isAddress": true - }, { - "value": "186359", - "n": 1, - "spent": true, - "hex": "76a91484f0258cb7974993e6af928921b7f699c51a309488ac", - "addresses": ["t1VzWtLj9CSAK3QnxA7uuiK6XhJrjGjKoy4"], - "isAddress": true - }], - "blockHash": "0000000000a8248c4a14a2dcb74d92855bf9440da9b7b1e6d4baa14ee7e3081c", - "blockHeight": 479017, - "confirmations": 116233, - "blockTime": 1549793065, - "value": "387356", - "valueIn": "387582", - "fees": "226", - "hex": "0400008085202f89019b2294e70b52417b96498df97c9add69ecc2963257298768c0e1c48a3264365a000000006b483045022100ec29a476dac49578339a92e6c20451aaf3ff6691efaf7d4d3113d07589771ca702203c0c173bdc356300edbd64cdfaa868b97c13ebc403026b283eb5e1fca398db8b012103729cc4211cf70f87c70c3cef90e0ca9b91e99b42364b8c600d5781277647de5f000000000225110300000000001976a9146fd73e7c147d8ccc15fda31d8429e70f302b843988acf7d70200000000001976a91484f0258cb7974993e6af928921b7f699c51a309488ac00000000000000000000000000000000000000" -}` - -const pendingTx = `{ - "txid": "a2d70bee124510c476f159fa83cdb34d663fc6020c81aad19b238601d679fed7", - "version": 4, - "vin": [{ - "txid": "5a3664328ac4e1c0688729573296c2ec69dd9a7cf98d49967b41520be794229b", - "n": 0, - "addresses": ["t1T7cLkvDVScjw95WguoAZbbT8mrdqVtpiD"], - "isAddress": true, - "value": "387582", - "hex": "483045022100ec29a476dac49578339a92e6c20451aaf3ff6691efaf7d4d3113d07589771ca702203c0c173bdc356300edbd64cdfaa868b97c13ebc403026b283eb5e1fca398db8b012103729cc4211cf70f87c70c3cef90e0ca9b91e99b42364b8c600d5781277647de5f" - }], - "vout": [{ - "value": "200997", - "n": 0, - "spent": true, - "hex": "76a9146fd73e7c147d8ccc15fda31d8429e70f302b843988ac", - "addresses": ["t1U4xs3qMxc2TL8wwYufmBngA5mewLHRwhM"], - "isAddress": true - }, { - "value": "186359", - "n": 1, - "spent": true, - "hex": "76a91484f0258cb7974993e6af928921b7f699c51a309488ac", - "addresses": ["t1VzWtLj9CSAK3QnxA7uuiK6XhJrjGjKoy4"], - "isAddress": true - }], - "blockHash": "0000000000a8248c4a14a2dcb74d92855bf9440da9b7b1e6d4baa14ee7e3081c", - "blockHeight": -1, - "confirmations": 116233, - "blockTime": 1549793065, - "value": "387356", - "valueIn": "387582", - "fees": "226", - "hex": "0400008085202f89019b2294e70b52417b96498df97c9add69ecc2963257298768c0e1c48a3264365a000000006b483045022100ec29a476dac49578339a92e6c20451aaf3ff6691efaf7d4d3113d07589771ca702203c0c173bdc356300edbd64cdfaa868b97c13ebc403026b283eb5e1fca398db8b012103729cc4211cf70f87c70c3cef90e0ca9b91e99b42364b8c600d5781277647de5f000000000225110300000000001976a9146fd73e7c147d8ccc15fda31d8429e70f302b843988acf7d70200000000001976a91484f0258cb7974993e6af928921b7f699c51a309488ac00000000000000000000000000000000000000" -}` - -var expectedOutgoingTx = blockatlas.Tx{ - ID: "df63ddab7d4eed2fb6cb40d4d0519e7e5ac7cf5ad556b2edbd45963ea1a2931c", - Coin: coin.BTC, - From: "3QJmV3qfvL9SuYo34YihAf3sRCW3qSinyC", - To: "3FjBW1KL9L8aYtdKzJ8FhCNxmXB7dXDRw4", - Inputs: []blockatlas.TxOutput{ - { - Address: "3QJmV3qfvL9SuYo34YihAf3sRCW3qSinyC", - Value: "777200", - }, - }, - Outputs: []blockatlas.TxOutput{ - { - Address: "3FjBW1KL9L8aYtdKzJ8FhCNxmXB7dXDRw4", - Value: "677012", - }, - }, - Fee: "100188", - Date: 1562945790, - Type: "transfer", - Status: blockatlas.StatusCompleted, - Block: 585094, - Sequence: 0, - Direction: blockatlas.DirectionSelf, - Meta: blockatlas.Transfer{ - Value: "677012", - Symbol: "BTC", - Decimals: 8, - }, -} - -var expectedIncomingTx = blockatlas.Tx{ - ID: "a2d70bee124510c476f159fa83cdb34d663fc6020c81aad19b238601d679fed7", - Coin: coin.ZEC, - From: "t1T7cLkvDVScjw95WguoAZbbT8mrdqVtpiD", - To: "t1U4xs3qMxc2TL8wwYufmBngA5mewLHRwhM", - Inputs: []blockatlas.TxOutput{ - { - Address: "t1T7cLkvDVScjw95WguoAZbbT8mrdqVtpiD", - Value: "387582", - }, - }, - Outputs: []blockatlas.TxOutput{ - { - Address: "t1U4xs3qMxc2TL8wwYufmBngA5mewLHRwhM", - Value: "200997", - }, - { - Address: "t1VzWtLj9CSAK3QnxA7uuiK6XhJrjGjKoy4", - Value: "186359", - }, - }, - Fee: "226", - Date: 1549793065, - Type: "transfer", - Status: blockatlas.StatusCompleted, - Block: 479017, - Sequence: 0, - Direction: blockatlas.DirectionIncoming, - Meta: blockatlas.Transfer{ - Value: "200997", - Symbol: "ZEC", - Decimals: 8, - }, -} - -var expectedPendingTx = blockatlas.Tx{ - ID: "a2d70bee124510c476f159fa83cdb34d663fc6020c81aad19b238601d679fed7", - Coin: coin.ZEC, - From: "t1T7cLkvDVScjw95WguoAZbbT8mrdqVtpiD", - To: "t1U4xs3qMxc2TL8wwYufmBngA5mewLHRwhM", - Inputs: []blockatlas.TxOutput{ - { - Address: "t1T7cLkvDVScjw95WguoAZbbT8mrdqVtpiD", - Value: "387582", - }, - }, - Outputs: []blockatlas.TxOutput{ - { - Address: "t1U4xs3qMxc2TL8wwYufmBngA5mewLHRwhM", - Value: "200997", - }, - { - Address: "t1VzWtLj9CSAK3QnxA7uuiK6XhJrjGjKoy4", - Value: "186359", - }, - }, - Fee: "226", - Date: 1549793065, - Type: "transfer", - Status: blockatlas.StatusCompleted, - Block: 0, - Sequence: 0, - Direction: blockatlas.DirectionIncoming, - Meta: blockatlas.Transfer{ - Value: "200997", - Symbol: "ZEC", - Decimals: 8, - }, -} - -func TestNormalizeTransfer(t *testing.T) { - - outgoingTxSet := mapset.NewSet() - outgoingTxSet.Add("3FjBW1KL9L8aYtdKzJ8FhCNxmXB7dXDRw4") - outgoingTxSet.Add("3QJmV3qfvL9SuYo34YihAf3sRCW3qSinyC") - - incomingTxSet := mapset.NewSet() - incomingTxSet.Add("t1U4xs3qMxc2TL8wwYufmBngA5mewLHRwhM") - incomingTxSet.Add("t1ZBs9xvRypkjXmci2SS6zbNWVhuWH1h93L") - incomingTxSet.Add("t1VZp67AK9zgdXwa35kwYrJ1Mh4NWjUENrM") - - var tests = []struct { - RawTx string - Expected blockatlas.Tx - AddressSet mapset.Set - }{ - {outgoingTx, expectedOutgoingTx, outgoingTxSet}, - {incomingTx, expectedIncomingTx, incomingTxSet}, - {pendingTx, expectedPendingTx, incomingTxSet}, - } - - for _, test := range tests { - var transaction Transaction - - rErr := json.Unmarshal([]byte(test.RawTx), &transaction) - if rErr != nil { - t.Fatal(rErr) - } - - var readyTx blockatlas.Tx - normTx, ok := normalizeTransfer(transaction, test.Expected.Coin, test.AddressSet) - if !ok { - t.Fatal("Bitcoin: Can't normalize transaction", readyTx) - } - readyTx = normTx - - actual, err := json.Marshal(&readyTx) - if err != nil { - t.Fatal(err) - } - - expected, err := json.Marshal(&test.Expected) - if err != nil { - t.Fatal(err) - } - - if !bytes.Equal(actual, expected) { - println(string(actual)) - println(string(expected)) - t.Error("Transactions not equal") - } - } -} - -// zpub: zpub6r9CEhEkruYbEcu2yQCaRKQ1qufTa4zLrx6ezs31P627UpAepVNBE2td3d3mHnSaXyRbwksRwDJGzLBWQeZPFMut8N3BvXpcwRwEWGEwAnq -var btcSet = mapset.NewSet("bc1qfrrncxmf7skye2glyef95xlpmrlmf2e8qlav2l", "bc1qxm90n0rxkadhdkvglev56k60qths73luzlnn7a", - "bc1q2sykr9c342mjpm9mwnps8ksk6e35lz75rpdlfe", "bc1qs86ucvr3unce2grvfp77433npy66nzha9w0e3c") -var btcInputs1 = []blockatlas.TxOutput{{Address: "bc1q2sykr9c342mjpm9mwnps8ksk6e35lz75rpdlfe"}} -var btcOutputs1 = []blockatlas.TxOutput{{Address: "bc1q6wf7tj62f0uwr6almah3666th2ejefdg72ek6t"}} -var btcInputs2 = []blockatlas.TxOutput{{ - Address: "3CgvDkzcJ7yMZe75jNBem6Bj6nkMAWwMEf"}, - {Address: "3LyzYcB54pm9EAMmzXpFfb1kzEDAFvqBgT"}, - {Address: "3Q6DYour5q5WdMhyXsyPgBeAqPCXchzCsF"}, - {Address: "3JZZM1rwst7G5izxbFL7KNvy7ZiZ47SVqG"}} -var btcOutputs2 = []blockatlas.TxOutput{ - {Address: "139f1CrnLWvVajGzs3ZtpQhbGWxM599sho"}, - {Address: "3LyzYcB54pm9EAMmzXpFfb1kzEDAFvqBgT"}, - {Address: "bc1q9mx5tm66zs7epa4skvyuf2vfuwmtnlttj74cnl"}, - {Address: "3JZZM1rwst7G5izxbFL7KNvy7ZiZ47SVqG"}} - -var dogeSet = mapset.NewSet("DB49sNjVdxyREXEBEzUV54TrQYYpvi3Be7") -var dogeInputs = []blockatlas.TxOutput{{Address: "DAukM5pPtGdbPxMX1u2LYHoyhbDhEFHbnH"}} -var dogeOutputs = []blockatlas.TxOutput{{Address: "DB49sNjVdxyREXEBEzUV54TrQYYpvi3Be7"}, {Address: "DAukM5pPtGdbPxMX1u2LYHoyhbDhEFHbnH"}} - -func TestInferDirection(t *testing.T) { - var tests = []struct { - AddressSet mapset.Set - Inputs []blockatlas.TxOutput - Outputs []blockatlas.TxOutput - Expected blockatlas.Direction - Coin uint - }{ - { - btcSet, - btcInputs1, - btcOutputs1, - blockatlas.DirectionOutgoing, - coin.BTC, - }, - { - btcSet, - btcInputs2, - btcOutputs2, - blockatlas.DirectionIncoming, - coin.BTC, - }, - { - dogeSet, - dogeInputs, - dogeOutputs, - blockatlas.DirectionIncoming, - coin.DOGE, - }, - } - - for _, test := range tests { - tx := blockatlas.Tx{ - Inputs: test.Inputs, - Outputs: test.Outputs, - } - - direction := InferDirection(&tx, test.AddressSet) - if direction != test.Expected { - t.Errorf("direction is not %s", test.Expected) - } - } -} - -func TestTransactionStatus(t *testing.T) { - var tests = []struct { - Tx Transaction - Expected blockatlas.Status - }{ - {Transaction{Confirmations: 0}, blockatlas.StatusPending}, - {Transaction{Confirmations: 1}, blockatlas.StatusCompleted}, - } - - for _, test := range tests { - assert.Equal(t, test.Expected, test.Tx.getStatus()) - } -} diff --git a/platform/bitcoin/base.go b/platform/bitcoin/base.go new file mode 100644 index 000000000..15f0a281d --- /dev/null +++ b/platform/bitcoin/base.go @@ -0,0 +1,33 @@ +package bitcoin + +import ( + "github.com/trustwallet/blockatlas/platform/bitcoin/blockbook" + "github.com/trustwallet/golibs/client" + "github.com/trustwallet/golibs/coin" + "github.com/trustwallet/golibs/network/middleware" +) + +type Platform struct { + client blockbook.Client + CoinIndex uint +} + +func Init(coin uint, api string) *Platform { + return &Platform{ + CoinIndex: coin, + client: blockbook.Client{Request: client.InitClient(api, middleware.SentryErrorHandler)}, + } +} + +func (p *Platform) Coin() coin.Coin { + return coin.Coins[p.CoinIndex] +} + +func (p *Platform) GetAddressesFromXpub(xpub string) ([]string, error) { + tokens, err := p.client.GetAddressesFromXpub(xpub) + addresses := make([]string, 0) + for _, token := range tokens { + addresses = append(addresses, token.Name) + } + return addresses, err +} diff --git a/platform/bitcoin/block.go b/platform/bitcoin/block.go new file mode 100644 index 000000000..a0248781d --- /dev/null +++ b/platform/bitcoin/block.go @@ -0,0 +1,23 @@ +package bitcoin + +import "github.com/trustwallet/golibs/types" + +func (p *Platform) CurrentBlockNumber() (int64, error) { + return p.client.GetCurrentBlockNumber() +} + +func (p *Platform) GetBlockByNumber(num int64) (*types.Block, error) { + block, err := p.client.GetAllTransactionsByBlockNumber(num) + if err != nil { + return nil, err + } + var normalized types.Txs + for _, tx := range block { + normalized = append(normalized, normalizeTransaction(tx, p.CoinIndex)) + } + return &types.Block{ + Number: num, + Txs: normalized, + }, nil + +} diff --git a/platform/bitcoin/blockbook/block.go b/platform/bitcoin/blockbook/block.go new file mode 100644 index 000000000..0894469d4 --- /dev/null +++ b/platform/bitcoin/blockbook/block.go @@ -0,0 +1,30 @@ +package blockbook + +import ( + "strings" + + "github.com/trustwallet/golibs/types" +) + +const ( + transactionError = "Internal server error: GetTransaction 0x" +) + +func (c *Client) GetBlockByNumber(num int64, coinIndex uint) (*types.Block, error) { + block, err := c.GetAllTransactionsByBlockNumber(num) + if err != nil { + err2, ok := err.(*ClientError) + if ok && strings.HasPrefix(err2.Error(), transactionError) { + return &types.Block{Number: num, Txs: types.Txs{}}, nil + } + return nil, err + } + txs := make(types.Txs, 0) + for _, srcTx := range block { + txs = append(txs, normalizeTx(&srcTx, coinIndex)) + } + return &types.Block{ + Number: num, + Txs: txs, + }, nil +} diff --git a/platform/bitcoin/blockbook/client.go b/platform/bitcoin/blockbook/client.go new file mode 100644 index 000000000..7aa51aade --- /dev/null +++ b/platform/bitcoin/blockbook/client.go @@ -0,0 +1,151 @@ +package blockbook + +import ( + "encoding/json" + "errors" + "fmt" + "net/url" + "strconv" + "sync" + + "github.com/trustwallet/golibs/client" + "github.com/trustwallet/golibs/types" +) + +type Client struct { + client.Request +} + +type ClientError struct { + Err string `json:"error"` +} + +func (c *ClientError) Error() string { + return c.Err +} + +// Block + +func (c *Client) GetCurrentBlockNumber() (int64, error) { + var nodeInfo NodeInfo + err := c.Get(&nodeInfo, "api/v2", nil) + if err != nil { + return 0, err + } + // If not in sync, latest block might not be available yet. + if !nodeInfo.Blockbook.InSync { + return 0, errors.New("not in sync to get current block number") + } + + return nodeInfo.Blockbook.BestHeight, nil +} + +// Tokens + +func (c *Client) GetTokens(address string) ([]Token, error) { + var res TransactionsList + path := fmt.Sprintf("api/v2/address/%s", address) + query := url.Values{"details": {"tokenBalances"}} + err := c.Get(&res, path, query) + return res.Tokens, err +} + +// Transactions +func (c *Client) GetAllTransactionsByBlockNumber(num int64) ([]Transaction, error) { + page := int64(1) + block, err := c.GetTransactionsByBlockNumber(num, page) + if err != nil { + httpError, ok := err.(*client.HttpError) + if ok { + var clientError ClientError + err2 := json.Unmarshal(httpError.Body, &clientError) + if err2 == nil { + return nil, &clientError + } + } + return nil, err + } + txPages := c.getAllBlockPages(block.TotalPages, num) + txs := append(txPages, block.TransactionList()...) + return txs, nil +} + +func (c *Client) GetTxs(address string) (TransactionsList, error) { + return c.getTransactionsForContract(address, "", types.TxPerPage) +} + +func (c *Client) GetTxsWithContract(address, contract string) (TransactionsList, error) { + return c.getTransactionsForContract(address, contract, types.TxPerPage) +} + +func (c *Client) GetTransactionsByBlockNumber(number int64, page int64) (block TransactionsList, err error) { + path := fmt.Sprintf("api/v2/block/%s", strconv.FormatInt(number, 10)) + args := url.Values{ + "page": {strconv.FormatInt(page, 10)}, + } + err = c.Get(&block, path, args) + return block, err +} + +func (c *Client) getTransactionsForContract(address, contract string, limit int) (transactions TransactionsList, err error) { + path := fmt.Sprintf("api/v2/address/%s", address) + err = c.Get(&transactions, path, url.Values{ + "page": {"1"}, + "details": {"txs"}, + "pageSize": {strconv.Itoa(limit)}, + "contract": {contract}, + }) + return transactions, err +} + +func (c *Client) GetTransactionsByXpub(xpub string) (transactions TransactionsList, err error) { + path := fmt.Sprintf("api/v2/xpub/%s", xpub) + args := url.Values{ + "pageSize": {strconv.Itoa(types.TxPerPage)}, + "details": {"txs"}, + "tokens": {"derived"}, + } + err = c.Get(&transactions, path, args) + return transactions, err +} + +func (c *Client) GetAddressesFromXpub(xpub string) (tokens []Token, err error) { + path := fmt.Sprintf("api/v2/xpub/%s", xpub) + args := url.Values{ + "pageSize": {strconv.Itoa(types.TxPerPage)}, + "details": {"txs"}, + "tokens": {"derived"}, + } + var transactions TransactionsList + err = c.Get(&transactions, path, args) + return transactions.Tokens, err +} + +func (c *Client) getAllBlockPages(total, num int64) []Transaction { + txs := make([]Transaction, 0) + if total <= 1 { + return txs + } + + start := int64(1) + var wg sync.WaitGroup + out := make(chan TransactionsList, int(total-start)) + wg.Add(int(total - start)) + for start < total { + start++ + go func(page, num int64, out chan TransactionsList, wg *sync.WaitGroup) { + defer wg.Done() + block, err := c.GetTransactionsByBlockNumber(num, page) + if err != nil { + return + } + out <- block + }(start, num, out, &wg) + } + wg.Wait() + close(out) + for r := range out { + txs = append(txs, r.TransactionList()...) + } + return txs +} diff --git a/platform/bitcoin/blockbook/mocks/blockbook_txs.json b/platform/bitcoin/blockbook/mocks/blockbook_txs.json new file mode 100644 index 000000000..e8053d5a0 --- /dev/null +++ b/platform/bitcoin/blockbook/mocks/blockbook_txs.json @@ -0,0 +1,218 @@ +{ + "transactions": [ + { + "txid": "0xb1a32935f9b015bcfdda1b2e3d281b3780d1a6f7a2d4406e05ec2b826b2349cb", + "vin": [ + { + "n": 0, + "addresses": ["0x7d8bf18C7cE84b3E175b339c4Ca93aEd1dD166F1"], + "isAddress": true + } + ], + "vout": [ + { + "value": "0", + "n": 0, + "addresses": ["0xc73e0383F3Aff3215E6f04B0331D58CeCf0Ab849"], + "isAddress": true + } + ], + "blockHash": "0x90d6b2e0fb0f983a15738206c8e9951db53624f5e9b29628fd8b71c5400430cb", + "blockHeight": 8958320, + "confirmations": 825021, + "blockTime": 1574107019, + "value": "0", + "fees": "227056700000000", + "tokenTransfers": [ + { + "type": "ERC20", + "from": "0x7d8bf18C7cE84b3E175b339c4Ca93aEd1dD166F1", + "to": "0xc73e0383F3Aff3215E6f04B0331D58CeCf0Ab849", + "token": "0x89d24A6b4CcB1B6fAA2625fE562bDD9a23260359", + "name": "Dai Stablecoin v1.0", + "symbol": "DAI", + "decimals": 18, + "value": "2255656573089233195" + }, + { + "type": "ERC20", + "from": "0xc73e0383F3Aff3215E6f04B0331D58CeCf0Ab849", + "to": "0xad37fd42185Ba63009177058208dd1be4b136e6b", + "token": "0x89d24A6b4CcB1B6fAA2625fE562bDD9a23260359", + "name": "Dai Stablecoin v1.0", + "symbol": "DAI", + "decimals": 18, + "value": "2255656573089233195" + }, + { + "type": "ERC20", + "from": "0x0000000000000000000000000000000000000000", + "to": "0x7d8bf18C7cE84b3E175b339c4Ca93aEd1dD166F1", + "token": "0x6B175474E89094C44Da98b954EedeAC495271d0F", + "name": "Dai Stablecoin", + "symbol": "DAI", + "decimals": 18, + "value": "2255656573089233195" + } + ], + "ethereumSpecific": { + "status": 1, + "nonce": 378, + "gasLimit": 3703313, + "gasUsed": 174659, + "gasPrice": "1300000000" + } + }, + { + "txid": "0x17bb2b5e61f34119d4d4fbfae406ad3d854f0a00f13013d77de9aab7179f183f", + "vin": [ + { + "n": 0, + "addresses": ["0x7d8bf18C7cE84b3E175b339c4Ca93aEd1dD166F1"], + "isAddress": true + } + ], + "vout": [ + { + "value": "0", + "n": 0, + "addresses": ["0x89d24A6b4CcB1B6fAA2625fE562bDD9a23260359"], + "isAddress": true + } + ], + "blockHash": "0xcee3a57858e3629785fb6e7ca34e68605fe3d2f149b73138f38314a3ef935723", + "blockHeight": 9852430, + "confirmations": 67071, + "blockTime": 1586627561, + "value": "0", + "fees": "87378000000000", + "tokenTransfers": [ + { + "type": "ERC20", + "from": "0x7d8bf18C7cE84b3E175b339c4Ca93aEd1dD166F1", + "to": "0x7d8bf18C7cE84b3E175b339c4Ca93aEd1dD166F1", + "token": "0x89d24A6b4CcB1B6fAA2625fE562bDD9a23260359", + "name": "Dai Stablecoin v1.0", + "symbol": "DAI", + "decimals": 18, + "value": "100000000000000" + } + ], + "ethereumSpecific": { + "status": 1, + "nonce": 523, + "gasLimit": 43323, + "gasUsed": 29126, + "gasPrice": "3000000000" + } + }, + { + "txid": "0x7a3929f2fad5e61f535ed5c1317f34e739655d582bc1b0161b9869b0957df6af", + "vin": [ + { + "n": 0, + "addresses": ["0x7d8bf18C7cE84b3E175b339c4Ca93aEd1dD166F1"], + "isAddress": true + } + ], + "vout": [ + { + "value": "567000000000000", + "n": 0, + "addresses": ["0x47331175b23C2f067204B506CA1501c26731C990"], + "isAddress": true + } + ], + "blockHash": "0xf08fd4b1d6ace92bf9516bbed37de100025f8b0879a80a92359a08f37e788b95", + "blockHeight": 10050786, + "confirmations": 43, + "blockTime": 1589278824, + "value": "567000000000000", + "fees": "407799043328112", + "ethereumSpecific": { + "status": 1, + "nonce": 535, + "gasLimit": 33000, + "gasUsed": 21064, + "gasPrice": "19360000158", + "data": "0xdeadbeef" + } + }, + { + "txid": "0xb1a56570bcb072d376630b987bd1f44ecc8f2c20ece52f02c9245296d3e3da39", + "vin": [ + { + "n": 0, + "addresses": ["0x2A0A572d77F6d6Ce62C6539E679d943824c3b218"], + "isAddress": true + } + ], + "vout": [ + { + "value": "0", + "n": 0, + "addresses": ["0xdAC17F958D2ee523a2206206994597C13D831ec7"], + "isAddress": true + } + ], + "blockHeight": -1, + "confirmations": 0, + "blockTime": 1589279659, + "value": "0", + "fees": "0", + "rbf": true, + "tokenTransfers": [ + { + "type": "ERC20", + "from": "0x2A0A572d77F6d6Ce62C6539E679d943824c3b218", + "to": "0x7d8bf18C7cE84b3E175b339c4Ca93aEd1dD166F1", + "token": "0xdAC17F958D2ee523a2206206994597C13D831ec7", + "name": "Tether USD", + "symbol": "USDT", + "decimals": 6, + "value": "23000000" + } + ], + "ethereumSpecific": { + "status": -1, + "nonce": 15647, + "gasLimit": 100000, + "gasUsed": null, + "gasPrice": "28560000000", + "data": "0xa9059cbb000000000000000000000000595031ff9bf6e0c1de20349e1377f43934f8951400000000000000000000000000000000000000000000000000000000015ef3c0" + } + }, + { + "txid": "0xfe7cce9928450e356f3332485e611781e407425b5888b8b2c7c66afaa4787cb1", + "vin": [ + { + "n": 0, + "addresses": ["0x267be1C1D684F78cb4F6a176C4911b741E4Ffdc0"], + "isAddress": true + } + ], + "vout": [ + { + "value": "295000000000000000", + "n": 0, + "addresses": ["0x7d8bf18C7cE84b3E175b339c4Ca93aEd1dD166F1"], + "isAddress": true + } + ], + "blockHeight": -1, + "confirmations": 0, + "blockTime": 1589287339, + "value": "295000000000000000", + "fees": "0", + "rbf": true, + "ethereumSpecific": { + "status": -1, + "nonce": 1282636, + "gasLimit": 30000, + "gasUsed": null, + "gasPrice": "24255000245", + "data": "0x" + } + } + ] +} diff --git a/platform/bitcoin/blockbook/mocks/expected_txs.json b/platform/bitcoin/blockbook/mocks/expected_txs.json new file mode 100644 index 000000000..1c1cdc528 --- /dev/null +++ b/platform/bitcoin/blockbook/mocks/expected_txs.json @@ -0,0 +1,127 @@ +[{ + "id": "0xb1a32935f9b015bcfdda1b2e3d281b3780d1a6f7a2d4406e05ec2b826b2349cb", + "coin": 60, + "from": "0x7d8bf18C7cE84b3E175b339c4Ca93aEd1dD166F1", + "to": "0xc73e0383F3Aff3215E6f04B0331D58CeCf0Ab849", + "fee": "227056700000000", + "date": 1574107019, + "block": 8958320, + "status": "completed", + "sequence": 378, + "token_transfers": [ + { + "name": "Dai Stablecoin v1.0", + "symbol": "DAI", + "token_id": "0x89d24A6b4CcB1B6fAA2625fE562bDD9a23260359", + "decimals": 18, + "value": "2255656573089233195", + "from": "0x7d8bf18C7cE84b3E175b339c4Ca93aEd1dD166F1", + "to": "0xc73e0383F3Aff3215E6f04B0331D58CeCf0Ab849" + }, + { + "name": "Dai Stablecoin v1.0", + "symbol": "DAI", + "token_id": "0x89d24A6b4CcB1B6fAA2625fE562bDD9a23260359", + "decimals": 18, + "value": "2255656573089233195", + "from": "0xc73e0383F3Aff3215E6f04B0331D58CeCf0Ab849", + "to": "0xad37fd42185Ba63009177058208dd1be4b136e6b" + }, + { + "name": "Dai Stablecoin", + "symbol": "DAI", + "token_id": "0x6B175474E89094C44Da98b954EedeAC495271d0F", + "decimals": 18, + "value": "2255656573089233195", + "from": "0x0000000000000000000000000000000000000000", + "to": "0x7d8bf18C7cE84b3E175b339c4Ca93aEd1dD166F1" + } + ], + "type": "contract_call", + "direction": "outgoing", + "memo": "", + "metadata": { + "input": "0x", + "value": "0" + } + },{ + "id": "0x17bb2b5e61f34119d4d4fbfae406ad3d854f0a00f13013d77de9aab7179f183f", + "coin": 60, + "from": "0x7d8bf18C7cE84b3E175b339c4Ca93aEd1dD166F1", + "to": "0x89d24A6b4CcB1B6fAA2625fE562bDD9a23260359", + "fee": "87378000000000", + "date": 1586627561, + "block": 9852430, + "status": "completed", + "sequence": 523, + "type": "token_transfer", + "direction": "yourself", + "memo": "", + "metadata": { + "name": "Dai Stablecoin v1.0", + "symbol": "DAI", + "token_id": "0x89d24A6b4CcB1B6fAA2625fE562bDD9a23260359", + "decimals": 18, + "value": "100000000000000", + "from": "0x7d8bf18C7cE84b3E175b339c4Ca93aEd1dD166F1", + "to": "0x7d8bf18C7cE84b3E175b339c4Ca93aEd1dD166F1" + } + },{ + "id": "0x7a3929f2fad5e61f535ed5c1317f34e739655d582bc1b0161b9869b0957df6af", + "coin": 60, + "from": "0x7d8bf18C7cE84b3E175b339c4Ca93aEd1dD166F1", + "to": "0x47331175b23C2f067204B506CA1501c26731C990", + "fee": "407799043328112", + "date": 1589278824, + "block": 10050786, + "status": "completed", + "sequence": 535, + "type": "contract_call", + "direction": "outgoing", + "memo": "", + "metadata": { + "input": "0xdeadbeef", + "value": "567000000000000" + } + },{ + "id": "0xb1a56570bcb072d376630b987bd1f44ecc8f2c20ece52f02c9245296d3e3da39", + "coin": 60, + "from": "0x2A0A572d77F6d6Ce62C6539E679d943824c3b218", + "to": "0xdAC17F958D2ee523a2206206994597C13D831ec7", + "fee": "2856000000000000", + "date": 1589279659, + "block": 0, + "status": "pending", + "sequence": 15647, + "type": "token_transfer", + "direction": "incoming", + "memo": "", + "metadata": { + "name": "Tether USD", + "symbol": "USDT", + "token_id": "0xdAC17F958D2ee523a2206206994597C13D831ec7", + "decimals": 6, + "value": "23000000", + "from": "0x2A0A572d77F6d6Ce62C6539E679d943824c3b218", + "to": "0x7d8bf18C7cE84b3E175b339c4Ca93aEd1dD166F1" + } + },{ + "id": "0xfe7cce9928450e356f3332485e611781e407425b5888b8b2c7c66afaa4787cb1", + "coin": 60, + "from": "0x267be1C1D684F78cb4F6a176C4911b741E4Ffdc0", + "to": "0x7d8bf18C7cE84b3E175b339c4Ca93aEd1dD166F1", + "fee": "727650007350000", + "date": 1589287339, + "block": 0, + "status": "pending", + "sequence": 1282636, + "type": "transfer", + "direction": "incoming", + "memo": "", + "metadata": { + "value": "295000000000000000", + "symbol": "ETH", + "decimals": 18 + } + } + ] \ No newline at end of file diff --git a/platform/bitcoin/blockbook/model.go b/platform/bitcoin/blockbook/model.go new file mode 100644 index 000000000..d538b0910 --- /dev/null +++ b/platform/bitcoin/blockbook/model.go @@ -0,0 +1,130 @@ +package blockbook + +import ( + "encoding/json" + "math/big" + + "github.com/trustwallet/golibs/types" +) + +type NodeInfo struct { + Blockbook *Blockbook `json:"blockbook"` +} + +type Blockbook struct { + BestHeight int64 `json:"bestHeight"` + InSync bool `json:"inSync"` +} + +type TokenTransfer struct { + Decimals uint `json:"decimals"` + From string `json:"from"` + Name string `json:"name"` + Symbol string `json:"symbol"` + To string `json:"to"` + Token string `json:"token"` + Type string `json:"type"` + Value string `json:"value"` +} + +// Token contains info about tokens held by an address +type Token struct { + Balance string `json:"balance,omitempty"` + Contract string `json:"contract"` + Decimals uint `json:"decimals"` + Name string `json:"name"` + Symbol string `json:"symbol"` + Type types.TokenType `json:"type"` +} + +// EthereumSpecific contains ethereum specific transaction data +type EthereumSpecific struct { + Status int `json:"status"` // -1 pending, 0 Fail, 1 OK + Nonce uint64 `json:"nonce"` + GasLimit *big.Int `json:"gasLimit"` + GasUsed *big.Int `json:"gasUsed"` + GasPrice string `json:"gasPrice"` + Data string `json:"data,omitempty"` +} + +type TransactionsList struct { + Page int64 `json:"page"` + TotalPages int64 `json:"totalPages"` + ItemsOnPage int64 `json:"itemsOnPage"` + Transactions []Transaction `json:"transactions,omitempty"` + Txs interface{} `json:"txs,omitempty"` + Tokens []Token `json:"tokens,omitempty"` + TxCount int64 `json:"txCount,omitempty"` + Hash string `json:"hash,omitempty"` +} + +func (tl *TransactionsList) TransactionList() []Transaction { + if tl.Transactions != nil { + return tl.Transactions + } + b, err := json.Marshal(tl.Txs) + if err != nil { + return tl.Transactions + } + var txs []Transaction + err = json.Unmarshal(b, &txs) + if err != nil { + return tl.Transactions + } + return txs +} + +type Transaction struct { + ID string `json:"txid"` + Version uint64 `json:"version"` + Vin []Output `json:"vin"` + Vout []Output `json:"vout"` + BlockHash string `json:"blockHash"` + BlockHeight int64 `json:"blockHeight"` + Confirmations uint64 `json:"confirmations"` + BlockTime int64 `json:"blockTime"` + Value string `json:"value"` + ValueOut string `json:"valueOut"` + Fees string `json:"fees"` + TokenTransfers []TokenTransfer `json:"tokenTransfers,omitempty"` + EthereumSpecific *EthereumSpecific `json:"ethereumSpecific,omitempty"` +} + +func (transaction Transaction) Amount() string { + if len(transaction.Value) == 0 { + return transaction.ValueOut + } + return transaction.Value +} + +func (transaction Transaction) GetStatus() types.Status { + if transaction.Confirmations == 0 { + return types.StatusPending + } + return types.StatusCompleted +} + +func (transaction Transaction) GetBlockHeight() uint64 { + if transaction.BlockHeight > 0 { + return uint64(transaction.BlockHeight) + } + return 0 +} + +type Output struct { + TxId string `json:"txid,omitempty"` + Value string `json:"value,omitempty"` + Addresses []string `json:"addresses,omitempty"` + ScriptPubKey ScriptPubKey `json:"scriptPubKey,omitempty"` +} + +type ScriptPubKey struct { + Addresses []string `json:"addresses,omitempty"` +} + +func (o Output) OutputAddress() []string { + if len(o.Addresses) == 0 { + return o.ScriptPubKey.Addresses + } + return o.Addresses +} diff --git a/platform/bitcoin/blockbook/model_extension.go b/platform/bitcoin/blockbook/model_extension.go new file mode 100644 index 000000000..007e9dbf6 --- /dev/null +++ b/platform/bitcoin/blockbook/model_extension.go @@ -0,0 +1,59 @@ +package blockbook + +import ( + "math/big" + + "github.com/trustwallet/golibs/types" +) + +func (s *EthereumSpecific) GetStatus() (types.Status, string) { + switch s.Status { + case -1: + return types.StatusPending, "" + case 0: + return types.StatusError, "Error" + case 1: + return types.StatusCompleted, "" + default: + return types.StatusError, "Unable to define transaction status" + } +} + +func (transaction *Transaction) FromAddress() string { + if len(transaction.Vin) > 0 && len(transaction.Vin[0].Addresses) > 0 { + return transaction.Vin[0].Addresses[0] + } + return "" +} + +func (transaction *Transaction) GetFee() string { + status, _ := transaction.EthereumSpecific.GetStatus() + if status != types.StatusPending { + return transaction.Fees + } + + gasLimit := transaction.EthereumSpecific.GasLimit + gasPrice, ok := new(big.Int).SetString(transaction.EthereumSpecific.GasPrice, 10) + if gasLimit == nil || !ok { + return "0" + } + fee := new(big.Int).Mul(gasLimit, gasPrice) + return fee.String() +} + +func (transaction *Transaction) ToAddress() string { + if len(transaction.Vout) > 0 && len(transaction.Vout[0].Addresses) > 0 { + return transaction.Vout[0].Addresses[0] + } + return "" +} + +func GetDirection(address, from, to string) types.Direction { + if address == from && address == to { + return types.DirectionSelf + } + if address == from { + return types.DirectionOutgoing + } + return types.DirectionIncoming +} diff --git a/platform/bitcoin/blockbook/token.go b/platform/bitcoin/blockbook/token.go new file mode 100644 index 000000000..da04de1b3 --- /dev/null +++ b/platform/bitcoin/blockbook/token.go @@ -0,0 +1,36 @@ +package blockbook + +import ( + "github.com/trustwallet/golibs/types" +) + +func (c *Client) GetTokenList(address string, coinIndex uint) ([]types.Token, error) { + tokens, err := c.GetTokens(address) + if err != nil { + return nil, err + } + return NormalizeTokens(tokens, coinIndex), nil +} + +func NormalizeTokens(tokens []Token, coinIndex uint) []types.Token { + assets := make([]types.Token, 0) + for _, srcToken := range tokens { + if srcToken.Balance == "0" || srcToken.Balance == "" { + continue + } + token := NormalizeToken(&srcToken, coinIndex) + assets = append(assets, token) + } + return assets +} + +func NormalizeToken(srcToken *Token, coinIndex uint) types.Token { + return types.Token{ + Name: srcToken.Name, + Symbol: srcToken.Symbol, + TokenID: srcToken.Contract, + Coin: coinIndex, + Decimals: srcToken.Decimals, + Type: types.GetEthereumTokenTypeByIndex(coinIndex), + } +} diff --git a/platform/bitcoin/blockbook/token_test.go b/platform/bitcoin/blockbook/token_test.go new file mode 100644 index 000000000..135527790 --- /dev/null +++ b/platform/bitcoin/blockbook/token_test.go @@ -0,0 +1,74 @@ +package blockbook + +import ( + "reflect" + "testing" + + "github.com/trustwallet/golibs/types" +) + +func TestNormalizeToken(t *testing.T) { + type args struct { + srcToken Token + coinIndex uint + } + tests := []struct { + name string + args args + want []types.Token + }{ + { + name: "Should normalize and return token with balance", + args: args{srcToken: Token{ + Balance: "100", + Type: "ERC20", + Name: "USD Coin", + Contract: "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48", + Symbol: "USDC", + Decimals: 6}, + coinIndex: 60}, + want: []types.Token{ + { + Type: "ERC20", + Name: "USD Coin", + TokenID: "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48", + Symbol: "USDC", + Decimals: 6, + Coin: 60, + }, + }, + }, + { + name: "Should not return token with zero balance", + args: args{srcToken: Token{ + Balance: "0", + Type: "ERC20", + Name: "USD Coin", + Contract: "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48", + Symbol: "USDC", + Decimals: 6}, + coinIndex: 60, + }, + want: []types.Token{}, + }, { + name: "Should not return token with zero balance", + args: args{srcToken: Token{ + Balance: "", + Type: "ERC20", + Name: "USD Coin", + Contract: "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48", + Symbol: "USDC", + Decimals: 6}, + coinIndex: 60, + }, + want: []types.Token{}, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + if got := NormalizeTokens([]Token{tt.args.srcToken}, tt.args.coinIndex); !reflect.DeepEqual(got, tt.want) { + t.Errorf("NormalizeToken() = %v, want %v", got, tt.want) + } + }) + } +} diff --git a/platform/bitcoin/blockbook/transaction.go b/platform/bitcoin/blockbook/transaction.go new file mode 100644 index 000000000..8a2ff2141 --- /dev/null +++ b/platform/bitcoin/blockbook/transaction.go @@ -0,0 +1,193 @@ +package blockbook + +import ( + "strings" + + Address "github.com/trustwallet/golibs/address" + "github.com/trustwallet/golibs/coin" + "github.com/trustwallet/golibs/types" +) + +func (c *Client) GetTransactions(address string, coinIndex uint) (types.Txs, error) { + page, err := c.GetTxs(address) + if err != nil { + return nil, err + } + return NormalizePage(page, address, "", coinIndex), nil +} + +func (c *Client) GetTokenTxs(address, token string, coinIndex uint) (types.Txs, error) { + page, err := c.GetTxsWithContract(address, token) + if err != nil { + return nil, err + } + return NormalizePage(page, address, token, coinIndex), nil +} + +func NormalizePage(srcPage TransactionsList, address, token string, coinIndex uint) (txs types.Txs) { + normalizedAddr, err := Address.EIP55Checksum(address) + if err != nil { + return + } + var normalizedToken string + if token != "" { + normalizedToken, err = Address.EIP55Checksum(token) + if err != nil { + return + } + } + for _, srcTx := range srcPage.Transactions { + tx := normalizeTxWithAddress(&srcTx, normalizedAddr, normalizedToken, coinIndex) + txs = append(txs, tx) + } + return txs +} + +func normalizeTx(srcTx *Transaction, coinIndex uint) types.Tx { + status, errReason := srcTx.EthereumSpecific.GetStatus() + normalized := types.Tx{ + ID: srcTx.ID, + Coin: coinIndex, + From: srcTx.FromAddress(), + To: srcTx.ToAddress(), + Fee: types.Amount(srcTx.GetFee()), + Date: srcTx.BlockTime, + Block: normalizeBlockHeight(srcTx.BlockHeight), + Status: status, + Error: errReason, + Sequence: srcTx.EthereumSpecific.Nonce, + TokenTransfers: normalizeTokenTransfers(srcTx.TokenTransfers), + } + fillMeta(&normalized, srcTx, coinIndex) + return normalized +} + +func normalizeTxWithAddress(srcTx *Transaction, address, token string, coinIndex uint) types.Tx { + normalized := normalizeTx(srcTx, coinIndex) + normalized.Direction = GetDirection(address, normalized.From, normalized.To) + fillMetaWithAddress(&normalized, srcTx, address, token, coinIndex) + return normalized +} + +func normalizeBlockHeight(height int64) uint64 { + if height < 0 { + return uint64(0) + } + return uint64(height) +} + +func normalizeTokenTransfers(tokenTransfers []TokenTransfer) []types.TokenTransfer { + result := make([]types.TokenTransfer, 0) + for _, transfer := range tokenTransfers { + result = append(result, types.TokenTransfer{ + Name: transfer.Name, + Symbol: transfer.Symbol, + TokenID: transfer.Token, + Decimals: transfer.Decimals, + Value: types.Amount(transfer.Value), + From: transfer.From, + To: transfer.To, + }) + } + return result +} + +func fillMeta(final *types.Tx, tx *Transaction, coinIndex uint) { + if ok := fillTokenTransfer(final, tx, coinIndex); !ok { + fillTransferOrContract(final, tx, coinIndex) + } +} + +func fillMetaWithAddress(final *types.Tx, tx *Transaction, address, token string, coinIndex uint) { + if ok := fillTokenTransferWithAddress(final, tx, address, token, coinIndex); !ok { + fillTransferOrContract(final, tx, coinIndex) + } +} + +func fillTokenTransfer(final *types.Tx, tx *Transaction, coinIndex uint) bool { + if len(tx.TokenTransfers) == 1 { + transfer := tx.TokenTransfers[0] + final.Meta = types.TokenTransfer{ + Name: transfer.Name, + Symbol: transfer.Symbol, + TokenID: transfer.Token, + Decimals: transfer.Decimals, + Value: types.Amount(transfer.Value), + From: transfer.From, + To: transfer.To, + } + final.TokenTransfers = []types.TokenTransfer{} + return true + } + return false +} + +func fillTokenTransferWithAddress(final *types.Tx, tx *Transaction, address, token string, coinIndex uint) bool { + if len(tx.TokenTransfers) == 1 { + transfer := tx.TokenTransfers[0] + if transfer.To == address || transfer.From == address { + // filter token if specified + if token != "" { + if token != transfer.Token { + return false + } + } + direction := GetDirection(address, transfer.From, transfer.To) + metadata := types.TokenTransfer{ + Name: transfer.Name, + Symbol: transfer.Symbol, + TokenID: transfer.Token, + Decimals: transfer.Decimals, + Value: types.Amount(transfer.Value), + } + if direction == types.DirectionSelf { + metadata.From = address + metadata.To = address + } else if direction == types.DirectionOutgoing { + metadata.From = address + metadata.To = transfer.To + } else { + metadata.From = transfer.From + metadata.To = address + } + final.Direction = direction + final.Meta = metadata + final.TokenTransfers = []types.TokenTransfer{} + return true + } + } + return false +} + +func fillTransferOrContract(final *types.Tx, tx *Transaction, coinIndex uint) { + gasUsed := tx.EthereumSpecific.GasUsed + if gasUsed != nil && gasUsed.Int64() == 21000 { + final.Meta = types.Transfer{ + Value: types.Amount(tx.Value), + Symbol: coin.Coins[coinIndex].Symbol, + Decimals: coin.Coins[coinIndex].Decimals, + } + return + } + data := tx.EthereumSpecific.Data + if data == "" { + // old node doesn't have data field + final.Meta = types.ContractCall{ + Input: "0x", + Value: tx.Value, + } + } else { + if len(strings.TrimPrefix(data, "0x")) > 0 { + final.Meta = types.ContractCall{ + Input: data, + Value: tx.Value, + } + } else { + final.Meta = types.Transfer{ + Value: types.Amount(tx.Value), + Symbol: coin.Coins[coinIndex].Symbol, + Decimals: coin.Coins[coinIndex].Decimals, + } + } + } +} diff --git a/platform/bitcoin/blockbook/transaction_test.go b/platform/bitcoin/blockbook/transaction_test.go new file mode 100644 index 000000000..0f7ece289 --- /dev/null +++ b/platform/bitcoin/blockbook/transaction_test.go @@ -0,0 +1,56 @@ +package blockbook + +import ( + "encoding/json" + "testing" + + "github.com/stretchr/testify/assert" + "github.com/trustwallet/golibs/mock" + "github.com/trustwallet/golibs/types" +) + +var ( + srcPage, _ = mock.JsonStringFromFilePath("mocks/blockbook_txs.json") + want, _ = mock.JsonStringFromFilePath("mocks/expected_txs.json") +) + +func TestNormalizeTxs(t *testing.T) { + type args struct { + srcPage string + address string + token string + coinIndex uint + } + tests := []struct { + name string + args args + want string + }{ + { + name: "Test normalize blockbook txs", + args: args{ + srcPage: srcPage, + address: "0x7d8bf18c7ce84b3e175b339c4ca93aed1dd166f1", + token: "", + coinIndex: 60, + }, + want: want, + }, + } + for _, tt := range tests { + var page TransactionsList + var txs types.Txs + err := json.Unmarshal([]byte(tt.args.srcPage), &page) + assert.Nil(t, err) + err = json.Unmarshal([]byte(tt.want), &txs) + assert.Nil(t, err) + t.Run(tt.name, func(t *testing.T) { + got := NormalizePage(page, tt.args.address, tt.args.token, tt.args.coinIndex) + gotJson, err := json.Marshal(got) + assert.Nil(t, err) + wantTxs, err := json.Marshal(txs) + assert.Nil(t, err) + assert.JSONEq(t, string(gotJson), string(wantTxs)) + }) + } +} diff --git a/platform/bitcoin/client.go b/platform/bitcoin/client.go deleted file mode 100644 index 4a9dae795..000000000 --- a/platform/bitcoin/client.go +++ /dev/null @@ -1,58 +0,0 @@ -package bitcoin - -import ( - "fmt" - "github.com/trustwallet/blockatlas/pkg/blockatlas" - "net/url" - "strconv" -) - -type Client struct { - blockatlas.Request -} - -func (c *Client) GetTransactions(address string) (transactions TransactionsList, err error) { - path := fmt.Sprintf("address/%s", address) - err = c.Get(&transactions, path, url.Values{ - "details": {"txs"}, - "pageSize": {strconv.FormatInt(blockatlas.TxPerPage*4, 10)}, - }) - return transactions, err -} - -func (c *Client) GetTransactionsByXpub(xpub string) (transactions TransactionsList, err error) { - path := fmt.Sprintf("v2/xpub/%s", xpub) - args := url.Values{ - "pageSize": {strconv.FormatInt(blockatlas.TxPerPage*4, 10)}, - "details": {"txs"}, - "tokens": {"derived"}, - } - err = c.Get(&transactions, path, args) - return transactions, err -} - -func (c *Client) GetAddressesFromXpub(xpub string) (tokens []Token, err error) { - path := fmt.Sprintf("v2/xpub/%s", xpub) - args := url.Values{ - "pageSize": {strconv.FormatInt(blockatlas.TxPerPage*4, 10)}, - "details": {"txs"}, - "tokens": {"derived"}, - } - var transactions TransactionsList - err = c.Get(&transactions, path, args) - return transactions.Tokens, err -} - -func (c *Client) GetTransactionsByBlock(number int64, page int64) (block TransactionsList, err error) { - path := fmt.Sprintf("v2/block/%s", strconv.FormatInt(number, 10)) - args := url.Values{ - "page": {strconv.FormatInt(page, 10)}, - } - err = c.Get(&block, path, args) - return block, err -} - -func (c *Client) GetBlockNumber() (status BlockchainStatus, err error) { - err = c.Get(&status, "v2", nil) - return status, err -} diff --git a/platform/bitcoin/mocks/incoming_tx.json b/platform/bitcoin/mocks/incoming_tx.json new file mode 100644 index 000000000..06f8258fc --- /dev/null +++ b/platform/bitcoin/mocks/incoming_tx.json @@ -0,0 +1,40 @@ +{ + "txid": "a2d70bee124510c476f159fa83cdb34d663fc6020c81aad19b238601d679fed7", + "version": 4, + "vin": [ + { + "txid": "5a3664328ac4e1c0688729573296c2ec69dd9a7cf98d49967b41520be794229b", + "n": 0, + "addresses": ["t1T7cLkvDVScjw95WguoAZbbT8mrdqVtpiD"], + "isAddress": true, + "value": "387582", + "hex": "483045022100ec29a476dac49578339a92e6c20451aaf3ff6691efaf7d4d3113d07589771ca702203c0c173bdc356300edbd64cdfaa868b97c13ebc403026b283eb5e1fca398db8b012103729cc4211cf70f87c70c3cef90e0ca9b91e99b42364b8c600d5781277647de5f" + } + ], + "vout": [ + { + "value": "200997", + "n": 0, + "spent": true, + "hex": "76a9146fd73e7c147d8ccc15fda31d8429e70f302b843988ac", + "addresses": ["t1U4xs3qMxc2TL8wwYufmBngA5mewLHRwhM"], + "isAddress": true + }, + { + "value": "186359", + "n": 1, + "spent": true, + "hex": "76a91484f0258cb7974993e6af928921b7f699c51a309488ac", + "addresses": ["t1VzWtLj9CSAK3QnxA7uuiK6XhJrjGjKoy4"], + "isAddress": true + } + ], + "blockHash": "0000000000a8248c4a14a2dcb74d92855bf9440da9b7b1e6d4baa14ee7e3081c", + "blockHeight": 479017, + "confirmations": 116233, + "blockTime": 1549793065, + "value": "387356", + "valueIn": "387582", + "fees": "226", + "hex": "0400008085202f89019b2294e70b52417b96498df97c9add69ecc2963257298768c0e1c48a3264365a000000006b483045022100ec29a476dac49578339a92e6c20451aaf3ff6691efaf7d4d3113d07589771ca702203c0c173bdc356300edbd64cdfaa868b97c13ebc403026b283eb5e1fca398db8b012103729cc4211cf70f87c70c3cef90e0ca9b91e99b42364b8c600d5781277647de5f000000000225110300000000001976a9146fd73e7c147d8ccc15fda31d8429e70f302b843988acf7d70200000000001976a91484f0258cb7974993e6af928921b7f699c51a309488ac00000000000000000000000000000000000000" +} diff --git a/platform/bitcoin/mocks/outgoing_tx.json b/platform/bitcoin/mocks/outgoing_tx.json new file mode 100644 index 000000000..4a0c75b77 --- /dev/null +++ b/platform/bitcoin/mocks/outgoing_tx.json @@ -0,0 +1,30 @@ +{ + "txid": "df63ddab7d4eed2fb6cb40d4d0519e7e5ac7cf5ad556b2edbd45963ea1a2931c", + "version": 1, + "vin": [ + { + "txid": "bf19be44d7dc3e1e6771801a1d250c7207fa9b09d8df9b0ee1b028b6c153475e", + "sequence": 4294967295, + "n": 0, + "addresses": ["3QJmV3qfvL9SuYo34YihAf3sRCW3qSinyC"], + "value": "777200", + "hex": "00483045022100e9d0db3bb20a5828ab9dae7cd8373064ce087cc9c8e3def87034d5c2f6f3abb9022047d7c27b355c6487cff40bfbd45742d26d727f3135b2396d8f1abc371c51870c01473044022016280108af73079a69f378218ad4259f02c4e4b6f52c573729650cb3645bc9180220785973cb4e5c4ec6340dc77dc56cec3fb74ebd7296cf1d14344d4f3e157658bb014cc952410491bba2510912a5bd37da1fb5b1673010e43d2c6d812c514e91bfa9f2eb129e1c183329db55bd868e209aac2fbc02cb33d98fe74bf23f0c235d6126b1d8334f864104865c40293a680cb9c020e7b1e106d8c1916d3cef99aa431a56d253e69256dac09ef122b1a986818a7cb624532f062c1d1f8722084861c5c3291ccffef4ec687441048d2455d2403e08708fc1f556002f1b6cd83f992d085097f9974ab08a28838f07896fbab08f39495e15fa6fad6edbfb1e754e35fa1c7844c41f322a1863d4621353ae" + } + ], + "vout": [ + { + "value": "677012", + "n": 0, + "hex": "a91499fa965ad13a9580ed7a64ac24b2ecad30f1209a87", + "addresses": ["3FjBW1KL9L8aYtdKzJ8FhCNxmXB7dXDRw4"] + } + ], + "blockHash": "00000000000000000011b58c01ede5a602eec61ebaf097aaa6e682ef2819536e", + "blockHeight": 585094, + "confirmations": 1997, + "blockTime": 1562945790, + "value": "677012", + "valueIn": "777200", + "fees": "100188", + "hex": "01000000015e4753c1b628b0e10e9bdfd8099bfa07720c251d1a8071671e3edcd744be19bf00000000fd5d0100483045022100e9d0db3bb20a5828ab9dae7cd8373064ce087cc9c8e3def87034d5c2f6f3abb9022047d7c27b355c6487cff40bfbd45742d26d727f3135b2396d8f1abc371c51870c01473044022016280108af73079a69f378218ad4259f02c4e4b6f52c573729650cb3645bc9180220785973cb4e5c4ec6340dc77dc56cec3fb74ebd7296cf1d14344d4f3e157658bb014cc952410491bba2510912a5bd37da1fb5b1673010e43d2c6d812c514e91bfa9f2eb129e1c183329db55bd868e209aac2fbc02cb33d98fe74bf23f0c235d6126b1d8334f864104865c40293a680cb9c020e7b1e106d8c1916d3cef99aa431a56d253e69256dac09ef122b1a986818a7cb624532f062c1d1f8722084861c5c3291ccffef4ec687441048d2455d2403e08708fc1f556002f1b6cd83f992d085097f9974ab08a28838f07896fbab08f39495e15fa6fad6edbfb1e754e35fa1c7844c41f322a1863d4621353aeffffffff0194540a000000000017a91499fa965ad13a9580ed7a64ac24b2ecad30f1209a8700000000" +} diff --git a/platform/bitcoin/mocks/pending_tx.json b/platform/bitcoin/mocks/pending_tx.json new file mode 100644 index 000000000..d90c87e77 --- /dev/null +++ b/platform/bitcoin/mocks/pending_tx.json @@ -0,0 +1,40 @@ +{ + "txid": "a2d70bee124510c476f159fa83cdb34d663fc6020c81aad19b238601d679fed7", + "version": 4, + "vin": [ + { + "txid": "5a3664328ac4e1c0688729573296c2ec69dd9a7cf98d49967b41520be794229b", + "n": 0, + "addresses": ["t1T7cLkvDVScjw95WguoAZbbT8mrdqVtpiD"], + "isAddress": true, + "value": "387582", + "hex": "483045022100ec29a476dac49578339a92e6c20451aaf3ff6691efaf7d4d3113d07589771ca702203c0c173bdc356300edbd64cdfaa868b97c13ebc403026b283eb5e1fca398db8b012103729cc4211cf70f87c70c3cef90e0ca9b91e99b42364b8c600d5781277647de5f" + } + ], + "vout": [ + { + "value": "200997", + "n": 0, + "spent": true, + "hex": "76a9146fd73e7c147d8ccc15fda31d8429e70f302b843988ac", + "addresses": ["t1U4xs3qMxc2TL8wwYufmBngA5mewLHRwhM"], + "isAddress": true + }, + { + "value": "186359", + "n": 1, + "spent": true, + "hex": "76a91484f0258cb7974993e6af928921b7f699c51a309488ac", + "addresses": ["t1VzWtLj9CSAK3QnxA7uuiK6XhJrjGjKoy4"], + "isAddress": true + } + ], + "blockHash": "0000000000a8248c4a14a2dcb74d92855bf9440da9b7b1e6d4baa14ee7e3081c", + "blockHeight": -1, + "confirmations": 116233, + "blockTime": 1549793065, + "value": "387356", + "valueIn": "387582", + "fees": "226", + "hex": "0400008085202f89019b2294e70b52417b96498df97c9add69ecc2963257298768c0e1c48a3264365a000000006b483045022100ec29a476dac49578339a92e6c20451aaf3ff6691efaf7d4d3113d07589771ca702203c0c173bdc356300edbd64cdfaa868b97c13ebc403026b283eb5e1fca398db8b012103729cc4211cf70f87c70c3cef90e0ca9b91e99b42364b8c600d5781277647de5f000000000225110300000000001976a9146fd73e7c147d8ccc15fda31d8429e70f302b843988acf7d70200000000001976a91484f0258cb7974993e6af928921b7f699c51a309488ac00000000000000000000000000000000000000" +} diff --git a/platform/bitcoin/model.go b/platform/bitcoin/model.go deleted file mode 100644 index 545a6b831..000000000 --- a/platform/bitcoin/model.go +++ /dev/null @@ -1,97 +0,0 @@ -package bitcoin - -import "encoding/json" - -type TransactionsList struct { - Page int64 `json:"page"` - TotalPages int64 `json:"totalPages"` - ItemsOnPage int64 `json:"itemsOnPage"` - Transactions []Transaction `json:"transactions,omitempty"` - Txs interface{} `json:"txs,omitempty"` - Tokens []Token `json:"tokens,omitempty"` - TxCount int64 `json:"txCount,omitempty"` - Hash string `json:"hash,omitempty"` -} - -func (tl *TransactionsList) TransactionList() []Transaction { - if tl.Transactions != nil { - return tl.Transactions - } - b, err := json.Marshal(tl.Txs) - if err != nil { - return tl.Transactions - } - var txs []Transaction - err = json.Unmarshal(b, &txs) - if err != nil { - return tl.Transactions - } - return txs -} - -type Tx struct { - ID string `json:"id"` -} - -type Transaction struct { - ID string `json:"txid"` - Version uint64 `json:"version"` - Vin []Output `json:"vin"` - Vout []Output `json:"vout"` - BlockHash string `json:"blockHash"` - BlockHeight int64 `json:"blockHeight"` - Confirmations uint64 `json:"confirmations"` - BlockTime uint64 `json:"blockTime"` - Value string `json:"value"` - ValueOut string `json:"valueOut"` - Fees string `json:"fees"` -} - -func (transaction Transaction) Amount() string { - if len(transaction.Value) == 0 { - return transaction.ValueOut - } - return transaction.Value -} - -type Output struct { - TxId string `json:"txid,omitempty"` - Value string `json:"value,omitempty"` - Addresses []string `json:"addresses,omitempty"` - ScriptPubKey ScriptPubKey `json:"scriptPubKey,omitempty"` -} - -type ScriptPubKey struct { - Addresses []string `json:"addresses,omitempty"` -} - -func (o Output) OutputAddress() []string { - if len(o.Addresses) == 0 { - return o.ScriptPubKey.Addresses - } - return o.Addresses -} - -type Token struct { - Type string `json:"type"` - Name string `json:"name"` - Path string `json:"path"` - Transfers int `json:"transfers"` - Balance string `json:"balance"` -} - -type BlockchainStatus struct { - Backend Backend `json:"backend"` -} - -type Backend struct { - Chain string `json:"chain"` - Blocks int64 `json:"blocks"` -} - -func (transaction Transaction) GetBlockHeight() uint64 { - if transaction.BlockHeight > 0 { - return uint64(transaction.BlockHeight) - } - return 0 -} diff --git a/platform/bitcoin/transaction.go b/platform/bitcoin/transaction.go new file mode 100644 index 000000000..878c630ac --- /dev/null +++ b/platform/bitcoin/transaction.go @@ -0,0 +1,142 @@ +package bitcoin + +import ( + "sort" + + "github.com/trustwallet/blockatlas/platform/bitcoin/blockbook" + + mapset "github.com/deckarep/golang-set" + "github.com/trustwallet/golibs/coin" + "github.com/trustwallet/golibs/numbers" + "github.com/trustwallet/golibs/types" +) + +func (p *Platform) GetTxsByAddress(address string) (types.Txs, error) { + txs, err := p.getTxsByAddress(address) + if err != nil { + return nil, err + } + sort.Sort(txs) + return txs, nil +} + +func (p *Platform) GetTxsByXpub(xpub string) (types.Txs, error) { + txs, err := p.getTxsByXpub(xpub) + if err != nil { + return nil, err + } + sort.Sort(txs) + return txs, nil +} + +func (p *Platform) getTxsByXpub(xpub string) (types.Txs, error) { + sourceTxs, err := p.client.GetTransactionsByXpub(xpub) + + if err != nil { + return types.Txs{}, err + } + + addressSet := mapset.NewSet() + for _, token := range sourceTxs.Tokens { + addressSet.Add(token.Name) + } + + txs := normalizeTxs(sourceTxs, p.CoinIndex, addressSet) + return txs, nil +} + +func (p *Platform) getTxsByAddress(address string) (types.Txs, error) { + sourceTxs, err := p.client.GetTxs(address) + if err != nil { + return types.Txs{}, err + } + addressSet := mapset.NewSet() + addressSet.Add(address) + txs := normalizeTxs(sourceTxs, p.CoinIndex, addressSet) + return txs, nil +} + +func normalizeTxs(sourceTxs blockbook.TransactionsList, coinIndex uint, addressSet mapset.Set) types.Txs { + var txs types.Txs + for _, transaction := range sourceTxs.TransactionList() { + if tx, ok := normalizeTransfer(transaction, coinIndex, addressSet); ok { + txs = append(txs, tx) + } + } + return txs +} + +func normalizeTransfer(transaction blockbook.Transaction, coinIndex uint, addressSet mapset.Set) (tx types.Tx, ok bool) { + tx = normalizeTransaction(transaction, coinIndex) + direction := types.InferDirection(&tx, addressSet) + value := types.InferValue(&tx, direction, addressSet) + + tx.Direction = direction + tx.Meta = types.Transfer{ + Value: value, + Symbol: coin.Coins[coinIndex].Symbol, + Decimals: coin.Coins[coinIndex].Decimals, + } + + return tx, true +} + +func normalizeTransaction(tx blockbook.Transaction, coinIndex uint) types.Tx { + inputs := parseOutputs(tx.Vin) + outputs := parseOutputs(tx.Vout) + from := "" + if len(inputs) > 0 { + from = inputs[0].Address + } + + to := "" + if len(outputs) > 0 { + to = outputs[0].Address + } + amount := types.Amount(tx.Amount()) + fees := types.Amount(numbers.GetAmountValue(tx.Fees)) + + return types.Tx{ + ID: tx.ID, + Coin: coinIndex, + From: from, + To: to, + Inputs: inputs, + Outputs: outputs, + Fee: fees, + Date: tx.BlockTime, + Type: types.TxTransfer, + Block: tx.GetBlockHeight(), + Status: tx.GetStatus(), + Sequence: 0, + Meta: types.Transfer{ + Value: amount, + Symbol: coin.Coins[coinIndex].Symbol, + Decimals: coin.Coins[coinIndex].Decimals, + }, + } +} + +func parseOutputs(outputs []blockbook.Output) (addresses []types.TxOutput) { + set := make(map[string]*types.TxOutput) + var ordered []string + for _, output := range outputs { + for _, address := range output.OutputAddress() { + if val, ok := set[address]; ok { + value := numbers.AddAmount(string(val.Value), output.Value) + val.Value = types.Amount(value) + } else { + amount := numbers.GetAmountValue(output.Value) + set[address] = &types.TxOutput{ + Address: address, + Value: types.Amount(amount), + } + ordered = append(ordered, address) + } + } + } + for _, val := range ordered { + addresses = append(addresses, *set[val]) + } + return addresses +} diff --git a/platform/bitcoin/transaction_test.go b/platform/bitcoin/transaction_test.go new file mode 100644 index 000000000..6bbe0648b --- /dev/null +++ b/platform/bitcoin/transaction_test.go @@ -0,0 +1,279 @@ +package bitcoin + +import ( + "encoding/json" + "reflect" + "testing" + + "github.com/trustwallet/blockatlas/platform/bitcoin/blockbook" + + mapset "github.com/deckarep/golang-set" + "github.com/stretchr/testify/assert" + "github.com/trustwallet/golibs/coin" + "github.com/trustwallet/golibs/mock" + "github.com/trustwallet/golibs/types" +) + +var ( + outgoingTx, _ = mock.JsonStringFromFilePath("mocks/" + "outgoing_tx.json") + incomingTx, _ = mock.JsonStringFromFilePath("mocks/" + "incoming_tx.json") + pendingTx, _ = mock.JsonStringFromFilePath("mocks/" + "pending_tx.json") + + expectedOutgoingTx = types.Tx{ + ID: "df63ddab7d4eed2fb6cb40d4d0519e7e5ac7cf5ad556b2edbd45963ea1a2931c", + Coin: coin.BITCOIN, + From: "3QJmV3qfvL9SuYo34YihAf3sRCW3qSinyC", + To: "3FjBW1KL9L8aYtdKzJ8FhCNxmXB7dXDRw4", + Inputs: []types.TxOutput{ + { + Address: "3QJmV3qfvL9SuYo34YihAf3sRCW3qSinyC", + Value: "777200", + }, + }, + Outputs: []types.TxOutput{ + { + Address: "3FjBW1KL9L8aYtdKzJ8FhCNxmXB7dXDRw4", + Value: "677012", + }, + }, + Fee: "100188", + Date: 1562945790, + Type: "transfer", + Status: types.StatusCompleted, + Block: 585094, + Sequence: 0, + Direction: types.DirectionSelf, + Meta: types.Transfer{ + Value: "677012", + Symbol: "BTC", + Decimals: 8, + }, + } + + expectedIncomingTx = types.Tx{ + ID: "a2d70bee124510c476f159fa83cdb34d663fc6020c81aad19b238601d679fed7", + Coin: coin.ZCASH, + From: "t1T7cLkvDVScjw95WguoAZbbT8mrdqVtpiD", + To: "t1U4xs3qMxc2TL8wwYufmBngA5mewLHRwhM", + Inputs: []types.TxOutput{ + { + Address: "t1T7cLkvDVScjw95WguoAZbbT8mrdqVtpiD", + Value: "387582", + }, + }, + Outputs: []types.TxOutput{ + { + Address: "t1U4xs3qMxc2TL8wwYufmBngA5mewLHRwhM", + Value: "200997", + }, + { + Address: "t1VzWtLj9CSAK3QnxA7uuiK6XhJrjGjKoy4", + Value: "186359", + }, + }, + Fee: "226", + Date: 1549793065, + Type: "transfer", + Status: types.StatusCompleted, + Block: 479017, + Sequence: 0, + Direction: types.DirectionIncoming, + Meta: types.Transfer{ + Value: "200997", + Symbol: "ZEC", + Decimals: 8, + }, + } + + expectedPendingTx = types.Tx{ + ID: "a2d70bee124510c476f159fa83cdb34d663fc6020c81aad19b238601d679fed7", + Coin: coin.ZCASH, + From: "t1T7cLkvDVScjw95WguoAZbbT8mrdqVtpiD", + To: "t1U4xs3qMxc2TL8wwYufmBngA5mewLHRwhM", + Inputs: []types.TxOutput{ + { + Address: "t1T7cLkvDVScjw95WguoAZbbT8mrdqVtpiD", + Value: "387582", + }, + }, + Outputs: []types.TxOutput{ + { + Address: "t1U4xs3qMxc2TL8wwYufmBngA5mewLHRwhM", + Value: "200997", + }, + { + Address: "t1VzWtLj9CSAK3QnxA7uuiK6XhJrjGjKoy4", + Value: "186359", + }, + }, + Fee: "226", + Date: 1549793065, + Type: "transfer", + Status: types.StatusCompleted, + Block: 0, + Sequence: 0, + Direction: types.DirectionIncoming, + Meta: types.Transfer{ + Value: "200997", + Symbol: "ZEC", + Decimals: 8, + }, + } +) + +func TestNormalizeTransfer(t *testing.T) { + + outgoingTxSet := mapset.NewSet() + outgoingTxSet.Add("3FjBW1KL9L8aYtdKzJ8FhCNxmXB7dXDRw4") + outgoingTxSet.Add("3QJmV3qfvL9SuYo34YihAf3sRCW3qSinyC") + + incomingTxSet := mapset.NewSet() + incomingTxSet.Add("t1U4xs3qMxc2TL8wwYufmBngA5mewLHRwhM") + incomingTxSet.Add("t1ZBs9xvRypkjXmci2SS6zbNWVhuWH1h93L") + incomingTxSet.Add("t1VZp67AK9zgdXwa35kwYrJ1Mh4NWjUENrM") + + tests := []struct { + RawTx string + Expected types.Tx + AddressSet mapset.Set + }{ + {outgoingTx, expectedOutgoingTx, outgoingTxSet}, + {incomingTx, expectedIncomingTx, incomingTxSet}, + {pendingTx, expectedPendingTx, incomingTxSet}, + } + + for _, test := range tests { + var transaction blockbook.Transaction + + rErr := json.Unmarshal([]byte(test.RawTx), &transaction) + if rErr != nil { + t.Fatal(rErr) + } + + var readyTx types.Tx + normTx, ok := normalizeTransfer(transaction, test.Expected.Coin, test.AddressSet) + if !ok { + t.Fatal("Bitcoin: Can't normalize transaction", readyTx) + } + readyTx = normTx + + actual, err := json.Marshal(&readyTx) + if err != nil { + t.Fatal(err) + } + + expected, err := json.Marshal(&test.Expected) + if err != nil { + t.Fatal(err) + } + + assert.JSONEq(t, string(actual), string(expected)) + } +} + +func TestTransactionStatus(t *testing.T) { + tests := []struct { + Tx blockbook.Transaction + Expected types.Status + }{ + {blockbook.Transaction{Confirmations: 0}, types.StatusPending}, + {blockbook.Transaction{Confirmations: 1}, types.StatusCompleted}, + } + + for _, test := range tests { + assert.Equal(t, test.Expected, test.Tx.GetStatus()) + } +} + +func TestParseOutputs(t *testing.T) { + tests := []struct { + name string + outputs string + want []types.TxOutput + }{ + { + name: "Test Doge inputs from 0xb02977b96e5c65fd807e28230375c1267ded1de7c2c43292bf36552283bc5696", + outputs: `[{ + "txid": "6f59c4d96566c84aecb8399884d781766fe39d3ec76c609e6c11b01192c07341", + "sequence": 4294967295, + "n": 0, + "addresses": [ + "DPoYGk1wGQ3uWs5G3exd9WKvVyu8weKYVA" + ], + "isAddress": true, + "value": "10000000", + "hex": "47304402207bb4fe5709874e5bc82c88945f8abb9aebdab996a1a619b0f01ec9a2ca3f862702204c02f986653bbf322ff5813322b72a7f7ac6cedfabf32d8e576be5eeee4acfc4012103565519e77659aae844889ae12609309f85a8d22bf815c4daa418e457c7cb01eb" + }, + { + "txid": "b476736ec08dc16942941103806ec16ce71ddde4d5422dcf6f05b4381c23b8b0", + "sequence": 4294967295, + "n": 1, + "addresses": [ + "DPoYGk1wGQ3uWs5G3exd9WKvVyu8weKYVA" + ], + "isAddress": true, + "value": "500000000", + "hex": "48304502210085426a63df0fa1343a3f7aa8903804a8e49815006f9ed65494b68a81588e605c02207a487df90dcc76e4cbe70358054084b97d407529912762fb784aac825c120125012103565519e77659aae844889ae12609309f85a8d22bf815c4daa418e457c7cb01eb" + }, + { + "txid": "239582019ca4dd5e4ba4441cdd949d67eb2461b6f0600d77245355f751bf9fb4", + "sequence": 4294967295, + "n": 2, + "addresses": [ + "DPoYGk1wGQ3uWs5G3exd9WKvVyu8weKYVA" + ], + "isAddress": true, + "value": "500000000", + "hex": "473044022047cad0afd2aa4ff9b3fc45a6afb40b9745c1b39499a96df803f899d189f3822c0220267464d2954de54825717b93e3597a0915c71aecf1215ed33021bef376813b9a012103565519e77659aae844889ae12609309f85a8d22bf815c4daa418e457c7cb01eb" + }]`, + want: []types.TxOutput{ + { + Address: "DPoYGk1wGQ3uWs5G3exd9WKvVyu8weKYVA", + Value: "1010000000", + }, + }, + }, + { + name: "Test Doge outputs from 0xb02977b96e5c65fd807e28230375c1267ded1de7c2c43292bf36552283bc5696", + outputs: `[{ + "value": "1000000000", + "n": 0, + "spent": true, + "hex": "76a914e34df4959b71f9a06af1eeb4f836e521067b777988ac", + "addresses": [ + "DRryKEukopEDv7cm6Y1Li6232VHEjnXptA" + ], + "isAddress": true + }, + { + "value": "9973378", + "n": 1, + "hex": "76a914ccb78d11b3850ac3252c1cbda0a2ceeaa833feaf88ac", + "addresses": [ + "DPoYGk1wGQ3uWs5G3exd9WKvVyu8weKYVA" + ], + "isAddress": true + }]`, + want: []types.TxOutput{ + { + Address: "DRryKEukopEDv7cm6Y1Li6232VHEjnXptA", + Value: "1000000000", + }, + { + Address: "DPoYGk1wGQ3uWs5G3exd9WKvVyu8weKYVA", + Value: "9973378", + }, + }, + }, + } + for _, tt := range tests { + var outputs []blockbook.Output + _ = json.Unmarshal([]byte(tt.outputs), &outputs) + want := parseOutputs(outputs) + t.Run(tt.name, func(t *testing.T) { + if !reflect.DeepEqual(want, tt.want) { + t.Errorf("parseOutputs() = %v, want %v", want, tt.want) + } + }) + } +} diff --git a/platform/cosmos/base.go b/platform/cosmos/base.go new file mode 100644 index 000000000..f5842cd0d --- /dev/null +++ b/platform/cosmos/base.go @@ -0,0 +1,23 @@ +package cosmos + +import ( + "github.com/trustwallet/golibs/client" + "github.com/trustwallet/golibs/coin" + "github.com/trustwallet/golibs/network/middleware" +) + +type Platform struct { + client Client + CoinIndex uint +} + +func Init(coin uint, api string) *Platform { + return &Platform{ + CoinIndex: coin, + client: Client{client.InitClient(api, middleware.SentryErrorHandler)}, + } +} + +func (p *Platform) Coin() coin.Coin { + return coin.Coins[p.CoinIndex] +} diff --git a/platform/cosmos/block.go b/platform/cosmos/block.go new file mode 100644 index 000000000..3d053733a --- /dev/null +++ b/platform/cosmos/block.go @@ -0,0 +1,20 @@ +package cosmos + +import "github.com/trustwallet/golibs/types" + +func (p *Platform) GetBlockByNumber(num int64) (*types.Block, error) { + srcTxs, err := p.client.GetBlockByNumber(num) + if err != nil { + return nil, err + } + + txs := p.NormalizeTxs(srcTxs.Txs) + return &types.Block{ + Number: num, + Txs: txs, + }, nil +} + +func (p *Platform) CurrentBlockNumber() (int64, error) { + return p.client.CurrentBlockNumber() +} diff --git a/platform/cosmos/client.go b/platform/cosmos/client.go index ea59ad1d2..106e1bfe5 100644 --- a/platform/cosmos/client.go +++ b/platform/cosmos/client.go @@ -2,23 +2,23 @@ package cosmos import ( "fmt" - "github.com/trustwallet/blockatlas/pkg/blockatlas" - "github.com/trustwallet/blockatlas/pkg/errors" - "github.com/trustwallet/blockatlas/pkg/logger" "net/url" "strconv" + "time" + + "github.com/trustwallet/golibs/client" ) // Client - the HTTP client type Client struct { - blockatlas.Request + client.Request } // GetAddrTxs - get all ATOM transactions for a given address -func (c *Client) GetAddrTxs(address string, tag string) (txs TxPage, err error) { +func (c *Client) GetAddrTxs(address, tag string, page int) (txs TxPage, err error) { query := url.Values{ tag: {address}, - "page": {"1"}, + "page": {strconv.Itoa(page)}, "limit": {"25"}, } err = c.Get(&txs, "txs", query) @@ -30,9 +30,9 @@ func (c *Client) GetAddrTxs(address string, tag string) (txs TxPage, err error) func (c *Client) GetValidators() (validators Validators, err error) { query := url.Values{ - "status": {"bonded"}, + "status": {"BOND_STATUS_BONDED"}, } - err = c.Get(&validators, "staking/validators", query) + err = c.GetWithCache(&validators, "staking/validators", query, time.Minute*10) return } @@ -42,27 +42,27 @@ func (c *Client) GetBlockByNumber(num int64) (txs TxPage, err error) { } func (c *Client) CurrentBlockNumber() (num int64, err error) { - var block Block - err = c.Get(&block, "blocks/latest", nil) + var latest LasteBlock + err = c.Get(&latest, "blocks/latest", nil) if err != nil { return num, err } - num, err = strconv.ParseInt(block.Meta.Header.Height, 10, 64) + num, err = strconv.ParseInt(latest.Block.Header.Height, 10, 64) if err != nil { - return num, errors.E("error to ParseInt", errors.TypePlatformUnmarshal).PushToSentry() + return num, err } return } func (c *Client) GetPool() (result StakingPool, err error) { - return result, c.Get(&result, "staking/pool", nil) + return result, c.GetWithCache(&result, "staking/pool", nil, time.Minute*20) } func (c *Client) GetInflation() (inflation Inflation, err error) { - err = c.Get(&inflation, "minting/inflation", nil) + err = c.GetWithCache(&inflation, "minting/inflation", nil, time.Minute*20) return } @@ -70,7 +70,7 @@ func (c *Client) GetDelegations(address string) (delegations Delegations, err er path := fmt.Sprintf("staking/delegators/%s/delegations", address) err = c.Get(&delegations, path, nil) if err != nil { - logger.Error(err, "Cosmos: Failed to get delegations for address") + return delegations, err } return } @@ -79,7 +79,7 @@ func (c *Client) GetUnbondingDelegations(address string) (delegations UnbondingD path := fmt.Sprintf("staking/delegators/%s/unbonding_delegations", address) err = c.Get(&delegations, path, nil) if err != nil { - logger.Error(err, "Cosmos: Failed to get unbonding delegations for address") + return delegations, err } return } diff --git a/platform/cosmos/mocks/claim_1.json b/platform/cosmos/mocks/claim_1.json new file mode 100644 index 000000000..647337e98 --- /dev/null +++ b/platform/cosmos/mocks/claim_1.json @@ -0,0 +1,96 @@ +{ + "height": "79678", + "txhash": "C382DCFDC30E2DA294421DAEAD5862F118592A7B000EE91F6BEF8452A1F525D7", + "gas_wanted": "1600000", + "gas_used": "492252", + "tx": { + "type": "cosmos-sdk/StdTx", + "value": { + "msg": [ + { + "type": "cosmos-sdk/MsgWithdrawDelegationReward", + "value": { + "delegator_address": "cosmos1cxehfdhfm96ljpktdxsj0k6xp9gtuheghwgqug", + "validator_address": "cosmosvaloper1ptyzewnns2kn37ewtmv6ppsvhdnmeapvtfc9y5" + } + }, + { + "type": "cosmos-sdk/MsgWithdrawDelegationReward", + "value": { + "delegator_address": "cosmos1cxehfdhfm96ljpktdxsj0k6xp9gtuheghwgqug", + "validator_address": "cosmosvaloper1fhr7e04ct0zslmkzqt9smakg3sxrdve6ulclj2" + } + }, + { + "type": "cosmos-sdk/MsgWithdrawDelegationReward", + "value": { + "delegator_address": "cosmos1cxehfdhfm96ljpktdxsj0k6xp9gtuheghwgqug", + "validator_address": "cosmosvaloper1we6knm8qartmmh2r0qfpsz6pq0s7emv3e0meuw" + } + } + ], + "fee": { + "amount": [ + { + "denom": "uatom", + "amount": "1000" + } + ], + "gas": "1600000" + }, + "memo": "" + } + }, + "timestamp": "2019-12-18T03:04:33Z", + "logs": [ + { + "events": [ + { + "type": "transfer", + "attributes": [ + { + "key": "recipient", + "value": "cosmos1cxehfdhfm96ljpktdxsj0k6xp9gtuheghwgqug" + } + ] + }, + { + "type": "withdraw_rewards", + "attributes": [ + { + "key": "amount", + "value": "1138uatom" + }, + { + "key": "validator", + "value": "cosmosvaloper1ptyzewnns2kn37ewtmv6ppsvhdnmeapvtfc9y5" + }, + { + "key": "amount", + "value": "40612uatom" + }, + { + "key": "validator", + "value": "cosmosvaloper1fhr7e04ct0zslmkzqt9smakg3sxrdve6ulclj2" + }, + { + "key": "amount", + "value": "954uatom" + }, + { + "key": "validator", + "value": "cosmosvaloper1we6knm8qartmmh2r0qfpsz6pq0s7emv3e0meuw" + }, + { + "key": "amount", + "value": "43574uatom" + }, + { + "key": "amount" + } + ] + } + ] + } + ] +} diff --git a/platform/cosmos/mocks/claim_2.json b/platform/cosmos/mocks/claim_2.json new file mode 100644 index 000000000..d1fcf21cc --- /dev/null +++ b/platform/cosmos/mocks/claim_2.json @@ -0,0 +1,100 @@ +{ + "height": "54561", + "txhash": "082BA88EC055A7C343A353297EAC104CE87C659E0DDD84621C9AC3C284232800", + "gas_wanted": "300000", + "gas_used": "156772", + "tx": { + "type": "cosmos-sdk/StdTx", + "value": { + "msg": [ + { + "type": "cosmos-sdk/MsgWithdrawDelegationReward", + "value": { + "delegator_address": "cosmos1y6yvdel7zys8x60gz9067fjpcpygsn62ae9x46", + "validator_address": "cosmosvaloper12w6tynmjzq4l8zdla3v4x0jt8lt4rcz5gk7zg2" + } + }, + { + "type": "cosmos-sdk/MsgDelegate", + "value": { + "delegator_address": "cosmos1y6yvdel7zys8x60gz9067fjpcpygsn62ae9x46", + "validator_address": "cosmosvaloper12w6tynmjzq4l8zdla3v4x0jt8lt4rcz5gk7zg2", + "amount": { + "denom": "uatom", + "amount": "2692326" + } + } + } + ], + "fee": { + "amount": [ + { + "denom": "uatom", + "amount": "0" + } + ], + "gas": "300000" + }, + "memo": "复投" + } + }, + "timestamp": "2019-12-16T02:21:03Z", + "logs": [ + { + "events": [ + { + "type": "delegate", + "attributes": [ + { + "key": "validator", + "value": "cosmosvaloper12w6tynmjzq4l8zdla3v4x0jt8lt4rcz5gk7zg2" + }, + { + "key": "amount", + "value": "2692326" + } + ] + }, + { + "type": "message", + "attributes": [ + { + "key": "sender", + "value": "cosmos1jv65s3grqf6v6jl3dp4t6c9t9rk99cd88lyufl" + }, + { + "key": "module", + "value": "distribution" + } + ] + }, + { + "type": "transfer", + "attributes": [ + { + "key": "recipient", + "value": "cosmos1y6yvdel7zys8x60gz9067fjpcpygsn62ae9x46" + }, + { + "key": "amount", + "value": "2692701uatom" + } + ] + }, + { + "type": "withdraw_rewards", + "attributes": [ + { + "key": "amount", + "value": "2692701uatom" + }, + { + "key": "validator", + "value": "cosmosvaloper12w6tynmjzq4l8zdla3v4x0jt8lt4rcz5gk7zg2" + } + ] + } + ] + } + ] +} diff --git a/platform/cosmos/mocks/delegate_tx.json b/platform/cosmos/mocks/delegate_tx.json new file mode 100644 index 000000000..bf21c5b2f --- /dev/null +++ b/platform/cosmos/mocks/delegate_tx.json @@ -0,0 +1,66 @@ +{ + "height": "1258202", + "txhash": "11078091D1D5BD84F4275B6CEE02170428944DB0E8EEC37E980551435F6D04C7", + "raw_log": "[{\"msg_index\":\"0\",\"success\":true,\"log\":\"\"}]", + "logs": [ + { + "msg_index": "0", + "success": true, + "log": "" + } + ], + "gas_wanted": "200000", + "gas_used": "103206", + "tags": [ + { + "key": "action", + "value": "delegate" + }, + { + "key": "delegator", + "value": "cosmos1237l0vauhw78qtwq045jd24ay4urpec6r3xfn3" + }, + { + "key": "destination-validator", + "value": "cosmosvaloper12w6tynmjzq4l8zdla3v4x0jt8lt4rcz5gk7zg2" + } + ], + "tx": { + "type": "auth/StdTx", + "value": { + "msg": [ + { + "type": "cosmos-sdk/MsgDelegate", + "value": { + "delegator_address": "cosmos1237l0vauhw78qtwq045jd24ay4urpec6r3xfn3", + "validator_address": "cosmosvaloper12w6tynmjzq4l8zdla3v4x0jt8lt4rcz5gk7zg2", + "amount": { + "denom": "uatom", + "amount": "49920" + } + } + } + ], + "fee": { + "amount": [ + { + "denom": "uatom", + "amount": "5000" + } + ], + "gas": "200000" + }, + "signatures": [ + { + "pub_key": { + "type": "tendermint/PubKeySecp256k1", + "value": "AsZL4GaIEGW6ogh1rEasxHtmirpeBnycLz4VR0rSVr9p" + }, + "signature": "w6sNVzTSsE32ERbBdYYySSp6nj+4xNODuq5GKRVb8q04jMHUbx9AhuZeAhYrkvdkzOl3bD7vRYGx9P1V6yHj0A==" + } + ], + "memo": "" + } + }, + "timestamp": "2019-08-01T04:10:16Z" +} diff --git a/platform/cosmos/mocks/delegation.json b/platform/cosmos/mocks/delegation.json new file mode 100644 index 000000000..a374e03db --- /dev/null +++ b/platform/cosmos/mocks/delegation.json @@ -0,0 +1,9 @@ +[ + { + "delegation": { + "delegator_address": "cosmos135qla4294zxarqhhgxsx0sw56yssa3z0f78pm0", + "validator_address": "cosmosvaloper1qwl879nx9t6kef4supyazayf7vjhennyh568ys", + "shares": "109999.000001746056062372" + } + } +] diff --git a/platform/cosmos/mocks/transfer.json b/platform/cosmos/mocks/transfer.json new file mode 100644 index 000000000..4c4587fb2 --- /dev/null +++ b/platform/cosmos/mocks/transfer.json @@ -0,0 +1,68 @@ +{ + "height": "151980", + "txhash": "E19B011D20D862DA0BEA7F24E3BC6DFF666EE6E044FCD9BD95B073478086DBB6", + "raw_log": "[{\"msg_index\":\"0\",\"success\":true,\"log\":\"\"}]", + "logs": [ + { + "msg_index": "0", + "success": true, + "log": "" + } + ], + "gas_wanted": "100000", + "gas_used": "27678", + "tags": [ + { + "key": "action", + "value": "send" + }, + { + "key": "sender", + "value": "cosmos1rw62phusuv9vzraezr55k0vsqssvz6ed52zyrl" + }, + { + "key": "recipient", + "value": "cosmos1nynns8ex9fq6sjjfj8k79ymkdz4sqth06xexae" + } + ], + "tx": { + "type": "auth/StdTx", + "value": { + "msg": [ + { + "type": "cosmos-sdk/MsgSend", + "value": { + "from_address": "cosmos1rw62phusuv9vzraezr55k0vsqssvz6ed52zyrl", + "to_address": "cosmos1nynns8ex9fq6sjjfj8k79ymkdz4sqth06xexae", + "amount": [ + { + "denom": "uatom", + "amount": "2271999999" + } + ] + } + } + ], + "fee": { + "amount": [ + { + "denom": "uatom", + "amount": "1" + } + ], + "gas": "100000" + }, + "signatures": [ + { + "pub_key": { + "type": "tendermint/PubKeySecp256k1", + "value": "A21fdP6IbVC9hER5smiim8I4EbFeIF/bW81IKwmmsdjH" + }, + "signature": "MuR85p714L94tCenogRqzLh1bsbmhKTjs1L9JJPdhSVwQKh61EGlLqYGoUeN/n9xb+OOR9ESUOh2CAzVulKoVQ==" + } + ], + "memo": "" + } + }, + "timestamp": "2019-05-04T17:57:57Z" +} diff --git a/platform/cosmos/mocks/transfer_failed.json b/platform/cosmos/mocks/transfer_failed.json new file mode 100644 index 000000000..e3afe3aec --- /dev/null +++ b/platform/cosmos/mocks/transfer_failed.json @@ -0,0 +1,48 @@ +{ + "height": "5552", + "txhash": "5E78C65A8C1A6C8239EBBBBF2E42020E6ADBA8037EDEA83BF88E1A9159CF13B8", + "code": 12, + "raw_log": "{\"codespace\":\"sdk\",\"code\":12,\"message\":\"out of gas in location: WritePerByte; gasWanted: 40000, gasUsed: 40480\"}", + "gas_wanted": "40000", + "gas_used": "40480", + "tx": { + "type": "cosmos-sdk/StdTx", + "value": { + "msg": [ + { + "type": "cosmos-sdk/MsgSend", + "value": { + "from_address": "cosmos1shpfyt7psrff2ux7nznxvj6f7gq59fcqng5mku", + "to_address": "cosmos1za4pu5gxm80fg6sx0956f88l2sx7jfg2vf7nlc", + "amount": [ + { + "denom": "uatom", + "amount": "100000" + } + ] + } + } + ], + "fee": { + "amount": [ + { + "denom": "uatom", + "amount": "2000" + } + ], + "gas": "40000" + }, + "signatures": [ + { + "pub_key": { + "type": "tendermint/PubKeySecp256k1", + "value": "A0IDIokqw01U2YcdylvqD/sJHW5w9puS5vZWSf2GUaqL" + }, + "signature": "1Kwp4dBZUbVV6Fk8AFcmNfSqi7MXFfqyLvHexFZXoqcKh+sNuezry89RhDAWgSMNLyaK20hI2XcUyks+Vo4QEQ==" + } + ], + "memo": "UniCoins registration rewards" + } + }, + "timestamp": "2019-12-12T03:21:42Z" +} diff --git a/platform/cosmos/mocks/transfer_kava.json b/platform/cosmos/mocks/transfer_kava.json new file mode 100644 index 000000000..f1a4e8570 --- /dev/null +++ b/platform/cosmos/mocks/transfer_kava.json @@ -0,0 +1,68 @@ +{ + "height": "151980", + "txhash": "E19B011D20D862DA0BEA7F24E3BC6DFF666EE6E044FCD9BD95B073478086DBB6", + "raw_log": "[{\"msg_index\":\"0\",\"success\":true,\"log\":\"\"}]", + "logs": [ + { + "msg_index": "0", + "success": true, + "log": "" + } + ], + "gas_wanted": "100000", + "gas_used": "27678", + "tags": [ + { + "key": "action", + "value": "send" + }, + { + "key": "sender", + "value": "kava17wcggpjx007uc09s8y4hwrj8f228mlwe0n0upn" + }, + { + "key": "recipient", + "value": "kava1z89utvygweg5l56fsk8ak7t6hh88fd0agl98n0" + } + ], + "tx": { + "type": "auth/StdTx", + "value": { + "msg": [ + { + "type": "cosmos-sdk/MsgSend", + "value": { + "from_address": "kava17wcggpjx007uc09s8y4hwrj8f228mlwe0n0upn", + "to_address": "kava1z89utvygweg5l56fsk8ak7t6hh88fd0agl98n0", + "amount": [ + { + "denom": "uatom", + "amount": "2271999999" + } + ] + } + } + ], + "fee": { + "amount": [ + { + "denom": "uatom", + "amount": "1" + } + ], + "gas": "100000" + }, + "signatures": [ + { + "pub_key": { + "type": "tendermint/PubKeySecp256k1", + "value": "A21fdP6IbVC9hER5smiim8I4EbFeIF/bW81IKwmmsdjH" + }, + "signature": "MuR85p714L94tCenogRqzLh1bsbmhKTjs1L9JJPdhSVwQKh61EGlLqYGoUeN/n9xb+OOR9ESUOh2CAzVulKoVQ==" + } + ], + "memo": "" + } + }, + "timestamp": "2019-05-04T17:57:57Z" +} diff --git a/platform/cosmos/mocks/unbonding.json b/platform/cosmos/mocks/unbonding.json new file mode 100644 index 000000000..b5b91aafd --- /dev/null +++ b/platform/cosmos/mocks/unbonding.json @@ -0,0 +1,14 @@ +[ + { + "delegator_address": "cosmos135qla4294zxarqhhgxsx0sw56yssa3z0f78pm0", + "validator_address": "cosmosvaloper1qwl879nx9t6kef4supyazayf7vjhennyh568ys", + "entries": [ + { + "creation_height": "0", + "completion_time": "2020-01-01T06:54:18.441436491Z", + "initial_balance": "109999", + "balance": "109999" + } + ] + } +] diff --git a/platform/cosmos/mocks/undelegate_tx.json b/platform/cosmos/mocks/undelegate_tx.json new file mode 100644 index 000000000..c10967a3c --- /dev/null +++ b/platform/cosmos/mocks/undelegate_tx.json @@ -0,0 +1,71 @@ +{ + "height": "1257037", + "txhash": "A1EC36741FEF681F4A77B8F6032AD081100EE5ECB4CC76AEAC2174BC6B871CFE", + "data": "0C0889ECF7EA0510FB9D8CAD03", + "raw_log": "[{\"msg_index\":\"0\",\"success\":true,\"log\":\"\"}]", + "logs": [ + { + "msg_index": "0", + "success": true, + "log": "" + } + ], + "gas_wanted": "200000", + "gas_used": "107804", + "tags": [ + { + "key": "action", + "value": "begin_unbonding" + }, + { + "key": "delegator", + "value": "cosmos137rrp4p8n0nqcft0mwc62tdnyhhzf80knv5t94" + }, + { + "key": "source-validator", + "value": "cosmosvaloper1te8nxpc2myjfrhaty0dnzdhs5ahdh5agzuym9v" + }, + { + "key": "end-time", + "value": "2019-08-22T01:55:21Z" + } + ], + "tx": { + "type": "auth/StdTx", + "value": { + "msg": [ + { + "type": "cosmos-sdk/MsgUndelegate", + "value": { + "delegator_address": "cosmos137rrp4p8n0nqcft0mwc62tdnyhhzf80knv5t94", + "validator_address": "cosmosvaloper1te8nxpc2myjfrhaty0dnzdhs5ahdh5agzuym9v", + "amount": { + "denom": "uatom", + "amount": "5100000000" + } + } + } + ], + "fee": { + "amount": [ + { + "denom": "uatom", + "amount": "5000" + } + ], + "gas": "200000" + }, + "signatures": [ + { + "pub_key": { + "type": "tendermint/PubKeySecp256k1", + "value": "A+tPzMXCW7vxmW5VN9Q/CO+fxnEXYlSMOklDVgaFutQD" + }, + "signature": "rh25A/RTm8TUTUGOGhufqxn9vLFef/04xEKMJLUD5QhBVabRADvEgAP1J842XTDtVBS0SpVD/MrPduqRp0nNzg==" + } + ], + "memo": "" + } + }, + "timestamp": "2019-08-01T01:55:21Z" +} diff --git a/platform/cosmos/mocks/validator.json b/platform/cosmos/mocks/validator.json new file mode 100644 index 000000000..ce86167a5 --- /dev/null +++ b/platform/cosmos/mocks/validator.json @@ -0,0 +1,26 @@ +{ + "operator_address": "cosmosvaloper1lktjhnzkpkz3ehrg8psvmwhafg56kfss3q3t8m", + "consensus_pubkey": { + "type": "tendermint/PubKeyEd25519", + "value": "z/Dg9WU/rlIB+LaQVMMHW/a7rvalfIcyz3VdOwfvguc=" + }, + "status": 3, + "tokens": "597103578752", + "delegator_shares": "597103578752.000000000000000000", + "description": { + "moniker": "Umbrella ☔", + "identity": "A530AC4D75991FE2", + "website": "https://umbrellavalidator.com", + "details": "One of the winners of Cosmos Game of Stakes, and HackAtom3." + }, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.070400000000000000", + "max_rate": "1.000000000000000000", + "max_change_rate": "0.100000000000000000" + }, + "update_time": "2020-09-01T18:40:38.071399488Z" + }, + "min_self_delegation": "1" +} diff --git a/platform/cosmos/model.go b/platform/cosmos/model.go index 09d7c2e82..49b705b2f 100644 --- a/platform/cosmos/model.go +++ b/platform/cosmos/model.go @@ -39,16 +39,17 @@ const ( // Tx - Base transaction object. Always returned as part of an array type Tx struct { - Block string `json:"height"` - Code int `json:"code"` - Date string `json:"timestamp"` - ID string `json:"txhash"` - Data Data `json:"tx"` - Events Events `json:"events"` + Block string `json:"height"` + Code int `json:"code"` + Date string `json:"timestamp"` + ID string `json:"txhash"` + Data Data `json:"tx"` + Logs Logs `json:"logs"` } type TxPage struct { - Txs []Tx `json:"txs"` + PageTotal string `json:"page_total"` + Txs []Tx `json:"txs"` } // Events @@ -57,13 +58,19 @@ type Event struct { Attributes Attributes `json:"Attributes"` } -type Events []*Event +type Events struct { + Events []Event `json:"events"` +} + +type Logs []*Events -func (e Events) GetWithdrawRewardValue() string { +func (l Logs) GetWithdrawRewardValue() string { result := int64(0) - for _, att := range e { - if att.Type == EventWithdrawRewards { - result += att.Attributes.GetWithdrawRewardValue() + for _, log := range l { + for _, att := range log.Events { + if att.Type == EventWithdrawRewards { + result += att.Attributes.GetWithdrawRewardValue() + } } } return strconv.FormatInt(result, 10) @@ -164,13 +171,17 @@ type Inflation struct { } type Delegations struct { - List []Delegation `json:"result"` + List []DelegationValue `json:"result"` +} + +type DelegationValue struct { + Delegation Delegation `json:"delegation"` } type Delegation struct { DelegatorAddress string `json:"delegator_address"` ValidatorAddress string `json:"validator_address"` - Shares string `json:"shares,omitempty"` + Shares string `json:"shares"` } func (d *Delegation) Value() string { @@ -205,17 +216,14 @@ type Pool struct { BondedTokens string `json:"bonded_tokens"` } -// Block - top object of get las block request -type Block struct { - Meta BlockMeta `json:"block_meta"` +type LasteBlock struct { + Block Block `json:"block"` } -//BlockMeta - "Block" sub object -type BlockMeta struct { +type Block struct { Header BlockHeader `json:"header"` } -//BlockHeader - "BlockMeta" sub object, height type BlockHeader struct { Height string `json:"height"` } diff --git a/platform/cosmos/stake.go b/platform/cosmos/stake.go index d6f17e17e..c66741255 100644 --- a/platform/cosmos/stake.go +++ b/platform/cosmos/stake.go @@ -1,15 +1,32 @@ package cosmos import ( - "github.com/trustwallet/blockatlas/coin" - "github.com/trustwallet/blockatlas/pkg/blockatlas" - "github.com/trustwallet/blockatlas/pkg/errors" - "github.com/trustwallet/blockatlas/pkg/logger" - services "github.com/trustwallet/blockatlas/services/assets" "strconv" "time" + + log "github.com/sirupsen/logrus" + "github.com/trustwallet/blockatlas/pkg/blockatlas" + "github.com/trustwallet/blockatlas/services/assets" + "github.com/trustwallet/golibs/coin" ) +const ( + lockTime = 1814400 // in seconds (21 days) + minimumAmount = "1" +) + +func (p *Platform) GetActiveValidators() (blockatlas.StakeValidators, error) { + validators, err := assets.GetValidatorsMap(p) + if err != nil { + return nil, err + } + result := make(blockatlas.StakeValidators, 0, len(validators)) + for _, v := range validators { + result = append(result, v) + } + return result, nil +} + func (p *Platform) GetValidators() (blockatlas.ValidatorPage, error) { results := make(blockatlas.ValidatorPage, 0) validators, err := p.client.GetValidators() @@ -27,7 +44,7 @@ func (p *Platform) GetValidators() (blockatlas.ValidatorPage, error) { } inflationValue, err := strconv.ParseFloat(inflation.Result, 32) if err != nil { - return nil, errors.E("error to parse inflationValue to float", errors.TypePlatformUnmarshal).PushToSentry() + return nil, err } for _, validator := range validators.Result { @@ -38,11 +55,15 @@ func (p *Platform) GetValidators() (blockatlas.ValidatorPage, error) { } func (p *Platform) GetDetails() blockatlas.StakingDetails { - //TODO: Find a way to have a dynamic + apr := blockatlas.DefaultAnnualReward + validators, err := p.GetValidators() + if err == nil { + apr = blockatlas.FindHightestAPR(validators) + } return blockatlas.StakingDetails{ - Reward: blockatlas.StakingReward{Annual: 11}, - MinimumAmount: blockatlas.Amount("0"), - LockTime: 1814400, + Reward: blockatlas.StakingReward{Annual: apr}, + MinimumAmount: minimumAmount, + LockTime: lockTime, Type: blockatlas.DelegationTypeDelegate, } } @@ -60,7 +81,7 @@ func (p *Platform) GetDelegations(address string) (blockatlas.DelegationsPage, e if delegations.List == nil && unbondingDelegations.List == nil { return results, nil } - validators, err := services.GetValidatorsMap(p) + validators, err := assets.GetValidatorsMap(p) if err != nil { return nil, err } @@ -75,25 +96,28 @@ func (p *Platform) UndelegatedBalance(address string) (string, error) { if err != nil { return "0", err } - for _, coin := range account.Account.Value.Coins { - if coin.Denom == p.Denom() { - return coin.Amount, nil + for _, c := range account.Account.Value.Coins { + if c.Denom == p.Denom() { + return c.Amount, nil } } return "0", nil } -func NormalizeDelegations(delegations []Delegation, validators blockatlas.ValidatorMap) []blockatlas.Delegation { +func NormalizeDelegations(delegations []DelegationValue, validators blockatlas.ValidatorMap) []blockatlas.Delegation { results := make([]blockatlas.Delegation, 0) for _, v := range delegations { - validator, ok := validators[v.ValidatorAddress] + validator, ok := validators[v.Delegation.ValidatorAddress] if !ok { - logger.Error(errors.E("Validator not found", errors.Params{"address": v.ValidatorAddress, "platform": "cosmos", "delegation": v.DelegatorAddress})) - continue + log.WithFields( + log.Fields{"address": v.Delegation.ValidatorAddress, "platform": "cosmos", "delegation": v.Delegation.DelegatorAddress}, + ).Warn("Validator not found") + validator = getUnknownValidator(v.Delegation.ValidatorAddress) + } delegation := blockatlas.Delegation{ Delegator: validator, - Value: v.Value(), + Value: v.Delegation.Value(), Status: blockatlas.DelegationStatusActive, } results = append(results, delegation) @@ -107,8 +131,10 @@ func NormalizeUnbondingDelegations(delegations []UnbondingDelegation, validators for _, entry := range v.Entries { validator, ok := validators[v.ValidatorAddress] if !ok { - logger.Error(errors.E("Validator not found", errors.Params{"address": v.ValidatorAddress, "platform": "cosmos", "delegation": v.DelegatorAddress})) - continue + log.WithFields( + log.Fields{"address": v.ValidatorAddress, "platform": "cosmos", "delegation": v.DelegatorAddress}, + ).Warn("Validator not found") + validator = getUnknownValidator(v.ValidatorAddress) } t, _ := time.Parse(time.RFC3339, entry.CompletionTime) delegation := blockatlas.Delegation{ @@ -128,12 +154,12 @@ func NormalizeUnbondingDelegations(delegations []UnbondingDelegation, validators func normalizeValidator(v Validator, p Pool, inflation float64) (validator blockatlas.Validator) { reward := CalculateAnnualReward(p, inflation, v) return blockatlas.Validator{ - Status: v.Status == 2, + Status: v.Status == 3, ID: v.Address, Details: blockatlas.StakingDetails{ Reward: blockatlas.StakingReward{Annual: reward}, - MinimumAmount: "0", - LockTime: 1814400, + MinimumAmount: minimumAmount, + LockTime: lockTime, Type: blockatlas.DelegationTypeDelegate, }, } @@ -168,3 +194,22 @@ func (p *Platform) Denom() DenomType { return DenomAtom } } + +func getUnknownValidator(address string) blockatlas.StakeValidator { + return blockatlas.StakeValidator{ + ID: address, + Status: false, + Info: blockatlas.StakeValidatorInfo{ + Name: "Decommissioned", + Description: "Decommissioned", + }, + Details: blockatlas.StakingDetails{ + Reward: blockatlas.StakingReward{ + Annual: 0, + }, + LockTime: lockTime, + MinimumAmount: minimumAmount, + Type: blockatlas.DelegationTypeDelegate, + }, + } +} diff --git a/platform/cosmos/stake_test.go b/platform/cosmos/stake_test.go index 66ba606b0..bf6c0f7f4 100644 --- a/platform/cosmos/stake_test.go +++ b/platform/cosmos/stake_test.go @@ -2,70 +2,42 @@ package cosmos import ( "encoding/json" - "github.com/trustwallet/blockatlas/pkg/blockatlas" "testing" + "github.com/trustwallet/blockatlas/pkg/blockatlas" + "github.com/stretchr/testify/assert" + "github.com/trustwallet/golibs/mock" ) -const validatorSrc = ` -{ - "operator_address": "cosmosvaloper1lktjhnzkpkz3ehrg8psvmwhafg56kfss3q3t8m", - "consensus_pubkey": "cosmosvalconspub1zcjduepqelcwpat987h9yq0ck6g9fsc8t0mththk547gwvk0w4wnkpl0stnspr3hdc", - "jailed": false, - "status": 2, - "tokens": "1557750969185", - "delegator_shares": "1557750969185.000000000000000000", - "description": { - "moniker": "Umbrella ☔", - "identity": "A530AC4D75991FE2", - "website": "https://umbrellavalidator.com", - "details": "One of the winners of Cosmos Game of Stakes, and HackAtom3." - }, - "unbonding_height": "0", - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.070400000000000000", - "max_rate": "1.000000000000000000", - "max_change_rate": "0.100000000000000000", - "update_time": "2019-08-05T07:10:23.689753607Z" - } - }, - "min_self_delegation": "1" -}` - -const delegationsSrc = ` -[ - { - "delegator_address": "cosmos135qla4294zxarqhhgxsx0sw56yssa3z0f78pm0", - "validator_address": "cosmosvaloper1qwl879nx9t6kef4supyazayf7vjhennyh568ys", - "shares": "109999.000001746056062372", - "balance": "0" - } -]` - -const unbondingDelegationsSrc = ` -[ - { - "delegator_address": "cosmos135qla4294zxarqhhgxsx0sw56yssa3z0f78pm0", - "validator_address": "cosmosvaloper1qwl879nx9t6kef4supyazayf7vjhennyh568ys", - "entries": [ - { - "creation_height": "0", - "completion_time": "2020-01-01T06:54:18.441436491Z", - "initial_balance": "109999", - "balance": "109999" - } - ] - } -]` - -var stakingPool = Pool{"1222", "200"} - -var cosmosValidator = Validator{Commission: CosmosCommission{CosmosCommissionRates{Rate: "0.4"}}} - -var inflation = 0.7 +var ( + validatorSrc, _ = mock.JsonStringFromFilePath("mocks/" + "validator.json") + delegationsSrc, _ = mock.JsonStringFromFilePath("mocks/" + "delegation.json") + unbondingDelegationsSrc, _ = mock.JsonStringFromFilePath("mocks/" + "unbonding.json") + stakingPool = Pool{"1222", "200"} + cosmosValidator = Validator{Commission: CosmosCommission{CosmosCommissionRates{Rate: "0.4"}}} + inflation = 0.7 + validatorMap = blockatlas.ValidatorMap{ + "cosmosvaloper1qwl879nx9t6kef4supyazayf7vjhennyh568ys": validator1, + } + validator1 = blockatlas.StakeValidator{ + ID: "cosmosvaloper1qwl879nx9t6kef4supyazayf7vjhennyh568ys", + Status: true, + Info: blockatlas.StakeValidatorInfo{ + Name: "Certus One", + Description: "Stake and earn rewards with the most secure and stable validator. Winner of the Game of Stakes. Operated by Certus One Inc. By delegating, you confirm that you are aware of the risk of slashing and that Certus One Inc is not liable for any potential damages to your investment.", + Image: "https://assets.trustwalletapp.com/blockchains/cosmos/validators/assets/cosmosvaloper1qwl879nx9t6kef4supyazayf7vjhennyh568ys/logo.png", + Website: "https://certus.one", + }, + Details: blockatlas.StakingDetails{ + Reward: blockatlas.StakingReward{ + Annual: 9.259735525366604, + }, + LockTime: lockTime, + MinimumAmount: minimumAmount, + }, + } +) func TestNormalizeValidator(t *testing.T) { var v Validator @@ -75,8 +47,8 @@ func TestNormalizeValidator(t *testing.T) { ID: v.Address, Details: blockatlas.StakingDetails{ Reward: blockatlas.StakingReward{Annual: 462.6619201898575}, - LockTime: 1814400, - MinimumAmount: "0", + LockTime: lockTime, + MinimumAmount: minimumAmount, Type: blockatlas.DelegationTypeDelegate, }, } @@ -89,30 +61,8 @@ func TestCalculateAnnualReward(t *testing.T) { assert.Equal(t, 298.61999703347686, result) } -var validator1 = blockatlas.StakeValidator{ - ID: "cosmosvaloper1qwl879nx9t6kef4supyazayf7vjhennyh568ys", - Status: true, - Info: blockatlas.StakeValidatorInfo{ - Name: "Certus One", - Description: "Stake and earn rewards with the most secure and stable validator. Winner of the Game of Stakes. Operated by Certus One Inc. By delegating, you confirm that you are aware of the risk of slashing and that Certus One Inc is not liable for any potential damages to your investment.", - Image: "https://raw.githubusercontent.com/trustwallet/assets/master/blockchains/cosmos/validators/assets/cosmosvaloper1qwl879nx9t6kef4supyazayf7vjhennyh568ys/logo.png", - Website: "https://certus.one", - }, - Details: blockatlas.StakingDetails{ - Reward: blockatlas.StakingReward{ - Annual: 9.259735525366604, - }, - LockTime: 1814400, - MinimumAmount: "0", - }, -} - -var validatorMap = blockatlas.ValidatorMap{ - "cosmosvaloper1qwl879nx9t6kef4supyazayf7vjhennyh568ys": validator1, -} - func TestNormalizeDelegations(t *testing.T) { - var delegations []Delegation + var delegations []DelegationValue err := json.Unmarshal([]byte(delegationsSrc), &delegations) assert.NoError(t, err) assert.NotNil(t, delegations) diff --git a/platform/cosmos/api.go b/platform/cosmos/transaction.go similarity index 50% rename from platform/cosmos/api.go rename to platform/cosmos/transaction.go index 400aa29d5..f483ecbe1 100644 --- a/platform/cosmos/api.go +++ b/platform/cosmos/transaction.go @@ -1,72 +1,59 @@ package cosmos import ( - "fmt" - "github.com/spf13/viper" - "github.com/trustwallet/blockatlas/coin" - "github.com/trustwallet/blockatlas/pkg/blockatlas" - "github.com/trustwallet/blockatlas/pkg/numbers" "strconv" "sync" "time" -) - -type Platform struct { - client Client - CoinIndex uint -} - -func (p *Platform) Init() error { - p.client = Client{blockatlas.InitClient(viper.GetString(p.ConfigKey()))} - return nil -} - -func (p *Platform) Coin() coin.Coin { - return coin.Coins[p.CoinIndex] -} - -func (p *Platform) ConfigKey() string { - return fmt.Sprintf("%s.api", p.Coin().Handle) -} - -func (p *Platform) GetBlockByNumber(num int64) (*blockatlas.Block, error) { - srcTxs, err := p.client.GetBlockByNumber(num) - if err != nil { - return nil, err - } - txs := p.NormalizeTxs(srcTxs.Txs) - return &blockatlas.Block{ - Number: num, - Txs: txs, - }, nil -} - -func (p *Platform) CurrentBlockNumber() (int64, error) { - return p.client.CurrentBlockNumber() -} + "github.com/trustwallet/golibs/numbers" + "github.com/trustwallet/golibs/types" +) -func (p *Platform) GetTxsByAddress(address string) (blockatlas.TxPage, error) { - srcTxs := make([]Tx, 0) +func (p *Platform) GetTxsByAddress(address string) (types.Txs, error) { tagsList := []string{"transfer.recipient", "message.sender"} - var wg sync.WaitGroup + out := make(chan []Tx, len(tagsList)) + wg.Add(len(tagsList)) for _, t := range tagsList { - wg.Add(1) - go func(tag, addr string) { + go func(tag, addr string, wg *sync.WaitGroup) { defer wg.Done() - txs, _ := p.client.GetAddrTxs(addr, tag) - srcTxs = append(srcTxs, txs.Txs...) - }(t, address) + page := 1 + txs, err := p.client.GetAddrTxs(addr, tag, page) + if err != nil { + return + } + // Condition when no more pages to paginate + if txs.PageTotal == "1" || txs.PageTotal == "0" { + out <- txs.Txs + return + } + + totalPages, err := strconv.Atoi(txs.PageTotal) + if err != nil { + return + } + // gaia does support sort option, paginate to get latest transactions by passing total pages page + // https://github.com/cosmos/gaia/blob/f61b391aee5d04364d2b5539692bbb187ad9b946/docs/resources/gaiacli.md#query-transactions + txs2, err := p.client.GetAddrTxs(addr, tag, totalPages) + if err != nil { + return + } + out <- txs2.Txs + }(t, address, &wg) } wg.Wait() + close(out) + srcTxs := make([]Tx, 0) + for r := range out { + srcTxs = append(srcTxs, r...) + } return p.NormalizeTxs(srcTxs), nil } // NormalizeTxs converts multiple Cosmos transactions -func (p *Platform) NormalizeTxs(srcTxs []Tx) blockatlas.TxPage { +func (p *Platform) NormalizeTxs(srcTxs []Tx) types.Txs { txMap := make(map[string]bool) - txs := make(blockatlas.TxPage, 0) + txs := make(types.Txs, 0) for _, srcTx := range srcTxs { _, ok := txMap[srcTx.ID] if ok { @@ -82,14 +69,14 @@ func (p *Platform) NormalizeTxs(srcTxs []Tx) blockatlas.TxPage { } // Normalize converts an Cosmos transaction into the generic model -func (p *Platform) Normalize(srcTx *Tx) (tx blockatlas.Tx, ok bool) { +func (p *Platform) Normalize(srcTx *Tx) (tx types.Tx, ok bool) { date, err := time.Parse("2006-01-02T15:04:05Z", srcTx.Date) if err != nil { - return blockatlas.Tx{}, false + return types.Tx{}, false } block, err := strconv.ParseUint(srcTx.Block, 10, 64) if err != nil { - return blockatlas.Tx{}, false + return types.Tx{}, false } // Sometimes fees can be null objects (in the case of no fees e.g. F044F91441C460EDCD90E0063A65356676B7B20684D94C731CF4FAB204035B41) fee := "0" @@ -98,23 +85,23 @@ func (p *Platform) Normalize(srcTx *Tx) (tx blockatlas.Tx, ok bool) { if len(qty) > 0 && qty != fee { fee, err = numbers.DecimalToSatoshis(srcTx.Data.Contents.Fee.FeeAmount[0].Quantity) if err != nil { - return blockatlas.Tx{}, false + return types.Tx{}, false } } } - status := blockatlas.StatusCompleted + status := types.StatusCompleted // https://github.com/cosmos/cosmos-sdk/blob/95ddc242ad024ca78a359a13122dade6f14fd676/types/errors/errors.go#L19 if srcTx.Code > 0 { - status = blockatlas.StatusFailed + status = types.StatusError } - tx = blockatlas.Tx{ + tx = types.Tx{ ID: srcTx.ID, Coin: p.Coin().ID, Date: date.Unix(), Status: status, - Fee: blockatlas.Amount(fee), + Fee: types.Amount(fee), Block: block, Memo: srcTx.Data.Contents.Memo, } @@ -131,13 +118,13 @@ func (p *Platform) Normalize(srcTx *Tx) (tx blockatlas.Tx, ok bool) { return tx, true case MessageValueDelegate: delegate := msg.Value.(MessageValueDelegate) - p.fillDelegate(&tx, delegate, srcTx.Events, msg.Type) + p.fillDelegate(&tx, delegate, srcTx.Logs, msg.Type) return tx, true } return tx, false } -func (p *Platform) fillTransfer(tx *blockatlas.Tx, transfer MessageValueTransfer) { +func (p *Platform) fillTransfer(tx *types.Tx, transfer MessageValueTransfer) { if len(transfer.Amount) == 0 { return } @@ -147,45 +134,49 @@ func (p *Platform) fillTransfer(tx *blockatlas.Tx, transfer MessageValueTransfer } tx.From = transfer.FromAddr tx.To = transfer.ToAddr - tx.Type = blockatlas.TxTransfer - tx.Meta = blockatlas.Transfer{ - Value: blockatlas.Amount(value), + tx.Type = types.TxTransfer + tx.Meta = types.Transfer{ + Value: types.Amount(value), Symbol: p.Coin().Symbol, Decimals: p.Coin().Decimals, } } -func (p *Platform) fillDelegate(tx *blockatlas.Tx, delegate MessageValueDelegate, events Events, msgType TxType) { - value, err := numbers.DecimalToSatoshis(delegate.Amount.Quantity) - if err != nil { - return +func (p *Platform) fillDelegate(tx *types.Tx, delegate MessageValueDelegate, logs Logs, msgType TxType) { + value := "" + if len(delegate.Amount.Quantity) > 0 { + var err error + value, err = numbers.DecimalToSatoshis(delegate.Amount.Quantity) + if err != nil { + return + } } tx.From = delegate.DelegatorAddr tx.To = delegate.ValidatorAddr - tx.Type = blockatlas.TxAnyAction + tx.Type = types.TxAnyAction - key := blockatlas.KeyStakeDelegate - title := blockatlas.KeyTitle("") + key := types.KeyStakeDelegate + title := types.KeyTitle("") switch msgType { case MsgDelegate: - tx.Direction = blockatlas.DirectionOutgoing - title = blockatlas.AnyActionDelegation + tx.Direction = types.DirectionOutgoing + title = types.AnyActionDelegation case MsgUndelegate: - tx.Direction = blockatlas.DirectionIncoming - title = blockatlas.AnyActionUndelegation + tx.Direction = types.DirectionIncoming + title = types.AnyActionUndelegation case MsgWithdrawDelegationReward: - tx.Direction = blockatlas.DirectionIncoming - title = blockatlas.AnyActionClaimRewards - key = blockatlas.KeyStakeClaimRewards - value = events.GetWithdrawRewardValue() + tx.Direction = types.DirectionIncoming + title = types.AnyActionClaimRewards + key = types.KeyStakeClaimRewards + value = logs.GetWithdrawRewardValue() } - tx.Meta = blockatlas.AnyAction{ + tx.Meta = types.AnyAction{ Coin: p.Coin().ID, Title: title, Key: key, Name: p.Coin().Name, Symbol: p.Coin().Symbol, Decimals: p.Coin().Decimals, - Value: blockatlas.Amount(value), + Value: types.Amount(value), } } diff --git a/platform/cosmos/transaction_test.go b/platform/cosmos/transaction_test.go new file mode 100644 index 000000000..e55f71101 --- /dev/null +++ b/platform/cosmos/transaction_test.go @@ -0,0 +1,239 @@ +package cosmos + +import ( + "encoding/json" + "testing" + + "github.com/stretchr/testify/assert" + + "github.com/trustwallet/golibs/coin" + "github.com/trustwallet/golibs/mock" + "github.com/trustwallet/golibs/types" +) + +var ( + transferSrc, _ = mock.JsonStringFromFilePath("mocks/" + "transfer.json") + transferSrcKava, _ = mock.JsonStringFromFilePath("mocks/" + "transfer_kava.json") + failedTransferSrc, _ = mock.JsonStringFromFilePath("mocks/" + "transfer_failed.json") + delegateSrc, _ = mock.JsonStringFromFilePath("mocks/" + "delegate_tx.json") + unDelegateSrc, _ = mock.JsonStringFromFilePath("mocks/" + "undelegate_tx.json") + claimRewardSrc1, _ = mock.JsonStringFromFilePath("mocks/" + "claim_1.json") + claimRewardSrc2, _ = mock.JsonStringFromFilePath("mocks/" + "claim_2.json") + + atom = coin.Cosmos() + kava = coin.Kava() + + transferDst = types.Tx{ + ID: "E19B011D20D862DA0BEA7F24E3BC6DFF666EE6E044FCD9BD95B073478086DBB6", + Coin: atom.ID, + From: "cosmos1rw62phusuv9vzraezr55k0vsqssvz6ed52zyrl", + To: "cosmos1nynns8ex9fq6sjjfj8k79ymkdz4sqth06xexae", + Fee: "1", + Date: 1556992677, + Block: 151980, + Status: types.StatusCompleted, + Type: types.TxTransfer, + Meta: types.Transfer{ + Value: "2271999999", + Symbol: coin.Cosmos().Symbol, + Decimals: 6, + }, + } + + transferDstKava = types.Tx{ + ID: "E19B011D20D862DA0BEA7F24E3BC6DFF666EE6E044FCD9BD95B073478086DBB6", + Coin: kava.ID, + From: "kava17wcggpjx007uc09s8y4hwrj8f228mlwe0n0upn", + To: "kava1z89utvygweg5l56fsk8ak7t6hh88fd0agl98n0", + Fee: "1", + Date: 1556992677, + Block: 151980, + Status: types.StatusCompleted, + Type: types.TxTransfer, + Meta: types.Transfer{ + Value: "2271999999", + Symbol: kava.Symbol, + Decimals: 6, + }, + } + + delegateDst = types.Tx{ + ID: "11078091D1D5BD84F4275B6CEE02170428944DB0E8EEC37E980551435F6D04C7", + Coin: atom.ID, + From: "cosmos1237l0vauhw78qtwq045jd24ay4urpec6r3xfn3", + To: "cosmosvaloper12w6tynmjzq4l8zdla3v4x0jt8lt4rcz5gk7zg2", + Fee: "5000", + Date: 1564632616, + Block: 1258202, + Status: types.StatusCompleted, + Type: types.TxAnyAction, + Direction: types.DirectionOutgoing, + Meta: types.AnyAction{ + Coin: atom.ID, + Title: types.AnyActionDelegation, + Key: types.KeyStakeDelegate, + Name: atom.Name, + Symbol: atom.Symbol, + Decimals: atom.Decimals, + Value: "49920", + }, + } + + unDelegateDst = types.Tx{ + ID: "A1EC36741FEF681F4A77B8F6032AD081100EE5ECB4CC76AEAC2174BC6B871CFE", + Coin: atom.ID, + From: "cosmos137rrp4p8n0nqcft0mwc62tdnyhhzf80knv5t94", + To: "cosmosvaloper1te8nxpc2myjfrhaty0dnzdhs5ahdh5agzuym9v", + Fee: "5000", + Date: 1564624521, + Block: 1257037, + Status: types.StatusCompleted, + Type: types.TxAnyAction, + Direction: types.DirectionIncoming, + Meta: types.AnyAction{ + Coin: atom.ID, + Title: types.AnyActionUndelegation, + Key: types.KeyStakeDelegate, + Name: atom.Name, + Symbol: atom.Symbol, + Decimals: atom.Decimals, + Value: "5100000000", + }, + } + + claimRewardDst2 = types.Tx{ + ID: "082BA88EC055A7C343A353297EAC104CE87C659E0DDD84621C9AC3C284232800", + Coin: atom.ID, + From: "cosmos1y6yvdel7zys8x60gz9067fjpcpygsn62ae9x46", + To: "cosmosvaloper12w6tynmjzq4l8zdla3v4x0jt8lt4rcz5gk7zg2", + Fee: "0", + Date: 1576462863, + Block: 54561, + Status: types.StatusCompleted, + Type: types.TxAnyAction, + Direction: types.DirectionIncoming, + Memo: "复投", + Meta: types.AnyAction{ + Coin: atom.ID, + Title: types.AnyActionClaimRewards, + Key: types.KeyStakeClaimRewards, + Name: atom.Name, + Symbol: atom.Symbol, + Decimals: atom.Decimals, + Value: "2692701", + }, + } + + claimRewardDst1 = types.Tx{ + ID: "C382DCFDC30E2DA294421DAEAD5862F118592A7B000EE91F6BEF8452A1F525D7", + Coin: atom.ID, + From: "cosmos1cxehfdhfm96ljpktdxsj0k6xp9gtuheghwgqug", + To: "cosmosvaloper1ptyzewnns2kn37ewtmv6ppsvhdnmeapvtfc9y5", + Fee: "1000", + Date: 1576638273, + Block: 79678, + Status: types.StatusCompleted, + Type: types.TxAnyAction, + Direction: types.DirectionIncoming, + Memo: "", + Meta: types.AnyAction{ + Coin: atom.ID, + Title: types.AnyActionClaimRewards, + Key: types.KeyStakeClaimRewards, + Name: atom.Name, + Symbol: atom.Symbol, + Decimals: atom.Decimals, + Value: "86278", + }, + } + + failedTransferDst = types.Tx{ + ID: "5E78C65A8C1A6C8239EBBBBF2E42020E6ADBA8037EDEA83BF88E1A9159CF13B8", + Coin: atom.ID, + From: "cosmos1shpfyt7psrff2ux7nznxvj6f7gq59fcqng5mku", + To: "cosmos1za4pu5gxm80fg6sx0956f88l2sx7jfg2vf7nlc", + Fee: "2000", + Date: 1576120902, + Block: 5552, + Status: types.StatusError, + Type: types.TxTransfer, + Memo: "UniCoins registration rewards", + Meta: types.Transfer{ + Value: "100000", + Symbol: coin.Cosmos().Symbol, + Decimals: 6, + }, + } +) + +type test struct { + name string + platform Platform + Data string + want types.Tx +} + +func TestNormalize(t *testing.T) { + + cosmos := Platform{CoinIndex: atom.ID} + kava := Platform{CoinIndex: coin.KAVA} + + tests := []test{ + { + "test transfer tx", + cosmos, + transferSrc, + transferDst, + }, + { + "test delegate tx", + cosmos, + delegateSrc, + delegateDst, + }, + { + "test undelegate tx", + cosmos, + unDelegateSrc, + unDelegateDst, + }, + { + "test claimReward tx 1", + cosmos, + claimRewardSrc1, + claimRewardDst1, + }, + { + "test claimReward tx 2", + cosmos, + claimRewardSrc2, + claimRewardDst2, + }, + { + "test failed tx", + cosmos, + failedTransferSrc, + failedTransferDst, + }, + { + "test kava transfer tx", + kava, + transferSrcKava, + transferDstKava, + }, + } + for _, tt := range tests { + testNormalize(t, tt) + } +} + +func testNormalize(t *testing.T, tt test) { + t.Run(tt.name, func(t *testing.T) { + var srcTx Tx + err := json.Unmarshal([]byte(tt.Data), &srcTx) + assert.Nil(t, err) + tx, ok := tt.platform.Normalize(&srcTx) + assert.True(t, ok) + assert.Equal(t, tt.want, tx, "transfer: tx don't equal") + }) +} diff --git a/platform/elrond/base.go b/platform/elrond/base.go new file mode 100644 index 000000000..eeb64940c --- /dev/null +++ b/platform/elrond/base.go @@ -0,0 +1,23 @@ +package elrond + +import ( + "github.com/trustwallet/golibs/client" + "github.com/trustwallet/golibs/coin" + "github.com/trustwallet/golibs/network/middleware" +) + +type Platform struct { + client Client + CoinIndex uint +} + +func Init(coin uint, api string) *Platform { + return &Platform{ + CoinIndex: coin, + client: Client{client.InitJSONClient(api, middleware.SentryErrorHandler)}, + } +} + +func (p *Platform) Coin() coin.Coin { + return coin.Coins[p.CoinIndex] +} diff --git a/platform/elrond/block.go b/platform/elrond/block.go new file mode 100644 index 000000000..10a0a99da --- /dev/null +++ b/platform/elrond/block.go @@ -0,0 +1,11 @@ +package elrond + +import "github.com/trustwallet/golibs/types" + +func (p *Platform) CurrentBlockNumber() (int64, error) { + return p.client.CurrentBlockNumber() +} + +func (p *Platform) GetBlockByNumber(num int64) (*types.Block, error) { + return p.client.GetBlockByNumber(num) +} diff --git a/platform/elrond/client.go b/platform/elrond/client.go new file mode 100644 index 000000000..38d9ef61e --- /dev/null +++ b/platform/elrond/client.go @@ -0,0 +1,73 @@ +package elrond + +import ( + "encoding/json" + "fmt" + "net/url" + + "github.com/trustwallet/golibs/client" + "github.com/trustwallet/golibs/types" +) + +type Client struct { + client.Request +} + +func (c *Client) CurrentBlockNumber() (num int64, err error) { + var networkStatus NetworkStatus + path := fmt.Sprintf("network/status/%s", metachainID) + err = c.getResponse(&networkStatus, path, nil) + if err != nil { + return 0, err + } + + latestNonce := networkStatus.Status.Nonce + + return int64(latestNonce), nil +} + +func (c *Client) GetBlockByNumber(height int64) (*types.Block, error) { + var blockRes BlockResponse + + path := fmt.Sprintf("hyperblock/by-nonce/%d", uint64(height)) + err := c.getResponse(&blockRes, path, nil) + if err != nil { + return nil, err + } + + block := blockRes.Block + txs := NormalizeTxs(block.Transactions, "", blockRes.Block) + + return &types.Block{ + Number: int64(block.Nonce), + Txs: txs, + }, nil +} + +func (c *Client) GetTxsOfAddress(address string) (types.Txs, error) { + var txPage TransactionsPage + // TODO: enable pagination of Elrond transactions in the future. + // TODO: currently Elrond only fetches the most recent 20 transactions. + path := fmt.Sprintf("address/%s/transactions", address) + err := c.getResponse(&txPage, path, nil) + if err != nil { + return nil, err + } + + txs := NormalizeTxs(txPage.Transactions, address, Block{}) + + return txs, nil +} + +func (c *Client) getResponse(result interface{}, path string, query url.Values) error { + var genericResponse GenericResponse + if err := c.Get(&genericResponse, path, query); err != nil { + return err + } + + if genericResponse.Code != "successful" { + return fmt.Errorf("%s", genericResponse.Error) + } + + return json.Unmarshal(genericResponse.Data, &result) +} diff --git a/platform/elrond/mocks/scr_negative_value.json b/platform/elrond/mocks/scr_negative_value.json new file mode 100644 index 000000000..a5cd93652 --- /dev/null +++ b/platform/elrond/mocks/scr_negative_value.json @@ -0,0 +1,9 @@ +{ + "hash": "a96ed4816f5312d00361cc16037e19e0cffa4765a79a808d54d89db58fd76aa6", + "value": "-2500000000000000000000", + "receiver": "erd1qqqqqqqqqqqqqqqpqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqplllst77y4l", + "sender": "erd1qqqqqqqqqqqqqqqpqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqplllst77y4l", + "gasPrice": 1000000000, + "signature": "", + "status": "success" +} diff --git a/platform/elrond/mocks/tx.json b/platform/elrond/mocks/tx.json new file mode 100644 index 000000000..95ca22c53 --- /dev/null +++ b/platform/elrond/mocks/tx.json @@ -0,0 +1,13 @@ +{ + "hash": "30d404cc7a42b0158b95f6adfbf9a517627d60f6c7e497c1442dfdb6460285df", + "nonce": 0, + "round": 35462, + "value": "82516976060558456822", + "receiver": "erd10yagg2vme2jns9zqf9xn8kl86fkc6dr063vnuj0mz2kk2jw0qwuqmfmaw0", + "sender": "4294967295", + "data": "ok", + "signature": "", + "timestamp": 1587715632, + "status": "Success", + "fee": "1000" +} diff --git a/platform/elrond/mocks/tx_2.json b/platform/elrond/mocks/tx_2.json new file mode 100644 index 000000000..f614f65d9 --- /dev/null +++ b/platform/elrond/mocks/tx_2.json @@ -0,0 +1,13 @@ +{ + "hash": "30d404cc7a42b0158b95f6adfbf9a517627d60f6c7e497c1442dfdb6460285df", + "nonce": 1, + "round": 100, + "value": "2000", + "receiver": "erd10yagg2vme2jns9zqf9xn8kl86fkc6dr063vnuj0mz2kk2jw0qwuqmfmaw0", + "sender": "erd10yagg2vme2jns9zqf9xn8kl86fkc6dr063vnuj0mz2kk2jw0qwuqmfmaw0", + "data": "money", + "signature": "", + "timestamp": 1588757256, + "status": "Pending", + "fee": "1500" +} diff --git a/platform/elrond/mocks/tx_3.json b/platform/elrond/mocks/tx_3.json new file mode 100644 index 000000000..555b93d00 --- /dev/null +++ b/platform/elrond/mocks/tx_3.json @@ -0,0 +1,15 @@ +{ + "hash": "30d404cc7a42b0158b95f6adfbf9a517627d60f6c7e497c1442dfdb6460285df", + "nonce": 19, + "round": 200, + "value": "2", + "receiver": "erd1v0ce6rapup6rwma5sltyv05xhp33u543nex75a7j39vsz9m6squq6mxm7y", + "sender": "erd10yagg2vme2jns9zqf9xn8kl86fkc6dr063vnuj0mz2kk2jw0qwuqmfmaw0", + "data": "test", + "signature": "", + "timestamp": 1588757256, + "status": "Fail", + "fee": "0", + "gasPrice": 5, + "gasLimit": 1000 +} diff --git a/platform/elrond/mocks/tx_4.json b/platform/elrond/mocks/tx_4.json new file mode 100644 index 000000000..01148eb58 --- /dev/null +++ b/platform/elrond/mocks/tx_4.json @@ -0,0 +1,13 @@ +{ + "hash": "30d404cc7a42b0158b95f6adfbf9a517627d60f6c7e497c1442dfdb6460285df", + "nonce": 19, + "round": 200, + "value": "2", + "receiver": "erd1v0ce6rapup6rwma5sltyv05xhp33u543nex75a7j39vsz9m6squq6mxm7y", + "sender": "erd10yagg2vme2jns9zqf9xn8kl86fkc6dr063vnuj0mz2kk2jw0qwuqmfmaw0", + "data": "test", + "signature": "", + "timestamp": 1588757256, + "status": "pending", + "fee": "5000" +} diff --git a/platform/elrond/mocks/tx_5.json b/platform/elrond/mocks/tx_5.json new file mode 100644 index 000000000..3052dd79b --- /dev/null +++ b/platform/elrond/mocks/tx_5.json @@ -0,0 +1,13 @@ +{ + "hash": "30d404cc7a42b0158b95f6adfbf9a517627d60f6c7e497c1442dfdb6460285df", + "nonce": 19, + "round": 200, + "value": "2", + "receiver": "erd1v0ce6rapup6rwma5sltyv05xhp33u543nex75a7j39vsz9m6squq6mxm7y", + "sender": "erd10yagg2vme2jns9zqf9xn8kl86fkc6dr063vnuj0mz2kk2jw0qwuqmfmaw0", + "data": "test", + "signature": "", + "timestamp": 1588757256, + "status": "success", + "fee": "5000" +} diff --git a/platform/elrond/mocks/tx_6.json b/platform/elrond/mocks/tx_6.json new file mode 100644 index 000000000..12cf70a76 --- /dev/null +++ b/platform/elrond/mocks/tx_6.json @@ -0,0 +1,13 @@ +{ + "hash": "30d404cc7a42b0158b95f6adfbf9a517627d60f6c7e497c1442dfdb6460285df", + "nonce": 25, + "value": "2", + "receiver": "erd1v0ce6rapup6rwma5sltyv05xhp33u543nex75a7j39vsz9m6squq6mxm7y", + "sender": "erd10yagg2vme2jns9zqf9xn8kl86fkc6dr063vnuj0mz2kk2jw0qwuqmfmaw0", + "data": "test", + "signature": "", + "status": "success", + "fee": "0", + "gasPrice": 5, + "gasLimit": 1000 +} diff --git a/platform/elrond/model.go b/platform/elrond/model.go new file mode 100644 index 000000000..705f8ea37 --- /dev/null +++ b/platform/elrond/model.go @@ -0,0 +1,116 @@ +package elrond + +import ( + "encoding/json" + "math/big" + "strings" + "time" + + "github.com/trustwallet/golibs/types" +) + +const roundDurationInSeconds = 6 +const mainnetStartTime = 1596117600 + +type GenericResponse struct { + Data json.RawMessage `json:"data"` + Code string `json:"code"` + Error string `json:"error"` +} + +type NetworkStatus struct { + Status StatusDetails `json:"status"` +} + +type StatusDetails struct { + Round float64 `json:"erd_current_round"` + Epoch float64 `json:"erd_epoch_number"` + Nonce float64 `json:"erd_nonce"` +} + +type BlockResponse struct { + Block Block `json:"hyperblock"` +} + +type Block struct { + Nonce uint64 `json:"nonce"` + Round uint64 `json:"round"` + Hash string `json:"hash"` + Transactions []Transaction `json:"transactions"` +} + +type TransactionsPage struct { + Transactions []Transaction `json:"transactions"` +} + +type Transaction struct { + Hash string `json:"hash"` + Nonce uint64 `json:"nonce"` + Value string `json:"value"` + Receiver string `json:"receiver"` + Sender string `json:"sender"` + Data string `json:"data"` + Timestamp time.Duration `json:"timestamp"` + Status string `json:"status"` + Fee string `json:"fee"` + GasPrice uint64 `json:"gasPrice,omitempty"` + GasLimit uint64 `json:"gasLimit,omitempty"` +} + +func (tx *Transaction) TxFee() types.Amount { + if tx.Fee != "0" && tx.Fee != "" { + return types.Amount(tx.Fee) + } + + // Hyperblocks API V1 does not provide the transaction fees (nor "gasUsed"). Hyperblocks API V2 will provide this information, as well. + // Until then, we can compute the fees deterministically (best-effort) in BlockAtlas, based on gasLimit and gasPrice. This logic will be soon removed from BlockAtlas, in a future PR, when the Hyperblocks API v2 becomes available. + // Note: For Smart Contract transactions, the refunds will be incompletely provided by the API (until Hyperblocks V2 becomes available): e.g. intra-shard refunds are not visible etc.) + + txFee := big.NewInt(0).SetUint64(tx.GasPrice) + txFee = txFee.Mul(txFee, big.NewInt(0).SetUint64(tx.GasLimit)) + + return types.Amount(txFee.String()) +} + +func (tx *Transaction) TxStatus() types.Status { + switch tx.Status { + case "Success", "success": + return types.StatusCompleted + case "Pending", "pending": + return types.StatusPending + default: + return types.StatusError + } +} + +func (tx *Transaction) Direction(address string) types.Direction { + switch { + case tx.Sender == address && tx.Receiver == address: + return types.DirectionSelf + case tx.Sender == address && tx.Receiver != address: + return types.DirectionOutgoing + default: + return types.DirectionIncoming + } +} + +func (tx *Transaction) HasNegativeValue() bool { + return strings.HasPrefix(tx.Value, "-") +} + +func (tx *Transaction) TxTimestamp(blockRound uint64) time.Duration { + if int64(tx.Timestamp) != 0 { + return tx.Timestamp + } + + // Minor issue (slight inconsistency) about the "timestamp" field: + // The transactions fetched by querying the endpoint "address/erd1.../transactions" come from our central Elastic Search database, and their timestamp refers to the moment of *including* those transactions in shard blocks (detail: at destination). + // However, the transactions fetched by querying the endpoint "hyperblock/by-nonce/..." come from another source - from our Observer Nodes - and their timestamp refers to the moment of *final acknowledgement*, + // according to the Protocol (detail: the moment when the Metachain notarizes the destination shard block containing the transactions). + // Note: the differences are small - e.g. a few seconds. + // This inconsistency will be fixed in Hyperblocks API V2. + + txTimestamp := mainnetStartTime + blockRound*roundDurationInSeconds + + return time.Duration(txTimestamp) +} diff --git a/platform/elrond/transaction.go b/platform/elrond/transaction.go new file mode 100644 index 000000000..d62c17d47 --- /dev/null +++ b/platform/elrond/transaction.go @@ -0,0 +1,59 @@ +package elrond + +import ( + "github.com/trustwallet/golibs/coin" + "github.com/trustwallet/golibs/types" +) + +const metachainID = "4294967295" + +func (p *Platform) GetTxsByAddress(address string) (types.Txs, error) { + return p.client.GetTxsOfAddress(address) +} + +// NormalizeTx converts an slice of Elrond transaction info a slice of generic model transaction +func NormalizeTxs(srcTxs []Transaction, address string, block Block) (txs types.Txs) { + for _, srcTx := range srcTxs { + tx, ok := NormalizeTx(srcTx, address, block) + if !ok { + continue + } + txs = append(txs, tx) + } + return txs +} + +// NormalizeTx converts an Elrond transaction into the generic model +func NormalizeTx(srcTx Transaction, address string, block Block) (tx types.Tx, ok bool) { + if srcTx.HasNegativeValue() { + return types.Tx{}, false + } + + tx = types.Tx{ + ID: srcTx.Hash, + Coin: coin.Elrond().ID, + Date: int64(srcTx.TxTimestamp(block.Round)), + Block: block.Nonce, + From: srcTx.Sender, + To: srcTx.Receiver, + Fee: srcTx.TxFee(), + Status: srcTx.TxStatus(), + Sequence: srcTx.Nonce, + Memo: srcTx.Data, + Meta: types.Transfer{ + Value: types.Amount(srcTx.Value), + Symbol: coin.Elrond().Symbol, + Decimals: coin.Elrond().Decimals, + }, + } + if address != "" { + tx.Direction = srcTx.Direction(address) + } + + // check if transaction sender is metachain shard (protocol transaction) + if srcTx.Sender == metachainID { + tx.From = "metachain" + } + + return tx, true +} diff --git a/platform/elrond/transaction_test.go b/platform/elrond/transaction_test.go new file mode 100644 index 000000000..4db07b7a8 --- /dev/null +++ b/platform/elrond/transaction_test.go @@ -0,0 +1,217 @@ +package elrond + +import ( + "encoding/json" + "testing" + + "github.com/stretchr/testify/require" + "github.com/trustwallet/golibs/coin" + "github.com/trustwallet/golibs/mock" + "github.com/trustwallet/golibs/types" +) + +var ( + userAddress = `erd10yagg2vme2jns9zqf9xn8kl86fkc6dr063vnuj0mz2kk2jw0qwuqmfmaw0` + txTransferSrc1, _ = mock.JsonStringFromFilePath("mocks/tx.json") + txTransferSrc2, _ = mock.JsonStringFromFilePath("mocks/tx_2.json") + txTransferSrc3, _ = mock.JsonStringFromFilePath("mocks/tx_3.json") + txTransferSrc4, _ = mock.JsonStringFromFilePath("mocks/tx_4.json") + txTransferSrc5, _ = mock.JsonStringFromFilePath("mocks/tx_5.json") + txTransferSrc6, _ = mock.JsonStringFromFilePath("mocks/tx_6.json") + scrNegativeValue, _ = mock.JsonStringFromFilePath("mocks/scr_negative_value.json") + + txTransfer1Normalized = types.Tx{ + ID: "30d404cc7a42b0158b95f6adfbf9a517627d60f6c7e497c1442dfdb6460285df", + Coin: coin.ELROND, + Date: int64(1587715632), + From: "metachain", + To: "erd10yagg2vme2jns9zqf9xn8kl86fkc6dr063vnuj0mz2kk2jw0qwuqmfmaw0", + Fee: "1000", + Status: types.StatusCompleted, + Memo: "ok", + Sequence: 0, + Meta: types.Transfer{ + Value: "82516976060558456822", + Symbol: coin.Elrond().Symbol, + Decimals: coin.Elrond().Decimals, + }, + Direction: types.DirectionOutgoing, + } + + txTransfer2Normalized = types.Tx{ + ID: "30d404cc7a42b0158b95f6adfbf9a517627d60f6c7e497c1442dfdb6460285df", + Coin: coin.ELROND, + Date: int64(1588757256), + From: "erd10yagg2vme2jns9zqf9xn8kl86fkc6dr063vnuj0mz2kk2jw0qwuqmfmaw0", + To: "erd10yagg2vme2jns9zqf9xn8kl86fkc6dr063vnuj0mz2kk2jw0qwuqmfmaw0", + Fee: "1500", + Status: types.StatusPending, + Memo: "money", + Sequence: 1, + Meta: types.Transfer{ + Value: "2000", + Symbol: coin.Elrond().Symbol, + Decimals: coin.Elrond().Decimals, + }, + Direction: types.DirectionSelf, + } + + txTransfer3Normalized = types.Tx{ + ID: "30d404cc7a42b0158b95f6adfbf9a517627d60f6c7e497c1442dfdb6460285df", + Coin: coin.ELROND, + Date: int64(1588757256), + From: "erd10yagg2vme2jns9zqf9xn8kl86fkc6dr063vnuj0mz2kk2jw0qwuqmfmaw0", + To: "erd1v0ce6rapup6rwma5sltyv05xhp33u543nex75a7j39vsz9m6squq6mxm7y", + Fee: "5000", + Status: types.StatusError, + Memo: "test", + Sequence: 19, + Meta: types.Transfer{ + Value: "2", + Symbol: coin.Elrond().Symbol, + Decimals: coin.Elrond().Decimals, + }, + Direction: types.DirectionOutgoing, + } + + txTransfer4Normalized = types.Tx{ + ID: "30d404cc7a42b0158b95f6adfbf9a517627d60f6c7e497c1442dfdb6460285df", + Coin: coin.ELROND, + Date: int64(1588757256), + From: "erd10yagg2vme2jns9zqf9xn8kl86fkc6dr063vnuj0mz2kk2jw0qwuqmfmaw0", + To: "erd1v0ce6rapup6rwma5sltyv05xhp33u543nex75a7j39vsz9m6squq6mxm7y", + Fee: "5000", + Status: types.StatusPending, + Memo: "test", + Sequence: 19, + Meta: types.Transfer{ + Value: "2", + Symbol: coin.Elrond().Symbol, + Decimals: coin.Elrond().Decimals, + }, + Direction: types.DirectionOutgoing, + } + + txTransfer5Normalized = types.Tx{ + ID: "30d404cc7a42b0158b95f6adfbf9a517627d60f6c7e497c1442dfdb6460285df", + Coin: coin.ELROND, + Date: int64(1588757256), + From: "erd10yagg2vme2jns9zqf9xn8kl86fkc6dr063vnuj0mz2kk2jw0qwuqmfmaw0", + To: "erd1v0ce6rapup6rwma5sltyv05xhp33u543nex75a7j39vsz9m6squq6mxm7y", + Fee: "5000", + Status: types.StatusCompleted, + Memo: "test", + Sequence: 19, + Meta: types.Transfer{ + Value: "2", + Symbol: coin.Elrond().Symbol, + Decimals: coin.Elrond().Decimals, + }, + Direction: types.DirectionOutgoing, + } + + txTransfer6Normalized = types.Tx{ + ID: "30d404cc7a42b0158b95f6adfbf9a517627d60f6c7e497c1442dfdb6460285df", + Coin: coin.ELROND, + From: "erd10yagg2vme2jns9zqf9xn8kl86fkc6dr063vnuj0mz2kk2jw0qwuqmfmaw0", + To: "erd1v0ce6rapup6rwma5sltyv05xhp33u543nex75a7j39vsz9m6squq6mxm7y", + Fee: "5000", + Status: types.StatusCompleted, + Memo: "test", + Sequence: 25, + Block: 620, + Date: 1596121554, + Meta: types.Transfer{ + Value: "2", + Symbol: coin.Elrond().Symbol, + Decimals: coin.Elrond().Decimals, + }, + Direction: types.DirectionOutgoing, + } +) + +type test struct { + name string + apiResponse string + expected *types.Tx +} + +func TestNormalize(t *testing.T) { + testNormalize(t, &test{ + name: "transferSuccess", + apiResponse: txTransferSrc1, + expected: &txTransfer1Normalized, + }) + + testNormalize(t, &test{ + name: "transferPending", + apiResponse: txTransferSrc2, + expected: &txTransfer2Normalized, + }) + + testNormalize(t, &test{ + name: "transferNotExecuted", + apiResponse: txTransferSrc3, + expected: &txTransfer3Normalized, + }) + + testNormalize(t, &test{ + name: "transferPendingNewStatus", + apiResponse: txTransferSrc4, + expected: &txTransfer4Normalized, + }) + + testNormalize(t, &test{ + name: "transferSuccessNewStatus", + apiResponse: txTransferSrc5, + expected: &txTransfer5Normalized, + }) +} + +func TestNormalizeTxs(t *testing.T) { + var tx1, tx2, tx3, scrNegative Transaction + + _ = json.Unmarshal([]byte(txTransferSrc1), &tx1) + _ = json.Unmarshal([]byte(txTransferSrc1), &tx2) + _ = json.Unmarshal([]byte(txTransferSrc1), &tx3) + _ = json.Unmarshal([]byte(scrNegativeValue), &scrNegative) + + txs := []Transaction{tx1, tx2, tx3, scrNegative} + normalizedTxs := NormalizeTxs(txs, userAddress, Block{}) + require.Equal(t, len(txs)-1, len(normalizedTxs)) +} + +func testNormalize(t *testing.T, _test *test) { + var tx Transaction + err := json.Unmarshal([]byte(_test.apiResponse), &tx) + if err != nil { + t.Error(err) + return + } + + normalizedTx, ok := NormalizeTx(tx, tx.Sender, Block{}) + require.True(t, ok, _test.name+": cannot normalize tx") + + resJSON, err := json.Marshal(&normalizedTx) + require.Nil(t, err) + + dstJSON, err := json.Marshal(&_test.expected) + require.Nil(t, err) + + require.Equal(t, string(dstJSON), string(resJSON)) +} + +func TestNormalizeTxsFromHyperblock(t *testing.T) { + var tx Transaction + + _ = json.Unmarshal([]byte(txTransferSrc6), &tx) + txs := []Transaction{tx} + + normalizedTxs := NormalizeTxs(txs, userAddress, Block{ + Nonce: 620, + Round: 659, + }) + require.Equal(t, len(txs), len(normalizedTxs)) + + require.Equal(t, types.Txs{txTransfer6Normalized}, normalizedTxs) +} diff --git a/platform/ethereum/api.go b/platform/ethereum/api.go deleted file mode 100644 index efd3b6ac4..000000000 --- a/platform/ethereum/api.go +++ /dev/null @@ -1,451 +0,0 @@ -package ethereum - -import ( - "fmt" - "github.com/gin-gonic/gin" - "github.com/spf13/viper" - "github.com/trustwallet/blockatlas/coin" - "github.com/trustwallet/blockatlas/pkg/address" - "github.com/trustwallet/blockatlas/pkg/blockatlas" - "github.com/trustwallet/blockatlas/pkg/logger" - "math/big" - "net/http" - "strconv" - "strings" -) - -var ( - supportedTypes = map[string]bool{"ERC721": true, "ERC1155": true} - slugTokens = map[string]bool{"ERC1155": true} -) - -type Platform struct { - client Client - collectionsClient CollectionsClient - CoinIndex uint - RpcURL string -} - -func (p *Platform) Init() error { - handle := coin.Coins[p.CoinIndex].Handle - - coinVar := fmt.Sprintf("%s.api", handle) - p.client = Client{blockatlas.InitClient(viper.GetString(coinVar))} - - collectionsApiVar := fmt.Sprintf("%s.collections_api", handle) - p.collectionsClient = CollectionsClient{blockatlas.InitClient(viper.GetString(collectionsApiVar))} - - collectionsApiKeyVar := fmt.Sprintf("%s.collections_api_key", handle) - p.collectionsClient.Headers["X-API-KEY"] = viper.GetString(collectionsApiKeyVar) - - p.RpcURL = viper.GetString("ethereum.rpc") - return nil -} - -func (p *Platform) Coin() coin.Coin { - return coin.Coins[p.CoinIndex] -} - -func (p *Platform) RegisterRoutes(router gin.IRouter) { - router.GET("/:address", func(c *gin.Context) { - p.getTransactions(c) - }) -} - -func (p *Platform) getTransactions(c *gin.Context) { - token := c.Query("token") - address := c.Param("address") - var srcPage *Page - var err error - - if token != "" { - srcPage, err = p.client.GetTxsWithContract(address, token) - } else { - srcPage, err = p.client.GetTxs(address) - } - - if apiError(c, err) { - return - } - - var txs []blockatlas.Tx - for _, srcTx := range srcPage.Docs { - txs = AppendTxs(txs, &srcTx, p.CoinIndex) - } - - page := blockatlas.TxPage(txs) - page.Sort() - c.JSON(http.StatusOK, &page) -} - -func extractBase(srcTx *Doc, coinIndex uint) (base blockatlas.Tx, ok bool) { - var status blockatlas.Status - var errReason string - if srcTx.Error == "" { - status = blockatlas.StatusCompleted - } else { - status = blockatlas.StatusFailed - errReason = srcTx.Error - } - - fee := calcFee(srcTx.GasPrice, srcTx.GasUsed) - - base = blockatlas.Tx{ - ID: srcTx.ID, - Coin: coinIndex, - From: srcTx.From, - To: srcTx.To, - Fee: blockatlas.Amount(fee), - Date: srcTx.Timestamp, - Block: srcTx.BlockNumber, - Status: status, - Error: errReason, - Sequence: srcTx.Nonce, - } - return base, true -} - -func AppendTxs(in []blockatlas.Tx, srcTx *Doc, coinIndex uint) (out []blockatlas.Tx) { - out = in - baseTx, ok := extractBase(srcTx, coinIndex) - if !ok { - return - } - - // Native ETH transaction - if len(srcTx.Ops) == 0 && srcTx.Input == "0x" { - transferTx := baseTx - transferTx.Meta = blockatlas.Transfer{ - Value: blockatlas.Amount(srcTx.Value), - Symbol: coin.Coins[coinIndex].Symbol, - Decimals: coin.Coins[coinIndex].Decimals, - } - out = append(out, transferTx) - } - - // Smart Contract Call - if len(srcTx.Ops) == 0 && srcTx.Input != "0x" { - contractTx := baseTx - contractTx.Meta = blockatlas.ContractCall{ - Input: srcTx.Input, - Value: srcTx.Value, - } - out = append(out, contractTx) - } - - if len(srcTx.Ops) == 0 { - return - } - op := &srcTx.Ops[0] - - if op.Type == blockatlas.TxTokenTransfer && op.Contract != nil { - tokenTx := baseTx - - tokenTx.Meta = blockatlas.TokenTransfer{ - Name: op.Contract.Name, - Symbol: op.Contract.Symbol, - TokenID: address.EIP55Checksum(op.Contract.Address), - Decimals: op.Contract.Decimals, - Value: blockatlas.Amount(op.Value), - From: op.From, - To: op.To, - } - out = append(out, tokenTx) - } - return -} - -func calcFee(gasPrice string, gasUsed string) string { - var gasPriceBig, gasUsedBig, feeBig big.Int - - gasPriceBig.SetString(gasPrice, 10) - gasUsedBig.SetString(gasUsed, 10) - - feeBig.Mul(&gasPriceBig, &gasUsedBig) - - return feeBig.String() -} - -func apiError(c *gin.Context, err error) bool { - if err != nil { - logger.Error(err, "Unhandled error") - c.AbortWithStatus(http.StatusInternalServerError) - return true - } - return false -} - -func (p *Platform) CurrentBlockNumber() (int64, error) { - return p.client.CurrentBlockNumber() -} - -func (p *Platform) GetBlockByNumber(num int64) (*blockatlas.Block, error) { - if srcPage, err := p.client.GetBlockByNumber(num); err == nil { - var txs []blockatlas.Tx - for _, srcTx := range srcPage { - txs = AppendTxs(txs, &srcTx, p.CoinIndex) - } - return &blockatlas.Block{ - Number: num, - ID: strconv.FormatInt(num, 10), - Txs: txs, - }, nil - } else { - return nil, err - } -} - -func (p *Platform) GetCollections(owner string) (blockatlas.CollectionPage, error) { - collections, err := p.collectionsClient.GetCollections(owner) - if err != nil { - return nil, err - } - page := NormalizeCollectionPage(collections, p.CoinIndex, owner) - return page, nil -} - -//TODO: remove once most of the clients will be updated (deadline: March 17th) -func (p *Platform) OldGetCollections(owner string) (blockatlas.CollectionPage, error) { - collections, err := p.collectionsClient.GetCollections(owner) - if err != nil { - return nil, err - } - page := OldNormalizeCollectionPage(collections, p.CoinIndex, owner) - return page, nil -} - -func (p *Platform) GetCollectibles(owner, collectibleID string) (blockatlas.CollectiblePage, error) { - collection, items, err := p.collectionsClient.GetCollectibles(owner, collectibleID) - if err != nil { - return nil, err - } - page := NormalizeCollectiblePage(collection, items, p.CoinIndex) - return page, nil -} - -func NormalizeCollectionPage(collections []Collection, coinIndex uint, owner string) (page blockatlas.CollectionPage) { - for _, collection := range collections { - if len(collection.Contracts) == 0 { - continue - } - item := NormalizeCollection(collection, coinIndex, owner) - if _, ok := supportedTypes[item.Type]; !ok { - continue - } - page = append(page, item) - } - return -} - -//TODO: remove once most of the clients will be updated (deadline: March 17th) -func (p *Platform) OldGetCollectibles(owner, collectibleID string) (blockatlas.CollectiblePage, error) { - collection, items, err := p.collectionsClient.OldGetCollectibles(owner, collectibleID) - if err != nil { - return nil, err - } - page := OldNormalizeCollectiblePage(collection, items, p.CoinIndex) - return page, nil -} - -//TODO: remove once most of the clients will be updated (deadline: March 17th) -func OldNormalizeCollectionPage(collections []Collection, coinIndex uint, owner string) (page blockatlas.CollectionPage) { - for _, collection := range collections { - if len(collection.Contracts) == 0 { - continue - } - item := OldNormalizeCollection(collection, coinIndex, owner) - if _, ok := supportedTypes[item.Type]; !ok { - continue - } - page = append(page, item) - } - return -} - -//TODO: remove once most of the clients will be updated (deadline: March 17th) -func OldNormalizeCollection(c Collection, coinIndex uint, owner string) blockatlas.Collection { - if len(c.Contracts) == 0 { - return blockatlas.Collection{} - } - - description := blockatlas.GetValidParameter(c.Description, c.Contracts[0].Description) - symbol := blockatlas.GetValidParameter(c.Contracts[0].Symbol, "") - collectionId := blockatlas.GetValidParameter(c.Contracts[0].Address, "") - version := blockatlas.GetValidParameter(c.Contracts[0].NftVersion, "") - collectionType := blockatlas.GetValidParameter(c.Contracts[0].Type, "") - if _, ok := slugTokens[collectionType]; ok { - collectionId = createCollectionId(collectionId, c.Slug) - } - - return blockatlas.Collection{ - Name: c.Name, - Symbol: symbol, - Slug: c.Slug, - ImageUrl: c.ImageUrl, - Description: description, - ExternalLink: c.ExternalUrl, - Total: int(c.Total.Int64()), - Id: collectionId, - CategoryAddress: collectionId, - Address: owner, - Version: version, - Coin: coinIndex, - Type: collectionType, - } -} - -//TODO: remove once most of the clients will be updated (deadline: March 17th) -func OldNormalizeCollectible(c *Collection, a Collectible, coinIndex uint) blockatlas.Collectible { - // TODO: fix unprotected code - address := blockatlas.GetValidParameter(c.Contracts[0].Address, "") - collectionType := blockatlas.GetValidParameter(c.Contracts[0].Type, "") - collectionID := address - if _, ok := slugTokens[collectionType]; ok { - collectionID = createCollectionId(address, c.Slug) - } - externalLink := blockatlas.GetValidParameter(a.ExternalLink, a.AssetContract.ExternalLink) - id := strings.Join([]string{a.AssetContract.Address, a.TokenId}, "-") - return blockatlas.Collectible{ - ID: id, - CollectionID: collectionID, - ContractAddress: address, - TokenID: a.TokenId, - CategoryContract: a.AssetContract.Address, - Name: a.Name, - Category: c.Name, - ImageUrl: a.ImagePreviewUrl, - ProviderLink: a.Permalink, - ExternalLink: externalLink, - Type: collectionType, - Description: a.Description, - Coin: coinIndex, - } -} - -//TODO: remove once most of the clients will be updated (deadline: March 17th) -func createCollectionId(address, slug string) string { - return fmt.Sprintf("%s---%s", address, slug) -} - -//TODO: remove once most of the clients will be updated (deadline: March 17th) -func getCollectionId(collectionId string) string { - s := strings.Split(collectionId, "---") - if len(s) != 2 { - return collectionId - } - return s[1] -} - -//TODO: remove once most of the clients will be updated (deadline: March 17th) -func OldNormalizeCollectiblePage(c *Collection, srcPage []Collectible, coinIndex uint) (page blockatlas.CollectiblePage) { - if len(c.Contracts) == 0 { - return - } - for _, src := range srcPage { - item := OldNormalizeCollectible(c, src, coinIndex) - if _, ok := supportedTypes[item.Type]; !ok { - continue - } - page = append(page, item) - } - return -} - -func NormalizeCollection(c Collection, coinIndex uint, owner string) blockatlas.Collection { - if len(c.Contracts) == 0 { - return blockatlas.Collection{} - } - - description := blockatlas.GetValidParameter(c.Description, c.Contracts[0].Description) - symbol := blockatlas.GetValidParameter(c.Contracts[0].Symbol, "") - version := blockatlas.GetValidParameter(c.Contracts[0].NftVersion, "") - collectionType := blockatlas.GetValidParameter(c.Contracts[0].Type, "") - - return blockatlas.Collection{ - Name: c.Name, - Symbol: symbol, - Slug: c.Slug, - ImageUrl: c.ImageUrl, - Description: description, - ExternalLink: c.ExternalUrl, - Total: int(c.Total.Int64()), - Id: c.Slug, - CategoryAddress: c.Slug, - Address: owner, - Version: version, - Coin: coinIndex, - Type: collectionType, - } -} - -func NormalizeCollectiblePage(c *Collection, srcPage []Collectible, coinIndex uint) (page blockatlas.CollectiblePage) { - if len(c.Contracts) == 0 { - return - } - for _, src := range srcPage { - item := NormalizeCollectible(c, src, coinIndex) - if _, ok := supportedTypes[item.Type]; !ok { - continue - } - page = append(page, item) - } - return -} - -func NormalizeCollectible(c *Collection, a Collectible, coinIndex uint) blockatlas.Collectible { - // TODO: fix unprotected code - address := blockatlas.GetValidParameter(c.Contracts[0].Address, "") - collectionType := blockatlas.GetValidParameter(c.Contracts[0].Type, "") - externalLink := blockatlas.GetValidParameter(a.ExternalLink, a.AssetContract.ExternalLink) - id := strings.Join([]string{a.AssetContract.Address, a.TokenId}, "-") - return blockatlas.Collectible{ - ID: id, - CollectionID: c.Slug, - ContractAddress: address, - TokenID: a.TokenId, - CategoryContract: a.AssetContract.Address, - Name: a.Name, - Category: c.Name, - ImageUrl: a.ImagePreviewUrl, - ProviderLink: a.Permalink, - ExternalLink: externalLink, - Type: collectionType, - Description: a.Description, - Coin: coinIndex, - } -} - -func (p *Platform) GetTokenListByAddress(address string) (blockatlas.TokenPage, error) { - account, err := p.client.GetTokens(address) - if err != nil { - return nil, err - } - return NormalizeTokens(account.Docs, *p), nil -} - -// NormalizeToken converts a Ethereum token into the generic model -func NormalizeToken(srcToken *Token, coinIndex uint) (t blockatlas.Token, ok bool) { - t = blockatlas.Token{ - Name: srcToken.Contract.Name, - Symbol: srcToken.Contract.Symbol, - TokenID: srcToken.Contract.Contract, - Coin: coinIndex, - Decimals: srcToken.Contract.Decimals, - Type: blockatlas.TokenTypeERC20, - } - - return t, true -} - -// NormalizeTxs converts multiple Ethereum tokens -func NormalizeTokens(srcTokens []Token, p Platform) []blockatlas.Token { - tokenPage := make([]blockatlas.Token, 0) - for _, srcToken := range srcTokens { - token, ok := NormalizeToken(&srcToken, p.CoinIndex) - if !ok { - continue - } - tokenPage = append(tokenPage, token) - } - return tokenPage -} diff --git a/platform/ethereum/api_test.go b/platform/ethereum/api_test.go deleted file mode 100644 index 11afe5af2..000000000 --- a/platform/ethereum/api_test.go +++ /dev/null @@ -1,518 +0,0 @@ -package ethereum - -import ( - "bytes" - "encoding/json" - "github.com/stretchr/testify/assert" - "github.com/trustwallet/blockatlas/pkg/blockatlas" - "math/big" - "testing" - - "github.com/trustwallet/blockatlas/coin" -) - -const tokenTransferSrc = ` -{ - "operations": [ - { - "transactionId": "0x7777854580f273df61e0162e1a41b3e1e05ab8b9f553036fa9329a90dd7e9ab2-0", - "contract": { - "address": "0xf3586684107ce0859c44aa2b2e0fb8cd8731a15a", - "symbol": "KBC", - "decimals": 7, - "totalSupply": "120000000000000000", - "name": "KaratBank Coin" - }, - "from": "0xd35f30d194684a391c63a6deced7d3dd5207c265", - "to": "0xaa4d790076f1bf7511a0a0ac498c89e13e1efe17", - "type": "token_transfer", - "value": "4291000000", - "coin": 60 - } - ], - "contract": null, - "_id": "0x7777854580f273df61e0162e1a41b3e1e05ab8b9f553036fa9329a90dd7e9ab2", - "blockNumber": 7491945, - "time": 1554248437, - "nonce": 88, - "from": "0xd35f30d194684a391c63a6deced7d3dd5207c265", - "to": "0xf3586684107ce0859c44aa2b2e0fb8cd8731a15a", - "value": "0", - "gas": "67497", - "gasPrice": "6900000256", - "gasUsed": "51921", - "input": "0xa9059cbb000000000000000000000000aa4d790076f1bf7511a0a0ac498c89e13e1efe1700000000000000000000000000000000000000000000000000000000ffc376c0", - "error": "", - "id": "0x7777854580f273df61e0162e1a41b3e1e05ab8b9f553036fa9329a90dd7e9ab2", - "coin": 60 -}` - -const contractCallSrc = ` -{ - "addresses": [ - "0x09862ed5908c0a336f9f92e5ffeb9768deac6091" - ], - "operations": [], - "contract": "0xe4dc0f23b1a3f2c47dc288a22f72e100e9b1cd70", - "_id": "0x34ab0028a9aa794d5cc12887e7b813cec17889948276b301028f24a408da6da4", - "blockNumber": 7522627, - "time": 1554661737, - "nonce": 534, - "from": "0xc9a16a82c284efc3cb0fe8c891ab85d6eba0eefb", - "to": "0xc67f9c909c4d185e4a5d21d642c27d05a145a76c", - "value": "1800000000000000000", - "gas": "1000000", - "gasPrice": "2000000000", - "gasUsed": "21340", - "input": "0xfffdefefed", - "error": "", - "id": "0x34ab0028a9aa794d5cc12887e7b813cec17889948276b301028f24a408da6da4", - "coin": 60 -} -` - -const transferSrc = ` -{ - "operations": [], - "contract": null, - "_id": "0x77f8a3b2203933493d103a1637de814b4853410b1fb2981c4d2cff4d7a3071ab", - "blockNumber": 7522781, - "time": 1554663642, - "nonce": 88, - "from": "0xf5aea47e57c058881b31ee8fce1002c409188f06", - "to": "0x0ae933a89d9e249d0873cfc7ca022fcb3f1280ce", - "value": "1999895000000000000", - "gas": "21000", - "gasPrice": "5000000000", - "gasUsed": "21000", - "input": "0x", - "error": "", - "id": "0x77f8a3b2203933493d103a1637de814b4853410b1fb2981c4d2cff4d7a3071ab", - "coin": 60 -}` - -const failedSrc = ` -{ - "operations": [], - "contract": null, - "_id": "0x8dfe7e859f7bdcea4e6f4ada18567d96a51c3aa29e618ef09b80ae99385e191e", - "blockNumber": 7522678, - "time": 1554662399, - "nonce": 1, - "from": "0x4b55af7ce28a113d794f9a9940fe1506f37aa619", - "to": "0xe65f787c8561a4b15771111bb427274dedfe85d7", - "value": "59859820000000000", - "gas": "21000", - "gasPrice": "3000000000", - "gasUsed": "21000", - "input": "0x", - "error": "Error", - "id": "0x8dfe7e859f7bdcea4e6f4ada18567d96a51c3aa29e618ef09b80ae99385e191e", - "coin": 60 -}` - -var tokenTransferDst = blockatlas.Tx{ - ID: "0x7777854580f273df61e0162e1a41b3e1e05ab8b9f553036fa9329a90dd7e9ab2", - Coin: coin.ETH, - From: "0xd35f30d194684a391c63a6deced7d3dd5207c265", - To: "0xf3586684107ce0859c44aa2b2e0fb8cd8731a15a", - Fee: "358254913291776", - Date: 1554248437, - Block: 7491945, - Sequence: 88, - Status: blockatlas.StatusCompleted, - Meta: blockatlas.TokenTransfer{ - Name: "KaratBank Coin", - Symbol: "KBC", - TokenID: "0xf3586684107CE0859c44aa2b2E0fB8cd8731a15a", - Decimals: 7, - Value: "4291000000", - From: "0xd35f30d194684a391c63a6deced7d3dd5207c265", - To: "0xaa4d790076f1bf7511a0a0ac498c89e13e1efe17", - }, -} - -var contractCallDst = blockatlas.Tx{ - ID: "0x34ab0028a9aa794d5cc12887e7b813cec17889948276b301028f24a408da6da4", - Coin: coin.ETH, - From: "0xc9a16a82c284efc3cb0fe8c891ab85d6eba0eefb", - To: "0xc67f9c909c4d185e4a5d21d642c27d05a145a76c", - Fee: "42680000000000", - Date: 1554661737, - Block: 7522627, - Sequence: 534, - Status: blockatlas.StatusCompleted, - Meta: blockatlas.ContractCall{ - Input: "0xfffdefefed", - Value: "1800000000000000000", - }, -} - -var transferDst = blockatlas.Tx{ - ID: "0x77f8a3b2203933493d103a1637de814b4853410b1fb2981c4d2cff4d7a3071ab", - Coin: coin.ETH, - From: "0xf5aea47e57c058881b31ee8fce1002c409188f06", - To: "0x0ae933a89d9e249d0873cfc7ca022fcb3f1280ce", - Fee: "105000000000000", - Date: 1554663642, - Block: 7522781, - Sequence: 88, - Status: blockatlas.StatusCompleted, - Meta: blockatlas.Transfer{ - Value: "1999895000000000000", - Symbol: "ETH", - Decimals: 18, - }, -} - -var transferContractDst = blockatlas.Tx{ - ID: "0x77f8a3b2203933493d103a1637de814b4853410b1fb2981c4d2cff4d7a3071ab", - Coin: coin.ETH, - From: "0xf5aea47e57c058881b31ee8fce1002c409188f06", - To: "0x0ae933a89d9e249d0873cfc7ca022fcb3f1280ce", - Fee: "105000000000000", - Date: 1554663642, - Block: 7522781, - Sequence: 88, - Status: blockatlas.StatusCompleted, - Meta: blockatlas.Transfer{ - Value: "1999895000000000000", - Symbol: "ETH", - Decimals: 18, - }, -} - -var failedDst = blockatlas.Tx{ - ID: "0x8dfe7e859f7bdcea4e6f4ada18567d96a51c3aa29e618ef09b80ae99385e191e", - Coin: coin.ETH, - From: "0x4b55af7ce28a113d794f9a9940fe1506f37aa619", - To: "0xe65f787c8561a4b15771111bb427274dedfe85d7", - Fee: "63000000000000", - Date: 1554662399, - Block: 7522678, - Sequence: 1, - Status: blockatlas.StatusFailed, - Error: "Error", - Meta: blockatlas.Transfer{ - Value: "59859820000000000", - Symbol: "ETH", - Decimals: 18, - }, -} - -type test struct { - name string - apiResponse string - expected *blockatlas.Tx - token bool -} - -func TestNormalize(t *testing.T) { - testNormalize(t, &test{ - name: "transfer", - apiResponse: transferSrc, - expected: &transferDst, - }) - testNormalize(t, &test{ - name: "token transfer", - apiResponse: tokenTransferSrc, - expected: &tokenTransferDst, - token: true, - }) - testNormalize(t, &test{ - name: "contract call", - apiResponse: contractCallSrc, - expected: &contractCallDst, - }) - testNormalize(t, &test{ - name: "failed transaction", - apiResponse: failedSrc, - expected: &failedDst, - }) -} - -func testNormalize(t *testing.T, _test *test) { - var doc Doc - err := json.Unmarshal([]byte(_test.apiResponse), &doc) - if err != nil { - t.Error(err) - return - } - res := AppendTxs(nil, &doc, coin.ETH) - - resJSON, err := json.Marshal(res) - if err != nil { - t.Fatal(err) - } - - dstJSON, err := json.Marshal([]blockatlas.Tx{*_test.expected}) - if err != nil { - t.Fatal(err) - } - - if !bytes.Equal(resJSON, dstJSON) { - println(string(resJSON)) - println(string(dstJSON)) - t.Error(_test.name + ": tx don't equal") - } -} - -const tokenSrc = ` -{ - "balance": "0", - "contract": { - "contract": "0xa14839c9837657efcde754ebeaf5cbecdd801b2a", - "address": "0xa14839c9837657efcde754ebeaf5cbecdd801b2a", - "name": "FusChain", - "decimals": 18, - "symbol": "FUS" - } -}` - -var tokenDst = blockatlas.Token{ - Name: "FusChain", - Symbol: "FUS", - Decimals: 18, - TokenID: "0xa14839c9837657efcde754ebeaf5cbecdd801b2a", - Coin: coin.ETH, - Type: blockatlas.TokenTypeERC20, -} - -type testToken struct { - name string - apiResponse string - expected *blockatlas.Token - token bool -} - -func TestNormalizeToken(t *testing.T) { - testNormalizeToken(t, &testToken{ - name: "token", - apiResponse: tokenSrc, - expected: &tokenDst, - }) -} - -func testNormalizeToken(t *testing.T, _test *testToken) { - var token Token - err := json.Unmarshal([]byte(_test.apiResponse), &token) - if err != nil { - t.Error(err) - return - } - tk, ok := NormalizeToken(&token, coin.ETH) - if !ok { - t.Errorf("token: token could not be normalized") - } - - resJSON, err := json.Marshal(&tk) - if err != nil { - t.Fatal(err) - } - - dstJSON, err := json.Marshal(_test.expected) - if err != nil { - t.Fatal(err) - } - - if !bytes.Equal(resJSON, dstJSON) { - println(string(resJSON)) - println(string(dstJSON)) - t.Error("token: token don't equal") - } -} - -const collectionsOwner = "0x0875BCab22dE3d02402bc38aEe4104e1239374a7" - -const collectionsSrc = ` -[ - { - "primary_asset_contracts": [ - { - "address": "0x06012c8cf97bead5deae237070f9587f8e7a266d", - "name": "CryptoKitties", - "symbol": "CKITTY", - "description": "CryptoKitties is a game centered around breedable, collectible, and oh-so-adorable creatures we call CryptoKitties! Each cat is one-of-a-kind and 100% owned by you; it cannot be replicated, taken away, or destroyed.", - "external_link": "https://www.cryptokitties.co/", - "nft_version": "1.0", - "schema_name": "ERC721", - "display_data": { - "images": [ - "https://storage.googleapis.com/ck-kitty-image/0x06012c8cf97bead5deae237070f9587f8e7a266d/564155.svg", - "https://storage.googleapis.com/ck-kitty-image/0x06012c8cf97bead5deae237070f9587f8e7a266d/546630.svg", - "https://storage.googleapis.com/ck-kitty-image/0x06012c8cf97bead5deae237070f9587f8e7a266d/441529.svg", - "https://storage.googleapis.com/ck-kitty-image/0x06012c8cf97bead5deae237070f9587f8e7a266d/552435.svg", - "https://storage.googleapis.com/ck-kitty-image/0x06012c8cf97bead5deae237070f9587f8e7a266d/524748.png", - "https://storage.googleapis.com/ck-kitty-image/0x06012c8cf97bead5deae237070f9587f8e7a266d/540800.svg" - ], - "card_display_style": "padded" - }, - "image_url": "https://storage.opensea.io/0x06012c8cf97bead5deae237070f9587f8e7a266d-featured-1556588705.png" - } - ], - "name": "CryptoKitties", - "slug": "cryptokitties", - "image_url": "https://storage.opensea.io/0x06012c8cf97bead5deae237070f9587f8e7a266d-featured-1556588705.png", - "description": "CryptoKitties is a game centered around breedable, collectible, and oh-so-adorable creatures we call CryptoKitties! Each cat is one-of-a-kind and 100% owned by you; it cannot be replicated, taken away, or destroyed.", - "external_url": "https://www.cryptokitties.co/", - "featured_image_url": "https://storage.opensea.io/0x06012c8cf97bead5deae237070f9587f8e7a266d-featured-1556589429.png", - "created_date": "2019-04-26T22:13:04.207050", - "owned_asset_count": 3 - }, - { - "primary_asset_contracts": [ - { - "address": "0xf629cbd94d3791c9250152bd8dfbdf380e2a3b9c", - "name": "Coin", - "symbol": "", - "description": null, - "external_link": null, - "nft_version": null, - "schema_name": "ERC20", - "display_data": {} - } - ], - "name": "Enjin Token", - "slug": "enjin-token", - "image_url": "https://storage.googleapis.com/opensea-static/tokens-high-res/ENJ.png", - "description": "This is the collection of owners of EnjinCoin", - "external_url": null, - "owned_asset_count": 20000000000000000000 - }, - { - "primary_asset_contracts": [ - { - "address": "0xfaafdc07907ff5120a76b34b731b278c38d6043c", - "name": "Enjin", - "symbol": "", - "description": "", - "external_link": null, - "nft_version": null, - "schema_name": "ERC1155", - "display_data": {}, - "owner": null, - "created_date": "2019-08-02T23:43:14.666153", - "asset_contract_type": "semi-fungible" - } - ], - "name": "Age of Rust", - "slug": "age-of-rust", - "image_url": "https://storage.opensea.io/age-of-rust-1561960816.jpg", - "description": "Year 4424: The search begins for new life on the other side of the galaxy. Explore abandoned space stations, mysterious caverns, and ruins on far away worlds in order to unlock puzzles and secrets! Beware the rogue machines!", - "external_url": "https://www.ageofrust.games/", - "featured_image_url": null, - "created_date": "2019-09-03T02:35:56.063685", - "owned_asset_count": 1 - } -] -` - -var collection1Dst = blockatlas.Collection{ - Name: "CryptoKitties", - Symbol: "CKITTY", - Slug: "cryptokitties", - ImageUrl: "https://storage.opensea.io/0x06012c8cf97bead5deae237070f9587f8e7a266d-featured-1556588705.png", - Description: "CryptoKitties is a game centered around breedable, collectible, and oh-so-adorable creatures we call CryptoKitties! Each cat is one-of-a-kind and 100% owned by you; it cannot be replicated, taken away, or destroyed.", - ExternalLink: "https://www.cryptokitties.co/", - Total: 3, - CategoryAddress: "cryptokitties", - Id: "cryptokitties", - Address: "0x0875BCab22dE3d02402bc38aEe4104e1239374a7", - Version: "1.0", - Coin: 60, - Type: "ERC721", -} - -var collection2Dst = blockatlas.Collection{ - Name: "Age of Rust", - Symbol: "", - Slug: "age-of-rust", - ImageUrl: "https://storage.opensea.io/age-of-rust-1561960816.jpg", - Description: "Year 4424: The search begins for new life on the other side of the galaxy. Explore abandoned space stations, mysterious caverns, and ruins on far away worlds in order to unlock puzzles and secrets! Beware the rogue machines!", - ExternalLink: "https://www.ageofrust.games/", - Total: 1, - CategoryAddress: "age-of-rust", - Id: "age-of-rust", - Address: "0x0875BCab22dE3d02402bc38aEe4104e1239374a7", - Version: "", - Coin: 60, - Type: "ERC1155", -} - -func TestNormalizeCollection(t *testing.T) { - var collections []Collection - err := json.Unmarshal([]byte(collectionsSrc), &collections) - assert.Nil(t, err) - page := NormalizeCollectionPage(collections, coin.ETH, collectionsOwner) - assert.Equal(t, len(page), 2, "collections could not be normalized") - expected := blockatlas.CollectionPage{collection1Dst, collection2Dst} - assert.Equal(t, page, expected, "collections don't equal") -} - -const collectibleSrc = ` -[ - { - "token_id": "54277541829991970107421667568590323026590803461896874578610080514640537714688", - "image_url": "https://storage.opensea.io/0xfaafdc07907ff5120a76b34b731b278c38d6043c/54277541829991970107421667568590323026590803461896874578610080514640537714688-1564858806.png", - "image_preview_url": "https://storage.opensea.io/0xfaafdc07907ff5120a76b34b731b278c38d6043c-preview/54277541829991970107421667568590323026590803461896874578610080514640537714688-1564858807.png", - "name": "Rustbits", - "description": "Rustbits are the main token of use within the Age of Rust game universe. You need Rustbits to not only play Age of Rust, but also to purchase in-game cryptoitems as well. Rustbits are radioactive rust scraped off of hulls of abandoned ships that are in orbit around a hidden planet, which is also a gas giant. The planet is so radioactive, it damages ships and kills anyone that gets close to it. Getting bits of rust off of ships is highly rare and prized.", - "external_link": "", - "asset_contract": { - "address": "0xfaafdc07907ff5120a76b34b731b278c38d6043c", - "name": "Enjin", - "external_link": null, - "nft_version": null, - "schema_name": "ERC1155", - "display_data": {} - }, - "permalink": "https://opensea.io/assets/0xfaafdc07907ff5120a76b34b731b278c38d6043c/54277541829991970107421667568590323026590803461896874578610080514640537714688" - } -] -` - -var collectibleCollectionDst = Collection{ - Name: "Age of Rust", - ImageUrl: "https://storage.opensea.io/age-of-rust-1561960816.jpg", - Description: "Year 4424: The search begins for new life on the other side of the galaxy. Explore abandoned space stations, mysterious caverns, and ruins on far away worlds in order to unlock puzzles and secrets! Beware the rogue machines!", - ExternalUrl: "https://www.ageofrust.games/", - Total: big.NewInt(1), - Slug: "age-of-rust", - Contracts: []PrimaryAssetContract{ - { - Name: "Age of Rust", - Address: "0x5574Cd97432cEd0D7Caf58ac3c4fEDB2061C98fB", - NftVersion: "", - Symbol: "", - Description: "", - Type: "ERC1155", - Url: "", - }, - }, -} - -var collectibleDst = blockatlas.Collectible{ - ID: "0xfaafdc07907ff5120a76b34b731b278c38d6043c-54277541829991970107421667568590323026590803461896874578610080514640537714688", - CollectionID: "age-of-rust", - TokenID: "54277541829991970107421667568590323026590803461896874578610080514640537714688", - CategoryContract: "0xfaafdc07907ff5120a76b34b731b278c38d6043c", - ContractAddress: "0x5574Cd97432cEd0D7Caf58ac3c4fEDB2061C98fB", - Category: "Age of Rust", - ImageUrl: "https://storage.opensea.io/0xfaafdc07907ff5120a76b34b731b278c38d6043c-preview/54277541829991970107421667568590323026590803461896874578610080514640537714688-1564858807.png", - ExternalLink: "", - ProviderLink: "https://opensea.io/assets/0xfaafdc07907ff5120a76b34b731b278c38d6043c/54277541829991970107421667568590323026590803461896874578610080514640537714688", - Type: "ERC1155", - Description: "Rustbits are the main token of use within the Age of Rust game universe. You need Rustbits to not only play Age of Rust, but also to purchase in-game cryptoitems as well. Rustbits are radioactive rust scraped off of hulls of abandoned ships that are in orbit around a hidden planet, which is also a gas giant. The planet is so radioactive, it damages ships and kills anyone that gets close to it. Getting bits of rust off of ships is highly rare and prized.", - Coin: 60, - Name: "Rustbits", -} - -func TestNormalizeCollectible(t *testing.T) { - var collectible []Collectible - err := json.Unmarshal([]byte(collectibleSrc), &collectible) - assert.Nil(t, err) - page := NormalizeCollectiblePage(&collectibleCollectionDst, collectible, coin.ETH) - assert.Equal(t, len(page), 1, "collectible could not be normalized") - expected := blockatlas.CollectiblePage{collectibleDst} - assert.Equal(t, page, expected, "collectible don't equal") -} diff --git a/platform/ethereum/base.go b/platform/ethereum/base.go new file mode 100644 index 000000000..18c246f6a --- /dev/null +++ b/platform/ethereum/base.go @@ -0,0 +1,39 @@ +package ethereum + +import ( + "github.com/trustwallet/blockatlas/platform/bitcoin/blockbook" + "github.com/trustwallet/blockatlas/platform/ethereum/bounce" + "github.com/trustwallet/blockatlas/platform/ethereum/opensea" + "github.com/trustwallet/golibs/client" + "github.com/trustwallet/golibs/coin" + "github.com/trustwallet/golibs/network/middleware" +) + +type Platform struct { + CoinIndex uint + client EthereumClient + collectible CollectibleClient +} + +func InitWithBlockbook(coinType uint, blockbookApi string) *Platform { + return &Platform{ + CoinIndex: coinType, + client: &blockbook.Client{Request: client.InitClient(blockbookApi, middleware.SentryErrorHandler)}, + } +} + +func InitWithOpenSea(coinType uint, blockbookApi, collectionApi, collectionKey string) *Platform { + platform := InitWithBlockbook(coinType, blockbookApi) + platform.collectible = opensea.InitClient(collectionApi, collectionKey) + return platform +} + +func InitWithBounce(coinType uint, blockbookApi, collectionApi string) *Platform { + platform := InitWithBlockbook(coinType, blockbookApi) + platform.collectible = bounce.InitClient(collectionApi) + return platform +} + +func (p *Platform) Coin() coin.Coin { + return coin.Coins[p.CoinIndex] +} diff --git a/platform/ethereum/block.go b/platform/ethereum/block.go new file mode 100644 index 000000000..b8860090d --- /dev/null +++ b/platform/ethereum/block.go @@ -0,0 +1,11 @@ +package ethereum + +import "github.com/trustwallet/golibs/types" + +func (p *Platform) CurrentBlockNumber() (int64, error) { + return p.client.GetCurrentBlockNumber() +} + +func (p *Platform) GetBlockByNumber(num int64) (*types.Block, error) { + return p.client.GetBlockByNumber(num, p.CoinIndex) +} diff --git a/platform/ethereum/bounce/client.go b/platform/ethereum/bounce/client.go new file mode 100644 index 000000000..465cf7956 --- /dev/null +++ b/platform/ethereum/bounce/client.go @@ -0,0 +1,88 @@ +package bounce + +import ( + "errors" + "fmt" + "net/url" + "strings" + + "github.com/trustwallet/golibs/client" + "github.com/trustwallet/golibs/network/middleware" +) + +const ( + httpScheme = "http" + ipfsScheme = "ipfs" +) + +type Client struct { + client.Request +} + +func InitClient(url string) *Client { + c := Client{client.InitClient(url, middleware.SentryErrorHandler)} + return &c +} + +func (c Client) getCollections(owner string) ([]Collection, error) { + query := url.Values{ + "user_address": {owner}, + } + var resp CollectionResponse + err := c.Get(&resp, "/v2/bsc/nft", query) + if err != nil { + return nil, err + } + return resp.Data.Collections, nil +} + +func (c Client) getCollectibles(owner string, collectionID string) ([]Collectible, error) { + query := url.Values{ + "user_address": {owner}, + "contract_address": {collectionID}, + } + + var resp CollectibleResponse + err := c.Get(&resp, "/v2/bsc/erc721", query) + if err != nil { + return nil, err + } + return resp.Data.Collectibles, err +} + +func fetchTokenURI(uri string) (info CollectionInfo, err error) { + url, err := url.Parse(uri) + if err != nil { + return + } + + var c client.Request + if strings.HasPrefix(url.Scheme, httpScheme) { + c = client.InitClient(uri, middleware.SentryErrorHandler) + } else if strings.HasPrefix(url.Scheme, ipfsScheme) { + c = client.InitClient(ipfsGatewayUrl(url), middleware.SentryErrorHandler) + } else { + return info, errors.New("not supported url scheme: " + url.Scheme) + } + + err = c.Get(&info, "", nil) + return +} + +func normalizeUrl(uri string) string { + url, err := url.Parse(uri) + if err != nil { + return uri + } + if url.Scheme != ipfsScheme { + return uri + } + return ipfsGatewayUrl(url) +} + +func ipfsGatewayUrl(url *url.URL) string { + components := strings.TrimPrefix(url.String(), ipfsScheme+"://") + components = strings.TrimPrefix(components, "/") + components = strings.TrimPrefix(components, "ipfs/") + return fmt.Sprintf("https://ipfs.io/ipfs/%s", components) +} diff --git a/platform/ethereum/bounce/client_test.go b/platform/ethereum/bounce/client_test.go new file mode 100644 index 000000000..96182f203 --- /dev/null +++ b/platform/ethereum/bounce/client_test.go @@ -0,0 +1,31 @@ +package bounce + +import ( + "testing" +) + +func Test_normalizeUrl(t *testing.T) { + tests := []struct { + name string + uri string + want string + }{ + { + name: "Test pancake bunny token uri", + uri: "ipfs://QmYu9WwPNKNSZQiTCDfRk7aCR472GURavR9M1qosDmqpev/swapsies.json", + want: "https://ipfs.io/ipfs/QmYu9WwPNKNSZQiTCDfRk7aCR472GURavR9M1qosDmqpev/swapsies.json", + }, + { + name: "Test url with ipfs prefix", + uri: "ipfs://ipfs/QmS3hmJqpHpvnCocqv9FTZbcSGDnvuFv4qWY3qnwkMpB9x", + want: "https://ipfs.io/ipfs/QmS3hmJqpHpvnCocqv9FTZbcSGDnvuFv4qWY3qnwkMpB9x", + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + if got := normalizeUrl(tt.uri); got != tt.want { + t.Errorf("normalizeUrl() = %v, want %v", got, tt.want) + } + }) + } +} diff --git a/platform/ethereum/bounce/collection.go b/platform/ethereum/bounce/collection.go new file mode 100644 index 000000000..db1925288 --- /dev/null +++ b/platform/ethereum/bounce/collection.go @@ -0,0 +1,125 @@ +package bounce + +import ( + "strconv" + + "github.com/trustwallet/blockatlas/pkg/blockatlas" + "github.com/trustwallet/golibs/types" +) + +var ( + nftVersion = "3.0" // opensea nft_version compatible +) + +func (c *Client) GetCollections(owner string, coinIndex uint) (types.CollectionPage, error) { + collections, err := c.getCollections(owner) + if err != nil { + return nil, err + } + return c.processCollections(collections, coinIndex, owner) + +} + +func (c *Client) GetCollectibles(owner, collectionID string, coinIndex uint) (types.CollectiblePage, error) { + collectibles, err := c.getCollectibles(owner, collectionID) + if err != nil { + return nil, err + } + return c.processCollectibles(collectibles, coinIndex) +} + +func (c *Client) processCollections(collections []Collection, coinIndex uint, owner string) (types.CollectionPage, error) { + page := make(types.CollectionPage, 0) + categories := map[string]*types.Collection{} + + for _, cl := range collections { + + // skip invalid balance + total, err := strconv.Atoi(cl.Balance) + if err != nil { + continue + } + + // udpate existed balance + existed, ok := categories[cl.ContractAddr] + if ok { + existed.Total = existed.Total + total + continue + } + + // skip empty info token + if len(cl.TokenURI) == 0 { + continue + } + + // fetch token info + info, err := fetchTokenURI(cl.TokenURI) + if err != nil { + return nil, err + } + + // skip empty name/image + if len(info.Name) == 0 || len(info.Image) == 0 { + continue + } + + contractName := cl.ContractName + if len(contractName) == 0 { + contractName = info.Name + } + + categories[cl.ContractAddr] = &types.Collection{ + Id: cl.ContractAddr, + Name: contractName, + ImageUrl: normalizeUrl(info.Image), + Description: info.Description, + ExternalLink: normalizeUrl(cl.TokenURI), + Total: total, + Address: owner, + Coin: coinIndex, + Type: "ERC" + cl.TokenType, + } + } + + for _, c := range categories { + page = append(page, *c) + } + return page, nil +} + +func (c *Client) processCollectibles(collectibles []Collectible, coinIndex uint) (types.CollectiblePage, error) { + if len(collectibles) == 0 { + return types.CollectiblePage{}, nil + } + page := make(types.CollectiblePage, 0) + for _, c := range collectibles { + info, err := fetchTokenURI(c.TokenURI) + if err != nil { + return nil, err + } + normalized := normalizeCollectible(c, coinIndex, info) + page = append(page, normalized) + } + return page, nil +} + +func normalizeCollectible(c Collectible, coinIndex uint, info CollectionInfo) types.Collectible { + category := c.ContractName + if len(category) == 0 { + category = info.Name + } + return types.Collectible{ + ID: blockatlas.GenCollectibleId(c.ContractAddr, c.TokenID), + CollectionID: c.ContractAddr, + TokenID: c.TokenID, + ContractAddress: c.ContractAddr, + Category: category, + ImageUrl: normalizeUrl(info.Image), + ExternalLink: normalizeUrl(c.TokenURI), + Type: string(types.ERC721), + Description: info.Description, + Coin: coinIndex, + Name: info.Name, + Version: nftVersion, + } +} diff --git a/platform/ethereum/bounce/collection_test.go b/platform/ethereum/bounce/collection_test.go new file mode 100644 index 000000000..a7da964f3 --- /dev/null +++ b/platform/ethereum/bounce/collection_test.go @@ -0,0 +1,87 @@ +package bounce + +import ( + "reflect" + "testing" + + "github.com/stretchr/testify/assert" + "github.com/trustwallet/golibs/coin" + "github.com/trustwallet/golibs/mock" + "github.com/trustwallet/golibs/types" +) + +func Test_normalizeCollectible(t *testing.T) { + type args struct { + filename string + coinIndex uint + info CollectionInfo + } + tests := []struct { + name string + args args + want types.Collectible + }{ + { + name: "Test empty contract name", + args: args{ + filename: "artwork_nft.json", + coinIndex: coin.SMARTCHAIN, + info: CollectionInfo{ + Name: "Hungry", + Description: "Animal Series", + Image: "https://d3ggs2vjn5heyw.cloudfront.net/static/nfts/artworks/d9dc679ec0614eb78b479aed21694305.jpg", + }, + }, + want: types.Collectible{ + ID: "0x5Bc94e9347F3b9Be8415bDfd24af16666704E44f-450", + CollectionID: "0x5Bc94e9347F3b9Be8415bDfd24af16666704E44f", + TokenID: "450", + ContractAddress: "0x5Bc94e9347F3b9Be8415bDfd24af16666704E44f", + Category: "Hungry", + ImageUrl: "https://d3ggs2vjn5heyw.cloudfront.net/static/nfts/artworks/d9dc679ec0614eb78b479aed21694305.jpg", + ExternalLink: "https://www.bakeryswap.org/api/v1/artworks/fb4576253e3d45cebf0ac4c8df8f1743", + Type: string(types.ERC721), + Description: "Animal Series", + Coin: coin.SMARTCHAIN, + Name: "Hungry", + Version: "3.0", + }, + }, + { + name: "Test pancake bunny", + args: args{ + filename: "pancake_bunny.json", + coinIndex: coin.SMARTCHAIN, + info: CollectionInfo{ + Name: "Swapsies", + Description: "These bunnies love nothing more than swapping pancakes. Especially on BSC.", + Image: "https://ipfs.io/ipfs/QmXdHqg3nywpNJWDevJQPtkz93vpfoHcZWQovFz2nmtPf5/swapsies.png", + }, + }, + want: types.Collectible{ + ID: "0xDf7952B35f24aCF7fC0487D01c8d5690a60DBa07-409", + CollectionID: "0xDf7952B35f24aCF7fC0487D01c8d5690a60DBa07", + TokenID: "409", + ContractAddress: "0xDf7952B35f24aCF7fC0487D01c8d5690a60DBa07", + Category: "Pancake Bunnies", + ImageUrl: "https://ipfs.io/ipfs/QmXdHqg3nywpNJWDevJQPtkz93vpfoHcZWQovFz2nmtPf5/swapsies.png", + ExternalLink: "https://ipfs.io/ipfs/QmYu9WwPNKNSZQiTCDfRk7aCR472GURavR9M1qosDmqpev/swapsies.json", + Type: string(types.ERC721), + Description: "These bunnies love nothing more than swapping pancakes. Especially on BSC.", + Coin: coin.SMARTCHAIN, + Name: "Swapsies", + Version: "3.0", + }, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + var c Collectible + err := mock.JsonModelFromFilePath("mocks/"+tt.args.filename, &c) + assert.Nil(t, err) + if got := normalizeCollectible(c, tt.args.coinIndex, tt.args.info); !reflect.DeepEqual(got, tt.want) { + t.Errorf("normalizeCollectible() = %v, want %v", got, tt.want) + } + }) + } +} diff --git a/platform/ethereum/bounce/mocks/artwork_nft.json b/platform/ethereum/bounce/mocks/artwork_nft.json new file mode 100644 index 000000000..1cc752141 --- /dev/null +++ b/platform/ethereum/bounce/mocks/artwork_nft.json @@ -0,0 +1,22 @@ +{ + "id": 63039, + "contract_addr": "0x5Bc94e9347F3b9Be8415bDfd24af16666704E44f", + "contract_name": "", + "token_type": "721", + "token_id": "450", + "owner_addr": "0x7d8bf18C7cE84b3E175b339c4Ca93aEd1dD166F1", + "balance": "1", + "token_uri": "https://www.bakeryswap.org/api/v1/artworks/fb4576253e3d45cebf0ac4c8df8f1743", + "name": null, + "description": null, + "image": null, + "metadata": { + "description": "Animal Series", + "image": "https://d3ggs2vjn5heyw.cloudfront.net/static/nfts/artworks/d9dc679ec0614eb78b479aed21694305.jpg", + "name": "Hungry", + "properties": { + "artist": "srnArt", + "public_profile_link": "https://twitter.com/srn_art?s=09" + } + } +} diff --git a/platform/ethereum/bounce/mocks/pancake_bunny.json b/platform/ethereum/bounce/mocks/pancake_bunny.json new file mode 100644 index 000000000..decb0f85a --- /dev/null +++ b/platform/ethereum/bounce/mocks/pancake_bunny.json @@ -0,0 +1,21 @@ +{ + "id": 48963, + "contract_addr": "0xDf7952B35f24aCF7fC0487D01c8d5690a60DBa07", + "contract_name": "Pancake Bunnies", + "token_type": "721", + "token_id": "409", + "owner_addr": "0x7d8bf18c7ce84b3e175b339c4ca93aed1dd166f1", + "balance": "1", + "token_uri": "ipfs://QmYu9WwPNKNSZQiTCDfRk7aCR472GURavR9M1qosDmqpev/swapsies.json", + "name": null, + "description": null, + "image": null, + "metadata": { + "attributes": { + "bunnyId": "0" + }, + "description": "These bunnies love nothing more than swapping pancakes. Especially on BSC.", + "image": "ipfs://QmXdHqg3nywpNJWDevJQPtkz93vpfoHcZWQovFz2nmtPf5/swapsies.png", + "name": "Swapsies" + } +} diff --git a/platform/ethereum/bounce/model.go b/platform/ethereum/bounce/model.go new file mode 100644 index 000000000..3fd49aac3 --- /dev/null +++ b/platform/ethereum/bounce/model.go @@ -0,0 +1,48 @@ +package bounce + +type Response struct { + Code int `json:"code"` + Msg string `json:"msg"` +} + +type Collectible struct { + ContractAddr string `json:"contract_addr"` + ContractName string `json:"contract_name,omitempty"` + TokenID string `json:"token_id"` + OwnerAddr string `json:"owner_addr"` + TokenURI string `json:"token_uri"` +} + +type CollectibleList struct { + Collectibles []Collectible `json:"tokens"` +} + +type CollectibleResponse struct { + Response + Data CollectibleList `json:"data"` +} + +type Collection struct { + ContractAddr string `json:"contract_addr"` + ContractName string `json:"contract_name,omitempty"` + TokenType string `json:"token_type"` + TokenID string `json:"token_id"` + OwnerAddr string `json:"owner_addr"` + Balance string `json:"balance"` + TokenURI string `json:"token_uri"` +} + +type CollectionList struct { + Collections []Collection `json:"nfts721"` +} + +type CollectionResponse struct { + Response + Data CollectionList `json:"data"` +} + +type CollectionInfo struct { + Name string `json:"name"` + Description string `json:"description"` + Image string `json:"image"` +} diff --git a/platform/ethereum/client.go b/platform/ethereum/client.go index 7393c990a..1d8693a00 100644 --- a/platform/ethereum/client.go +++ b/platform/ethereum/client.go @@ -1,47 +1,16 @@ package ethereum -import ( - "fmt" - "github.com/trustwallet/blockatlas/pkg/blockatlas" - "net/url" -) - -type Client struct { - blockatlas.Request -} - -func (c *Client) GetTxs(address string) (*Page, error) { - return c.getTxs(url.Values{"address": {address}}) -} - -func (c *Client) GetTxsWithContract(address, contract string) (*Page, error) { - return c.getTxs(url.Values{"address": {address}, "contract": {contract}}) -} - -func (c *Client) getTxs(query url.Values) (page *Page, err error) { - err = c.Get(&page, "transactions", query) - return -} - -func (c *Client) GetBlockByNumber(num int64) (page []Doc, err error) { - path := fmt.Sprintf("transactions/block/%d", num) - err = c.Get(&page, path, nil) - return -} - -func (c *Client) CurrentBlockNumber() (int64, error) { - var nodeInfo NodeInfo - err := c.Get(&nodeInfo, "node_info", nil) - if err != nil { - return 0, err - } - return nodeInfo.LatestBlock, nil +import "github.com/trustwallet/golibs/types" + +type EthereumClient interface { + GetTransactions(address string, coinIndex uint) (types.Txs, error) + GetTokenTxs(address, token string, coinIndex uint) (types.Txs, error) + GetTokenList(address string, coinIndex uint) ([]types.Token, error) + GetCurrentBlockNumber() (int64, error) + GetBlockByNumber(num int64, coinIndex uint) (*types.Block, error) } -func (c *Client) GetTokens(address string) (tp *TokenPage, err error) { - query := url.Values{ - "address": {address}, - } - err = c.Get(&tp, "tokens", query) - return +type CollectibleClient interface { + GetCollections(owner string, coinIndex uint) (types.CollectionPage, error) + GetCollectibles(owner, collectionID string, coinIndex uint) (types.CollectiblePage, error) } diff --git a/platform/ethereum/collection.go b/platform/ethereum/collection.go new file mode 100644 index 000000000..2ef9e7670 --- /dev/null +++ b/platform/ethereum/collection.go @@ -0,0 +1,13 @@ +package ethereum + +import ( + "github.com/trustwallet/golibs/types" +) + +func (p *Platform) GetCollections(owner string) (types.CollectionPage, error) { + return p.collectible.GetCollections(owner, p.CoinIndex) +} + +func (p *Platform) GetCollectibles(owner, collectionID string) (types.CollectiblePage, error) { + return p.collectible.GetCollectibles(owner, collectionID, p.CoinIndex) +} diff --git a/platform/ethereum/collections_client.go b/platform/ethereum/collections_client.go deleted file mode 100644 index c6689d156..000000000 --- a/platform/ethereum/collections_client.go +++ /dev/null @@ -1,100 +0,0 @@ -package ethereum - -import ( - "github.com/trustwallet/blockatlas/pkg/blockatlas" - "github.com/trustwallet/blockatlas/pkg/errors" - "net/url" - "strconv" - "strings" -) - -type CollectionsClient struct { - blockatlas.Request -} - -func (c CollectionsClient) GetCollections(owner string) (page []Collection, err error) { - query := url.Values{ - "asset_owner": {owner}, - "limit": {"1000"}, - } - err = c.Get(&page, "api/v1/collections", query) - return -} - -func (c CollectionsClient) GetCollectibles(owner string, collectibleID string) (*Collection, []Collectible, error) { - collections, err := c.GetCollections(owner) - if err != nil { - return nil, nil, err - } - collection := searchCollection(collections, collectibleID) - if collection == nil { - return nil, nil, errors.E("collectible not found", errors.TypePlatformClient, - errors.Params{"collectibleID": collectibleID}).PushToSentry() - } - - query := url.Values{ - "owner": {owner}, - "limit": {strconv.Itoa(300)}, - } - - query.Set("collection", collection.Slug) - - var page CollectiblePage - err = c.Get(&page, "api/v1/assets", query) - return collection, page.Collectibles, err -} - -//TODO: remove once most of the clients will be updated (deadline: March 17th) -func (c CollectionsClient) OldGetCollectibles(owner string, collectibleID string) (*Collection, []Collectible, error) { - collections, err := c.GetCollections(owner) - if err != nil { - return nil, nil, err - } - id := getCollectionId(collectibleID) - collection := oldSearchCollection(collections, id) - if collection == nil { - return nil, nil, errors.E("collectible not found", errors.TypePlatformClient, - errors.Params{"collectibleID": collectibleID}).PushToSentry() - } - - query := url.Values{ - "owner": {owner}, - "limit": {strconv.Itoa(300)}, - } - - for _, i := range collection.Contracts { - if _, ok := slugTokens[i.Type]; ok { - query.Set("collection", collection.Slug) - break - } - query.Add("asset_contract_addresses", i.Address) - } - - var page CollectiblePage - err = c.Get(&page, "api/v1/assets", query) - return collection, page.Collectibles, err -} - -func searchCollection(collections []Collection, collectibleID string) *Collection { - for _, i := range collections { - if strings.EqualFold(i.Slug, collectibleID) { - return &i - } - } - return nil -} - -//TODO: remove once most of the clients will be updated (deadline: March 17th) -func oldSearchCollection(collections []Collection, collectibleID string) *Collection { - for _, i := range collections { - if strings.EqualFold(i.Slug, collectibleID) { - return &i - } - for _, contract := range i.Contracts { - if strings.EqualFold(contract.Address, collectibleID) { - return &i - } - } - } - return nil -} diff --git a/platform/ethereum/collections_client_test.go b/platform/ethereum/collections_client_test.go deleted file mode 100644 index 8cc118320..000000000 --- a/platform/ethereum/collections_client_test.go +++ /dev/null @@ -1,49 +0,0 @@ -package ethereum - -import ( - "fmt" - "github.com/stretchr/testify/assert" - "testing" -) - -var c1 = Collection{ - Slug: "enjin", - Contracts: []PrimaryAssetContract{{ - Address: "0xfaafdc07907ff5120a76b34b731b278c38d6043c", - }}, -} -var c2 = Collection{ - Slug: "cryptokitties", - Contracts: []PrimaryAssetContract{{ - Address: "0x5574Cd97432cEd0D7Caf58ac3c4fEDB2061C98fB", - }}, -} -var c3 = Collection{ - Slug: "age-of-rust", - Contracts: []PrimaryAssetContract{{ - Address: "0x0875BCab22dE3d02402bc38aEe4104e1239374a7", - }}, -} - -func TestSearchCollection(t *testing.T) { - var tests = []struct { - collections []Collection - collectibleID string - result *Collection - }{ - {[]Collection{c1, c2, c3}, "enjin", &c1}, - {[]Collection{c1, c2, c3}, "cryptokitties", &c2}, - {[]Collection{c1, c2}, "age-of-rust", nil}, - {[]Collection{c1, c2, c3}, "age-of-rust", &c3}, - {[]Collection{c1, c2}, "cryptokitties", &c2}, - {[]Collection{c1}, "age-of-rust", nil}, - {[]Collection{c1, c3}, "enjin", &c1}, - } - for i, tt := range tests { - t.Run(fmt.Sprintf("searchCollection %d", i), func(t *testing.T) { - s := searchCollection(tt.collections, tt.collectibleID) - assert.EqualValues(t, s, tt.result) - }) - } - -} diff --git a/platform/ethereum/ens.go b/platform/ethereum/ens.go deleted file mode 100644 index c6929449d..000000000 --- a/platform/ethereum/ens.go +++ /dev/null @@ -1,63 +0,0 @@ -package ethereum - -import ( - "github.com/ethereum/go-ethereum/ethclient" - cc "github.com/hewigovens/go-coincodec" - CoinType "github.com/trustwallet/blockatlas/coin" - "github.com/trustwallet/blockatlas/pkg/blockatlas" - "github.com/trustwallet/blockatlas/pkg/errors" - "github.com/trustwallet/blockatlas/pkg/logger" - ens "github.com/wealdtech/go-ens/v3" -) - -func (p *Platform) Lookup(coins []uint64, name string) ([]blockatlas.Resolved, error) { - var result []blockatlas.Resolved - client, err := ethclient.Dial(p.RpcURL) - if err != nil { - return result, errors.E(err, "can't dial to ethereum rpc") - } - defer client.Close() - resolver, err := ens.NewResolver(client, name) - if err != nil { - return result, errors.E(err, "new ens resolver failed") - } - for _, coin := range coins { - // try to get multi coin address - address, err := addressForCoin(resolver, coin, name) - if err != nil { - logger.Error(errors.E(err, errors.Params{"coin": coin, "name": name})) - continue - } - result = append(result, blockatlas.Resolved{Coin: coin, Result: address}) - } - - return result, nil -} - -func addressForCoin(resolver *ens.Resolver, coin uint64, name string) (string, error) { - address, err := resolver.MultiAddress(coin) - if err != nil { - if coin == CoinType.ETH { - // user may not set multi coin address - result, err := lookupLegacyETH(resolver, name) - if err != nil { - return "", errors.E(err, "query legacy address failed") - } - return result, nil - } - return "", errors.E(err, "query multi coin address failed") - } - encoded, err := cc.ToString(address, uint32(coin)) - if err != nil { - return "", errors.E(err, "encode to address failed") - } - return encoded, nil -} - -func lookupLegacyETH(resolver *ens.Resolver, name string) (string, error) { - address, err := resolver.Address() - if err != nil { - return "", errors.E(err, "query address failed") - } - return address.Hex(), nil -} diff --git a/platform/ethereum/model.go b/platform/ethereum/model.go deleted file mode 100644 index df481539b..000000000 --- a/platform/ethereum/model.go +++ /dev/null @@ -1,109 +0,0 @@ -package ethereum - -import ( - "github.com/trustwallet/blockatlas/pkg/blockatlas" - "math/big" -) - -type Page struct { - Total uint `json:"total"` - Docs []Doc `json:"docs"` -} - -type TokenPage struct { - Total uint `json:"total"` - Docs []Token `json:"docs"` -} - -type Token struct { - Balance string `json:"balance"` - Contract Contract `json:"contract"` -} - -type Doc struct { - Ops []Op `json:"operations"` - Contract string `json:"contract"` - ID string `json:"id"` - BlockNumber uint64 `json:"blockNumber"` - Timestamp int64 `json:"time"` - Nonce uint64 `json:"nonce"` - From string `json:"from"` - To string `json:"to"` - Value string `json:"value"` - Gas string `json:"gas"` - GasPrice string `json:"gasPrice"` - GasUsed string `json:"gasUsed"` - Input string `json:"input"` - Error string `json:"error"` - Coin uint `json:"coin"` -} - -type Op struct { - TxID string `json:"transactionId"` - Contract *Contract `json:"contract"` - From string `json:"from"` - To string `json:"to"` - Type blockatlas.TransactionType `json:"type"` - Value string `json:"value"` - Coin uint `json:"coin"` -} - -type Contract struct { - Address string `json:"address"` - Symbol string `json:"symbol"` - Decimals uint `json:"decimals"` - TotalSupply string `json:"totalSupply,omitempty"` - Name string `json:"name"` - Contract string `json:"contract,omitempty"` -} - -type NodeInfo struct { - LatestBlock int64 `json:"latest_block"` -} - -type Collection struct { - Name string `json:"name"` - ImageUrl string `json:"image_url"` - Description string `json:"description"` - ExternalUrl string `json:"external_url"` - Slug string `json:"slug"` - Total *big.Int `json:"owned_asset_count"` - Contracts []PrimaryAssetContract `json:"primary_asset_contracts"` -} - -type PrimaryAssetContract struct { - Name string `json:"name"` - Address string `json:"address"` - NftVersion string `json:"nft_version"` - Symbol string `json:"symbol"` - Description string `json:"description"` - Type string `json:"schema_name"` - Data DisplayData `json:"display_data"` - Url string `json:"external_link"` -} - -type DisplayData struct { - Images []string `json:"images"` -} - -type CollectiblePage struct { - Collectibles []Collectible `json:"assets"` -} - -type Collectible struct { - TokenId string `json:"token_id"` - AssetContract CollectibleContract `json:"asset_contract"` - ImageUrl string `json:"image_url"` - ImagePreviewUrl string `json:"image_preview_url"` - Name string `json:"name"` - ExternalLink string `json:"external_link"` - Permalink string `json:"permalink"` - Description string `json:"description"` -} - -type CollectibleContract struct { - Address string `json:"address"` - Category string `json:"name"` - ExternalLink string `json:"external_link"` - Type string `json:"schema_name"` -} diff --git a/platform/ethereum/opensea/client.go b/platform/ethereum/opensea/client.go new file mode 100644 index 000000000..8a308deb3 --- /dev/null +++ b/platform/ethereum/opensea/client.go @@ -0,0 +1,40 @@ +package opensea + +import ( + "net/url" + "strconv" + + "github.com/trustwallet/golibs/client" + "github.com/trustwallet/golibs/network/middleware" +) + +type Client struct { + client.Request +} + +func InitClient(api string, apiKey string) *Client { + c := Client{client.InitClient(api, middleware.SentryErrorHandler)} + c.Headers["X-API-KEY"] = apiKey + return &c +} + +func (c Client) GetCollectionsByOwner(owner string) (page []Collection, err error) { + query := url.Values{ + "asset_owner": {owner}, + "limit": {"1000"}, + } + err = c.Get(&page, "api/v1/collections", query) + return +} + +func (c Client) GetCollectiblesByCollectionId(owner string, collectionId string) ([]Collectible, error) { + query := url.Values{ + "owner": {owner}, + "collection": {collectionId}, + "limit": {strconv.Itoa(300)}, + } + + var page CollectiblePage + err := c.Get(&page, "api/v1/assets", query) + return page.Collectibles, err +} diff --git a/platform/ethereum/opensea/collection.go b/platform/ethereum/opensea/collection.go new file mode 100644 index 000000000..b202988f6 --- /dev/null +++ b/platform/ethereum/opensea/collection.go @@ -0,0 +1,85 @@ +package opensea + +import ( + "github.com/trustwallet/blockatlas/pkg/blockatlas" + "github.com/trustwallet/golibs/asset" + "github.com/trustwallet/golibs/coin" + "github.com/trustwallet/golibs/types" +) + +var ( + supportedTypes = map[string]bool{"ERC721": true, "ERC1155": true} +) + +func (c *Client) GetCollections(owner string, coinIndex uint) (types.CollectionPage, error) { + collections, err := c.GetCollectionsByOwner(owner) + if err != nil { + return nil, err + } + return NormalizeCollections(collections, coinIndex, owner), nil + +} + +func (c *Client) GetCollectibles(owner, collectionId string, coinIndex uint) (types.CollectiblePage, error) { + items, err := c.GetCollectiblesByCollectionId(owner, collectionId) + if err != nil { + return nil, err + } + return NormalizeCollectiblePage(items, coinIndex), nil +} + +func NormalizeCollections(collections []Collection, coinIndex uint, owner string) (page types.CollectionPage) { + for _, collection := range collections { + item := NormalizeCollection(collection, coinIndex, owner) + page = append(page, item) + } + return page +} + +func NormalizeCollection(c Collection, coinIndex uint, owner string) types.Collection { + return types.Collection{ + Name: c.Name, + ImageUrl: c.ImageUrl, + Description: c.Description, + ExternalLink: c.ExternalUrl, + Total: int(c.Total.Int64()), + Id: c.Slug, + Address: owner, + Coin: coinIndex, + } +} + +func NormalizeCollectiblePage(collectibles []Collectible, coinIndex uint) (page types.CollectiblePage) { + for _, collectible := range collectibles { + item := NormalizeCollectible(collectible, coinIndex) + if _, ok := supportedTypes[item.Type]; ok { + page = append(page, item) + } + } + return page +} + +func NormalizeCollectible(c Collectible, coinIndex uint) types.Collectible { + collectible := types.Collectible{ + ID: blockatlas.GenCollectibleId(c.AssetContract.Address, c.TokenId), + CollectionID: c.Collection.Slug, + TokenID: c.TokenId, + ContractAddress: c.AssetContract.Address, + Name: c.Name, + Category: c.Collection.Name, + ImageUrl: c.ImagePreviewUrl, + ProviderLink: c.Permalink, + ExternalLink: c.Collection.ExternalLink, + Type: c.AssetContract.Type, + Description: c.Description, + Coin: coinIndex, + Version: c.AssetContract.Version, + } + if c.FeeToken != nil { + collectible.TransferFee = &types.CollectibleTransferFee{ + Asset: asset.BuildID(coin.ETHEREUM, c.FeeToken.Address), + Amount: c.TransferFee, + } + } + return collectible +} diff --git a/platform/ethereum/opensea/collection_test.go b/platform/ethereum/opensea/collection_test.go new file mode 100644 index 000000000..c2beb0056 --- /dev/null +++ b/platform/ethereum/opensea/collection_test.go @@ -0,0 +1,89 @@ +package opensea + +import ( + "encoding/json" + "testing" + + "github.com/stretchr/testify/assert" + "github.com/trustwallet/golibs/coin" + "github.com/trustwallet/golibs/mock" + "github.com/trustwallet/golibs/types" +) + +var ( + collectionsOwnerV4 = "0x0875BCab22dE3d02402bc38aEe4104e1239374a7" + collectionsSrcV4, _ = mock.JsonStringFromFilePath("mocks/opensea_collections.json") + collectibleSrcV4, _ = mock.JsonStringFromFilePath("mocks/opensea_collectible.json") + + collection1DstV4 = types.Collection{ + Name: "CryptoKitties", + ImageUrl: "https://storage.opensea.io/0x06012c8cf97bead5deae237070f9587f8e7a266d-featured-1556588705.png", + Description: "CryptoKitties is a game centered around breedable, collectible, and oh-so-adorable creatures we call CryptoKitties! Each cat is one-of-a-kind and 100% owned by you; it cannot be replicated, taken away, or destroyed.", + ExternalLink: "https://www.cryptokitties.co/", + Total: 3, + Id: "cryptokitties", + Address: "0x0875BCab22dE3d02402bc38aEe4104e1239374a7", + Coin: 60, + } + + collection2DstV4 = types.Collection{ + Name: "Age of Rust", + ImageUrl: "https://storage.opensea.io/age-of-rust-1561960816.jpg", + Description: "Year 4424: The search begins for new life on the other side of the galaxy. Explore abandoned space stations, mysterious caverns, and ruins on far away worlds in order to unlock puzzles and secrets! Beware the rogue machines!", + ExternalLink: "https://www.ageofrust.games/", + Total: 1, + Id: "age-of-rust", + Address: "0x0875BCab22dE3d02402bc38aEe4104e1239374a7", + Coin: 60, + } + + collection3DstV4 = types.Collection{ + Name: "Gods Unchained", + ImageUrl: "https://lh3.googleusercontent.com/yArciVdcDv3O2R-O8XCxx3YEYZdzpiCMdossjUgv0kpLIluUQ1bYN_dyEk5xcvBEOgeq0zNIoWOh7TL9DvUEv--OLQ=s60", + Description: "Gods Unchained is a free-to-play, turn-based competitive trading card game in which cards can be bought and sold on the OpenSea marketplace. Players use their collection to build decks of cards, and select a God to play with at the start of each match. The goal of the game is to reduce your opponent's life to zero. Each deck contains exactly 30 cards. On OpenSea, cards can be sold for a fixed price, auctioned, or sold in bundles.", + ExternalLink: "https://godsunchained.com/?refcode=0x5b3256965e7C3cF26E11FCAf296DfC8807C01073", + Total: 535, + Id: "gods-unchained", + Address: "0x0875BCab22dE3d02402bc38aEe4104e1239374a7", + Coin: 60, + } + + collectibleDstV4 = types.Collectible{ + ID: "0xfaafdc07907ff5120a76b34b731b278c38d6043c-54277541829991970107421667568590323026590803461896874578610080514640537714688", + CollectionID: "age-of-rust", + TokenID: "54277541829991970107421667568590323026590803461896874578610080514640537714688", + ContractAddress: "0xfaafdc07907ff5120a76b34b731b278c38d6043c", + Category: "Age of Rust", + ImageUrl: "https://storage.opensea.io/0xfaafdc07907ff5120a76b34b731b278c38d6043c-preview/54277541829991970107421667568590323026590803461896874578610080514640537714688-1564858807.png", + ExternalLink: "https://opensea.io/", + ProviderLink: "https://opensea.io/assets/0xfaafdc07907ff5120a76b34b731b278c38d6043c/54277541829991970107421667568590323026590803461896874578610080514640537714688", + Type: "ERC1155", + Description: "Rustbits are the main token of use within the Age of Rust game universe. You need Rustbits to not only play Age of Rust, but also to purchase in-game cryptoitems as well. Rustbits are radioactive rust scraped off of hulls of abandoned ships that are in orbit around a hidden planet, which is also a gas giant. The planet is so radioactive, it damages ships and kills anyone that gets close to it. Getting bits of rust off of ships is highly rare and prized.", + Coin: 60, + Name: "Rustbits", + TransferFee: &types.CollectibleTransferFee{ + Asset: "c60_t0xf629cbd94d3791c9250152bd8dfbdf380e2a3b9c", + Amount: "0", + }, + } +) + +func TestNormalizeCollectionV4(t *testing.T) { + var collections []Collection + err := json.Unmarshal([]byte(collectionsSrcV4), &collections) + assert.Nil(t, err) + page := NormalizeCollections(collections, coin.ETHEREUM, collectionsOwnerV4) + assert.Equal(t, 3, len(page), "collections could not be normalized") + expected := types.CollectionPage{collection1DstV4, collection2DstV4, collection3DstV4} + assert.Equal(t, page, expected, "collections don't equal") +} + +func TestNormalizeCollectibleV4(t *testing.T) { + var collectibles []Collectible + err := json.Unmarshal([]byte(collectibleSrcV4), &collectibles) + assert.Nil(t, err) + page := NormalizeCollectiblePage(collectibles, coin.ETHEREUM) + assert.Equal(t, len(page), 1, "collectible could not be normalized") + expected := types.CollectiblePage{collectibleDstV4} + assert.Equal(t, page, expected, "collectible don't equal") +} diff --git a/platform/ethereum/opensea/mocks/opensea_collectible.json b/platform/ethereum/opensea/mocks/opensea_collectible.json new file mode 100644 index 000000000..137029c93 --- /dev/null +++ b/platform/ethereum/opensea/mocks/opensea_collectible.json @@ -0,0 +1,35 @@ +[ + { + "token_id": "54277541829991970107421667568590323026590803461896874578610080514640537714688", + "image_url": "https://storage.opensea.io/0xfaafdc07907ff5120a76b34b731b278c38d6043c/54277541829991970107421667568590323026590803461896874578610080514640537714688-1564858806.png", + "image_preview_url": "https://storage.opensea.io/0xfaafdc07907ff5120a76b34b731b278c38d6043c-preview/54277541829991970107421667568590323026590803461896874578610080514640537714688-1564858807.png", + "name": "Rustbits", + "description": "Rustbits are the main token of use within the Age of Rust game universe. You need Rustbits to not only play Age of Rust, but also to purchase in-game cryptoitems as well. Rustbits are radioactive rust scraped off of hulls of abandoned ships that are in orbit around a hidden planet, which is also a gas giant. The planet is so radioactive, it damages ships and kills anyone that gets close to it. Getting bits of rust off of ships is highly rare and prized.", + "external_link": "", + "asset_contract": { + "address": "0xfaafdc07907ff5120a76b34b731b278c38d6043c", + "name": "Enjin", + "external_link": null, + "nft_version": null, + "schema_name": "ERC1155", + "display_data": {} + }, + "collection": { + "slug": "age-of-rust", + "name": "Age of Rust", + "external_url": "https://opensea.io/" + }, + "permalink": "https://opensea.io/assets/0xfaafdc07907ff5120a76b34b731b278c38d6043c/54277541829991970107421667568590323026590803461896874578610080514640537714688", + "transfer_fee_payment_token": { + "id": 18, + "symbol": "ENJ", + "address": "0xf629cbd94d3791c9250152bd8dfbdf380e2a3b9c", + "image_url": "https://lh3.googleusercontent.com/l9kffrrCmJQ4rmUONIKoV2tx1cQr3ejM2oKhtg08njtUo11tCCwmvTVgA2wD3akBIoMTdepIwrc62e105rRtmin6", + "name": "Enjin Token", + "decimals": 18, + "eth_price": "0.000950396392036", + "usd_price": "1.610000000000000098" + }, + "transfer_fee": "0" + } +] diff --git a/platform/ethereum/opensea/mocks/opensea_collections.json b/platform/ethereum/opensea/mocks/opensea_collections.json new file mode 100644 index 000000000..f59bfab50 --- /dev/null +++ b/platform/ethereum/opensea/mocks/opensea_collections.json @@ -0,0 +1,219 @@ +[ + { + "primary_asset_contracts": [ + { + "address": "0x06012c8cf97bead5deae237070f9587f8e7a266d", + "name": "CryptoKitties", + "symbol": "CKITTY", + "description": "CryptoKitties is a game centered around breedable, collectible, and oh-so-adorable creatures we call CryptoKitties! Each cat is one-of-a-kind and 100% owned by you; it cannot be replicated, taken away, or destroyed.", + "external_link": "https://www.cryptokitties.co/", + "nft_version": "1.0", + "schema_name": "ERC721", + "display_data": { + "images": [ + "https://storage.googleapis.com/ck-kitty-image/0x06012c8cf97bead5deae237070f9587f8e7a266d/564155.svg", + "https://storage.googleapis.com/ck-kitty-image/0x06012c8cf97bead5deae237070f9587f8e7a266d/546630.svg", + "https://storage.googleapis.com/ck-kitty-image/0x06012c8cf97bead5deae237070f9587f8e7a266d/441529.svg", + "https://storage.googleapis.com/ck-kitty-image/0x06012c8cf97bead5deae237070f9587f8e7a266d/552435.svg", + "https://storage.googleapis.com/ck-kitty-image/0x06012c8cf97bead5deae237070f9587f8e7a266d/524748.png", + "https://storage.googleapis.com/ck-kitty-image/0x06012c8cf97bead5deae237070f9587f8e7a266d/540800.svg" + ], + "card_display_style": "padded" + }, + "image_url": "https://storage.opensea.io/0x06012c8cf97bead5deae237070f9587f8e7a266d-featured-1556588705.png" + } + ], + "name": "CryptoKitties", + "slug": "cryptokitties", + "image_url": "https://storage.opensea.io/0x06012c8cf97bead5deae237070f9587f8e7a266d-featured-1556588705.png", + "description": "CryptoKitties is a game centered around breedable, collectible, and oh-so-adorable creatures we call CryptoKitties! Each cat is one-of-a-kind and 100% owned by you; it cannot be replicated, taken away, or destroyed.", + "external_url": "https://www.cryptokitties.co/", + "featured_image_url": "https://storage.opensea.io/0x06012c8cf97bead5deae237070f9587f8e7a266d-featured-1556589429.png", + "created_date": "2019-04-26T22:13:04.207050", + "owned_asset_count": 3 + }, + { + "primary_asset_contracts": [ + { + "address": "0xfaafdc07907ff5120a76b34b731b278c38d6043c", + "name": "Enjin", + "symbol": "", + "description": "", + "external_link": null, + "nft_version": null, + "schema_name": "ERC1155", + "display_data": {}, + "owner": null, + "created_date": "2019-08-02T23:43:14.666153", + "asset_contract_type": "semi-fungible" + } + ], + "name": "Age of Rust", + "slug": "age-of-rust", + "image_url": "https://storage.opensea.io/age-of-rust-1561960816.jpg", + "description": "Year 4424: The search begins for new life on the other side of the galaxy. Explore abandoned space stations, mysterious caverns, and ruins on far away worlds in order to unlock puzzles and secrets! Beware the rogue machines!", + "external_url": "https://www.ageofrust.games/", + "featured_image_url": null, + "created_date": "2019-09-03T02:35:56.063685", + "owned_asset_count": 1 + }, + { + "primary_asset_contracts": [ + { + "address": "0xee85966b4974d3c6f71a2779cc3b6f53afbc2b68", + "asset_contract_type": "fungible", + "created_date": "2019-10-16T07:36:16.102163", + "name": "Rare Chest", + "nft_version": null, + "opensea_version": null, + "owner": 1610615, + "schema_name": "ERC20", + "symbol": "", + "total_supply": "1", + "description": "Gods Unchained is a free-to-play, turn-based competitive trading card game in which cards can be bought and sold on the OpenSea marketplace. Players use their collection to build decks of cards, and select a God to play with at the start of each match. The goal of the game is to reduce your opponent's life to zero. Each deck contains exactly 30 cards. On OpenSea, cards can be sold for a fixed price, auctioned, or sold in bundles.", + "external_link": "https://godsunchained.com/?refcode=0x5b3256965e7C3cF26E11FCAf296DfC8807C01073", + "image_url": "https://lh3.googleusercontent.com/yArciVdcDv3O2R-O8XCxx3YEYZdzpiCMdossjUgv0kpLIluUQ1bYN_dyEk5xcvBEOgeq0zNIoWOh7TL9DvUEv--OLQ=s60", + "default_to_fiat": false, + "dev_buyer_fee_basis_points": 0, + "dev_seller_fee_basis_points": 0, + "only_proxied_transfers": false, + "opensea_buyer_fee_basis_points": 0, + "opensea_seller_fee_basis_points": 250, + "buyer_fee_basis_points": 0, + "seller_fee_basis_points": 250, + "payout_address": null + }, + { + "address": "0x20d4cec36528e1c4563c1bfbe3de06aba70b22b4", + "asset_contract_type": "fungible", + "created_date": "2019-10-16T08:06:42.727997", + "name": "Legendary Chest", + "nft_version": null, + "opensea_version": null, + "owner": 1610615, + "schema_name": "ERC20", + "symbol": "", + "total_supply": "1", + "description": "Gods Unchained is a free-to-play, turn-based competitive trading card game in which cards can be bought and sold on the OpenSea marketplace. Players use their collection to build decks of cards, and select a God to play with at the start of each match. The goal of the game is to reduce your opponent's life to zero. Each deck contains exactly 30 cards. On OpenSea, cards can be sold for a fixed price, auctioned, or sold in bundles.", + "external_link": "https://godsunchained.com/?refcode=0x5b3256965e7C3cF26E11FCAf296DfC8807C01073", + "image_url": "https://lh3.googleusercontent.com/yArciVdcDv3O2R-O8XCxx3YEYZdzpiCMdossjUgv0kpLIluUQ1bYN_dyEk5xcvBEOgeq0zNIoWOh7TL9DvUEv--OLQ=s60", + "default_to_fiat": false, + "dev_buyer_fee_basis_points": 0, + "dev_seller_fee_basis_points": 0, + "only_proxied_transfers": false, + "opensea_buyer_fee_basis_points": 0, + "opensea_seller_fee_basis_points": 250, + "buyer_fee_basis_points": 0, + "seller_fee_basis_points": 250, + "payout_address": null + }, + { + "address": "0x0e3a2a1f2146d86a604adc220b4967a898d7fe07", + "asset_contract_type": "non-fungible", + "created_date": "2019-11-01T06:39:04.363034", + "name": "Gods Unchained Cards", + "nft_version": "3.0", + "opensea_version": null, + "owner": 1691695, + "schema_name": "ERC721", + "symbol": "", + "total_supply": "1", + "description": "Gods Unchained is a free-to-play, turn-based competitive trading card game in which cards can be bought and sold on the OpenSea marketplace. Players use their collection to build decks of cards, and select a God to play with at the start of each match. The goal of the game is to reduce your opponent's life to zero. Each deck contains exactly 30 cards. On OpenSea, cards can be sold for a fixed price, auctioned, or sold in bundles.", + "external_link": "https://godsunchained.com/?refcode=0x5b3256965e7C3cF26E11FCAf296DfC8807C01073", + "image_url": "https://lh3.googleusercontent.com/yArciVdcDv3O2R-O8XCxx3YEYZdzpiCMdossjUgv0kpLIluUQ1bYN_dyEk5xcvBEOgeq0zNIoWOh7TL9DvUEv--OLQ=s60", + "default_to_fiat": false, + "dev_buyer_fee_basis_points": 0, + "dev_seller_fee_basis_points": 0, + "only_proxied_transfers": false, + "opensea_buyer_fee_basis_points": 0, + "opensea_seller_fee_basis_points": 250, + "buyer_fee_basis_points": 0, + "seller_fee_basis_points": 250, + "payout_address": null + }, + { + "address": "0x564cb55c655f727b61d9baf258b547ca04e9e548", + "asset_contract_type": "non-fungible", + "created_date": "2019-10-29T12:28:37.643714", + "name": "Gods Unchained", + "nft_version": "3.0", + "opensea_version": null, + "owner": 1691695, + "schema_name": "ERC721", + "symbol": "", + "total_supply": "205", + "description": "Gods Unchained is a free-to-play, turn-based competitive trading card game in which cards can be bought and sold on the OpenSea marketplace. Players use their collection to build decks of cards, and select a God to play with at the start of each match. The goal of the game is to reduce your opponent's life to zero. Each deck contains exactly 30 cards. On OpenSea, cards can be sold for a fixed price, auctioned, or sold in bundles.", + "external_link": "https://godsunchained.com/?refcode=0x5b3256965e7C3cF26E11FCAf296DfC8807C01073", + "image_url": "https://lh3.googleusercontent.com/yArciVdcDv3O2R-O8XCxx3YEYZdzpiCMdossjUgv0kpLIluUQ1bYN_dyEk5xcvBEOgeq0zNIoWOh7TL9DvUEv--OLQ=s60", + "default_to_fiat": false, + "dev_buyer_fee_basis_points": 0, + "dev_seller_fee_basis_points": 0, + "only_proxied_transfers": false, + "opensea_buyer_fee_basis_points": 0, + "opensea_seller_fee_basis_points": 250, + "buyer_fee_basis_points": 0, + "seller_fee_basis_points": 250, + "payout_address": null + } + ], + "traits": { + "mana": { + "min": 1, + "max": 18 + }, + "health": { + "min": 1, + "max": 16 + }, + "attack": { + "min": 1, + "max": 16 + } + }, + "stats": { + "seven_day_volume": 270.564697067863, + "seven_day_change": -0.014179906699531201, + "total_volume": 11825.0384171324, + "count": 6835331, + "num_owners": 10791, + "market_cap": 150892.14138332763, + "average_price": 0.0396514694030496, + "items_sold": 298233 + }, + "banner_image_url": null, + "chat_url": null, + "created_date": "2019-11-13T03:01:42.051246", + "default_to_fiat": false, + "description": "Gods Unchained is a free-to-play, turn-based competitive trading card game in which cards can be bought and sold on the OpenSea marketplace. Players use their collection to build decks of cards, and select a God to play with at the start of each match. The goal of the game is to reduce your opponent's life to zero. Each deck contains exactly 30 cards. On OpenSea, cards can be sold for a fixed price, auctioned, or sold in bundles.", + "dev_buyer_fee_basis_points": "0", + "dev_seller_fee_basis_points": "0", + "display_data": { + "images": [ + "https://storage.googleapis.com/opensea-prod.appspot.com/0x6ebeaf8e8e946f0716e6533a6f2cefc83f60e8ab/25233.png", + "https://storage.googleapis.com/opensea-prod.appspot.com/0x6ebeaf8e8e946f0716e6533a6f2cefc83f60e8ab/152875.png", + "https://storage.googleapis.com/opensea-prod.appspot.com/0x6ebeaf8e8e946f0716e6533a6f2cefc83f60e8ab/25669.png", + "https://storage.googleapis.com/opensea-prod.appspot.com/0x6ebeaf8e8e946f0716e6533a6f2cefc83f60e8ab/9237.png", + "https://storage.googleapis.com/opensea-prod.appspot.com/0x6ebeaf8e8e946f0716e6533a6f2cefc83f60e8ab/9228.png", + "https://storage.googleapis.com/opensea-prod.appspot.com/0x6ebeaf8e8e946f0716e6533a6f2cefc83f60e8ab/9231.png" + ], + "card_display_style": "contain" + }, + "external_url": "https://godsunchained.com/?refcode=0x5b3256965e7C3cF26E11FCAf296DfC8807C01073", + "featured": true, + "featured_image_url": "https://storage.opensea.io/0x6ebeaf8e8e946f0716e6533a6f2cefc83f60e8ab-featured-1556589419.png", + "hidden": false, + "image_url": "https://lh3.googleusercontent.com/yArciVdcDv3O2R-O8XCxx3YEYZdzpiCMdossjUgv0kpLIluUQ1bYN_dyEk5xcvBEOgeq0zNIoWOh7TL9DvUEv--OLQ=s60", + "is_subject_to_whitelist": false, + "large_image_url": "https://lh3.googleusercontent.com/yArciVdcDv3O2R-O8XCxx3YEYZdzpiCMdossjUgv0kpLIluUQ1bYN_dyEk5xcvBEOgeq0zNIoWOh7TL9DvUEv--OLQ", + "name": "Gods Unchained", + "only_proxied_transfers": false, + "opensea_buyer_fee_basis_points": "0", + "opensea_seller_fee_basis_points": "250", + "payout_address": null, + "require_email": false, + "short_description": null, + "slug": "gods-unchained", + "wiki_url": null, + "owned_asset_count": 535 + } +] diff --git a/platform/ethereum/opensea/model.go b/platform/ethereum/opensea/model.go new file mode 100644 index 000000000..0f00276fc --- /dev/null +++ b/platform/ethereum/opensea/model.go @@ -0,0 +1,68 @@ +package opensea + +import ( + "math/big" +) + +type Collection struct { + Name string `json:"name"` + ImageUrl string `json:"image_url"` + Description string `json:"description"` + ExternalUrl string `json:"external_url"` + Slug string `json:"slug"` + Total *big.Int `json:"owned_asset_count"` + Contracts []PrimaryAssetContract `json:"primary_asset_contracts"` +} + +type PrimaryAssetContract struct { + Name string `json:"name"` + Address string `json:"address"` + NftVersion string `json:"nft_version"` + Symbol string `json:"symbol"` + Description string `json:"description"` + Type string `json:"schema_name"` + Data DisplayData `json:"display_data"` + Url string `json:"external_link"` +} + +type TransferFeeToken struct { + Address string `json:"address"` +} + +type DisplayData struct { + Images []string `json:"images"` +} + +type CollectiblePage struct { + Collectibles []Collectible `json:"assets"` +} + +type Collectible struct { + TokenId string `json:"token_id"` + AssetContract AssetContract `json:"asset_contract"` + ImageUrl string `json:"image_url"` + ImagePreviewUrl string `json:"image_preview_url"` + Name string `json:"name"` + ExternalLink string `json:"external_link"` + Permalink string `json:"permalink"` + Description string `json:"description"` + Collection CollectibleCollections `json:"collection"` + + // only available for ERC1155 + FeeToken *TransferFeeToken `json:"transfer_fee_payment_token,omitempty"` + TransferFee string `json:"transfer_fee,omitempty"` +} + +type CollectibleCollections struct { + Name string `json:"name"` + Slug string `json:"slug"` + ExternalLink string `json:"external_url"` +} + +type AssetContract struct { + Address string `json:"address"` + Category string `json:"name"` + ExternalLink string `json:"external_link"` + Type string `json:"schema_name"` + Version string `json:"nft_version"` +} diff --git a/platform/ethereum/transaction.go b/platform/ethereum/transaction.go new file mode 100644 index 000000000..8be6891bf --- /dev/null +++ b/platform/ethereum/transaction.go @@ -0,0 +1,25 @@ +package ethereum + +import ( + "github.com/trustwallet/golibs/types" +) + +func (p *Platform) GetTxsByAddress(address string) (types.Txs, error) { + return p.client.GetTransactions(address, p.CoinIndex) +} + +func (p *Platform) GetTokenTxsByAddress(address string, token string) (types.Txs, error) { + return p.client.GetTokenTxs(address, token, p.CoinIndex) +} + +func (p *Platform) GetTokenListByAddress(address string) ([]types.Token, error) { + return p.client.GetTokenList(address, p.CoinIndex) +} + +func (p *Platform) GetTokenListIdsByAddress(address string) ([]string, error) { + assets, err := p.GetTokenListByAddress(address) + if err != nil { + return []string{}, err + } + return types.GetAssetsIds(assets), nil +} diff --git a/platform/ethereum/transaction_test.go b/platform/ethereum/transaction_test.go new file mode 100644 index 000000000..44077cc7b --- /dev/null +++ b/platform/ethereum/transaction_test.go @@ -0,0 +1,68 @@ +package ethereum + +import ( + "testing" + + "github.com/stretchr/testify/assert" + "github.com/trustwallet/golibs/types" +) + +type Client string + +var ( + tx = types.Tx{ + ID: "1", + Coin: 60, + From: "A", + To: "B", + } + page = types.Txs{tx} + c Client +) + +func getTxClientMock() EthereumClient { + return &c +} +func TestPlatform_GetTokenTxsByAddress(t *testing.T) { + p := Platform{ + client: getTxClientMock(), + } + + resp, err := p.GetTxsByAddress("A") + assert.Nil(t, err) + assert.Equal(t, page, resp) +} + +func TestPlatform_GetTxsByAddress(t *testing.T) { + p := Platform{ + client: getTxClientMock(), + } + + resp, err := p.GetTokenTxsByAddress("A", "") + assert.Nil(t, err) + assert.Equal(t, page, resp) +} + +func (c Client) GetTransactions(address string, coinIndex uint) (types.Txs, error) { + txs := make(types.Txs, 0) + txs = append(txs, tx) + return txs, nil +} + +func (c Client) GetTokenTxs(address, token string, coinIndex uint) (types.Txs, error) { + txs := make(types.Txs, 0) + txs = append(txs, tx) + return txs, nil +} + +func (c Client) GetTokenList(address string, coinIndex uint) ([]types.Token, error) { + return []types.Token{}, nil +} + +func (c Client) GetCurrentBlockNumber() (int64, error) { + return 0, nil +} + +func (c Client) GetBlockByNumber(num int64, coinIndex uint) (*types.Block, error) { + return nil, nil +} diff --git a/platform/filecoin/base.go b/platform/filecoin/base.go new file mode 100644 index 000000000..ce454d3fa --- /dev/null +++ b/platform/filecoin/base.go @@ -0,0 +1,26 @@ +package filecoin + +import ( + "github.com/trustwallet/blockatlas/platform/filecoin/explorer" + "github.com/trustwallet/blockatlas/platform/filecoin/rpc" + "github.com/trustwallet/golibs/client" + "github.com/trustwallet/golibs/coin" + "github.com/trustwallet/golibs/network/middleware" +) + +type Platform struct { + client rpc.Client + explorer explorer.Client +} + +func Init(api, explorerApi string) *Platform { + p := &Platform{ + client: rpc.Client{Request: client.InitClient(api, middleware.SentryErrorHandler)}, + explorer: explorer.Client{Request: client.InitClient(explorerApi, middleware.SentryErrorHandler)}, + } + return p +} + +func (p *Platform) Coin() coin.Coin { + return coin.Filecoin() +} diff --git a/platform/filecoin/block.go b/platform/filecoin/block.go new file mode 100644 index 000000000..f4ed2eb6e --- /dev/null +++ b/platform/filecoin/block.go @@ -0,0 +1,65 @@ +package filecoin + +import ( + "github.com/trustwallet/blockatlas/platform/filecoin/rpc" + "github.com/trustwallet/golibs/coin" + "github.com/trustwallet/golibs/types" +) + +func (p *Platform) CurrentBlockNumber() (int64, error) { + response, err := p.client.GetBlockHeight() + if err != nil { + return 0, err + } + return int64(response.Height), nil +} + +func (p *Platform) GetBlockByNumber(num int64) (*types.Block, error) { + chainHeadResponse, err := p.client.GetTipSetByHeight(num) + if err != nil { + return nil, err + } + blockResponses := make([]rpc.BlockMessageResponse, 0, len(chainHeadResponse.GetCids())) + for _, cid := range chainHeadResponse.GetCids() { + blockResponse, err := p.client.GetBlockMessage(cid) + if err != nil { + return nil, err + } + blockResponses = append(blockResponses, blockResponse) + } + + return normalizeBlockResponses(uint64(chainHeadResponse.Height), uint64(chainHeadResponse.GetTimestamp()), blockResponses), nil +} + +func normalizeBlockResponses(num, timestamp uint64, responses []rpc.BlockMessageResponse) *types.Block { + var result types.Block + result.Number = int64(num) + for _, resp := range responses { + for _, msg := range resp.SecpkMessages { + tx := normalizeBlockTx(num, timestamp, msg) + result.Txs = append(result.Txs, tx) + } + } + return &result +} + +func normalizeBlockTx(num, timestamp uint64, msg rpc.SecpkMessage) types.Tx { + return types.Tx{ + Coin: coin.Filecoin().ID, + From: msg.Message.From, + To: msg.Message.To, + // todo: use StateGetReceipt + https://documenter.getpostman.com/view/4872192/SWLh5mUd?version=latest + Fee: "0", + Block: num, + Date: int64(timestamp), + Status: types.StatusCompleted, + Sequence: uint64(msg.Message.Nonce), + Type: types.TxTransfer, + Memo: "", + Meta: types.Transfer{ + Value: types.Amount(msg.Message.Value), + Symbol: coin.Filecoin().Symbol, + Decimals: coin.Filecoin().Decimals, + }, + } +} diff --git a/platform/filecoin/block_test.go b/platform/filecoin/block_test.go new file mode 100644 index 000000000..36c51148a --- /dev/null +++ b/platform/filecoin/block_test.go @@ -0,0 +1,85 @@ +package filecoin + +import ( + "encoding/json" + "fmt" + "net/http" + "net/http/httptest" + "testing" + + "github.com/stretchr/testify/assert" + "github.com/trustwallet/golibs/mock" +) + +func TestPlatform_CurrentBlockNumber(t *testing.T) { + chainHead, err := mock.JsonStringFromFilePath("mocks/ChainHead.json") + assert.Nil(t, err) + + data := make(map[string]func(http.ResponseWriter, *http.Request)) + data["/"] = func(w http.ResponseWriter, r *http.Request) { + w.WriteHeader(http.StatusOK) + if _, err := fmt.Fprint(w, chainHead); err != nil { + panic(err) + } + } + + server := httptest.NewServer(mock.CreateMockedAPI(data)) + defer server.Close() + + p := Init(server.URL, "") + block, err := p.CurrentBlockNumber() + assert.Nil(t, err) + assert.Equal(t, int64(243590), block) +} + +func TestPlatform_GetBlockByNumber(t *testing.T) { + data := make(map[string]func(http.ResponseWriter, *http.Request)) + data["/"] = func(w http.ResponseWriter, r *http.Request) { + w.WriteHeader(http.StatusOK) + + type Request map[string]interface{} + var p Request + + err := json.NewDecoder(r.Body).Decode(&p) + if err != nil { + panic(err) + } + + resp, ok := p["method"] + if !ok { + panic("bad json request") + } + var d string + + switch resp { + case "Filecoin.ChainGetTipSetByHeight": + chainHead, err := mock.JsonStringFromFilePath("mocks/ChainGetTipSetByHeight.json") + if err != nil { + panic(err) + } + d = chainHead + case "Filecoin.ChainGetBlockMessages": + blockMsg, err := mock.JsonStringFromFilePath("mocks/ChainGetBlockMessages.json") + if err != nil { + panic(err) + } + d = blockMsg + } + + if _, err := fmt.Fprint(w, d); err != nil { + panic(err) + } + } + + server := httptest.NewServer(mock.CreateMockedAPI(data)) + defer server.Close() + + p := Init(server.URL, "") + block, err := p.GetBlockByNumber(243590) + assert.Nil(t, err) + + blockJson, _ := json.Marshal(block) + wanted, _ := mock.JsonStringFromFilePath("mocks/response.json") + + assert.JSONEq(t, string(blockJson), wanted) +} diff --git a/platform/filecoin/explorer/client.go b/platform/filecoin/explorer/client.go new file mode 100644 index 000000000..30d59e237 --- /dev/null +++ b/platform/filecoin/explorer/client.go @@ -0,0 +1,23 @@ +package explorer + +import ( + "fmt" + "net/url" + "strconv" + + "github.com/trustwallet/golibs/client" +) + +type Client struct { + client.Request +} + +func (c Client) GetMessagesByAddress(address string, pageSize int) (res Response, err error) { + path := fmt.Sprintf("api/v1/address/%s/messages", address) + query := url.Values{"pageSize": {strconv.Itoa(pageSize)}} + err = c.Get(&res, path, query) + if err != nil { + return res, err + } + return +} diff --git a/platform/filecoin/explorer/models.go b/platform/filecoin/explorer/models.go new file mode 100644 index 000000000..389d00a27 --- /dev/null +++ b/platform/filecoin/explorer/models.go @@ -0,0 +1,22 @@ +package explorer + +type Response struct { + TotalCount int `json:"totalCount"` + Messages []Message `json:"messages"` +} + +type Receipt struct { + ExitCode int `json:"exitCode"` +} + +type Message struct { + Cid string `json:"cid"` + Height uint64 `json:"height"` + Timestamp int64 `json:"timestamp"` + From string `json:"from"` + To string `json:"to"` + Nonce uint64 `json:"nonce"` + Value string `json:"value"` + Method string `json:"method"` + Receipt Receipt `json:"receipt"` +} diff --git a/platform/filecoin/mocks/ChainGetBlockMessages.json b/platform/filecoin/mocks/ChainGetBlockMessages.json new file mode 100644 index 000000000..13cad238d --- /dev/null +++ b/platform/filecoin/mocks/ChainGetBlockMessages.json @@ -0,0 +1,2882 @@ +{ + "jsonrpc": "2.0", + "result": { + "BlsMessages": [ + { + "Version": 0, + "To": "f062473", + "From": "f3qbgrbvdjmdstalvmefvisjjjfyslpjjnvxximaidqrr33defn3qfdzlkthsnuyfzc6bks72mfxky4qiajqbq", + "Nonce": 61933, + "Value": "122760309660224659", + "GasLimit": 56726101, + "GasFeeCap": "1322142693", + "GasPremium": "661071346", + "Method": 7, + "Params": "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" + }, + { + "Version": 0, + "To": "f062473", + "From": "f3qbgrbvdjmdstalvmefvisjjjfyslpjjnvxximaidqrr33defn3qfdzlkthsnuyfzc6bks72mfxky4qiajqbq", + "Nonce": 61934, + "Value": "121192496968008715", + "GasLimit": 15962483, + "GasFeeCap": "2349258570", + "GasPremium": "1174629285", + "Method": 6, + "Params": "igMZeHXYKlgpAAGC4gOB6AIggik0zQ76qfvPzTn8Vhl/D66vPsyIZgAgDhmGyKmsKkEaAAOyW4AaABtnUvQAAAA=" + }, + { + "Version": 0, + "To": "f066102", + "From": "f3xbhu7ukbh2uwy6ayzgtb2xwevdn6mpiiyfnpczjmt6rvpnemyu542dvboqw24i2nfcnw5vxvh2hp76v77ogq", + "Nonce": 201683, + "Value": "122414013498084734", + "GasLimit": 57261793, + "GasFeeCap": "1099999999", + "GasPremium": "130646", + "Method": 7, + "Params": "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" + }, + { + "Version": 0, + "To": "f023530", + "From": "f3u5nfw77pc7l2dsnlbzxz3jcafyjymgbkxbp4vifaoojcvhzv3sgroez6z7rrlxh5z3xpuw4pcnwiks6xvyna", + "Nonce": 1373233, + "Value": "122697769864899223", + "GasLimit": 62472096, + "GasFeeCap": "1099999999", + "GasPremium": "130581", + "Method": 7, + "Params": "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" + }, + { + "Version": 0, + "To": "f023530", + "From": "f3u5nfw77pc7l2dsnlbzxz3jcafyjymgbkxbp4vifaoojcvhzv3sgroez6z7rrlxh5z3xpuw4pcnwiks6xvyna", + "Nonce": 1373234, + "Value": "122695666052819139", + "GasLimit": 65087096, + "GasFeeCap": "1099999999", + "GasPremium": "130093", + "Method": 7, + "Params": "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" + }, + { + "Version": 0, + "To": "f023530", + "From": "f3u5nfw77pc7l2dsnlbzxz3jcafyjymgbkxbp4vifaoojcvhzv3sgroez6z7rrlxh5z3xpuw4pcnwiks6xvyna", + "Nonce": 1373235, + "Value": "122695449505459998", + "GasLimit": 70317096, + "GasFeeCap": "1099999999", + "GasPremium": "130215", + "Method": 7, + "Params": "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" + }, + { + "Version": 0, + "To": "f023530", + "From": "f3u5nfw77pc7l2dsnlbzxz3jcafyjymgbkxbp4vifaoojcvhzv3sgroez6z7rrlxh5z3xpuw4pcnwiks6xvyna", + "Nonce": 1373236, + "Value": "122695456350969745", + "GasLimit": 70317096, + "GasFeeCap": "1099999999", + "GasPremium": "130089", + "Method": 7, + "Params": "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" + }, + { + "Version": 0, + "To": "f023530", + "From": "f3u5nfw77pc7l2dsnlbzxz3jcafyjymgbkxbp4vifaoojcvhzv3sgroez6z7rrlxh5z3xpuw4pcnwiks6xvyna", + "Nonce": 1373237, + "Value": "122696242323970072", + "GasLimit": 54895846, + "GasFeeCap": "1099999999", + "GasPremium": "129495", + "Method": 7, + "Params": "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" + }, + { + "Version": 0, + "To": "f023530", + "From": "f3u5nfw77pc7l2dsnlbzxz3jcafyjymgbkxbp4vifaoojcvhzv3sgroez6z7rrlxh5z3xpuw4pcnwiks6xvyna", + "Nonce": 1373238, + "Value": "122696242323970072", + "GasLimit": 57416793, + "GasFeeCap": "1099999999", + "GasPremium": "130037", + "Method": 7, + "Params": "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" + }, + { + "Version": 0, + "To": "f023530", + "From": "f3u5nfw77pc7l2dsnlbzxz3jcafyjymgbkxbp4vifaoojcvhzv3sgroez6z7rrlxh5z3xpuw4pcnwiks6xvyna", + "Nonce": 1373239, + "Value": "122696242534250876", + "GasLimit": 60125846, + "GasFeeCap": "1099999999", + "GasPremium": "129580", + "Method": 7, + "Params": "ghoADNd+WQeAtGyAW1qo8JCYg8S8MQI1YdwtZkIRHh/+IGxoXwIHL/apKRFAKfInMIqP1UduTxW6qj1w6+mmbfR126LhIJTqH4Zt8cx69Vshds59R764Mr0Wu/tEO0PwRpbT8ryJnWWqFUG71nVDi28wX7HsuRjso3vqUPx+apDTnMH+r1jV+yJB/lOXcYywvUaOpdSCBbDSs4dFPd7kWcgyHoNAyGzGvGLfkMi4HtKFDaMq/Yy80qkopZ2OGQ20HCvP7WUf4HDkt9KCXxiDjMTCauwAgdcdMRL6lUY0gxxpkEKWJ04tHAoSTpM9hJ8JvdDkmWNNKf2Bl+OREPcn3jHKJWGzBlY8ECqkdSZQWo51uNrmFvIKOFmEopjaEkrxRqn0Oyr+BAaeDH76nqafGmtayNat4xf2k9ccKa81oRlho7jXW6OlrlvMpPDtlKo0PM4NoGVsvVNOqBlc+DyQho8Jvgo25grcMV+68Sq8sxi2QvsrrK9ew2E6n/Q+mKbdmwmnVSPI08i/kkc+YUJG/5CWjyetXge1GOuVopraLGmmVKDaivChGTV1u5xig9sDWjdI1zOmNUXairs1KDkXr+wqjJdmiYeKbPXXRYJ0/veZeHLXMJENv3DQQeryJLTPP3H9JWpE9X/dDSR3QWZpSVXIsucQ8zqO6fBHzc446ewPdb4pTYNSJLVVYl44mCpBI8ucsyZweP2ptODdodGwQt+M1z1sIUip6uZxjqGbRVntJVMFbPFsGKSi+H2W9FO3LVxdfqEo6VjBpsmg7IfhSwTVZ9n0Zfk0sWFhlbEIJ7TbHnkCFXLiXeIv2TWPUPS7/KC5om0uvHMtlTnZeTQowNu6STHuKxExS2+g43QiAjuwtSupVevS5PQq3+8hiTPWPah4D0RlKoK3DYJTzEjQdZdqqLmn1Gz5cU9QKhW58gst7CdIzUdm+VN+W9JTiDsmOuW6wkrF2bX3ljA16APmBQpPNbY1qvLma/8oLSXuDhuUpbUBrk2gtkGiqhpqpkjowYrYlrYZ4AYjuRxqliNgja0umYFsETJiAKcu/PwKFuGKtOnrbkBBmMIg99LccDy7GMMkAcfQp6X1tzajZupp1X2e2cZcCwuULhV/Ksr4EVSxDuoWFOhxN4SXJb7xRXu7g6HYI10L/inPFsSUKSeWRxv1qiRKSXnJHkIsEe/XD/G4uiqY/r+dPPTqVkhAEhNV20igBi973EAckpfz6zBJh5G8p3m12YGXPesI7vKnumHu39YWXduRUOlyDv44iwokvHh34djqGjNMoz/vJX/+dnOrW5MXRpLQcc0mxbAlx3HF7aYyMpdGbSLX7M3jgUVKUWujwJvtXiyvouWODzAhiqEMxQv7Kdq80F0ynRotXm+gL9KOs4CFj1w4H39Rqis2+UbbwtiGSBg3FyLdm4TOMWtnaDdsnznsm9ngNo3C5FR4BHFyQaKR6h1TG3AXq+z/uRPlICnJSTxwjhGAcEutAO/hovSObTjjG+NaV0EDac+J0IB2skATtPq1A+kzyRkg6PcIcM3bg6RgqEFKNczPYkmfrhMf7PQ02RpB4iLwazH5grwQyjEmPlxvEkmuJntvuhOZlMzMjlpQjnUmWzxZgJglwVZgNivnuqvhiOsUc/bxOx5OcvNal4Bdma8U4eyD+xiKQkrftnnrAvKAUgG1O7vzwwNKVEdpZzl89JiO6r0pGYM/w0vrtHRR8kHXs2OldtL5+b6GDdSrmKIMZ2QtUZVTLV48SXbaFDL9Aezh+fYVZuvUseRQpWTkGRett568rnl37WhmmawhqmUb3fN89Dn7ZOwuc5TAApmMN6TtnFx1mcXMX+xoXICMNZhQUXs3VLmV3QXC8fRPr3OGwZY69NIzxWr2e0l/rTnghDX08u1Oz+mLABZA/Dbi5bKgN69085+3+eoKEomgF7A2Oyy03vLnmO/e1ZfgUdqyFAToPQMmfQR7atR24OEy9e/dSSr4wtohj+IBksERtghkTRsKEpk9tCDp0R3S5AIPlp47Tu126ABxQ3xa+wylkYjzR2myBCTYZNkzTks6kVZh63tlZHkOqH7/f9UKk/ACG+jGEtoTzmPo+gHNJg0gOH8j7sIyTBBErazR7Zd/i57+ak02mZVPAMqA6SNIvTbCMxq+txv41rSWeuwv8Cbw5RwZ8DR4UKBse+eLp4ZJCk3vfhztuCa4rF4o9KLTvXrlWzTb4ZbfVWcY+2yLCmVXkYJ9hUHRxg7ywplo5lAUr5+IzWLPv+3N+g+rOJxNkn5lffaYVuGtUkkQ0ZOvQEecPl+9hnaRXZvL1j65S++VhPueEDOXo8drad+egVi1YXN5NKi81G/LZVCNQ2EcwVgo1e9oOV9uNY4LI539drlxtWMEWK+2ZW5dr+ccBBiCgC7VPo5vqP/UQEFhOededmwpGWxFtGETNe9R2krjjzHuBwhVwV9X4h7EvZ3fKWyPFRBDD3tCc2CQzWsjN65kD65ECgRpO4ZB1yhkH47ZiQUkkpxTAtUgrsE8HlhCzi4Wk0y2qdHoGl3rhFxO8cFcn3qby9Vo+byHavfaNoVGCpJ5" + }, + { + "Version": 0, + "To": "f023530", + "From": "f3u5nfw77pc7l2dsnlbzxz3jcafyjymgbkxbp4vifaoojcvhzv3sgroez6z7rrlxh5z3xpuw4pcnwiks6xvyna", + "Nonce": 1373240, + "Value": "121191532823564220", + "GasLimit": 49270421, + "GasFeeCap": "1099999999", + "GasPremium": "131042", + "Method": 6, + "Params": "igMaAAzkN9gqWCkAAYLiA4HoAiBGmuuhbRnWvt2fjHVahensPxPLCxFS1t8GmvpDp7n8PhoAA6+6gBoAC9BZ9AAAAA==" + }, + { + "Version": 0, + "To": "f023530", + "From": "f3u5nfw77pc7l2dsnlbzxz3jcafyjymgbkxbp4vifaoojcvhzv3sgroez6z7rrlxh5z3xpuw4pcnwiks6xvyna", + "Nonce": 1373241, + "Value": "122696242323970072", + "GasLimit": 57510846, + "GasFeeCap": "1099999999", + "GasPremium": "131385", + "Method": 7, + "Params": "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" + }, + { + "Version": 0, + "To": "f023530", + "From": "f3u5nfw77pc7l2dsnlbzxz3jcafyjymgbkxbp4vifaoojcvhzv3sgroez6z7rrlxh5z3xpuw4pcnwiks6xvyna", + "Nonce": 1373242, + "Value": "122697234375112311", + "GasLimit": 62646793, + "GasFeeCap": "1099999999", + "GasPremium": "129719", + "Method": 7, + "Params": "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" + }, + { + "Version": 0, + "To": "f066102", + "From": "f3xbhu7ukbh2uwy6ayzgtb2xwevdn6mpiiyfnpczjmt6rvpnemyu542dvboqw24i2nfcnw5vxvh2hp76v77ogq", + "Nonce": 201684, + "Value": "122690854497365062", + "GasLimit": 59879293, + "GasFeeCap": "1099999999", + "GasPremium": "129772", + "Method": 7, + "Params": "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" + }, + { + "Version": 0, + "To": "f023530", + "From": "f3u5nfw77pc7l2dsnlbzxz3jcafyjymgbkxbp4vifaoojcvhzv3sgroez6z7rrlxh5z3xpuw4pcnwiks6xvyna", + "Nonce": 1373243, + "Value": "122696242323970072", + "GasLimit": 65261793, + "GasFeeCap": "1099999999", + "GasPremium": "129301", + "Method": 7, + "Params": "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" + }, + { + "Version": 0, + "To": "f01012", + "From": "f3q2kzhc2zzwdclfj6imgiffn2xvtyfu42tz7h2gfstj7j7xjlxgefnh35dxnc3frwvpr35hgayldy6kssrt2a", + "Nonce": 590150, + "Value": "122775790697436945", + "GasLimit": 70013903, + "GasFeeCap": "1428287750", + "GasPremium": "126494", + "Method": 7, + "Params": "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" + }, + { + "Version": 0, + "To": "f01012", + "From": "f3q2kzhc2zzwdclfj6imgiffn2xvtyfu42tz7h2gfstj7j7xjlxgefnh35dxnc3frwvpr35hgayldy6kssrt2a", + "Nonce": 590151, + "Value": "121191532823564220", + "GasLimit": 23838781, + "GasFeeCap": "4194845365", + "GasPremium": "125234", + "Method": 6, + "Params": "igMaABLNp9gqWCkAAYLiA4HoAiAPEvNFx4NoGGF4GNsGR5fzs52GsvfMFRMJLjPew8LKAxoAA7B/gBoAG2Kw9AAAAA==" + }, + { + "Version": 0, + "To": "f017665", + "From": "f3tdtgqemnvckqzfj6y5odjsun5ri5pl3ps7l62d5bef3ssjjkfelhw7etgakrmzzpdpy7tnzjya5sllc4xdoq", + "Nonce": 7910, + "Value": "122396137073606521", + "GasLimit": 59284851, + "GasFeeCap": "1686771549", + "GasPremium": "125607", + "Method": 7, + "Params": "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" + }, + { + "Version": 0, + "To": "f017665", + "From": "f3tdtgqemnvckqzfj6y5odjsun5ri5pl3ps7l62d5bef3ssjjkfelhw7etgakrmzzpdpy7tnzjya5sllc4xdoq", + "Nonce": 7911, + "Value": "122396708499485462", + "GasLimit": 61991403, + "GasFeeCap": "1613126904", + "GasPremium": "126444", + "Method": 7, + "Params": "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" + }, + { + "Version": 0, + "To": "f064908", + "From": "f3sz2qsm4epwxarbgecpyp6t5e26uvn3ciouxaib7becp6r3dnjfp6cuwlinpfwpqeczg2w3udnqejennit2gq", + "Nonce": 24315, + "Value": "122486005296693490", + "GasLimit": 62358043, + "GasFeeCap": "1603642372", + "GasPremium": "125757", + "Method": 7, + "Params": "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" + }, + { + "Version": 0, + "To": "f060805", + "From": "f3vn5qxkoo7rx5r7xgkbfhgnfgbbjqczooual6u2chnnig7ynzn6tdjc6rwzqpsubc7v2zhdi7h5yvaig5zfya", + "Nonce": 222893, + "Value": "122713131291931816", + "GasLimit": 50956356, + "GasFeeCap": "1962463720", + "GasPremium": "125158", + "Method": 7, + "Params": "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" + }, + { + "Version": 0, + "To": "f060805", + "From": "f3vn5qxkoo7rx5r7xgkbfhgnfgbbjqczooual6u2chnnig7ynzn6tdjc6rwzqpsubc7v2zhdi7h5yvaig5zfya", + "Nonce": 222894, + "Value": "122716954489189285", + "GasLimit": 53853513, + "GasFeeCap": "1856889076", + "GasPremium": "126286", + "Method": 7, + "Params": "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" + }, + { + "Version": 0, + "To": "f060805", + "From": "f3vn5qxkoo7rx5r7xgkbfhgnfgbbjqczooual6u2chnnig7ynzn6tdjc6rwzqpsubc7v2zhdi7h5yvaig5zfya", + "Nonce": 222895, + "Value": "122715790385892663", + "GasLimit": 56468513, + "GasFeeCap": "1770898412", + "GasPremium": "124738", + "Method": 7, + "Params": "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" + }, + { + "Version": 0, + "To": "f030347", + "From": "f3wy3ecnyzyu5jw2o2jythtzabkavohdqurbz5lhy2xylr7coxjegmg4spjfosqy5o3dtwsi4idtmucrubi7xa", + "Nonce": 436202, + "Value": "121190891386160866", + "GasLimit": 80315846, + "GasFeeCap": "1245084313", + "GasPremium": "125259", + "Method": 6, + "Params": "igMaAAWC4tgqWCkAAYLiA4HoAiAXjGeAenPKhEYhjOMlet3eNt9FCdsmh+wZ1Y/nvOlWEBoAA7K+gBoAG2ea9AAAAA==" + }, + { + "Version": 0, + "To": "f010035", + "From": "f3ulm32bibybv7srwsq25dhl7grvbnyjyonmps5fgtpi65qsauf7dxbn4wlisjtpya7wsjuz6pqvzma5wak4cq", + "Nonce": 215181, + "Value": "121191532823564220", + "GasLimit": 36045333, + "GasFeeCap": "2774284260", + "GasPremium": "124738", + "Method": 6, + "Params": "igMaAALqe9gqWCkAAYLiA4HoAiBGv9fYWeoxCQE1gJb9/XzvkcCMxcCuvt+Fg3UI3w7rZxoAA68wgBoAG2Ii9AAAAA==" + }, + { + "Version": 0, + "To": "f010035", + "From": "f3ulm32bibybv7srwsq25dhl7grvbnyjyonmps5fgtpi65qsauf7dxbn4wlisjtpya7wsjuz6pqvzma5wak4cq", + "Nonce": 215182, + "Value": "121191532823564220", + "GasLimit": 36210978, + "GasFeeCap": "2761593459", + "GasPremium": "125514", + "Method": 6, + "Params": "igMaAALs69gqWCkAAYLiA4HoAiCIuUn1XgB41HB7nYxpTgnNGwxZtV7qvyylQFaCiVNVMxoAA7GrgBoAG2Ii9AAAAA==" + }, + { + "Version": 0, + "To": "f010035", + "From": "f3ulm32bibybv7srwsq25dhl7grvbnyjyonmps5fgtpi65qsauf7dxbn4wlisjtpya7wsjuz6pqvzma5wak4cq", + "Nonce": 215183, + "Value": "122742216349605539", + "GasLimit": 56775153, + "GasFeeCap": "1761333870", + "GasPremium": "125378", + "Method": 7, + "Params": "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" + }, + { + "Version": 0, + "To": "f010035", + "From": "f3ulm32bibybv7srwsq25dhl7grvbnyjyonmps5fgtpi65qsauf7dxbn4wlisjtpya7wsjuz6pqvzma5wak4cq", + "Nonce": 215184, + "Value": "121191750964018119", + "GasLimit": 36627833, + "GasFeeCap": "2730164244", + "GasPremium": "125513", + "Method": 6, + "Params": "igMaAALrwdgqWCkAAYLiA4HoAiAFWVYgXDdWNgMy1eDJS+MY6GINDFLqZS6BIfdP1tZEFBoAA7BsgBoAG2Ii9AAAAA==" + }, + { + "Version": 0, + "To": "f09652", + "From": "f3ro3i54tule2vtdcsjdkzjkf6djx3wwe5znv5h4kwxprxjyojvgyqtyvxus5bj73dy64x4paiqriwupmei3va", + "Nonce": 2244661, + "Value": "121215981842951395", + "GasLimit": 80315846, + "GasFeeCap": "1245084313", + "GasPremium": "125222", + "Method": 6, + "Params": "igMaAA001dgqWCkAAYLiA4HoAiB+Zs3mG6oe4qFDLwMOT+qI4HE/MR4czzA3Wo6UT7IFBRoAA7BUgBoAG2o19AAAAA==" + }, + { + "Version": 0, + "To": "f030347", + "From": "f3wy3ecnyzyu5jw2o2jythtzabkavohdqurbz5lhy2xylr7coxjegmg4spjfosqy5o3dtwsi4idtmucrubi7xa", + "Nonce": 436203, + "Value": "121190891386160866", + "GasLimit": 80315846, + "GasFeeCap": "1245084313", + "GasPremium": "124262", + "Method": 6, + "Params": "igMaAAQEXdgqWCkAAYLiA4HoAiBuk/KHXz6m/M0Q9N9+pFSwS1+kiLpMZ3JhTLYmZfHKBxoAA7KAgBoAG2ea9AAAAA==" + }, + { + "Version": 0, + "To": "f030347", + "From": "f3wy3ecnyzyu5jw2o2jythtzabkavohdqurbz5lhy2xylr7coxjegmg4spjfosqy5o3dtwsi4idtmucrubi7xa", + "Nonce": 436204, + "Value": "121190891386160866", + "GasLimit": 80315846, + "GasFeeCap": "1245084313", + "GasPremium": "125768", + "Method": 6, + "Params": "igMaAAJ5fdgqWCkAAYLiA4HoAiA4vCrfAM5yWihPiLQ6/mncOjaiYbH6dv3zSwZWdmBMQhoAA7KjgBoAG2ea9AAAAA==" + }, + { + "Version": 0, + "To": "f030347", + "From": "f3wy3ecnyzyu5jw2o2jythtzabkavohdqurbz5lhy2xylr7coxjegmg4spjfosqy5o3dtwsi4idtmucrubi7xa", + "Nonce": 436205, + "Value": "121191102922431314", + "GasLimit": 80315846, + "GasFeeCap": "1245084313", + "GasPremium": "124559", + "Method": 6, + "Params": "igMaAAJ5T9gqWCkAAYLiA4HoAiAMjbfejFQ9fx/TUlq7yg8HP4QwCMQr1F1mD0ZTIzceKBoAA7JQgBoAG2ea9AAAAA==" + }, + { + "Version": 0, + "To": "f030347", + "From": "f3wy3ecnyzyu5jw2o2jythtzabkavohdqurbz5lhy2xylr7coxjegmg4spjfosqy5o3dtwsi4idtmucrubi7xa", + "Nonce": 436206, + "Value": "121191102922431314", + "GasLimit": 80315846, + "GasFeeCap": "1245084313", + "GasPremium": "126342", + "Method": 6, + "Params": "igMZ83fYKlgpAAGC4gOB6AIgGzHNjecC1XypcmQ2EIEAGgNW+V6AKmWtH+gTfqq3LFIaAAOx+YAaABtnmvQAAAA=" + }, + { + "Version": 0, + "To": "f022922", + "From": "f3ux4a7ylxkjhquc6t3csakgalxqlizkjth2xva57y4y67rafuy2efdlouxghatyijl3zwzmrke3i6l5z2fd5q", + "Nonce": 8502, + "Value": "122743480499653955", + "GasLimit": 56672351, + "GasFeeCap": "1764528879", + "GasPremium": "126366", + "Method": 7, + "Params": "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" + }, + { + "Version": 0, + "To": "f030347", + "From": "f3wy3ecnyzyu5jw2o2jythtzabkavohdqurbz5lhy2xylr7coxjegmg4spjfosqy5o3dtwsi4idtmucrubi7xa", + "Nonce": 436207, + "Value": "122754365630378849", + "GasLimit": 80315846, + "GasFeeCap": "1245084313", + "GasPremium": "124447", + "Method": 7, + "Params": "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" + }, + { + "Version": 0, + "To": "f030347", + "From": "f3wy3ecnyzyu5jw2o2jythtzabkavohdqurbz5lhy2xylr7coxjegmg4spjfosqy5o3dtwsi4idtmucrubi7xa", + "Nonce": 436208, + "Value": "121191102922431314", + "GasLimit": 80315846, + "GasFeeCap": "1245084313", + "GasPremium": "125224", + "Method": 6, + "Params": "igMaAAQEgtgqWCkAAYLiA4HoAiDbbtSLkYiiT//Q5p5woO5IRmU4m408+h/Sf2iZ/TrnGxoAA7LBgBoAG2ea9AAAAA==" + }, + { + "Version": 0, + "To": "f030347", + "From": "f3wy3ecnyzyu5jw2o2jythtzabkavohdqurbz5lhy2xylr7coxjegmg4spjfosqy5o3dtwsi4idtmucrubi7xa", + "Nonce": 436209, + "Value": "121191102922431314", + "GasLimit": 80315846, + "GasFeeCap": "1245084313", + "GasPremium": "124718", + "Method": 6, + "Params": "igMaAAJ5dNgqWCkAAYLiA4HoAiCnHexDnKrIS8GleRb3cp9Z31bhpYL0Lto/1Vrts8JHORoAA7KHgBoAG2ea9AAAAA==" + }, + { + "Version": 0, + "To": "f030347", + "From": "f3wy3ecnyzyu5jw2o2jythtzabkavohdqurbz5lhy2xylr7coxjegmg4spjfosqy5o3dtwsi4idtmucrubi7xa", + "Nonce": 436210, + "Value": "122754344480600755", + "GasLimit": 80315846, + "GasFeeCap": "1245084313", + "GasPremium": "125311", + "Method": 7, + "Params": "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" + }, + { + "Version": 0, + "To": "f030347", + "From": "f3wy3ecnyzyu5jw2o2jythtzabkavohdqurbz5lhy2xylr7coxjegmg4spjfosqy5o3dtwsi4idtmucrubi7xa", + "Nonce": 436211, + "Value": "121191316741862868", + "GasLimit": 80315846, + "GasFeeCap": "1245084313", + "GasPremium": "125332", + "Method": 6, + "Params": "igMaAAQEgNgqWCkAAYLiA4HoAiBEApDWAwuMyb9ruD5ZJJsvC42fCtWbni3UpVHIsA+NKBoAA7K/gBoAG2ea9AAAAA==" + }, + { + "Version": 0, + "To": "f030347", + "From": "f3wy3ecnyzyu5jw2o2jythtzabkavohdqurbz5lhy2xylr7coxjegmg4spjfosqy5o3dtwsi4idtmucrubi7xa", + "Nonce": 436212, + "Value": "122755188912942362", + "GasLimit": 80315846, + "GasFeeCap": "1245084313", + "GasPremium": "126003", + "Method": 7, + "Params": "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" + }, + { + "Version": 0, + "To": "f030347", + "From": "f3wy3ecnyzyu5jw2o2jythtzabkavohdqurbz5lhy2xylr7coxjegmg4spjfosqy5o3dtwsi4idtmucrubi7xa", + "Nonce": 436213, + "Value": "122755427313041337", + "GasLimit": 80315846, + "GasFeeCap": "1245084313", + "GasPremium": "125374", + "Method": 7, + "Params": "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" + }, + { + "Version": 0, + "To": "f030347", + "From": "f3wy3ecnyzyu5jw2o2jythtzabkavohdqurbz5lhy2xylr7coxjegmg4spjfosqy5o3dtwsi4idtmucrubi7xa", + "Nonce": 436214, + "Value": "121191316741862868", + "GasLimit": 80315846, + "GasFeeCap": "1245084313", + "GasPremium": "124431", + "Method": 6, + "Params": "igMZ9A/YKlgpAAGC4gOB6AIgMzeU587paJshliehEmgTEmrlgDorWeudd4+9fs3VVAcaAAOywYAaABtnmvQAAAA=" + }, + { + "Version": 0, + "To": "f030347", + "From": "f3wy3ecnyzyu5jw2o2jythtzabkavohdqurbz5lhy2xylr7coxjegmg4spjfosqy5o3dtwsi4idtmucrubi7xa", + "Nonce": 436215, + "Value": "122755188912942362", + "GasLimit": 80315846, + "GasFeeCap": "1245084313", + "GasPremium": "124613", + "Method": 7, + "Params": "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" + }, + { + "Version": 0, + "To": "f030347", + "From": "f3wy3ecnyzyu5jw2o2jythtzabkavohdqurbz5lhy2xylr7coxjegmg4spjfosqy5o3dtwsi4idtmucrubi7xa", + "Nonce": 436216, + "Value": "121191316741862868", + "GasLimit": 80315846, + "GasFeeCap": "1245084313", + "GasPremium": "124919", + "Method": 6, + "Params": "igMZ8dzYKlgpAAGC4gOB6AIgs0GRwKSjB0IRGpXuRZfDiF9WnB4ngEYt83ngGO+VrFcaAAOvy4AaABtnmvQAAAA=" + }, + { + "Version": 0, + "To": "f030347", + "From": "f3wy3ecnyzyu5jw2o2jythtzabkavohdqurbz5lhy2xylr7coxjegmg4spjfosqy5o3dtwsi4idtmucrubi7xa", + "Nonce": 436217, + "Value": "122756027681018569", + "GasLimit": 80315846, + "GasFeeCap": "1245084313", + "GasPremium": "124924", + "Method": 7, + "Params": "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" + }, + { + "Version": 0, + "To": "f030347", + "From": "f3wy3ecnyzyu5jw2o2jythtzabkavohdqurbz5lhy2xylr7coxjegmg4spjfosqy5o3dtwsi4idtmucrubi7xa", + "Nonce": 436218, + "Value": "122756177830657766", + "GasLimit": 80315846, + "GasFeeCap": "1245084313", + "GasPremium": "125123", + "Method": 7, + "Params": "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" + }, + { + "Version": 0, + "To": "f010035", + "From": "f3ulm32bibybv7srwsq25dhl7grvbnyjyonmps5fgtpi65qsauf7dxbn4wlisjtpya7wsjuz6pqvzma5wak4cq", + "Nonce": 215185, + "Value": "122755917527069422", + "GasLimit": 59390153, + "GasFeeCap": "1683780811", + "GasPremium": "124986", + "Method": 7, + "Params": "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" + }, + { + "Version": 0, + "To": "f01012", + "From": "f3q2kzhc2zzwdclfj6imgiffn2xvtyfu42tz7h2gfstj7j7xjlxgefnh35dxnc3frwvpr35hgayldy6kssrt2a", + "Nonce": 590152, + "Value": "122776007428521729", + "GasLimit": 51762653, + "GasFeeCap": "1931894796", + "GasPremium": "123953", + "Method": 7, + "Params": "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" + }, + { + "Version": 0, + "To": "f01012", + "From": "f3q2kzhc2zzwdclfj6imgiffn2xvtyfu42tz7h2gfstj7j7xjlxgefnh35dxnc3frwvpr35hgayldy6kssrt2a", + "Nonce": 590153, + "Value": "121191532823564220", + "GasLimit": 24368478, + "GasFeeCap": "4103662116", + "GasPremium": "125327", + "Method": 6, + "Params": "igMaABSOZtgqWCkAAYLiA4HoAiBY4ECmlYfVx1s963Jc95jfGTB+oi7lLCgGVvLlarz6NxoAA7IigBoAG2Kw9AAAAA==" + }, + { + "Version": 0, + "To": "f01012", + "From": "f3q2kzhc2zzwdclfj6imgiffn2xvtyfu42tz7h2gfstj7j7xjlxgefnh35dxnc3frwvpr35hgayldy6kssrt2a", + "Nonce": 590154, + "Value": "122774574058792739", + "GasLimit": 54471706, + "GasFeeCap": "1835815459", + "GasPremium": "124613", + "Method": 7, + "Params": "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" + }, + { + "Version": 0, + "To": "f01012", + "From": "f3q2kzhc2zzwdclfj6imgiffn2xvtyfu42tz7h2gfstj7j7xjlxgefnh35dxnc3frwvpr35hgayldy6kssrt2a", + "Nonce": 590155, + "Value": "122751843808482455", + "GasLimit": 67290153, + "GasFeeCap": "1486101539", + "GasPremium": "125964", + "Method": 7, + "Params": "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" + }, + { + "Version": 0, + "To": "f01012", + "From": "f3q2kzhc2zzwdclfj6imgiffn2xvtyfu42tz7h2gfstj7j7xjlxgefnh35dxnc3frwvpr35hgayldy6kssrt2a", + "Nonce": 590156, + "Value": "122744018363934596", + "GasLimit": 69906403, + "GasFeeCap": "1430484128", + "GasPremium": "124958", + "Method": 7, + "Params": "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" + }, + { + "Version": 0, + "To": "f01012", + "From": "f3q2kzhc2zzwdclfj6imgiffn2xvtyfu42tz7h2gfstj7j7xjlxgefnh35dxnc3frwvpr35hgayldy6kssrt2a", + "Nonce": 590157, + "Value": "122780338629473282", + "GasLimit": 64308513, + "GasFeeCap": "1555004078", + "GasPremium": "124932", + "Method": 7, + "Params": "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" + }, + { + "Version": 0, + "To": "f01012", + "From": "f3q2kzhc2zzwdclfj6imgiffn2xvtyfu42tz7h2gfstj7j7xjlxgefnh35dxnc3frwvpr35hgayldy6kssrt2a", + "Nonce": 590158, + "Value": "122779590573780423", + "GasLimit": 67017566, + "GasFeeCap": "1492146103", + "GasPremium": "125681", + "Method": 7, + "Params": "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" + }, + { + "Version": 0, + "To": "f01012", + "From": "f3q2kzhc2zzwdclfj6imgiffn2xvtyfu42tz7h2gfstj7j7xjlxgefnh35dxnc3frwvpr35hgayldy6kssrt2a", + "Nonce": 590159, + "Value": "122772451406606032", + "GasLimit": 69538513, + "GasFeeCap": "1438052033", + "GasPremium": "124188", + "Method": 7, + "Params": "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" + }, + { + "Version": 0, + "To": "f023678", + "From": "f3w2xf4h44st6qtwoncs2fzwjvpclzh3luaktjv4gchysjv74es62nh7n3m5spmpag3pawjfprieop7yfyiraa", + "Nonce": 88065, + "Value": "122711999841970259", + "GasLimit": 56453513, + "GasFeeCap": "1771368949", + "GasPremium": "124471", + "Method": 7, + "Params": "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" + }, + { + "Version": 0, + "To": "f023678", + "From": "f3w2xf4h44st6qtwoncs2fzwjvpclzh3luaktjv4gchysjv74es62nh7n3m5spmpag3pawjfprieop7yfyiraa", + "Nonce": 88066, + "Value": "122715528785623399", + "GasLimit": 53841013, + "GasFeeCap": "1857320180", + "GasPremium": "125623", + "Method": 7, + "Params": "ghl/nlkHgKN/bfDslcp7xGL6MlEM8LDqnq/PiRNwW9/8QYCqXz+H06Hh58iXB4ESC3UFnIEkOoPoYmmGTqzNGDY+ZZNfuHneLx9bWhnAiYGzLNojwtZ9NNpShNs4uSoOUQgJthrHDw4HSIMaytruTsnucjo7UDG+QJC5hujUQBK8Mkdzg66btBq/73Z1ZiqZiacxUwDke7fmPk2kZO0/osZJDhuaY3oQZmDcl8xjADAH8/yEVRyUtyru85NA5NeI2ZsLof9ql6PX58cBueDEzUwG2q1VCflF1qdeKH1USGbj4fKmlU5+Cgh3RLzPHSGeWdp2Z2igCol77cNVfh2EClYqwfM9+h2Q9Ob5WqNQjqhQpmNg40ZJUAmAm5okLJoL+HbQdzPoKBLVlogQLxthvnLf1JRoFowxjBBxDgHmWbTUfi7KijcSIOz7C78NaClvFRoMnc9OR7BtISfrS6GAvMQu7rEzI6cgg03avk2XXUz+Kfyp4KcUlmfOGdcVngok4VnpmvcNhZSuWbjk6inlUL4mDqoMn1GjWw42CsFa/+idovzSZY4plcidS/CRhs1rDJSdWgclEbFVxUGl+9GMrtfNcjk0OkGXhtXD20IbSSkzyuyQMTITuPh6zfH6rMwaHU4ihXxL7gSm0+2UJmHXRXbyZnC3E7Gfp1tNJlH3jzmXbncOfFQ+lwaLJUSLvgJ811RkmOGBPbb5pOA+YnvvIUwJ972426PQ6i9mhsBKaSemxcEs7I53DkgWdnB439I0k+v1hN3Q+7AnK8Zj0YA1AdTJlPbo0rY8AvimcjjXyih5y+KVqlVmQSGr2mXC1601Yp8952nwfY8f1I75lYBLadrYmAtOmfEAnfE8Tiq1K070DS/ANGvoznM50C4jotM2uSmZPP86MQKlv3kZaJ78Hd/d7h54wPYmJ5bgJ4FNbKel8bXHCunmfoaUctVTQB8gLGCyKd6+SoM3xshpUjSwiAzQA6VUKUcWzahvjN9V09fMsF8//tkHVI3WrGZU8awe6ppGisQnopZn6nysOa/7MjC0wRD5lE/voOtKmCauTWn0/RR3/fcnMAU7eASegqI2TdlEUGcq35J1Cu8xdcSeizOoEwzeIpA4dNiLvhjZ05ckNJyW8exayNm3PvXHSeQDNT7PrT7aPxj5mCScfEwkzeYJ7K1Top4TsFXAHTNtGkh+pWT+qVd08TpOBVi1xFkU/zxxxH3C1Jmg0MRqwhOggcsUXhZYwcjDxovlYPkQpG8Sw1sLfHTiKv2JeV/3taxOXxYh1oPbaaUrEBQdpFR/TixPN61CPOkLqs+nEdS4+7bL4lfvnMqRTitN/GyJatW14mHZQmFaJbP+xPLA6mJEMj8HgpvrbMp5hj91RYSY439EHh2Nksc1Cqskl8gEONvXEDcNPLYMoQQwkm6/uFi3BYwyb0ID0RpSuKGoyeS2TtmTiv/ZNMzeKvsFwDq1uvpsxMYJtGasvpX6G1pSPZU6Zk2cWoFu6fKM1/L1+kosm29g9bH5qqvqW6CS5RpGwdUKivRCN1lVC6rEm7XwnMdqa8po1lU/yOMdIVs7hO5896opYhr13tl0efbuNq2sGCV4WCo7eLZwbKDyBl4iQJQS/zfCvvbwJBus3c4vqSaX3FSwhWCo6SnttRLUjPkjbGubWPRJaSaaIQDDAKaEqpIP61YGLuKviW4S0+6qZnLHgb0Ce6Y2NWvqaSCjqFlKMzM1SHAfDRcrkaGH2Z9gHmHsT0J2wDT8k3IPspIkkJNUUfHq3pCpdZHK7vez40vzJ2q7t5G0pNbpeJQiUY2rxmf9tFqQym6vY12PH/CazsnXi0/D+7xAeJ+5vSRn5jA4xVQ/AVwT7mKW4Ze3bbYgrIkbj/7c68b2XFOe73h4bkBQmZ2cWMP8rrgXc1yzRjHNPUqLTyIkNarUPhW54/VkVG47LVYkrvK/U9nJBGhPtFEWIawYujZGm2S9Vo66Fm6+PNs77W6O+y1dtqNtuak4wvQ18GHAy/rQc9eRIos61XIkkxHWQotSLBpaek6OIrdneul3nD5e+BczOqvsBe1xspZAMDdSqcdn5/Rpdgf/r69tOVVYRA09yqnrqpS7P0pvTPng222u4QXIFre3mPmlrKik3xer+Cod3ofNLF/+aAsJns3d9aqblYGPiaI920Dfpm7oiRKuRN1SlxGX0+00eSAGWlkfl8lmqXikemYt63Ti8ee6PxPB6XIebK5I0V67G3S9VIyPREUH7aboMPMqYPP87wsgbBGj3eIoNNS/DJiKgpc//sU5auCtKw91tnClPCAOCVeDOxrAz5UxjmwlDmc/mKuYv1DJKfQwIvFYMvfVmNFtm3orPWPNl6JyuPkJM76yWIZ3Cl4HGa9arXlyAf/0Jf7c0k5oa3v976bsx771ojrY412jmG3Xu2ykF2Tjl6V1ewGLFzTqzRjN0BBJNrmrIgEWXUsQy2zUt1ybzvkNVPjsZbzPfRcKwfNpbWnfUoBvLyJsC+RSJIoUetXwIGIIGEjcO5Pk5KXrvnbAoOBFqR46UBSl1XVTZ0C6pPEVUlHUquP+GJu9Xg==" + }, + { + "Version": 0, + "To": "f061740", + "From": "f3q4crr65gnmgldb4asgawtsro53jcmmn7bavuwpfulib2scbwqn32dzzcfbm7tsel72d7t52kpb6cy7chqmbq", + "Nonce": 9170, + "Value": "122768904580932846", + "GasLimit": 50852303, + "GasFeeCap": "983239638", + "GasPremium": "100974", + "Method": 7, + "Params": "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" + }, + { + "Version": 0, + "To": "f02490", + "From": "f3qlp7se6vaw6yg3sjm2pme3xbfw7avhjng2ilmkejujbmxrsv7v5netdonvcrj5rez5epawkxpnzaei27esna", + "Nonce": 152261, + "Value": "121193537706136508", + "GasLimit": 19124728, + "GasFeeCap": "1307208133", + "GasPremium": "100674", + "Method": 6, + "Params": "igMaAAE/wNgqWCkAAYLiA4HoAiAOo6lUgLI9Nf1Xupmmh5IEEs7+M5ppFmx6MNJY3tqgEhoAA7G8gBoAG2q59AAAAA==" + }, + { + "Version": 0, + "To": "f01012", + "From": "f3q2kzhc2zzwdclfj6imgiffn2xvtyfu42tz7h2gfstj7j7xjlxgefnh35dxnc3frwvpr35hgayldy6kssrt2a", + "Nonce": 590160, + "Value": "121192144352524001", + "GasLimit": 24148478, + "GasFeeCap": "1035261932", + "GasPremium": "101508", + "Method": 6, + "Params": "igMaABSOZ9gqWCkAAYLiA4HoAiAsemQbfANc8lC8X/9tIyuecAfM6BRJ6irud6yf35ZGCBoAA7IjgBoAG2Kw9AAAAA==" + }, + { + "Version": 0, + "To": "f023825", + "From": "f3woozrthpt5dqlb5kqmg4ytq4vt3fypdjauuyvr6olwszwffc6sl64olnz7smfsrkqfymxg7d2l4hl5egpz4q", + "Nonce": 167008, + "Value": "121193537706136508", + "GasLimit": 21673478, + "GasFeeCap": "1153483534", + "GasPremium": "100801", + "Method": 6, + "Params": "igMaAAFnr9gqWCkAAYLiA4HoAiAiVezmx9qjB5tFXIieW5tpk3TB/oBRr/OCLqXDTRKUPBoAA7FygBoAG2Gb9AAAAA==" + }, + { + "Version": 0, + "To": "f022922", + "From": "f3ux4a7ylxkjhquc6t3csakgalxqlizkjth2xva57y4y67rafuy2efdlouxghatyijl3zwzmrke3i6l5z2fd5q", + "Nonce": 8503, + "Value": "121189668022108035", + "GasLimit": 17643478, + "GasFeeCap": "2833908371", + "GasPremium": "100657", + "Method": 6, + "Params": "igMZD5DYKlgpAAGC4gOB6AIgIFI9s/43Kvzj7VaBAGZc+eanNqV1FD9K6eZAX/glYVUaAAOvzoAaABtnqPQAAAA=" + }, + { + "Version": 0, + "To": "f02723", + "From": "f3rjqeslxvswwtydbd3kayqodwslzx7lkbkj5sd75s5w7czsadqz2vpkm5nj5zjqqqumhbhf5cswzd4ueggrea", + "Nonce": 103220, + "Value": "122767878924261053", + "GasLimit": 53842263, + "GasFeeCap": "10524911434", + "GasPremium": "100787", + "Method": 7, + "Params": "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" + }, + { + "Version": 0, + "To": "f02723", + "From": "f3rjqeslxvswwtydbd3kayqodwslzx7lkbkj5sd75s5w7czsadqz2vpkm5nj5zjqqqumhbhf5cswzd4ueggrea", + "Nonce": 103221, + "Value": "121193649549989127", + "GasLimit": 18190333, + "GasFeeCap": "10280067024", + "GasPremium": "101022", + "Method": 6, + "Params": "igMZn/DYKlgpAAGC4gOB6AIg/ruPCfTzapIG4qy7TyCw1Yk3z14p+ugJgd2Xy0lYhQgaAAOt0YAaABtmE/QAAAA=" + }, + { + "Version": 0, + "To": "f056611", + "From": "f3qcma4wxrrzzs5y2azge73qtcpjihjpsqdehcqbfkqa3po2yoyjwbvwau4qyrxnt6sva3ihf7vbhtba5vfwsq", + "Nonce": 64846, + "Value": "121193649549989127", + "GasLimit": 19754036, + "GasFeeCap": "1265564161", + "GasPremium": "101179", + "Method": 6, + "Params": "igMZj7rYKlgpAAGC4gOB6AIg3cza/LQi6AKhSo/Vwz2D05HPD/uVPytX/qlJKtBYFSoaAAOxkIAaABti+/QAAAA=" + }, + { + "Version": 0, + "To": "f024563", + "From": "f3vgrp6y5iqp7df6jc7ibzzythlkluei5x3vivwajsko3k6za3utrr5ajly4mhgiv3xggox62nmbb4odfqih3q", + "Nonce": 466675, + "Value": "121193537706136508", + "GasLimit": 21104513, + "GasFeeCap": "1184580757", + "GasPremium": "100685", + "Method": 6, + "Params": "igMaAAOX9tgqWCkAAYLiA4HoAiCOtez3abjQga+NETnV9LhQcP8ehsYLDs3EW18IovC1FxoAA7J6gBoAC7ox9AAAAA==" + }, + { + "Version": 0, + "To": "f024563", + "From": "f3vgrp6y5iqp7df6jc7ibzzythlkluei5x3vivwajsko3k6za3utrr5ajly4mhgiv3xggox62nmbb4odfqih3q", + "Nonce": 466676, + "Value": "121193649549989127", + "GasLimit": 21818566, + "GasFeeCap": "1145813157", + "GasPremium": "99757", + "Method": 6, + "Params": "igMaAAOVttgqWCkAAYLiA4HoAiD7bz1yjLfM0YYivGULuSHTP8GYMQL/2rNjTQWnEAvaaxoAA7HygBoAC7ox9AAAAA==" + }, + { + "Version": 0, + "To": "f024563", + "From": "f3vgrp6y5iqp7df6jc7ibzzythlkluei5x3vivwajsko3k6za3utrr5ajly4mhgiv3xggox62nmbb4odfqih3q", + "Nonce": 466677, + "Value": "122741859352305200", + "GasLimit": 51052908, + "GasFeeCap": "979376140", + "GasPremium": "101163", + "Method": 7, + "Params": "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" + }, + { + "Version": 0, + "To": "f062931", + "From": "f3rim5daueumelcqpfy7zzp3rgfzb5x63dyumgk3jggsk56luojtsth4gbcv4yxgrkveg3nt4w4l3bsr4hssxa", + "Nonce": 49697, + "Value": "121193649549989127", + "GasLimit": 24215891, + "GasFeeCap": "5000000000", + "GasPremium": "100658", + "Method": 6, + "Params": "igMaAAYhWdgqWCkAAYLiA4HoAiA5Mr/z2zAfiL96IZD85gscMuJxKgYO/uDfh3eCeo+4KxoAA7JxgBoAC8ef9AAAAA==" + }, + { + "Version": 0, + "To": "f062931", + "From": "f3rim5daueumelcqpfy7zzp3rgfzb5x63dyumgk3jggsk56luojtsth4gbcv4yxgrkveg3nt4w4l3bsr4hssxa", + "Nonce": 49698, + "Value": "121193649549989127", + "GasLimit": 25805333, + "GasFeeCap": "5000000000", + "GasPremium": "100844", + "Method": 6, + "Params": "igMaABPcq9gqWCkAAYLiA4HoAiBK06uYWBCKFhad+QmgnTz7vO4LhsW3EESfkBna9q+YFBoAA7G8gBoAC8ef9AAAAA==" + }, + { + "Version": 0, + "To": "f029404", + "From": "f3rvi2y7hexd7kjfathsxnopwb63llezb2yznyi5qdceulwiwuz2hyuksqxzrrehop674ue5v2nnpmykd2dlqq", + "Nonce": 49070, + "Value": "122768968070332201", + "GasLimit": 50853553, + "GasFeeCap": "983215469", + "GasPremium": "100522", + "Method": 7, + "Params": "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" + }, + { + "Version": 0, + "To": "f02438", + "From": "f3uuvgrmepryqhcpmxtcucbjsbasvcl4k226lkiyl4v7ko75zqirrbsys7jt3cqxb5jgviubit5jcfkzqbsa6a", + "Nonce": 1231061, + "Value": "122769140028509879", + "GasLimit": 57953856, + "GasFeeCap": "5000000000", + "GasPremium": "100259", + "Method": 7, + "Params": "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" + }, + { + "Version": 0, + "To": "f02438", + "From": "f3uuvgrmepryqhcpmxtcucbjsbasvcl4k226lkiyl4v7ko75zqirrbsys7jt3cqxb5jgviubit5jcfkzqbsa6a", + "Nonce": 1231062, + "Value": "122769140028509879", + "GasLimit": 60945066, + "GasFeeCap": "5000000000", + "GasPremium": "100409", + "Method": 7, + "Params": "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" + }, + { + "Version": 0, + "To": "f02438", + "From": "f3uuvgrmepryqhcpmxtcucbjsbasvcl4k226lkiyl4v7ko75zqirrbsys7jt3cqxb5jgviubit5jcfkzqbsa6a", + "Nonce": 1231063, + "Value": "122768540505553218", + "GasLimit": 63466013, + "GasFeeCap": "5000000000", + "GasPremium": "100019", + "Method": 7, + "Params": "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" + }, + { + "Version": 0, + "To": "f02438", + "From": "f3uuvgrmepryqhcpmxtcucbjsbasvcl4k226lkiyl4v7ko75zqirrbsys7jt3cqxb5jgviubit5jcfkzqbsa6a", + "Nonce": 1231064, + "Value": "122768497028977053", + "GasLimit": 66081013, + "GasFeeCap": "5000000000", + "GasPremium": "100452", + "Method": 7, + "Params": "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" + }, + { + "Version": 0, + "To": "f02438", + "From": "f3uuvgrmepryqhcpmxtcucbjsbasvcl4k226lkiyl4v7ko75zqirrbsys7jt3cqxb5jgviubit5jcfkzqbsa6a", + "Nonce": 1231065, + "Value": "122769148210786525", + "GasLimit": 68696013, + "GasFeeCap": "5000000000", + "GasPremium": "100604", + "Method": 7, + "Params": "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" + }, + { + "Version": 0, + "To": "f056226", + "From": "f3rwocizqhzxr6epnkcndektzfcrhpbzj7z5xaqpihkgrfxwqmwfic42ttar6t7nekinfwqha3soogqa6vagcq", + "Nonce": 26575, + "Value": "121193537706136508", + "GasLimit": 20924983, + "GasFeeCap": "1194744100", + "GasPremium": "100383", + "Method": 6, + "Params": "igMZVPXYKlgpAAGC4gOB6AIgDkOq/Okrg0+xEg0slwNV7awDYivpdOuiQaX/bAAwaz8aAAOxIYAaABthLvQAAAA=" + }, + { + "Version": 0, + "To": "f02626", + "From": "f3sqwodtyqnzhf5hohcwlhir6pkheacdqd53bgqyud76fsbwdcplrlmn52wpucllg6x3ajnptap4mafsecq2ra", + "Nonce": 269625, + "Value": "122767706604381323", + "GasLimit": 50955106, + "GasFeeCap": "981255931", + "GasPremium": "100592", + "Method": 7, + "Params": "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" + }, + { + "Version": 0, + "To": "f02626", + "From": "f3sqwodtyqnzhf5hohcwlhir6pkheacdqd53bgqyud76fsbwdcplrlmn52wpucllg6x3ajnptap4mafsecq2ra", + "Nonce": 269626, + "Value": "121193649549989127", + "GasLimit": 18028566, + "GasFeeCap": "1386688214", + "GasPremium": "100175", + "Method": 6, + "Params": "igMaAAaO6tgqWCkAAYLiA4HoAiC35nt7igG/5I3v69x4JyR512ADIv2IyctlZN6SAQNKbhoAA7JDgBoAG2hi9AAAAA==" + }, + { + "Version": 0, + "To": "f023825", + "From": "f3woozrthpt5dqlb5kqmg4ytq4vt3fypdjauuyvr6olwszwffc6sl64olnz7smfsrkqfymxg7d2l4hl5egpz4q", + "Nonce": 167009, + "Value": "122768003437599101", + "GasLimit": 50955106, + "GasFeeCap": "981255931", + "GasPremium": "100096", + "Method": 7, + "Params": "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" + }, + { + "Version": 0, + "To": "f066259", + "From": "f3vccjwrbqfu64arsar2frk6beqk6hp76jn7zoc4eahayh7r4dt6hrdpybanwgmzqzjmrprceow5tzcmygyglq", + "Nonce": 30329, + "Value": "122708859176893247", + "GasLimit": 51611101, + "GasFeeCap": "968783828", + "GasPremium": "100254", + "Method": 7, + "Params": "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" + }, + { + "Version": 0, + "To": "f024483", + "From": "f3sxw2cm574k2byhi5d4ax4h556ywvi36gbbf4uvgmybtejpmp7bd5p7pvz6t2cdwifsgcreeilf7ecfeaot4a", + "Nonce": 124911, + "Value": "122756413322397522", + "GasLimit": 57957606, + "GasFeeCap": "5000000000", + "GasPremium": "100344", + "Method": 7, + "Params": "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" + }, + { + "Version": 0, + "To": "f063869", + "From": "f3tfkiryke7x57vfpmzkplefvq3l45zbbdi2s7hoteu4j7dkxmf746ac3ynwegocpfwsqvgspcz5gh2hsrgraq", + "Nonce": 85717, + "Value": "122769020608844046", + "GasLimit": 57952606, + "GasFeeCap": "5000000000", + "GasPremium": "100148", + "Method": 7, + "Params": "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" + }, + { + "Version": 0, + "To": "f09696", + "From": "f3rajqmgo6oemabzarpiv4klfr3nkimzxx5sjnqfvefrazaxsoqhkwv3ucsb3dc4jmny3tts5owtlmf7vcbuka", + "Nonce": 1376, + "Value": "0", + "GasLimit": 744145733, + "GasFeeCap": "10280066222", + "GasPremium": "100220", + "Method": 5, + "Params": "hQ+BggBAgYIIWMCxTgAVAT6BxFcprATrUctaaxsGA89GhA1iJd1FmuUJ2Uo9wEqpZaVocWbYyfscMnSNGoLsIMx8hB8NMBcMH6vLzQVHEeASXs2F8Qz/9FCMN8DtXP5wd6V+z4tF6l3BoG8NrWERZKOWSFRlF13+zZVtd5MgDzu+N+6+iW3rBDyhMSU1QkShqRG16OG0p0n2ibWoDug9IWy4TbrRJdtKlW3vAaE2xjpKZUJrUwmXYnCJIxOFnLpV1QKCCC/7i5BCmMEaAAO3bVggJJ9sfEgOhJmN/XDKgAs2wpLvGXW4ArqhxFodbtB4l2Q=" + }, + { + "Version": 0, + "To": "f069919", + "From": "f3vlny6twbkprq2jden4z7xrb624bxz3v25ncoqkqdus2mwly4k3pxw7pp4jim4jsxqhhgxgehqbkqsigff5nq", + "Nonce": 9593, + "Value": "122768003437599101", + "GasLimit": 50852303, + "GasFeeCap": "983239638", + "GasPremium": "100544", + "Method": 7, + "Params": "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" + }, + { + "Version": 0, + "To": "f023200", + "From": "f3uqsdyf6744kzvde6uyyq6j7sfip4o3jqdt6blrdpytvrv5itqcb3zy3s3cpdayjvm3zafeqzp6gw3synha2a", + "Nonce": 729, + "Value": "0", + "GasLimit": 658939956, + "GasFeeCap": "4552766868", + "GasPremium": "100272", + "Method": 5, + "Params": "hQyBggBAgYIIWMCRl49uQUC9mZnSBiZuZ2vJxUpbeGgs28na3CJUxJy0Ya3/K9D5pIHBx7W6p+EHjritdWznB0fqjGUgI6nwg/eqLA/uwo7B/trjOYlf9QPWFwX3YZguya+8+fJfRxKamfcThV3KGMPbMPAm/1ChZgigp5WsFz8DqJkp9cN9TqxRFAJ4rnRrpn9OtUlPkMDH3h2MOWUBTw8nO3Pykb8hGllb0UB7h/qwBBRlqxHjBeiF+gRvz4pYeithVG3VxDPdwBAaAAO3aVggU6EMoocHbe4ygRdHMtiTFu9sXVs0Mb8Ygm1kq/qLzVo=" + }, + { + "Version": 0, + "To": "f02770", + "From": "f3wcfa5vw7t54rilkeee63x4w6fhytjznk4ywaxjrbr5g5cxogvvrgllwcjtgd4hd5uask7ulzpq4qhk45pu7q", + "Nonce": 4052271, + "Value": "0", + "GasLimit": 32884453, + "GasFeeCap": "957899466", + "GasPremium": "100892", + "Method": 6, + "Params": "igMaADsiUdgqWCkAAYLiA4HoAiDyoIUiSwa4kP51dNhLOWJZeYC023Lu4HL5FeunSj1aHRoAA7GNgBoAG2Oj9AAAAA==" + }, + { + "Version": 0, + "To": "f02770", + "From": "f3wcfa5vw7t54rilkeee63x4w6fhytjznk4ywaxjrbr5g5cxogvvrgllwcjtgd4hd5uask7ulzpq4qhk45pu7q", + "Nonce": 4052272, + "Value": "0", + "GasLimit": 61709138, + "GasFeeCap": "972303324", + "GasPremium": "99914", + "Method": 7, + "Params": "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" + }, + { + "Version": 0, + "To": "f034701", + "From": "f3v4tkxokoxt3cgo4eec4obq67q2wwlca4ofcaowndlqvdmkurm6lrtm3fusetp3lw63pcuoya4vw7mdoscamq", + "Nonce": 8202, + "Value": "122718951853673043", + "GasLimit": 51523171, + "GasFeeCap": "970437165", + "GasPremium": "99990", + "Method": 7, + "Params": "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" + }, + { + "Version": 0, + "To": "f010528", + "From": "f3vsfvzod3ajckprbkjwoa4aigxggvlxexamssjyl4bleemgdyfzr7tn75b4zvzjbqh4mci2zbv6hxwai24eua", + "Nonce": 11719, + "Value": "0", + "GasLimit": 24589046, + "GasFeeCap": "4066851556", + "GasPremium": "99564", + "Method": 6, + "Params": "igMZFZrYKlgpAAGC4gOB6AIgnS6FcO30rCB/A85R2MvCLX0vv7Oo6jCBd/xpiEeJJxoaAAOxLpg9GgAUG1kaABQcnRoAFBzSGgAUHREaABQd2xoAFB3yGgAUHkEaABQeQBoAFB56GgAUHu8aABQe7hoAFB9WGgAUH8IaABQfpBoAFCB6GgAUIHUaABQgeRoAFCDdGgAUIgYaABQjUxoAFCLzGgAUI1QaABQi8hoAFCQkGgAUJGYaABQkMxoAFCTiGgAUJOEaABQk2xoAFCVSGgAUJRkaABQlGBoAFCW6GgAUJfIaABQmfxoAFCZ+GgAUJqMaABQnERoAFCdFGgAUJ4kaABQnthoAFCe4GgAUJ7kaABQoDxoAFCiBGgAUKKwaABQo6RoAFClQGgAUKdQaABQp0xoAFCpNGgAUKqQaABQq2BoAFCrXGgAUKsgaABQrZhoAFCsxGgAULC0aABQtGxoAFC0cGgAULcQaAAvMxPQAAAA=" + }, + { + "Version": 0, + "To": "f070501", + "From": "f3qc5qsbj4urud7tnd4luszvry2z5w3fwprggynnyxdcyyma3cvw4bv2vk2rduma4kbnkwruotgdisgvgmb23a", + "Nonce": 37019, + "Value": "121193537706136508", + "GasLimit": 16195071, + "GasFeeCap": "1543679555", + "GasPremium": "100162", + "Method": 6, + "Params": "igMZVfPYKlgpAAGC4gOB6AIglqxW8jRr6rgFCZQ0Yr9tQhGHa3JNd9DQpt9H72ptM0EaAAOxeYAaABtmvPQAAAA=" + }, + { + "Version": 0, + "To": "f070501", + "From": "f3qc5qsbj4urud7tnd4luszvry2z5w3fwprggynnyxdcyyma3cvw4bv2vk2rduma4kbnkwruotgdisgvgmb23a", + "Nonce": 37020, + "Value": "121193537706136508", + "GasLimit": 16614426, + "GasFeeCap": "1504716443", + "GasPremium": "99607", + "Method": 6, + "Params": "igMZVbzYKlgpAAGC4gOB6AIgfbrreWXvoNYE3GnpgR//LriQQhJX+0UARLwveLtMJxMaAAOxTYAaABtmvPQAAAA=" + }, + { + "Version": 0, + "To": "f070501", + "From": "f3qc5qsbj4urud7tnd4luszvry2z5w3fwprggynnyxdcyyma3cvw4bv2vk2rduma4kbnkwruotgdisgvgmb23a", + "Nonce": 37021, + "Value": "121193649549989127", + "GasLimit": 16840676, + "GasFeeCap": "1484500978", + "GasPremium": "100920", + "Method": 6, + "Params": "igMZVdTYKlgpAAGC4gOB6AIg/L9Vhg9A1U1uplZnWtEClPTUEx7O4W7PhHe/d8OG7ygaAAOxXIAaABtmvPQAAAA=" + }, + { + "Version": 0, + "To": "f034544", + "From": "f3ud6wdb6rmph2k4iyjelcq5imdah2cwex33cel3mxpcvpxyfqlgtfkxnl5vxia7dkwwhov34socwmc2nhbi3q", + "Nonce": 105197, + "Value": "122709345795189305", + "GasLimit": 57955106, + "GasFeeCap": "5000000000", + "GasPremium": "100070", + "Method": 7, + "Params": "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" + }, + { + "Version": 0, + "To": "f025002", + "From": "f3v4ww2ac5o6l4djogf23gb4pnosre7m7374qw3rsocts73nfhy5ecvwzmyut3n4jkcoddqhe7sli77tsbi7ma", + "Nonce": 802197, + "Value": "121193148447007677", + "GasLimit": 34484473, + "GasFeeCap": "5000000000", + "GasPremium": "99924", + "Method": 6, + "Params": "igMaAWyzxNgqWCkAAYLiA4HoAiDW54JD7fImBLMWc8bhBBtyarxijp0sZt/G40Ha0gkFCxoAA7K6gBoAC8ea9AAAAA==" + }, + { + "Version": 0, + "To": "f025002", + "From": "f3v4ww2ac5o6l4djogf23gb4pnosre7m7374qw3rsocts73nfhy5ecvwzmyut3n4jkcoddqhe7sli77tsbi7ma", + "Nonce": 802198, + "Value": "121193260185693775", + "GasLimit": 34000078, + "GasFeeCap": "5000000000", + "GasPremium": "99596", + "Method": 6, + "Params": "igMaAV1xgtgqWCkAAYLiA4HoAiBpBXz7+VvTgxTkI9XnqGLLOy9K0HbjXS4/qSlKKG9GURoAA7KqgBoAC8eb9AAAAA==" + }, + { + "Version": 0, + "To": "f025002", + "From": "f3v4ww2ac5o6l4djogf23gb4pnosre7m7374qw3rsocts73nfhy5ecvwzmyut3n4jkcoddqhe7sli77tsbi7ma", + "Nonce": 802199, + "Value": "121193260185693775", + "GasLimit": 33790636, + "GasFeeCap": "5000000000", + "GasPremium": "100313", + "Method": 6, + "Params": "igMaAWaZGtgqWCkAAYLiA4HoAiASB/4SQt52vQPc2Oqc2WLC7ZxhQSzWv9+Yu4kEqE9GBhoAA7JCgBoAC8eb9AAAAA==" + }, + { + "Version": 0, + "To": "f025002", + "From": "f3v4ww2ac5o6l4djogf23gb4pnosre7m7374qw3rsocts73nfhy5ecvwzmyut3n4jkcoddqhe7sli77tsbi7ma", + "Nonce": 802200, + "Value": "121193260185693775", + "GasLimit": 33405723, + "GasFeeCap": "5000000000", + "GasPremium": "100073", + "Method": 6, + "Params": "igMaAMZu0NgqWCkAAYLiA4HoAiAaA+MNi5e4+5gIOFWyqi9CUs0FISlOysWC1ow6lM3RSxoAA7K7gBoAC8eb9AAAAA==" + }, + { + "Version": 0, + "To": "f042635", + "From": "f3rs6t75upu6a7zpnq3hkhxampoqnsz4rpvjjotdixxbrb2nqatllfsdemr3v2un25xx4z7mt2uww64exvjq7a", + "Nonce": 47303, + "Value": "122768734461156087", + "GasLimit": 50946356, + "GasFeeCap": "981424461", + "GasPremium": "99853", + "Method": 7, + "Params": "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" + }, + { + "Version": 0, + "To": "f014395", + "From": "f3u44q4ha2k2ojdkhxflnby3rjeh7khm36eb5ggrj3v3ylq2bv4ufh6wwhblupqlcscduq5d5xqnmbbcrseo6q", + "Nonce": 103799, + "Value": "122768679653994746", + "GasLimit": 50943856, + "GasFeeCap": "1962945247", + "GasPremium": "99498", + "Method": 7, + "Params": "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" + }, + { + "Version": 0, + "To": "f014395", + "From": "f3u44q4ha2k2ojdkhxflnby3rjeh7khm36eb5ggrj3v3ylq2bv4ufh6wwhblupqlcscduq5d5xqnmbbcrseo6q", + "Nonce": 103800, + "Value": "122768990236801771", + "GasLimit": 53838513, + "GasFeeCap": "1857406425", + "GasPremium": "100025", + "Method": 7, + "Params": "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" + }, + { + "Version": 0, + "To": "f025005", + "From": "f3sk3iog3qhjiz34nhzunbcndvptfj5ed2463qaoxm6hoc4qzy6mo2swgttcyj22mkcro634gg6x7p7i4zsfcq", + "Nonce": 56165, + "Value": "122768639563121807", + "GasLimit": 57952606, + "GasFeeCap": "5000000000", + "GasPremium": "99486", + "Method": 7, + "Params": "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" + }, + { + "Version": 0, + "To": "f063869", + "From": "f3tfkiryke7x57vfpmzkplefvq3l45zbbdi2s7hoteu4j7dkxmf746ac3ynwegocpfwsqvgspcz5gh2hsrgraq", + "Nonce": 85718, + "Value": "121193649549989127", + "GasLimit": 22351583, + "GasFeeCap": "5000000000", + "GasPremium": "99804", + "Method": 6, + "Params": "igMaAAMYUNgqWCkAAYLiA4HoAiDjfeJ0ly9DC4/EOyadEZsGa3GEkGaLKl2EE2qb3r7oLhoAA7J2gBoAC8ef9AAAAA==" + }, + { + "Version": 0, + "To": "f063869", + "From": "f3tfkiryke7x57vfpmzkplefvq3l45zbbdi2s7hoteu4j7dkxmf746ac3ynwegocpfwsqvgspcz5gh2hsrgraq", + "Nonce": 85719, + "Value": "121193649549989127", + "GasLimit": 22579083, + "GasFeeCap": "5000000000", + "GasPremium": "100442", + "Method": 6, + "Params": "igMaAAxAHNgqWCkAAYLiA4HoAiBXLZwhJvR4Z5sCjmsh/CeumgpgJ0scsWW3XjuBTnxRGhoAA7LZgBoAC8ef9AAAAA==" + }, + { + "Version": 0, + "To": "f02490", + "From": "f3qlp7se6vaw6yg3sjm2pme3xbfw7avhjng2ilmkejujbmxrsv7v5netdonvcrj5rez5epawkxpnzaei27esna", + "Nonce": 152262, + "Value": "121193537706136508", + "GasLimit": 19060373, + "GasFeeCap": "1311621761", + "GasPremium": "100245", + "Method": 6, + "Params": "igMaAAFAKtgqWCkAAYLiA4HoAiClQJL/Q5il+HDys/ycAvuQHssafDmkZgUc066IPkh4LhoAA7G9gBoAG2q59AAAAA==" + }, + { + "Version": 0, + "To": "f02490", + "From": "f3qlp7se6vaw6yg3sjm2pme3xbfw7avhjng2ilmkejujbmxrsv7v5netdonvcrj5rez5epawkxpnzaei27esna", + "Nonce": 152263, + "Value": "121193649549989127", + "GasLimit": 18935373, + "GasFeeCap": "1320280302", + "GasPremium": "100033", + "Method": 6, + "Params": "igMaAAFACdgqWCkAAYLiA4HoAiADF04Gnra8VU53u4k3GmOiJ6rN7h2xGopseIZaZx+YSxoAA7G9gBoAG2q59AAAAA==" + }, + { + "Version": 0, + "To": "f02490", + "From": "f3qlp7se6vaw6yg3sjm2pme3xbfw7avhjng2ilmkejujbmxrsv7v5netdonvcrj5rez5epawkxpnzaei27esna", + "Nonce": 152264, + "Value": "121193649549989127", + "GasLimit": 18330588, + "GasFeeCap": "1363840592", + "GasPremium": "100049", + "Method": 6, + "Params": "igMaAAE/q9gqWCkAAYLiA4HoAiACEaD12Tus2RcZq6d7ArT7R0MHjleSi7uWFJMiClQGBhoAA7G8gBoAG2q59AAAAA==" + }, + { + "Version": 0, + "To": "f039515", + "From": "f3vq7krz36z3aprqkdwve5njq5grk4im6udi4xcs6d5y24gozdydlaeq3qadptzt2pkkhwdo52cnwlpy7fhbcq", + "Nonce": 97713, + "Value": "122763647555888672", + "GasLimit": 50950106, + "GasFeeCap": "1373893118", + "GasPremium": "99549", + "Method": 7, + "Params": "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" + }, + { + "Version": 0, + "To": "f024016", + "From": "f3sxklgufxdf3dzdluvudjqugr3v5hr3l6vcwjunsdo3nrhvtzsjejf2tlkttsw4pzut7vwkbrag7skjq3l2pq", + "Nonce": 85789, + "Value": "122768103851199153", + "GasLimit": 50857303, + "GasFeeCap": "983142971", + "GasPremium": "100583", + "Method": 7, + "Params": "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" + }, + { + "Version": 0, + "To": "f024015", + "From": "f3qgj3kzglrkipapieveoppnvoq6vxnvpp62cqtf6nzqsocptzwg3hgpgsklnmbtalc4l43lv4gwbrz26dugfq", + "Nonce": 88256, + "Value": "122767874298661230", + "GasLimit": 50948856, + "GasFeeCap": "981376304", + "GasPremium": "100962", + "Method": 7, + "Params": "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" + }, + { + "Version": 0, + "To": "f02626", + "From": "f3sqwodtyqnzhf5hohcwlhir6pkheacdqd53bgqyud76fsbwdcplrlmn52wpucllg6x3ajnptap4mafsecq2ra", + "Nonce": 269627, + "Value": "121193649549989127", + "GasLimit": 17754728, + "GasFeeCap": "1408075640", + "GasPremium": "99846", + "Method": 6, + "Params": "igMaAAaOotgqWCkAAYLiA4HoAiChlHv6Q16GsfghrO/Wxd0IrWPxjmmHjKtYaskRiOdmOhoAA7IrgBoAG2hi9AAAAA==" + }, + { + "Version": 0, + "To": "f062619", + "From": "f3ucf2agr73uvr2prinrjfub3unvftrjbafpk34l4x7vwjw2stvos5ygnksfv3bghgllrcgv2sfjsaucsssb3q", + "Nonce": 127086, + "Value": "122754414950240392", + "GasLimit": 72461188, + "GasFeeCap": "966034396", + "GasPremium": "100", + "Method": 7, + "Params": "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" + }, + { + "Version": 0, + "To": "f062619", + "From": "f3ucf2agr73uvr2prinrjfub3unvftrjbafpk34l4x7vwjw2stvos5ygnksfv3bghgllrcgv2sfjsaucsssb3q", + "Nonce": 127087, + "Value": "122756725122938685", + "GasLimit": 54156403, + "GasFeeCap": "1292552609", + "GasPremium": "100", + "Method": 7, + "Params": "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" + }, + { + "Version": 0, + "To": "f062619", + "From": "f3ucf2agr73uvr2prinrjfub3unvftrjbafpk34l4x7vwjw2stvos5ygnksfv3bghgllrcgv2sfjsaucsssb3q", + "Nonce": 127088, + "Value": "121192826880132287", + "GasLimit": 14588478, + "GasFeeCap": "4798307266", + "GasPremium": "100", + "Method": 6, + "Params": "igMZ+SDYKlgpAAGC4gOB6AIgLr+eYX2OJI7V4v8uDUZ8Jre4Zn+5GQhX5Ployqmpn1kaAAOzL4AaABOUkvQAAAA=" + }, + { + "Version": 0, + "To": "f062619", + "From": "f3ucf2agr73uvr2prinrjfub3unvftrjbafpk34l4x7vwjw2stvos5ygnksfv3bghgllrcgv2sfjsaucsssb3q", + "Nonce": 127089, + "Value": "122753783997758719", + "GasLimit": 56768903, + "GasFeeCap": "1233069450", + "GasPremium": "100", + "Method": 7, + "Params": "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" + }, + { + "Version": 0, + "To": "f062619", + "From": "f3ucf2agr73uvr2prinrjfub3unvftrjbafpk34l4x7vwjw2stvos5ygnksfv3bghgllrcgv2sfjsaucsssb3q", + "Nonce": 127090, + "Value": "122753783997758719", + "GasLimit": 59381403, + "GasFeeCap": "1178820244", + "GasPremium": "100", + "Method": 7, + "Params": "ghn3vlkHgJNwLao1B9DXfmWf3sZWmhdAtaWIYHtixmFWJ/hsZ7HmxGIP5iWxGrRkSjy4fmHYaq5Con+Mb3NOTCswxv4SAcTJaiHt5stFhhugboWnZcEw6Ue+oMzKj1jJPcuLenEVkAWAKBntDNign12nJOMFLgffNR6yKwwpQyQZC2lJ6PzApJ547I6E9gXYK0Pq64+gj4T+lrIvaLu0QmCoWtfm6Sti4HpKtFrKy3mGaC01dp2r/JX8u+5jBIwfCdyaGqwNB6+TOUTie2VkFdBPkcI1NBCq1R/1i/BpDMaeu5mkIH6JOieM3T0taCocqHX9B6zzpKazHy61g4lUrmdStS6gCU9wNBxH3DTMRs2ukS5TfBMJJ25+5aDx3jKe3wfgwXpnSRm2wWjoNB0Id/nlQDKzeXo3WyXzIBh1/0H5M3zNp854ZOR7vNM0uwxdvvwgAJKlo4vrNCabQXiD8gIVPl+YobdOmhz+0aofDWcDJ4U3iqg40LLU1JnJtTaCqdQuTe9gy6XzGiqXrIvrpUiCba3S+ueY5O29JjV63TW8ITMGP0sVuTNHFct7qarn4iSFdUBMYq+rxfdFxfaViuGY0w3Pi4rh+1MFE0hbFIpu7+HwNXh7DgEbmHRXCstOq3yNYoM02gmLrw8BI3LJHupvMiGNAGmi9eg4LXHoGnuf7JKoveZWhBow2TKt/6Jn5zFx6iikT6mMtpDeYk6kqGpNXzRDlldhvcCSCJj53Pmvrn3Gn7T7VoUwR3cdHyh5tNFQ9gmKCpVzLwVEhyYrtq9Y4gUCxMe4SZzkR9fRdjNHIM0fmAbkHbPkErowhMGdWPsfo+HqmJPepwamDoW3tCCeKkquNmdG13sMZ9eNj89Gy92zXvG9Wg497mLayzY26sVro2DQ/xfgY2cHZOQilzlTwn0xgK0QUO5520vDLbL0sviPCL11qdJapHDUSPI4M/GWfkiGCI9f9BMY4iyGna3AeF3nPQKsvqxakFWKCR/e2mZiEC/t1tE4sHHWvs2OtKRcyfdboKIXrfO0uV8eJ+aC4M8nj3y1r8wEZqiV6uqi7hDzBrs3pNTOAV2RgEi1KWCNg+mn/7d7kF7+ktH0n550W8/ypat9jA2+0opE3BovEvyYpsvs/hekp6mOZ+ahF+Jfy1E2uAMsmVzEiSEhaRuu0u9qeAewWsgi9bonuCneSF263HRFUpd85zzbP96rcWpbyOh/eK28S9vh+3WyUZ9WZSXivx+xUrnBP3uDmNEN/HMzS+xPKBpDifxI7jUMbhuVMjD5bJWfLK7XdzII+O9sFBasMVJdY5LlHCSk/73gLq5UwQfOrd/weImoU00pvYT+E4xrtrgn6nSouH7JZRlslwdQd/nkBAHNVVCt3U5LUWbhLEZUOTVil/QyvEIvncAuXQOlnBU07tkzkMYiE0ovMkGUBGI7yERyfAhL225nv+ZZp5R03dyGhjuBsLhQR1U+sNrB+KSG1HlPM/bDQ+BjfS5dZkGU45HjKxh0NQT7ulYSej1WplUYqmQ0OHMhv3qv5EaKH5hrTMa+R7KtBARUb7/iOXtHaQiuJZVaHBvY+DIkD3iUDUmBC9r+vDDzrPlYSbMHh4RJVghtAG0D5oJ5xLN1aAGC3nvBtK4u3N1DvLpr0s2t4xFHw7gCwnlnVYnC+/8zHhHqsIMljspAb1ZJS8eYCmFHKIeHvO2eqEyCiQEQPGVwuSAm59jsSwcQeeH5zJMJSKtWyHnYWFuDxS/LIkR9fEb2mwLCfmfkK3AXSmZcNtgFJ6/KZ83fecRCpo/00D//qZnkmOL9qJN3WClnr57RzSJEDovYB9FzEE0vcNNBZOCoRCC8MehLcUj6QqSCu6vk9qXKL5AChsSd1+2afwSQIYHdh1t9/lhOdraLOITPTPsqU6KgIugTI4fNnwXDsYCxbBbc5wgq+oUT6BIwoFrWTHyU2cMcohf1FrpAEGxLVhnqGG5f2LknfspidgmAoraOyKKenm/3aPN6bTIo1mZQXa6Zn6a6UfiZ+s+/5J5sfj7j08IBjtU6qzbG4ovI0PBxuo6PJCtpsULUTpc4AXgb3XM3uRTyQMO8yjY6hLeHn9Tv8n7zspvh5zFeTEt8PZW9OqhYOh0zR6hwrhTBqHEfXI+KHPGTpU0L1BefDYyJCRcgGSplMvzy4xDPMSCIHLe2rggzyFO130L5zNJ/0odCDLTDHAM9xCcoihz8aYiB6tgHjJ4lP807VFOrYEHbblH1koE6TlkmxdNc18YYiK0vYrWHUS01qlixGuOAbGKw1eYTvNdWliTV2WYsyEffulM2eLk4DZvPeW6Rl14MkHPzQJwdicFkoOyePJon2kWcE7FlDCc8yK9BudKXlzjrffmnjq5fn87JqSn9QgT2aqfWXHbTJSFexDcj0jZGAlyOXWx91EhUwBUZMAKYFik//envDAKQSHENmNIp7tv+sXPzETs/Wo2UgL64oUrpHkaFo2RaIafJrfdP9km/sRJM+YSDvau5Q4svJ/ObQMN63WBEwwPjWvEfIvLeJPihvpNNhQNRn+LNWEy8iAfENhGIg3CsQw==" + }, + { + "Version": 0, + "To": "f062619", + "From": "f3ucf2agr73uvr2prinrjfub3unvftrjbafpk34l4x7vwjw2stvos5ygnksfv3bghgllrcgv2sfjsaucsssb3q", + "Nonce": 127091, + "Value": "122754738281267011", + "GasLimit": 61993903, + "GasFeeCap": "1129143296", + "GasPremium": "100", + "Method": 7, + "Params": "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" + }, + { + "Version": 0, + "To": "f062619", + "From": "f3ucf2agr73uvr2prinrjfub3unvftrjbafpk34l4x7vwjw2stvos5ygnksfv3bghgllrcgv2sfjsaucsssb3q", + "Nonce": 127092, + "Value": "122752513875793063", + "GasLimit": 64606403, + "GasFeeCap": "1083483938", + "GasPremium": "100", + "Method": 7, + "Params": "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" + }, + { + "Version": 0, + "To": "f062619", + "From": "f3ucf2agr73uvr2prinrjfub3unvftrjbafpk34l4x7vwjw2stvos5ygnksfv3bghgllrcgv2sfjsaucsssb3q", + "Nonce": 127093, + "Value": "122755128376244721", + "GasLimit": 67218903, + "GasFeeCap": "1041373733", + "GasPremium": "100", + "Method": 7, + "Params": "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" + }, + { + "Version": 0, + "To": "f062619", + "From": "f3ucf2agr73uvr2prinrjfub3unvftrjbafpk34l4x7vwjw2stvos5ygnksfv3bghgllrcgv2sfjsaucsssb3q", + "Nonce": 127094, + "Value": "122755566180601001", + "GasLimit": 69831403, + "GasFeeCap": "1002414343", + "GasPremium": "100", + "Method": 7, + "Params": "ghn4KVkHgJVZqGRPGmVbNkEJuzKZyJNpznSjleR6LrUWAOsHqu7CZxd9mGWWJjQObcQqkPSWFbTBhsKdBX0j2vOZKA+AMmnx5o0e53P4RAoeXAxqCUgPKVKqqn5yTquS8EWzCEf7hxLHOInRcqzhTlwd8lRxXYvbuLWAxrhmpbpAEoHj9Ya9+pqyMntRvd+vSv1Rn/EJm4X5rR8Wc0uJolYYNZKrxiUvby+11jpVcz9nq7ggESEP8QU0iE9wBbsKvKSV7EKNnaPyu8gtmMXEr/4CYM6coCsh5kvtMahp45q8CQcA3q9hU0l06at1mPZvXelfiOjGTq5Z+ClUICxdETWGEBXEqyqu02+WppUt9GUN22wfnTIiYZKWEvQ8DKSU1S8zSpO8NBXLQvVuLcCPVf51B4R1VFeDKKp/qPelhwiH9YoXAHtEsPg1w3Qs/OovyDo6Ts7KqrYvHwYd5K93XPCllLtxhZ26R/bokGLp7IqVG3+idxPzeDmkuSyyjXqpKQIdBUZMcoVVS473hh2cDgtzd6Szll9K6SjnGaalTV2/ORgDkeoayTrjVTK6FJlwReQ5lIeLpaG2UO6RcXFiXhzp5+uOwF9Dgt4Lm4+Rpf6FFPrlM7dbZINif3D928V8cM4BKOV7dQ5UB2egjhrjpDsudH51Dzwz/pwWJfZejocNRg0gDSG6Guflwbenvk1hCSkVbeFESIgPDSiVnyjvsmbmgGojC2YAlhrGRE/7l3f87jrfFsNfkYYcVIwEiusFMRzhFyhlEKzov9bZ6kEarUbKLiz9yjtzewwogBTSCCp38iZ7QmK7aN+bVFG7qWvMcqdR2seiObBpeh4zvh2+0YYUf4ZnqtDJGX1LIQooay4Z7e+jmkSEuoOr6gKt3CePvEDr4h/2uRI98ttF76ETa/3JpgT5nMaQcLBuH95RE47phBtP5K6392F6pOVSJiAGFiiijIe4nZjxXeKPCVidrHPA7repAwixGAg5wgLmM/AkD48cW0liW63DAL8lAQoC3dkCJ62ryYqrtUce7wYzKcXr7nxT1pQteus6VbRnbYHzjlyB8ipvSnj7GjOC3GtEW3ZSPQJHDJWMc2CkEsSyc1IUcjY2sla+mmTNHCi2h1XEdYYnXywG4jKD8k0K/iDqZK0EuBuF3BDs5snATiB8wbHa33vA0cVXlrj13BjBKrJb9FhI7GGdILP0f3AGvMN/2y0khuErGqwflNJgA8HDiQfsDTDDtU/nO5A5y7dzA28qGj+nFjelIHi0f14O7ClBTeYSZRcxeLlbnhhHUWoWhrvn6oXM7DUJl9SFtMje2AMBlugm7FMDA5X8adkkvAnuOdnjWWNW/Zc6MeDq2RvgKjQxezCN7KDvc8f0WxLH51p5zTzfSjZXMOObZAB766ww9RtrGo9odBL1zbV605jwvQfIMASr4fhSnIIb46cwR8VaCvGi8LkFCTYerV+nRvXHkyiBpswP2JhdQzVpsQYc2sYrorSLKu2SJluM79qq88FNESE3RQNCGsT1u3FFzzWTitFTBG4Ru4MLWtRFPQPLWAQjt9KlxUr+ViNsA2fTiJDCep9NpvX+g+r0m2wWphQ6qjCEig9xuJNrB88G/icJqLo9c0NswM0aVSiwkZojhwJIGwZNNqYUm5iCyBBbTdvQUWL8bSz6nwX4vFPUHYIP8me3ST0R7THw6377OcE4HexaSYbRsHNZJ4+AcfsdP5KBELg2H/7wIITi1uQtvjlzvYHzIejdnHatEOGm8Xbau9wXmlqybhENDQFhw8W6tMX8UCte9HZsZLMUpRscRvZ/8K/Ott6O9/pnqU/qLm3N8AEV4iao/GgVidGUukUhqMN2RvJ+AAfPaKBZLCpSQb510KMI9XIqgc2HGjLl8SI65eONZNGgymUtSshR14s8u1+tUacc7L4p5BPhE4ZIVwORyv6dpjvdNINfyBrjGSfr3KqZsvS1Ge8+sTKiUoHpoHXL+AZX9wHxpZI5uX/3b0zMuNMTgMpR5+rU50d1C2tH8u5TL01Wse0wUQbXIpchrUPqKJYtYSd2H7HujEg19yH2GmeiczuRD6Y4YrCHzbvO67+HBcoBLZswPQ1ZA7hkf6jcyiY14cvyx7mzgczMhgtXSI7zpFTnXUDwK3y9k502kfdJZr2zNfn9Vv9ILhQJxvtcfche4ai7fxkBCTM2ewqT71K+j9qEzpo66/IQq5bnXfIyxbHPIJVxU8XT7Cy9CMzbxkAMsyM0KJnEsRkp1cYOrPmt8ZjdXrZRrDXEsnGgJAA4BGVIMoGUpa3o0QinT72J4BYWNFXoX5Nn8LiJIGg30zllx7tHAD7gtkWQaaGt4KEPq3FtII0kXVtpnm45iqgfx5jmiD3QCK1kL/O+6VPprxPIG18ZSe/RYTkVSPQUvS5PDsX5e7z4OucjSJthdp2eTM8iN97V6QRc3ZH0rEwb04jFRdKC1nL2YeF+Ry931nej514PLUQUilJHuWv/issPUdf/NSVZda670kd14hsMafwBO0P7W1WzC6tna0WCOUfL8iG1I6TTqJ6xWZFAJ1tksGygr2H5WA==" + }, + { + "Version": 0, + "To": "f062619", + "From": "f3ucf2agr73uvr2prinrjfub3unvftrjbafpk34l4x7vwjw2stvos5ygnksfv3bghgllrcgv2sfjsaucsssb3q", + "Nonce": 127095, + "Value": "122748613666641373", + "GasLimit": 51503601, + "GasFeeCap": "1359128267", + "GasPremium": "100", + "Method": 7, + "Params": "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" + }, + { + "Version": 0, + "To": "f062619", + "From": "f3ucf2agr73uvr2prinrjfub3unvftrjbafpk34l4x7vwjw2stvos5ygnksfv3bghgllrcgv2sfjsaucsssb3q", + "Nonce": 127096, + "Value": "122755541281474075", + "GasLimit": 54210153, + "GasFeeCap": "1291271028", + "GasPremium": "100", + "Method": 7, + "Params": "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" + }, + { + "Version": 0, + "To": "f062619", + "From": "f3ucf2agr73uvr2prinrjfub3unvftrjbafpk34l4x7vwjw2stvos5ygnksfv3bghgllrcgv2sfjsaucsssb3q", + "Nonce": 127097, + "Value": "122757959054991489", + "GasLimit": 56822653, + "GasFeeCap": "1231903058", + "GasPremium": "100", + "Method": 7, + "Params": "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" + }, + { + "Version": 0, + "To": "f062619", + "From": "f3ucf2agr73uvr2prinrjfub3unvftrjbafpk34l4x7vwjw2stvos5ygnksfv3bghgllrcgv2sfjsaucsssb3q", + "Nonce": 127098, + "Value": "121193038989510198", + "GasLimit": 14923478, + "GasFeeCap": "4690595583", + "GasPremium": "100", + "Method": 6, + "Params": "igMZ+SPYKlgpAAGC4gOB6AIgwT2wh4DbEeT2D3W4y5eSBBN8BkucsOhEHQDymzkbQQ0aAAOzMIAaABOUkvQAAAA=" + }, + { + "Version": 0, + "To": "f062619", + "From": "f3ucf2agr73uvr2prinrjfub3unvftrjbafpk34l4x7vwjw2stvos5ygnksfv3bghgllrcgv2sfjsaucsssb3q", + "Nonce": 127099, + "Value": "122758972752364377", + "GasLimit": 59435153, + "GasFeeCap": "1177754181", + "GasPremium": "100", + "Method": 7, + "Params": "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" + }, + { + "Version": 0, + "To": "f062619", + "From": "f3ucf2agr73uvr2prinrjfub3unvftrjbafpk34l4x7vwjw2stvos5ygnksfv3bghgllrcgv2sfjsaucsssb3q", + "Nonce": 127100, + "Value": "122756359815676352", + "GasLimit": 62047653, + "GasFeeCap": "1128165153", + "GasPremium": "100", + "Method": 7, + "Params": "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" + }, + { + "Version": 0, + "To": "f062619", + "From": "f3ucf2agr73uvr2prinrjfub3unvftrjbafpk34l4x7vwjw2stvos5ygnksfv3bghgllrcgv2sfjsaucsssb3q", + "Nonce": 127101, + "Value": "122758972752364377", + "GasLimit": 64660153, + "GasFeeCap": "1082583271", + "GasPremium": "100", + "Method": 7, + "Params": "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" + }, + { + "Version": 0, + "To": "f062619", + "From": "f3ucf2agr73uvr2prinrjfub3unvftrjbafpk34l4x7vwjw2stvos5ygnksfv3bghgllrcgv2sfjsaucsssb3q", + "Nonce": 127102, + "Value": "122756749910654062", + "GasLimit": 67272653, + "GasFeeCap": "1040541689", + "GasPremium": "100", + "Method": 7, + "Params": "ghn4MFkHgJceloxBAdxxLgV0q8cY3sTwrwMXF3pi0DTitFK+a5VOnN6q8/dWY6GEWHxpieWLS6Pp/wcMY9oBs5qdg5ka5AVtOldlFaP5GrybhIBmVAc0pf0V0MdwKNVP5l8n7IwQ0xKiJ8WV4cQMUoicSexFyKxb/VAJ8lQwlIeulFKTq9QuiIWXR8v0zbtXWjrg+Auf4rPKWGaA2iv302Fs3BAWEMJGo6tzC3vGGjnWE+iBJjG1dwzakJri1j55KD9UM0CoArEZwuqbYO6asKa5eUxajF1sahK4WeNjOJASyE3YDHU5jdTA+U+LZX3RptXiJu5QLYeM0OGFIDda8nOKjzdf0/J5ey8YvrK2yDdOBHYGishRcY6Be99wnrMWIZd1juvbmhBWKN9RbUXius+eJprFjjMRlOAguzScvzIhCB9jnv7BN71fg5bctuONXj+TO68EPanXFbTYY1BMMzcICSF6kjIOeVMYRjFTNxsTgNSmnINclX0OJj2amC+Sl2vmPNbyyZQFYZs2O9Yf2blfqO3qqYpA3NBkTwtyH0xvPbMdV5ISl7Aa5hbbFw7v2cJued9a4Ie/OOunEYiVWoglmWX3PiNac4JuPs2msvMMtg6j6mvl6h0NJSimGbYDidWVvLwkhAZZkLYvxyUqhrWPYKGSEGykrYIn885McPOcT7JMECINedQYhzWYV/jHb3uHZ+vWCoyDB3f4sN0SqM2vkEZxRkeufYadZ5awdIrcowOu5A2Xssn/Gt75of832/9Pk069zYJzPOEd3jtid8V+v6XSpq0FkHJzxR5qJtNabWTU9Jfy8U5Eyxkt2uU6SFGvUdG9FZQVawyxuNGgaxOsDI3wtQfrfkFBJGwyvQW05q/Oe1KQdNPj6pIomJ85KI4mYl+oPxNlEInc5ARXuzBb65CXBnykrBojibnKfAK1TadVjUKrYvHZgabJKg9/9I2JAL5BlobAbuhJGdkTZNrVyVoK79Bhr8kNTd1zvoezKkwm7JN+EBUHNyCuzC3NBgix1LfYmIhLJeVL9OCrw3+i11+4QSAJ48WN4Kf+oOYSWrTQsKPRqTzUBEjxyjA4KhJzPkvNKJdT+EsU1Un3jN+G0LdyNG4h2AAd9v/1YeoHyWesBOItxwqthvyTc4oiWhNYFKoS9BNT/0nPXNl0rY8iEghP3FO/OIggKUS+WC3UNeZTvjdLnFL4zviJR4NoFHjzqaJ3Y7WOmox5kbWVCFy4LWHraBfJMJ1zzOs85RKDlExFuvbcTWMuAVPBlkdbyrv/R+DjIpJqD0ve22glXbJ034Ynu/nRFJYKRdix+t3MLzIDqOYSQgxlYZB0E8KBBdxpsB5Ig7T0U+APJ6Rv9PYpSzDwC++oGDClu6KGODhP6Ap3rqUwRwTHsog/7abqVPGIsy0ZMAa2zQjSkwI7vuJmHLEmm1VRjuklVLrmxYzPkrzupb226zcGFxr6ZavieCltJWvaOoYhoegJXNkRRVgfiBrgYfW//Cu/wc9AViCH5Onf8jt7oM6hFyFR9UVZFepM8ItUFqYumKTNIljygAJSIhnc7OJeAECtjOM1MKvE6tmF0F+S5TYqE+isbJIb3c7S9pb+5Y6RzOAKZWvkaP59qs5olsUTSsNntGHjEZc62nQzQB6YR5txhKlnNNQv+RWcU4po9Q1EUw5MhAH+GnBMKeSsj4QBHFuxq19pcbHCz+l2qIZiW0esKoNBy0QAYH9nAILaJI3tnEWqoOVvz4+j9BwQA4XlxxSCkmqm+2fOmmgsXOHPEtSrzF+X9iIlniVTb/tfd6qQl0ZYoHadEQz/bAXJpv7gi1BexRBNar1ijpj4H2ooerhbuwaGeY2MpOezxwf1ia1DyMnKZ/AmivNrrjTHQoEcKJ9mW7AgUj7L/sNEK1alq9DA8YHIvG/D45JBjRxp2A8O60PQY1sHW585FCXnU007bx4navQ8Uiq0mUrV19t+NYXXTgWwl3t+V1bnsRD27a8JI0azQrxvEXPuuwDGyRrazhdBjK2G1iIKWKJBt9Zl5KsBrMVkkbXK9pkAUxeVZ5ABt1kv0Ve2O+SynANRzrV+nj32xJOb86Bz8VtB2hk3OcnbFVW7WTmUyKK4zRQcXpX8Ut4QdZ2LOV/VGC78MEVF8vYeI3pjFl2fxSQgAXWJTitgyRb80Dcb4xS3a+LokBcziZRHYNC4P/YJUAbxpLsE2x7eJlbv7jK+wkeJh+09+ZuabonHeoAwQBV7lo9Svq2jWFJcW8PIQvwRE9SwEK1SjhGhvFNe/rSCMd+Ao/5OCkAOGiM1mmBfnea9Trdg/LTSsTJp1RezSYZSkSWYtu2VSH3q2P/f6xP9MsOCZxpLOP+it3xqnPNt6CeJXmuYQ4nqGOsBgkJObCoBe2YyZH7a+u/kpfkY1d+Ezxbc66LD1tjjDhyy6CkgCotULNVTeBO8TBFpC0EQoEE7q2jqBbUkLJZ33D/cjtxA1IlfxFxs95lSFZqI41a3xkQrT3Wh8qKuE4To4zPScDa2IUtkaIgLoXjaRyWAY9qvFttE+KiSuD9/e4nufZyRNnZ3wYXCSw==" + }, + { + "Version": 0, + "To": "f062619", + "From": "f3ucf2agr73uvr2prinrjfub3unvftrjbafpk34l4x7vwjw2stvos5ygnksfv3bghgllrcgv2sfjsaucsssb3q", + "Nonce": 127103, + "Value": "122759461256536804", + "GasLimit": 69886403, + "GasFeeCap": "1001625452", + "GasPremium": "100", + "Method": 7, + "Params": "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" + }, + { + "Version": 0, + "To": "f062619", + "From": "f3ucf2agr73uvr2prinrjfub3unvftrjbafpk34l4x7vwjw2stvos5ygnksfv3bghgllrcgv2sfjsaucsssb3q", + "Nonce": 127104, + "Value": "122757766430967115", + "GasLimit": 51558601, + "GasFeeCap": "1357678421", + "GasPremium": "100", + "Method": 7, + "Params": "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" + }, + { + "Version": 0, + "To": "f062619", + "From": "f3ucf2agr73uvr2prinrjfub3unvftrjbafpk34l4x7vwjw2stvos5ygnksfv3bghgllrcgv2sfjsaucsssb3q", + "Nonce": 127105, + "Value": "122753885295610962", + "GasLimit": 54265153, + "GasFeeCap": "1289962270", + "GasPremium": "100", + "Method": 7, + "Params": "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" + }, + { + "Version": 0, + "To": "f062619", + "From": "f3ucf2agr73uvr2prinrjfub3unvftrjbafpk34l4x7vwjw2stvos5ygnksfv3bghgllrcgv2sfjsaucsssb3q", + "Nonce": 127106, + "Value": "121193260185693775", + "GasLimit": 15160978, + "GasFeeCap": "4617116389", + "GasPremium": "100", + "Method": 6, + "Params": "igMZ+WjYKlgpAAGC4gOB6AIg40lmdZj8r3lTQoeRg7WZfYR2HetQrmc6sSard4uY7mkaAAOzToAaABOUkvQAAAA=" + }, + { + "Version": 0, + "To": "f062619", + "From": "f3ucf2agr73uvr2prinrjfub3unvftrjbafpk34l4x7vwjw2stvos5ygnksfv3bghgllrcgv2sfjsaucsssb3q", + "Nonce": 127107, + "Value": "122757299618655422", + "GasLimit": 56877653, + "GasFeeCap": "1230711822", + "GasPremium": "100", + "Method": 7, + "Params": "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" + }, + { + "Version": 0, + "To": "f062619", + "From": "f3ucf2agr73uvr2prinrjfub3unvftrjbafpk34l4x7vwjw2stvos5ygnksfv3bghgllrcgv2sfjsaucsssb3q", + "Nonce": 127108, + "Value": "122757299618655422", + "GasLimit": 59490153, + "GasFeeCap": "1176665321", + "GasPremium": "100", + "Method": 7, + "Params": "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" + }, + { + "Version": 0, + "To": "f062619", + "From": "f3ucf2agr73uvr2prinrjfub3unvftrjbafpk34l4x7vwjw2stvos5ygnksfv3bghgllrcgv2sfjsaucsssb3q", + "Nonce": 127109, + "Value": "121193260185693775", + "GasLimit": 15050978, + "GasFeeCap": "4650860562", + "GasPremium": "100", + "Method": 6, + "Params": "igMZ+RXYKlgpAAGC4gOB6AIgLJtI/DFbSZ8C+/mEbyXFSJeCmpxt1L3ZmlmGRRHdTmEaAAOy+IAaABOUkvQAAAA=" + }, + { + "Version": 0, + "To": "f062619", + "From": "f3ucf2agr73uvr2prinrjfub3unvftrjbafpk34l4x7vwjw2stvos5ygnksfv3bghgllrcgv2sfjsaucsssb3q", + "Nonce": 127110, + "Value": "122760563480110772", + "GasLimit": 62102653, + "GasFeeCap": "1127166016", + "GasPremium": "100", + "Method": 7, + "Params": "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" + }, + { + "Version": 0, + "To": "f062619", + "From": "f3ucf2agr73uvr2prinrjfub3unvftrjbafpk34l4x7vwjw2stvos5ygnksfv3bghgllrcgv2sfjsaucsssb3q", + "Nonce": 127111, + "Value": "122762095018351560", + "GasLimit": 64715153, + "GasFeeCap": "1081663207", + "GasPremium": "100", + "Method": 7, + "Params": "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" + }, + { + "Version": 0, + "To": "f062619", + "From": "f3ucf2agr73uvr2prinrjfub3unvftrjbafpk34l4x7vwjw2stvos5ygnksfv3bghgllrcgv2sfjsaucsssb3q", + "Nonce": 127112, + "Value": "122760994791186490", + "GasLimit": 67327653, + "GasFeeCap": "1039691670", + "GasPremium": "100", + "Method": 7, + "Params": "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" + }, + { + "Version": 0, + "To": "f062619", + "From": "f3ucf2agr73uvr2prinrjfub3unvftrjbafpk34l4x7vwjw2stvos5ygnksfv3bghgllrcgv2sfjsaucsssb3q", + "Nonce": 127113, + "Value": "122759250841580819", + "GasLimit": 69940153, + "GasFeeCap": "1000855688", + "GasPremium": "100", + "Method": 7, + "Params": "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" + }, + { + "Version": 0, + "To": "f062619", + "From": "f3ucf2agr73uvr2prinrjfub3unvftrjbafpk34l4x7vwjw2stvos5ygnksfv3bghgllrcgv2sfjsaucsssb3q", + "Nonce": 127114, + "Value": "122758443760984234", + "GasLimit": 51612351, + "GasFeeCap": "1356264511", + "GasPremium": "100", + "Method": 7, + "Params": "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" + }, + { + "Version": 0, + "To": "f062619", + "From": "f3ucf2agr73uvr2prinrjfub3unvftrjbafpk34l4x7vwjw2stvos5ygnksfv3bghgllrcgv2sfjsaucsssb3q", + "Nonce": 127115, + "Value": "122762095018351560", + "GasLimit": 54318903, + "GasFeeCap": "1288685819", + "GasPremium": "100", + "Method": 7, + "Params": "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" + }, + { + "Version": 0, + "To": "f062619", + "From": "f3ucf2agr73uvr2prinrjfub3unvftrjbafpk34l4x7vwjw2stvos5ygnksfv3bghgllrcgv2sfjsaucsssb3q", + "Nonce": 127116, + "Value": "122758635195443421", + "GasLimit": 56931403, + "GasFeeCap": "1229549884", + "GasPremium": "100", + "Method": 7, + "Params": "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" + }, + { + "Version": 0, + "To": "f062619", + "From": "f3ucf2agr73uvr2prinrjfub3unvftrjbafpk34l4x7vwjw2stvos5ygnksfv3bghgllrcgv2sfjsaucsssb3q", + "Nonce": 127117, + "Value": "122760273970954837", + "GasLimit": 59543903, + "GasFeeCap": "1175603151", + "GasPremium": "100", + "Method": 7, + "Params": "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" + }, + { + "Version": 0, + "To": "f062619", + "From": "f3ucf2agr73uvr2prinrjfub3unvftrjbafpk34l4x7vwjw2stvos5ygnksfv3bghgllrcgv2sfjsaucsssb3q", + "Nonce": 127118, + "Value": "122761937365430127", + "GasLimit": 51612351, + "GasFeeCap": "1356264511", + "GasPremium": "100", + "Method": 7, + "Params": "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" + }, + { + "Version": 0, + "To": "f062619", + "From": "f3ucf2agr73uvr2prinrjfub3unvftrjbafpk34l4x7vwjw2stvos5ygnksfv3bghgllrcgv2sfjsaucsssb3q", + "Nonce": 127119, + "Value": "121193428109079852", + "GasLimit": 14813478, + "GasFeeCap": "4725426398", + "GasPremium": "100", + "Method": 6, + "Params": "igMZ+RbYKlgpAAGC4gOB6AIgTFA8/ERxObGBdX/6k/7iwvfNsfkkGRo5QyXjXdZPbiUaAAOy+IAaABOUkvQAAAA=" + }, + { + "Version": 0, + "To": "f062619", + "From": "f3ucf2agr73uvr2prinrjfub3unvftrjbafpk34l4x7vwjw2stvos5ygnksfv3bghgllrcgv2sfjsaucsssb3q", + "Nonce": 127120, + "Value": "122764152977456832", + "GasLimit": 54318903, + "GasFeeCap": "1288685819", + "GasPremium": "100", + "Method": 7, + "Params": "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" + }, + { + "Version": 0, + "To": "f062619", + "From": "f3ucf2agr73uvr2prinrjfub3unvftrjbafpk34l4x7vwjw2stvos5ygnksfv3bghgllrcgv2sfjsaucsssb3q", + "Nonce": 127121, + "Value": "122759417454006572", + "GasLimit": 56931403, + "GasFeeCap": "1229549884", + "GasPremium": "100", + "Method": 7, + "Params": "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" + }, + { + "Version": 0, + "To": "f062619", + "From": "f3ucf2agr73uvr2prinrjfub3unvftrjbafpk34l4x7vwjw2stvos5ygnksfv3bghgllrcgv2sfjsaucsssb3q", + "Nonce": 127122, + "Value": "122763624317044665", + "GasLimit": 59543903, + "GasFeeCap": "1175603151", + "GasPremium": "100", + "Method": 7, + "Params": "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" + }, + { + "Version": 0, + "To": "f062619", + "From": "f3ucf2agr73uvr2prinrjfub3unvftrjbafpk34l4x7vwjw2stvos5ygnksfv3bghgllrcgv2sfjsaucsssb3q", + "Nonce": 127123, + "Value": "122765282966544619", + "GasLimit": 62102653, + "GasFeeCap": "1127166016", + "GasPremium": "100", + "Method": 7, + "Params": "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" + }, + { + "Version": 0, + "To": "f024066", + "From": "f3qawdlt6il7unbnnby47325tpv24ikuisoiikz47njf3fkiyrqmvmhefbquqwsa65lhowdc2ynoqo6uzj2uxq", + "Nonce": 21320, + "Value": "122768933700265780", + "GasLimit": 50853553, + "GasFeeCap": "1966430939", + "GasPremium": "99940", + "Method": 7, + "Params": "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" + }, + { + "Version": 0, + "To": "f070501", + "From": "f3qc5qsbj4urud7tnd4luszvry2z5w3fwprggynnyxdcyyma3cvw4bv2vk2rduma4kbnkwruotgdisgvgmb23a", + "Nonce": 37022, + "Value": "122768507334115016", + "GasLimit": 50947606, + "GasFeeCap": "981400382", + "GasPremium": "99446", + "Method": 7, + "Params": "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" + }, + { + "Version": 0, + "To": "f056226", + "From": "f3rwocizqhzxr6epnkcndektzfcrhpbzj7z5xaqpihkgrfxwqmwfic42ttar6t7nekinfwqha3soogqa6vagcq", + "Nonce": 26576, + "Value": "121193649549989127", + "GasLimit": 21913176, + "GasFeeCap": "1140866116", + "GasPremium": "99479", + "Method": 6, + "Params": "igMZVQnYKlgpAAGC4gOB6AIg2z9GfUczIzquNDMr3MEoPsGPqenClOKvbQ0VbaJaOEUaAAOxJYAaABthLvQAAAA=" + }, + { + "Version": 0, + "To": "f017193", + "From": "f3ucs3aul2hcx2zufrhp2ltpc4gxzpp2cdees5ti6lqeto7ejppxnjuoj3c7fa4vanhzuqv64kvddkdb3chu6a", + "Nonce": 96652, + "Value": "122677249059697153", + "GasLimit": 51508601, + "GasFeeCap": "970711668", + "GasPremium": "100445", + "Method": 7, + "Params": "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" + }, + { + "Version": 0, + "To": "f015932", + "From": "f3xasu2sehnfhqum767vhcbwilpicjtqe5j62agncdcqufkltbevemclw3g7xpt5bxgfu77zt6wbervysriyka", + "Nonce": 272324, + "Value": "122697968289429455", + "GasLimit": 62699293, + "GasFeeCap": "999999999", + "GasPremium": "1", + "Method": 7, + "Params": "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" + }, + { + "Version": 0, + "To": "f015932", + "From": "f3xasu2sehnfhqum767vhcbwilpicjtqe5j62agncdcqufkltbevemclw3g7xpt5bxgfu77zt6wbervysriyka", + "Nonce": 272325, + "Value": "121179019654112259", + "GasLimit": 19171926, + "GasFeeCap": "999999999", + "GasPremium": "1", + "Method": 6, + "Params": "igMaAAJUhtgqWCkAAYLiA4HoAiA5PPmsGAZnH/YWUiNQ06VdOc/GqpxusoFQwvUGp4lNYxoAA7HzgBoAG2OT9AAAAA==" + }, + { + "Version": 0, + "To": "f015932", + "From": "f3xasu2sehnfhqum767vhcbwilpicjtqe5j62agncdcqufkltbevemclw3g7xpt5bxgfu77zt6wbervysriyka", + "Nonce": 272326, + "Value": "122699817160760096", + "GasLimit": 65314293, + "GasFeeCap": "999999999", + "GasPremium": "1", + "Method": 7, + "Params": "ghoAAlKIWQeApAaEeaNrK5ZjMvDRv982vuEihOLTFRvdl52H15TK8BwHVvWyKmLq9i/4JLTiZSVYtRdMKti5SA3B5UYA88nU++7O/C6J+sK9vdYoPmvtwQ+D48zui9wXX8NpM0GkPJEzCAZWxkBT8ImPHGAD+EO6AZSwTRMVrF7bfN+eY6wV82gmmaoGqu92PpRDKTm4lechtgYrpEpG2VFfItfbQoY39XIy0PZtMN6hp2ZU6a3dN3T4mfrUPK1zMQf0RMDS+xuwld3Q86i7gO+QasJ0XON82wf3HN5lkDV04k7pnnxQ4d/iBqk2xlG1CGGWLrgxLR57twX9GXCo9xy3xVS1NJX4Jr/Erthge1LRB5NC+RqtFhFn7yy5w3LwdQju/LSnSAFFFqJAqZCowfYlByW+8Q5Fzw5/M480YXYlwWAmF4LSa+iMqwaim5et7uDMmNUDxYETgAV4Ia4wLtSuJlgniOHQ8sdIcnzuDqKpGnmCakEB0LPWlVoMOYYbHWKAKP/rwpRIjvUz172ymWz53h9qDlLDn5gesubr4/zOY6vvClXLIBxYlOUOrdgsB9UW2OGEG/lng+z7Pmo/cEUg02yfIIFEhezq1UgCQ8PXn9SqIKECZMMY16fC9CeNXLijkHUmLlQRAPApCRuY+re+KqXn10pGWezuLLXEZLQUjgb+KKYWkJgHQrn1jDlUJ6ZaB6CIwA5jh+2Ds7nS/SrMJMegsT06LSnjZ9Lgws0GQ+T9DnZ6iwSdjRrkPJ07cJoxCdCbrjdzp1x3Ps+dZze8xEBeZCUFgVTSutUFzO6kZaWao5ETPbCLPbgJhhmlr1+xJEiv82qtjEmNoEuyiuNZ9pYy2EJ4rz9ILHSheB8GbXkHHYrFjHFdhtTpAI2T9Hkp8nughc5oDHbanHcD8V9KWGgP4pb65wYQ87WWMkKDGAdfF0cF+CsXALHxX61Q3qkyEWxcjRzujR68NHGHKbM9HRS3jc6dcc3u5IRg/uHCmMdOfVAxnPIuO6qGKxlH35eGFJ7GvP9PhwXas41d6mwplhnhRzlrp1YF7AJQn37mFtGwAAO3Y1GSVV4HEgodLa+gahsehOx+hecxDjnvYfDncxl+dFXfFJLoI0JtH+zfaY10K4GXAWPdosGul/YGZw1wPiyn/5D/FY36eh2Su9tGtuGPwGaWKw15di/EpeH0wMlK2hF5+lrAmx4UXvOjRpwj3uWBlS2qjIxLU6sV7E3LUipka0iZ5p58uJva9hh8Npf8QK95JlPxf7GegmxQ+Ye3cFpAZvY9g7Z8ySGY3dOBROCiWfedDmvx8XYYakctQVAUHIEqy34OqwONJtecwU+DD+GhlQKEt2Mo3MCNNb87I9PgNQIdqm4WT4eBoJ773ZKCREIMj4KbO6UAqbsjPd/t/Z+9XZfuAD0kMwg6qaAnM/pjd6hv5OM9IwVTpOsed/GprzweG6ja/jUlbey63h/TF05uIN22g7oOYoytyEfJF3po2HBGbi4rufJvZ9chxvZo1vVD4Ep6Ik9G2UL6JcO/SIGDzIs2l8dcu6b73nu7S5VSrPW8y6jsmSrDaNd6ay1QYH2v08ZQhjQ+8EpvASC0VgQaZp9ajO1c7GifEmhuyGcLm/9gwjfTQBXR1xacIE/dgaR7ysPDxb14oOEhBKUEoSonL62RAHTXRmWjSGHFiiauAqrQyg/xqqh/70xAXPgSn71lllWSiuAjZw6Wem1+RDBnleKtlRoVYmtjA7G8OhSy6RClq723DAbMAsBaCeLcMP8f4fg+R4c09FBF4cFej8bxeCpvkjGAIIDfjLKtjBcwWwPKldU1l7fA4brUCaYh6ZKb5+42qtToVFKjCu2PE47vNZtei7vKH1Z7weZ0JIpGSJDEbnHYpgT041SIpu7vGvncfreeWGpsYID6A5p+gSfZCuNNDsyC39ew5irvpWE+3jEyCEgQHNageIdGfKa3Ou865g1fXHdLlw5+DawBujNpdek6iwrdrDSIKr2ibTW5GijXeUymshSwGhw38dMALtG/7SuJhAUIkfJRz1wUNR3jVmORkDWUykZJHEtOqaNQvEQ2hZnNB33tQtkIgcG25hRY+q7ATLQ3NBY1Bor6/tR9d3tPjWMwf9PmelcSQKOEszv83KFjPw5ykLBQeqe4BkYUBpaN4h5jmDMvMCHjUSqyGKX6EWoiuUS8Q+9ad6j55itg5qMQYUF3DBF1V5CA9Gny7ELieVgWiSybJ8NBTeeXGy8NtMnJI3CybO9wZxKK8QrIFu1VfhZRM0JsRp4OkXjZ9fdupVWuEKggSLObr8CBqgd9ks8xN3su3nzI1qAAqQhC5BgV/za3K2Jw2wKMm8pUgRemUE7d5R32BmobyOaWrqhjsg4zDjGy9USHOSLt/CWYDV6JaYLUG9QQ4ycsQSZNutxxctynu6r8IPmdWjNA5kHFGYpXlsdNDAoaH1xsClJ57p0EdQ79gPcCpPqlQLypncG4V+h69kK4SazI3Sy467DAlS3tES2cXVNkZz2MTJd+Kz6v59UTbvJVut7wheg1fubp49vzzCPOuarYWUKJ7Xxx" + }, + { + "Version": 0, + "To": "f015932", + "From": "f3xasu2sehnfhqum767vhcbwilpicjtqe5j62agncdcqufkltbevemclw3g7xpt5bxgfu77zt6wbervysriyka", + "Nonce": 272327, + "Value": "122700103126176033", + "GasLimit": 67929293, + "GasFeeCap": "999999999", + "GasPremium": "1", + "Method": 7, + "Params": "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" + }, + { + "Version": 0, + "To": "f015932", + "From": "f3xasu2sehnfhqum767vhcbwilpicjtqe5j62agncdcqufkltbevemclw3g7xpt5bxgfu77zt6wbervysriyka", + "Nonce": 272328, + "Value": "122700380388985778", + "GasLimit": 70544293, + "GasFeeCap": "999999999", + "GasPremium": "1", + "Method": 7, + "Params": "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" + }, + { + "Version": 0, + "To": "f015932", + "From": "f3xasu2sehnfhqum767vhcbwilpicjtqe5j62agncdcqufkltbevemclw3g7xpt5bxgfu77zt6wbervysriyka", + "Nonce": 272329, + "Value": "121179289731961081", + "GasLimit": 19291926, + "GasFeeCap": "999999999", + "GasPremium": "1", + "Method": 6, + "Params": "igMaAAJUc9gqWCkAAYLiA4HoAiAuQu/wkT+evMVRmZx1pK8qXGEnqIDvXtALyNjnildZTBoAA7HsgBoAG2OT9AAAAA==" + }, + { + "Version": 0, + "To": "f015932", + "From": "f3xasu2sehnfhqum767vhcbwilpicjtqe5j62agncdcqufkltbevemclw3g7xpt5bxgfu77zt6wbervysriyka", + "Nonce": 272330, + "Value": "122701560056894480", + "GasLimit": 51728688, + "GasFeeCap": "999999999", + "GasPremium": "1", + "Method": 7, + "Params": "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" + }, + { + "Version": 0, + "To": "f015932", + "From": "f3xasu2sehnfhqum767vhcbwilpicjtqe5j62agncdcqufkltbevemclw3g7xpt5bxgfu77zt6wbervysriyka", + "Nonce": 272331, + "Value": "121179562045129755", + "GasLimit": 19175676, + "GasFeeCap": "999999999", + "GasPremium": "1", + "Method": 6, + "Params": "igMaAAJUydgqWCkAAYLiA4HoAiAo98lqNTfHYaNJnh3JuDVc9Z9bvWbRWmrd8UhOi4//GxoAA7IMgBoAG2OT9AAAAA==" + }, + { + "Version": 0, + "To": "f015932", + "From": "f3xasu2sehnfhqum767vhcbwilpicjtqe5j62agncdcqufkltbevemclw3g7xpt5bxgfu77zt6wbervysriyka", + "Nonce": 272332, + "Value": "121179562045129755", + "GasLimit": 19299426, + "GasFeeCap": "999999999", + "GasPremium": "1", + "Method": 6, + "Params": "igMaAAJUuNgqWCkAAYLiA4HoAiD3Ej24dGzjoSOGzTaMw5TuN4nZKkd3YIN+j6Y3S+M7TRoAA7IGgBoAG2OT9AAAAA==" + }, + { + "Version": 0, + "To": "f015932", + "From": "f3xasu2sehnfhqum767vhcbwilpicjtqe5j62agncdcqufkltbevemclw3g7xpt5bxgfu77zt6wbervysriyka", + "Nonce": 272333, + "Value": "121179562045129755", + "GasLimit": 19521926, + "GasFeeCap": "999999999", + "GasPremium": "1", + "Method": 6, + "Params": "igMaAAJUv9gqWCkAAYLiA4HoAiCqR0zwtfzuzjn7Y37jA8F746aOBluoa68rczWV+81mShoAA7IIgBoAG2OT9AAAAA==" + }, + { + "Version": 0, + "To": "f015932", + "From": "f3xasu2sehnfhqum767vhcbwilpicjtqe5j62agncdcqufkltbevemclw3g7xpt5bxgfu77zt6wbervysriyka", + "Nonce": 272334, + "Value": "121179836579518752", + "GasLimit": 19636926, + "GasFeeCap": "999999999", + "GasPremium": "1", + "Method": 6, + "Params": "igMaAAJUttgqWCkAAYLiA4HoAiCmva6TvefhQS4A5CRwiz3RCY5+Hwzc/jRML7zlYdq8TxoAA7IFgBoAG2OT9AAAAA==" + }, + { + "Version": 0, + "To": "f015932", + "From": "f3xasu2sehnfhqum767vhcbwilpicjtqe5j62agncdcqufkltbevemclw3g7xpt5bxgfu77zt6wbervysriyka", + "Nonce": 272335, + "Value": "121179836579518752", + "GasLimit": 19638176, + "GasFeeCap": "999999999", + "GasPremium": "1", + "Method": 6, + "Params": "igMaAAJUpdgqWCkAAYLiA4HoAiCQkpinbBlJYEEgyRjQoDs26LyV6bjO9WZsvfjPtMyASRoAA7H/gBoAG2OT9AAAAA==" + }, + { + "Version": 0, + "To": "f015932", + "From": "f3xasu2sehnfhqum767vhcbwilpicjtqe5j62agncdcqufkltbevemclw3g7xpt5bxgfu77zt6wbervysriyka", + "Nonce": 272336, + "Value": "122703763715088896", + "GasLimit": 54531793, + "GasFeeCap": "999999999", + "GasPremium": "1", + "Method": 7, + "Params": "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" + }, + { + "Version": 0, + "To": "f015932", + "From": "f3xasu2sehnfhqum767vhcbwilpicjtqe5j62agncdcqufkltbevemclw3g7xpt5bxgfu77zt6wbervysriyka", + "Nonce": 272337, + "Value": "122703481204289764", + "GasLimit": 57146793, + "GasFeeCap": "999999999", + "GasPremium": "1", + "Method": 7, + "Params": "ghoAAlLGWQeAuQqmNwNd4HnPVSWSbC1R2lQ63AcBEJaG/kTIBVfppO1iYy9R4/XWlGuiGyGtloBtpwh18C4r7swCpKZutdq7iK3sdGvbGSQ+2wzBfYZaFjXkFJHULXaUkRh2iR9uy045Dv5BbhHrjhIKZASRJs2sEuvk72hk7fS6nD7ey4pB/lKnFaoWIWlTV2OCttp4Ffa/q1w2JPjhhI0MqD5OVaSCT+A6Z4PpzcZpr7+UZVxeHhdx5QYJ0fngGn2i02IfFevYkpcwRhzooG7qg0ldDf7TvXOILPL1BxrAUS0qnTaek7goksoZLGTeHvLxrLAqFOuij8GJ6gVYU7XLd83GSmyhWbVOle7xRDmfpTbyXY/3l01ii3jKDgA+RWCCiPIrAOavDsFgJPJFr/98VU5AHA5W4dlC7tSJdzB3IoKxrz2+WeIvyKPQ4nU717qzqCjnmluhlXpkX45t8xA4M3A5q0Uf4UOYd9+ACsD6AHVyI0Ulc8iB9ZI01dTD0WXApu8e8fKxqQw4stUviwxLC6VqL5kAn75+SXOWQl7WfE2xDbW+YkrOfcSSl/HIkxf1T/eZI9kgrN6tpSYLRrHsEzqGPZzu7c42MTW1EEC8CizgduBPWTxNhPO0kzaB0eMF6B5KI8o2B3v4LynNCMfLv6Wx34GeYcMjUZewDqzjP33i/zjbJdJ4blGQPKE86Y+MAQtQ8FhvrQam8iefDSCVG7bPs6FXRQCD7ub8R2HAVOtTWt+i7SSRODgls0IIRKL5w6guMz0fiVT8HgIoiN3SbiTe66TZNVVZa7ceo6GlWp8AW2UFS5KBwhS9b7ruuKGqqV+deIvGpfqWyfx+QgtrV47zlfavJ8Lqc5M0toLz13Z8gMME/X66S0zhYqZMAyyuYiFpgurDCKEKv8n+qk+r4iEaA08OY5w4D9BSP1inWbHTEN8a7XqTj8MS4qqTZ3iO8i89b7/Qh7XmKP5F6vog/mfwtlq2msdTbwFJszvx62LKhfVbouVl7KcNnxvsC4JUjycl2uDEqwHn2yVf1MlRgTGvVQNmssHL+dxjzFGPL2W4LbbPZfaOnAGnhxQy4WG5QyH1rlAesimM1Ma5m54Kkm5+2iy+uBvo8zBIVO/37MHP86O3jAsXoTKp2cVE6s1DriSU0D8iDexol3UZKNr6fnKZMLcJ/yYIhrO4539ddL820iYXwZ4Twwaf74xNWN0CV8aUPFlOkuZyMc9vNdy1H4pCFTbR7eqTrtHJZrZJTU60yws+XjnRXnE1jmOxhY4xQ4shoJa3jPGfiMRq6bFDrl04Az698vbGja4WKmHjCCL7KKuyGNB3Fe33/v0xV1q84GVkvOGPmTsaG5d95iLIgBzWZprySPdQTjhLQxvU1PgAB1o/lY4m5+e3EvdIF+nUroA+8WlCGVLH9/RiQIt+mCaueC5NOql5rBVQ2cYiP7alIOVqVUUIaVEtf1B/kFY/JxNMfJZRo/A805DoX40f2ox2gu864Ugtt0FhHfoXr6ItfPh3+yb9vgHMnt30d9RCc5I/YxfKhcg2530mRp9wSph49RFlSzuQKzdVfibjIOlxuzj0xvfVfGWurqD145SAfCtO0H97k1UcR4ISpZb2THqHlzuTj2ugf0XzZBxbmWEh5K6cVGknsFyZ9KACzySjIxxUp8MOFvy2PlUdTl9tAf3+vSkwvfw4dWtYxn4dKoQn8PYtR9ls4dPfXykRci5iiqUg25pfpQa+2u43vqEp6bzU2rpNv2ZaSv2CWq0xpViGiXfxA8Kt3L5/2rWamsVpqOhMwubNqxRcmmqe5lAfv/Y3CL9k2Hys0BPxdccuIGQ4ZgKdi1pyd5seotblSX7XLPY9ugZVgMgcUjb6lIVTu6hXzCN0BkQPOP9apoCLGSj3mruTHaEMTE7CGJzwcGlaswZcMnfFEJxsI775iNUCYO3dn8oprdKSX+8kb+byyAM0Aw4wfi+0oeUAE25ZVChs+5tB3D+KgefBVzB5wEvZfal2/XjU5lPO5euRmximAbNpIbzW48JmtK86cErrTfuN/vkfjATetyk0uJFaqAn/CuVpvkVcxbS156aqVsk948PM1mg3GhS2DC2mZhF/0Ke36PknOGdvp2q8e3ee4AEAA9j0UKPIZ0nk2lN/i7lJL/0jIIBzQOAQQz+EGdddN1IzXyHed/1KGRQqMRCEERI1Yb/H4ZgeUgzbr9+tfdEJIfbqJktOgxeNfheTkuosLAnPsNrwKNFIraYMq7/jR2fHoryfbFY9Ja4KBDt0APeGfiBsw+Htmj9mTB9YIMfqfvGKhOJkH4Hhgg8qTfqhhdFwAZYgEHbDzh/2gjWztu9saW9NuUvzgS6eYf9yY40+c8Nro2UrtFSTq4miE2wRH0AEkbLwayXHtNskoSDvmhJiUH7qMcWwLMJhAV51k+tO1212KkY0ikNsB2WcVoSIY4lur5BkyXV9/Zvj43L4rxmjFSPU52ra/fYtdrgHpfwl2v/A7v30tE48i6boeVL4ZeHjBPTCi/1jSp3UpFyizci7J9DM/fCYfuQ6k1SpYRVsYcAoBtRCkUSE" + }, + { + "Version": 0, + "To": "f015932", + "From": "f3xasu2sehnfhqum767vhcbwilpicjtqe5j62agncdcqufkltbevemclw3g7xpt5bxgfu77zt6wbervysriyka", + "Nonce": 272338, + "Value": "121180081954957656", + "GasLimit": 19188176, + "GasFeeCap": "999999999", + "GasPremium": "1", + "Method": 6, + "Params": "igMaAAJU1tgqWCkAAYLiA4HoAiANpmpGjhAvJIES5NP3SiQMfi01pSH+0sx2va3DtoOBahoAA7IRgBoAG2OT9AAAAA==" + }, + { + "Version": 0, + "To": "f015932", + "From": "f3xasu2sehnfhqum767vhcbwilpicjtqe5j62agncdcqufkltbevemclw3g7xpt5bxgfu77zt6wbervysriyka", + "Nonce": 272339, + "Value": "122704596871133811", + "GasLimit": 59761793, + "GasFeeCap": "999999999", + "GasPremium": "1", + "Method": 7, + "Params": "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" + } + ], + "SecpkMessages": [ + { + "Message": { + "Version": 0, + "To": "f029223", + "From": "f13sb4pa34qzf35txnan4fqjfkwwqgldz6ekh5trq", + "Nonce": 246187, + "Value": "0", + "GasLimit": 3840470, + "GasFeeCap": "11900926092", + "GasPremium": "100704", + "Method": 2, + "Params": "hFUBLtmWFhIkU5XtOOjxXacrWwHtZWRJAAdRfXdOxHXaAEA=" + }, + "Signature": { + "Type": 1, + "Data": "m6eCh1ymdv2ehwuV+zDXBuKTUnd0eSPHwMy+Y2knvitQhqdfhKNs1Bg4dbBT/4dQR4Pc7vDEAWiA/mVnJOannAE=" + } + }, + { + "Message": { + "Version": 0, + "To": "f026582", + "From": "f13sb4pa34qzf35txnan4fqjfkwwqgldz6ekh5trq", + "Nonce": 246188, + "Value": "0", + "GasLimit": 3840470, + "GasFeeCap": "11900926092", + "GasPremium": "99962", + "Method": 2, + "Params": "hFUBynEq90h80yKxW9Tubwzzx8NvF3tJAAdMPDYMkcm+AEA=" + }, + "Signature": { + "Type": 1, + "Data": "IQxkwxRDeX6jkkT2RMH0kPZwN/46vuEUiEbtcl+AFkJCbY6wfuMsKN0qedrH9nRUs+/Pl6TTK27bNH5xNzqOlQE=" + } + }, + { + "Message": { + "Version": 0, + "To": "f029084", + "From": "f13sb4pa34qzf35txnan4fqjfkwwqgldz6ekh5trq", + "Nonce": 246189, + "Value": "0", + "GasLimit": 3840470, + "GasFeeCap": "11900926092", + "GasPremium": "99599", + "Method": 2, + "Params": "hFUBih37uGsnRLnKXmOKlhXypygZ9opJAB0OWFIh5RFQAEA=" + }, + "Signature": { + "Type": 1, + "Data": "Qgf+s9aj4b97XlAWfjhPUeba1+ZoBvD/LWW2QDpyECwQUAikS80a/us7VNG86P65jACZP9KLX7H9giQ2yuvjNAA=" + } + }, + { + "Message": { + "Version": 0, + "To": "f026721", + "From": "f13sb4pa34qzf35txnan4fqjfkwwqgldz6ekh5trq", + "Nonce": 246190, + "Value": "0", + "GasLimit": 3840470, + "GasFeeCap": "11900926092", + "GasPremium": "99978", + "Method": 2, + "Params": "hFUBXvqhyAN7TNVuiBiZLx2PRsBfimpJAAfcRapI7AYhAEA=" + }, + "Signature": { + "Type": 1, + "Data": "5YOCgCuTp07qn0AQNfPy3yLLNkZSyJxn8k91hH4dsVcjrVqTYTzHqQ1lGexdiRQeWah/SepnG1NYG5/z2SixyAE=" + } + }, + { + "Message": { + "Version": 0, + "To": "f027694", + "From": "f13sb4pa34qzf35txnan4fqjfkwwqgldz6ekh5trq", + "Nonce": 246191, + "Value": "0", + "GasLimit": 3840470, + "GasFeeCap": "11900926092", + "GasPremium": "99711", + "Method": 2, + "Params": "hFUBLQW46WxDslg+GgyxcyEQPNN0bIZJABbSFKUrvGdLAEA=" + }, + "Signature": { + "Type": 1, + "Data": "OEYhFJaCmcgu6GoNtLsIAys+7VceJ+iaAuQTkaJbQ6or89UkkL2427VXD73FeVkOm4XNsK9sEUfQt3S8kPO3DwE=" + } + }, + { + "Message": { + "Version": 0, + "To": "f028389", + "From": "f13sb4pa34qzf35txnan4fqjfkwwqgldz6ekh5trq", + "Nonce": 246192, + "Value": "0", + "GasLimit": 3840470, + "GasFeeCap": "11900926092", + "GasPremium": "99877", + "Method": 2, + "Params": "hFUBLjcdJrKnodTsGj0qonu3XvbsvENJAAj/F1BB4Aq4AEA=" + }, + "Signature": { + "Type": 1, + "Data": "FOcosAmC1nJ+Qn9krm6Uot30nw5ALS7ZGqAulfvYFmNtjX3iZ0HcXLk1gUR1yyQJVYRRpeq76YsG+rrB27Q2ngA=" + } + }, + { + "Message": { + "Version": 0, + "To": "f027138", + "From": "f13sb4pa34qzf35txnan4fqjfkwwqgldz6ekh5trq", + "Nonce": 246193, + "Value": "0", + "GasLimit": 3840470, + "GasFeeCap": "11900926092", + "GasPremium": "100406", + "Method": 2, + "Params": "hFUBhgN0Wxa9q+LW4UFQEcbjl248l7ZJAJZTyBrklEHcAEA=" + }, + "Signature": { + "Type": 1, + "Data": "P21qnhfEwCCzjVHuuWWSzO7GiNmK423dCnPtHGK+haFrLZu9L0vXxiY3ppG9oylIB2IuwpEpviKjy8ai/Z+kdQA=" + } + }, + { + "Message": { + "Version": 0, + "To": "f028945", + "From": "f13sb4pa34qzf35txnan4fqjfkwwqgldz6ekh5trq", + "Nonce": 246194, + "Value": "0", + "GasLimit": 3840470, + "GasFeeCap": "11900926092", + "GasPremium": "99748", + "Method": 2, + "Params": "hFUBv9wkfoRlwdm6CSvanJdttMdDJgJJAIFCVfZA3U/6AEA=" + }, + "Signature": { + "Type": 1, + "Data": "eQj4kaH9EKIMYqjn0BHDI5e15dOFGOHKAn+l84D+SG9oG9TWnz+rfrlm0wjdzDkpKTGY3l5Uy7eGltxp+VkD/gA=" + } + }, + { + "Message": { + "Version": 0, + "To": "f028250", + "From": "f13sb4pa34qzf35txnan4fqjfkwwqgldz6ekh5trq", + "Nonce": 246195, + "Value": "0", + "GasLimit": 3840470, + "GasFeeCap": "11900926092", + "GasPremium": "99927", + "Method": 2, + "Params": "hFUB9qfa8HjGsD8K7busaPt4JNQnSyRJACBvHV/8A1nRAEA=" + }, + "Signature": { + "Type": 1, + "Data": "fTEdh5ackzxnUR3ZNViB+PmiWD+Za37euqGfUBSBLpA9KI56rnOzu1c9ZwofeuF4BGX4dbmOxnrsn2IM9EVLDwE=" + } + }, + { + "Message": { + "Version": 0, + "To": "f027555", + "From": "f13sb4pa34qzf35txnan4fqjfkwwqgldz6ekh5trq", + "Nonce": 246196, + "Value": "0", + "GasLimit": 3840470, + "GasFeeCap": "11900926092", + "GasPremium": "100456", + "Method": 2, + "Params": "hFUBzsrFoSc06Wu1VTKgOdwbOReVD/BJACsBhOvuk32oAEA=" + }, + "Signature": { + "Type": 1, + "Data": "i3zDn1vx1OzOmyrhV4TiZel9hUzUwxzx8OolPZJZq+8MxYCYX0HqPvRGFgFxszMUeS8ytpsLEwmyXY6BXjCKHgE=" + } + }, + { + "Message": { + "Version": 0, + "To": "f026860", + "From": "f13sb4pa34qzf35txnan4fqjfkwwqgldz6ekh5trq", + "Nonce": 246197, + "Value": "0", + "GasLimit": 3840470, + "GasFeeCap": "11900926092", + "GasPremium": "100102", + "Method": 2, + "Params": "hFUBTN6KgwVxwWnnzO1GnDpzO6guRoFJAAjjV+nw5+p2AEA=" + }, + "Signature": { + "Type": 1, + "Data": "+4b63o71fJgvUFnp7mWEl+StLOZeQkf8AkW11GCHM1A61BDHZBSgUBrfJ8iH3CrKsGIZpLuABu4Im5Z8tFkAfQA=" + } + }, + { + "Message": { + "Version": 0, + "To": "f028806", + "From": "f13sb4pa34qzf35txnan4fqjfkwwqgldz6ekh5trq", + "Nonce": 246198, + "Value": "0", + "GasLimit": 3840470, + "GasFeeCap": "11900926092", + "GasPremium": "150074", + "Method": 2, + "Params": "hFUBLE6eTeuaj48AaE86g+38LlL2GOZKAA2cN78jOR5zpwBA" + }, + "Signature": { + "Type": 1, + "Data": "FmJoKqvYQoktwMLtAwS89kormqUpeDjxfH2SvR1h/wUquxAGtocrMLWsMsiDalYv5BWTu6xQSWw3BzivttcHIgA=" + } + }, + { + "Message": { + "Version": 0, + "To": "f026999", + "From": "f13sb4pa34qzf35txnan4fqjfkwwqgldz6ekh5trq", + "Nonce": 246199, + "Value": "0", + "GasLimit": 3840470, + "GasFeeCap": "11900926092", + "GasPremium": "150175", + "Method": 2, + "Params": "hFUBvKZ3FI5LTDX1bnqs8YNH8fqpQC5JADDHb7tfhQKWAEA=" + }, + "Signature": { + "Type": 1, + "Data": "1GeBXwCaQsK4cYGIjUzkk916iwhKtTyAmIr8dbXd30UVkUwFMfs7gP3IVvuzcKOA7Uj658/q/jykdkNuvGfLAwE=" + } + }, + { + "Message": { + "Version": 0, + "To": "f028528", + "From": "f13sb4pa34qzf35txnan4fqjfkwwqgldz6ekh5trq", + "Nonce": 246200, + "Value": "0", + "GasLimit": 3840470, + "GasFeeCap": "11900926092", + "GasPremium": "150023", + "Method": 2, + "Params": "hFUB279Cpr+lLh/H/715+vGUs7UggU5JAJ3uv0liocsOAEA=" + }, + "Signature": { + "Type": 1, + "Data": "N65ZqKj5ZEdUz9XxH5QU/OofOcXWMTOlghOs4BCjODYyAf91STzviuGZE2YZ+qB5LbhjwipfzhiGQ/BUPa9LRgE=" + } + }, + { + "Message": { + "Version": 0, + "To": "f028667", + "From": "f13sb4pa34qzf35txnan4fqjfkwwqgldz6ekh5trq", + "Nonce": 246201, + "Value": "0", + "GasLimit": 3840470, + "GasFeeCap": "11900926092", + "GasPremium": "149402", + "Method": 2, + "Params": "hFUBpQSlxMbaZk6y+U10yxl4PCRLSOZJABR+0cU4cw3BAEA=" + }, + "Signature": { + "Type": 1, + "Data": "GDRFkkeDCxFyr0zXzRo/ktG7yYRZLff86H3c0PjBeng1xfipXRKfc1GvudlgdeSn6oQlYkdrZ6AXFSypOlLu8wA=" + } + }, + { + "Message": { + "Version": 0, + "To": "f2mgv6khl6s6oukeyi3nm3ja67s7fl3cecy2stvny", + "From": "f1i5kvaeurfv27jncddyvcuzgegm4j46y5u7okcza", + "Nonce": 2, + "Value": "0", + "GasLimit": 2221245, + "GasFeeCap": "3151385821", + "GasPremium": "100251", + "Method": 2, + "Params": "hFUBWOH9mBZi9VpvZ//EniBh/RK4GdFKAHp17DNOF2wAAABA" + }, + "Signature": { + "Type": 1, + "Data": "854MORzeNgax2hri62cDbwi+AW74Ij7HIbDA72mLySZAjSxpaN8DJNJGNNfnnLE+JCdGwWmWuKutOt0cUKv3HQA=" + } + } + ], + "Cids": [ + { + "/": "bafy2bzacedfv6z3dbz3y7l747wtm6v4sjih7yksw2bto4e5fmxwxytqf4t2cg" + }, + { + "/": "bafy2bzacea6v4gwltmtugdvwreujmnmf3k3igia5h7ytsfvyq5yik3jhbgznw" + }, + { + "/": "bafy2bzacec6ug37mcecfch4idqeaypbbskuqzckrfwhfrttkdxhdkihqhczli" + }, + { + "/": "bafy2bzacebnfxdc5vynxvpkqkgyilkdgad4wae3l42sl57tvj4jqqwei3zsrq" + }, + { + "/": "bafy2bzaceaofo6byvss2v257wsbpdct6pxzxjgi5ht6uo2nqdqzhcgmnnuwym" + }, + { + "/": "bafy2bzacec6wg7jjfxmabxklzs4gpwg62dqvg57spi4eqobndej6yxr6agili" + }, + { + "/": "bafy2bzaceb6mtzdviiicoumekvsl3kadtd3yyvnjilrpb2e4hvwchigxo2glk" + }, + { + "/": "bafy2bzacebp2wypw6vb3ghpp6bbcwttz4nifq2mkqe7rv3fw3ixuo5fwlbs7m" + }, + { + "/": "bafy2bzacec5qmbiufrhfsqkuwp4qlrhh4pza6c7to4m25prg2rvtlukutxumg" + }, + { + "/": "bafy2bzaceaccblunht2awecxt4gaarl2wbwspgvqqojnogpdgcfbqqc5n6svy" + }, + { + "/": "bafy2bzaceakpqtg7krgtnohzdbce5eswhfthq33qnniqq3snideletfn37m24" + }, + { + "/": "bafy2bzaceag5f455wukvnau2hymrlzh2rml5uz4fegeakagrbun22knbosu4s" + }, + { + "/": "bafy2bzacec746nf7ekbavo5secupvrzfk2q7ifqa3fx7nk2it6avsqeneejvi" + }, + { + "/": "bafy2bzaceaww2tmafgu7ia2w6tdjjlmln4c2s47qvzi3l6l6th6y5qtzwh2ps" + }, + { + "/": "bafy2bzacec6wa2kuywzasa7iz77u72v5xw6mfqowniv2ya2i72ncfs6vbjry6" + }, + { + "/": "bafy2bzacedlomnr45f4u6anm52iuv5lx67iqzryl6ggre22zhds5ga7wxwjl2" + }, + { + "/": "bafy2bzacedbde5bqyv4ayw4lafwnhqoz3z65ry6mzc5v7injaa5aelmmqhfb2" + }, + { + "/": "bafy2bzacecze7cp3p44ahuec7ma7givzblrvw7apbodvrfrowxct4372qlotu" + }, + { + "/": "bafy2bzacedh25tm65ivdko7oaz3jexjfyqpfyka2dq2r2quj4pgesjvq5ulbc" + }, + { + "/": "bafy2bzacecbk5holugw25qsxyt5doqlkts5zbzorhbad2wqojg4wp5ufiz5ta" + }, + { + "/": "bafy2bzacecmp5axn5rdx7bdnziwrechwfje4visnvyhs3y6zzhiuyn4lahvy4" + }, + { + "/": "bafy2bzacecgbdau27zy2n7xfyulbtibwjbtgmifxgd5hzvhuaq7i4pa43rsbk" + }, + { + "/": "bafy2bzaceb2w22i4x6y6j6p2mwrlcf4rpujpgzmiabkbai27vvws6p44tf7yi" + }, + { + "/": "bafy2bzacedmhgz55fv3xynuiknbmzu73b4ygfhqzdjvpqqd3clhqagifat5wq" + }, + { + "/": "bafy2bzacebzgoioyaxifebx63juczjmxd2nczwvy23ox32aflgu4saudqfihm" + }, + { + "/": "bafy2bzaceap76ommz77b2deqgn6ptphcnrjf2wmdpj46yexw3gg7l5xwazq4c" + }, + { + "/": "bafy2bzaceat3x7txyon6kxhc2beyvm6qr4pst2lswog6oanr7q4h76mviwsz4" + }, + { + "/": "bafy2bzaceag23ennnhcruxlevz5lq2cjx2obs4v4ps7zljemnargjwwzfj5ew" + }, + { + "/": "bafy2bzaceaaj2ycdfrtr7su42ax7vmbi3duklia3ddkai74ao4r433tvm7s5o" + }, + { + "/": "bafy2bzaceaqfnlwsypu73cmdi57i3542lx6onaciqux25vgi7yy4cxuroqohs" + }, + { + "/": "bafy2bzaceb4av53xh7cneavhg7cepo6f323lorgyn5f3w36fy46gs5ijcradg" + }, + { + "/": "bafy2bzacedpzkh7o3sg77c6shvf4vzjzrc4ka7uaq2dhlnefl27kwsxgck54o" + }, + { + "/": "bafy2bzacebnwzfm45ja7czdxsgldimsanju3sotyfth4so5aklg4bqjs5nwsc" + }, + { + "/": "bafy2bzacebgfg7mutvfivcqxwhki7lzygjv26yi4haxgngzejswjtishmtxps" + }, + { + "/": "bafy2bzaceangs6rq7iyy23vlsgn5vvwwx4pc7l73eelne7zpanun5dqy3xbeo" + }, + { + "/": "bafy2bzacea374omrotklarane74qvrydqonmtisskjfrd7braioditlb63hry" + }, + { + "/": "bafy2bzaceddofj57vkpjlqsk6s3t2atbblujq4fpvj657h4s5yvs7ieumkds4" + }, + { + "/": "bafy2bzaceaevdhwukiimdidv7xb2pdsikeelhg5jaayfquedcz7aprhhpql76" + }, + { + "/": "bafy2bzaceb7f5owlaekmrk7nhjac4z5mqqjgkiskh3yz5ueclopw3fu6bld7u" + }, + { + "/": "bafy2bzacebca7qjuntdymntls55dj3bsjnqfwvhz242phafrfyg42ze663kdy" + }, + { + "/": "bafy2bzacealpttnpjqnabrgo434ebuxjzwoitzdnkd7e7kpz2oymupzrkj2nm" + }, + { + "/": "bafy2bzacecrtb64vj3oxeuq3gvuvulmwsndfsyxw2d4cqa7cas5srnw6fkkjo" + }, + { + "/": "bafy2bzaceb6kvwm2b7eafk3srx47r3nju4wi6gjiqphn7toec24jb6wthzjrm" + }, + { + "/": "bafy2bzacedfmde6stug4hsjhnmqbjfqaxoo5htj7z7dhlgx6dm4egez2ubvsa" + }, + { + "/": "bafy2bzacebi5rr4i7oc6wbsd7ccelr25zhv22epawfiwrktu5yj5sr3kocd3k" + }, + { + "/": "bafy2bzacea7zwmpow4wj3yoyn6blub72zatryg2kpxsogqfdtrn74detisd2o" + }, + { + "/": "bafy2bzaced5pglehbf2f63cpdqhq7uw3nqjqipisvamzv4vj7o7uezxlcsjmg" + }, + { + "/": "bafy2bzaceaaeqln7mu5se43l4eg3ojozgnxpymddvduufxvexasesy6ra6v5e" + }, + { + "/": "bafy2bzaceagpksixm5j7yzk4nq7rnxy6zl2orhnfwyrkuvj6optrlxdrvkqa6" + }, + { + "/": "bafy2bzaceaqorfq4oa5e66ssw4oyryglxcpy6bvpq3dee56uaie2vs7rpoypi" + }, + { + "/": "bafy2bzaceaui57wgpuj5e3pkqfque5hrssrm7i7pnnhqteahia6nvwb2ekfis" + }, + { + "/": "bafy2bzacea2yapvdbqztp64iet3dtrkw4yke5qtjj3an4jirb3cy4ngzm6yce" + }, + { + "/": "bafy2bzacedqdcymquiwv2dex3us7mn44bgxatvxc52ouvno5vfdyttkv3cxr6" + }, + { + "/": "bafy2bzacednf746l62lowyxzzc6hdwo6qnqu6y3l5hwc3wtt3a5nat5j3thy2" + }, + { + "/": "bafy2bzaceb6qhy7gg3mkoouc6hxgj37hzmymxnq64cvzhnkj2kojyrkwvz6yi" + }, + { + "/": "bafy2bzaceae76z7ls5wc377ymh2geu36pmnx4pa44nkbxnf76csd7mrohieua" + }, + { + "/": "bafy2bzacealqllipxfdedv3vp7fhaiz5excj24palkoqj36jigzstdkmazjls" + }, + { + "/": "bafy2bzacedrz3pi3fehjnofeo5evwngtkqbvzev2erpzzuazdduzkgv67fsli" + }, + { + "/": "bafy2bzaceahe4jfesujxtlfahmo4l77wz77sk5i2vyfrpr4zy7ml3fokybg34" + }, + { + "/": "bafy2bzacebkep72hujq3xt4t5jycmvslgb3tfs4jbltl2ol73qlxd5wauygsm" + }, + { + "/": "bafy2bzaceac3vzbrjsdtzq4mcblggv4avc52erbw3nj4dwgrcdqbs3pffzftk" + }, + { + "/": "bafy2bzaceaprxoe5wgdswiqramvrit2ozn5pkrqvotxuww6xvskwky5jpceds" + }, + { + "/": "bafy2bzacedpxow7sb2roz2iasn56nam2pec5ol4k5y5gd6iqr64qgkfo4rvba" + }, + { + "/": "bafy2bzacedlodifjgof4azs4i5rt4w4chvexlnxhgwnkayabeuz5hkqwmc3tq" + }, + { + "/": "bafy2bzacecjfvxn3d6oxsey7t4nq7bwbdnb2magaydn7abtznjnjtdmin3zqi" + }, + { + "/": "bafy2bzacedxoyikiomoh3pcr7tuoddoqknx6k5w2ut5pojigkcluzfukczeza" + }, + { + "/": "bafy2bzaceaxaxbv6kr423c4gmtid4ito67wywwhknz745xuicw6wpzcbpwmfg" + }, + { + "/": "bafy2bzacebveeiuw27o6xygc7egfbiplou3wyf5tnmh3i3yy4zxxofhb2ldxg" + }, + { + "/": "bafy2bzacedmzcojbg7i2bcp7r47n6xk26qzgmd6b3dfsmfkromgzdjnr6vnhw" + }, + { + "/": "bafy2bzacecfti2ujdzcneomi3tfdciblrcm24hlonvep4uu7f7sknxs6nbv22" + }, + { + "/": "bafy2bzacedrhnwihhmkcyuhgf55sz3zwrb7s6btjxgbqu3nkp43yl4c6nwmwe" + }, + { + "/": "bafy2bzacedhqgvkn3i5ri72mo5bcxfpmzltkyl5osiduox6lj5pzs7qoyzeas" + }, + { + "/": "bafy2bzaceds5jr6unpcoo6deadvqbeqq6hgjoopij4b5dkgxeeqriq7lel2nm" + }, + { + "/": "bafy2bzacean37yl6houpzikd7qcaf65xppuhsspkkyzeyds7azosd23y35ljy" + }, + { + "/": "bafy2bzacea3raqfvay7am4ddcwf4oyjgzptvqoey35tis6i7d5wizcxsfhybg" + }, + { + "/": "bafy2bzaceaqepycsr6uizmlmcoqjqp74hnipq5ei5caiezm725vjsffrhxawo" + }, + { + "/": "bafy2bzacec646a4ftg3bhnucavra2dozdgkp3vd2y4ntlhsfzmd3ibwjlay4q" + }, + { + "/": "bafy2bzacedpo633dm7i2zfwj2xgaxcrozl6jpqdp3tz6kzcray2ihw2ehhdbg" + }, + { + "/": "bafy2bzaceb5g5okyglzg3csdudhxrbseymxud66nqrswwer3pbitksalohmcq" + }, + { + "/": "bafy2bzacedudoknop5psrvo7boijutxfg6l26gcir25gtxmpu2sjmxznxed2w" + }, + { + "/": "bafy2bzacebi3xylknfutifsy3yuxzdqoxyooiv5gxpyq6tenxmrm4bsh4pe4u" + }, + { + "/": "bafy2bzacedopnrqpxqcjgds2kpmiorb5k7533r4pja3vmo3l2lb5sabof4tbw" + }, + { + "/": "bafy2bzacedujbxmjj7kog3u7qks3wftx3n7t3wkkps5shtr2tycoq2uoo6mbc" + }, + { + "/": "bafy2bzacedki3dd4bv6ieh3yucyd3vg4xp7pu3r2v5t7iwal3fyhkm6354mig" + }, + { + "/": "bafy2bzacechjqrkcivj2l7uqrz2azmwizkuo5ik3l4xis7fgacxcqkecgfhvu" + }, + { + "/": "bafy2bzacebdcw6rslqzw3sg7qgauz7vp3pajgknujle5ifgie2ndnmo6kjwlq" + }, + { + "/": "bafy2bzacebv3t3vbrzx5ej7zgvshv3tw552t2fpx3x2my6zvwjce2wtsykuky" + }, + { + "/": "bafy2bzacec46ycpz4fs64vg45ltzksc2cooqlftpxdp47d64ad3fdoodi53z6" + }, + { + "/": "bafy2bzacedoz2clu3wachh2rdtgt6cxwxebnuz6ivpobvf66zz6jhkei4vpme" + }, + { + "/": "bafy2bzaceaufl4egkumh2vc5vfetthk2dh25t4s7id6ppxh6q7pqvsgwkp4xu" + }, + { + "/": "bafy2bzacebrwbqhv7unpqtkoqlwgza27c72jqr2fnnalazqngwh2k2jdeuoge" + }, + { + "/": "bafy2bzaced2xeldtp2q4ds5jkofacsl3bystskkqocwe3vzv5mwndu3g6v43i" + }, + { + "/": "bafy2bzaceaom3igg2pm6ojezqji655vmsfwn4fjk4jr7vkvqoy2di2p2nlye2" + }, + { + "/": "bafy2bzaceah2ihyli5b6drwdrcx5bjuqh3ur7iueqoeopvqlvodjzeb5esopc" + }, + { + "/": "bafy2bzacebqfqdq3nrdk4hikr44n763mahabj5cytay3rpyogyv7hxdxu4jzi" + }, + { + "/": "bafy2bzacedx6n6ilzummihlwqzvp2vpee3wf4sanp2igxxyueeurvfsumev7i" + }, + { + "/": "bafy2bzacecignffu6vcvbgyfsjfcnnhbz6ynjh2ziiqvfds2ufynu7n6scpai" + }, + { + "/": "bafy2bzaceazq7o25lxa6hfhzlc6aud5aiqyimdmjuexxtboyrc7jpjnhneiae" + }, + { + "/": "bafy2bzacecjmdph662yb4d2kko4bd4lchay75pslryq6ijis3y2sbx2ynl7v2" + }, + { + "/": "bafy2bzaceddztfslaohw246jytacdwtqfvibr4o7vshgckxw7slbcpxcpssei" + }, + { + "/": "bafy2bzacedecgc4i25j7ph74yyqz7utnztk7qpnsf4xvmuiqcsazux2t5lckk" + }, + { + "/": "bafy2bzacech5lo62kxb4w4te2zxovr4btrpymutyy5jio5nyjff46os2jlhh2" + }, + { + "/": "bafy2bzaceav4l6zvbx4wtyojeryirgwvjxdohmtsa3ud5opmgjzvedm4phrts" + }, + { + "/": "bafy2bzaced3gbhak2oupe3swpnpvfa7es4eiarvvonugvtwbecy5yrjbasjem" + }, + { + "/": "bafy2bzaceaxvrb6udo3oar2kfeb6b64f6fwjcf7ub4uwke2temwxufq7tqlsq" + }, + { + "/": "bafy2bzaced7edis3oajcdvgyrd2vrioxhm7ffabq37ya3iviocofckhxrpzsa" + }, + { + "/": "bafy2bzacecvfj2lsmwvq5nb2izcyzydbxtdgukavuqajvx6znqelravpirmlc" + }, + { + "/": "bafy2bzaceck4xyrmt3lrut2cqdrdcwblenmrvkvib7iioh7jhz5qxylxaisjk" + }, + { + "/": "bafy2bzacedodfnmepxcdifxup52okfiyx6gwrfaezcgxwdjmy5cexi5czwuxc" + }, + { + "/": "bafy2bzacecvbkg3k3mqt5f6ghocbrxep5bqzlpp5rmiwztw4zedrijtbydwnu" + }, + { + "/": "bafy2bzacedspuejjyvs22olevpm2augoq7pqwfq5jqqtuzg3selxfmrydnz66" + }, + { + "/": "bafy2bzacebguomvmhooifkxvwlmwzstw6sly2iictpygpgipyitxl5kwbwlli" + }, + { + "/": "bafy2bzacedidy4dni7zhpj6b6hvvvhteuvjrzj3onjrmoeqmbgxmoxsinstiu" + }, + { + "/": "bafy2bzaceaxhbuyxqpkvbhtnx7uwnr7ejombalfy6wdw3azt23gzuqzupbrtc" + }, + { + "/": "bafy2bzacecy6k6rah4tfanivk3eghc2qewirukaxtzjabotolnededxjqqnrc" + }, + { + "/": "bafy2bzacebx2swrcd6qawlhm6jpidtcwchiuoxtnzzuk2fgz4e7gnvgrs2nz4" + }, + { + "/": "bafy2bzaceccrzwgdxuwwk72tnpju6lnqwz65hov5mg4ooqdox3n5mnv4ocdak" + }, + { + "/": "bafy2bzacec5jcdiwul3qq274ye6ay2olyoij6hybuajlvfqgzrqsuucm2adqa" + }, + { + "/": "bafy2bzacecq3dhlmj4iab4byyzhfapfha25juwurfmjycw2btbymdk6f5b3su" + }, + { + "/": "bafy2bzacebm6pxzyizpxgbianayazfe5imzurbvmx43i6glrxj7piiyznivq2" + }, + { + "/": "bafy2bzacebb7wbtkmlnbmbssmjd3raqljouz7iadkuqy7pofsuy6duq3s2qn2" + }, + { + "/": "bafy2bzacedxortgzv234wnnddevk3ofu5sgvglvoeodddoyo45rgxdi76im46" + }, + { + "/": "bafy2bzacecm5hr6uvs5dvkxbhcfuf5cwnyb4bj6grt4mlrtrjukj47pf5keh6" + }, + { + "/": "bafy2bzaced3tuzh5ravyfnqjyx5e26uymsxxsdmspeijj27afxurgjermjsm6" + }, + { + "/": "bafy2bzacedfapkrtkgog6yuimjrzh4tup5qmtms24iegi6jj5236ae6jyqula" + }, + { + "/": "bafy2bzacea6f6pkynzcmadgzjpftohjbh5t2hny5ru7jo7js6v7yigjrqe4ai" + }, + { + "/": "bafy2bzacec42mhil5aacpkzvgqfvwiutxicd25ozo7aouk3pwtydcoshb3mh4" + }, + { + "/": "bafy2bzacebxnc5u7ma7lzk2n2hhub4o3qcalckl4kdgo3z3legbwdubj7n56i" + }, + { + "/": "bafy2bzacedyfk2lj4vwfv2id5csq4hfhfcbhfw5if4grjj44imfaob5xpryvy" + }, + { + "/": "bafy2bzacebd2g5mkgfrdpaegxwa35iul27532mls3nje3zqs5c7sezfufq2sw" + }, + { + "/": "bafy2bzaceaoonskvzte43reugau6652ecgxwcpjcxxdp3t7xvkg5kxd5gle6c" + }, + { + "/": "bafy2bzaceayutpz7wu6pgrdfeaqxjhfdhc5sqg5y2viyjvs5f2fmbjfccw5k4" + }, + { + "/": "bafy2bzacedgdn2nu7quq6e3wrfza5pjlmjoy7xlcopi6bmzawuidcosnhp3eq" + }, + { + "/": "bafy2bzaceblbu2jadc6hjuli5v5jvdoqosoidvmwkunuk2h5zrnl37ayen2f4" + }, + { + "/": "bafy2bzacecbmuvsyu2ayypf6ycdqpvbqh4i4zqxrgdkj5bbhwl3ntrkp35rgq" + }, + { + "/": "bafy2bzacebauvtwqrgw7uzy5ndk2htporh5owd7hcghrbx5tgszszd7oz2glq" + }, + { + "/": "bafy2bzacea4oyafell327v4othtmluxhxzwymzlvcwd2hyvqqwmaoyhhz4ejq" + }, + { + "/": "bafy2bzacebgtp2hig7fe6vvmg2qb3bpsvwgons4ajgd2mewvi4hmrv3k4pc32" + }, + { + "/": "bafy2bzacearrgqrihpgsxim6dycxvpqxc2zus6myxarvdxaw55s7wx63qmf4e" + }, + { + "/": "bafy2bzacecaufl6i37x3yueswkwgqbqle2gyd5x62mrgqtv6r6kniaykfb26e" + }, + { + "/": "bafy2bzaceb27vbmz3b6vnxrhcknj2k7ywscvti7hwz62hjvajcbuntfjya55a" + }, + { + "/": "bafy2bzacealzoacizh34y5otjrf6cm2bxq2v4rjss3mvk3qbobbdffllq65ce" + }, + { + "/": "bafy2bzaceax4ndy7yjbys4alma3pduuniyxv6pyz4zq4th5bxup3nyqi3o2uq" + }, + { + "/": "bafy2bzacebmv3xp2mumpt4b7hawq2eirlqahm2qjbuus7a2vzg7rejbreee6y" + }, + { + "/": "bafy2bzacedhxbtme5dbl4ewsa2zsr7mphd5gtwimxy6mag73e3qv6hc3qqtwq" + }, + { + "/": "bafy2bzacea3zpvmys7jtkbqip35jxryiiuxxmd7mhxbzq2loivzz4dpdtnpjm" + }, + { + "/": "bafy2bzaceb7vit7tkehsttrshl4na6y66iqmy4ei5damhtezoliqquue5dzsq" + }, + { + "/": "bafy2bzaceczzngeovyp5rlbxk3anqxshw46m6xsux5g2hb6clcvi72z2gfbq2" + }, + { + "/": "bafy2bzaceb2zduelngpedvemug5t7tgmeep7shhcwmjwd3qj2emau66k6aqhm" + }, + { + "/": "bafy2bzacedwnnsn7fn4uncghicc5mpjxhqb4s4fzp4gfrcz36bkzu5bd5xpjo" + }, + { + "/": "bafy2bzacedw6qldlkdyzo2lumxy5zqkjxyl5555zezb3rp7hif5cirb6smwng" + }, + { + "/": "bafy2bzaceavxubnlv6w2jzltgyql3tzrxyioyvtznt3yqngajl4m4gzzuiioy" + }, + { + "/": "bafy2bzacecjn2znf7c65k625ry5dvizq2inq7yrwxlcy63xqs2tl5x4kujbo2" + }, + { + "/": "bafy2bzaceatyiutvzk5fgyg6sgsxwgrghxbe6awl6wwp4haofbcadxqtzdrcs" + }, + { + "/": "bafy2bzacecyjt42zntvnmp55thtdxiqcxephkbxkq6oypcte63b4rgat6opr2" + }, + { + "/": "bafy2bzacea2bn2kjgfpcenqfkdzricsja4s5cw4ee5a22ypn2xdlzj2hd2jq4" + }, + { + "/": "bafy2bzacecqif6y5pci22pjjnvmcyk7dta5xe4ikhw2yv75fgualkhksznk7q" + }, + { + "/": "bafy2bzacecr27smdgxi5js2hxg7izbn66liymo234qqx6c4yjoglc7quediac" + }, + { + "/": "bafy2bzacedrvkmzhmelnulxrfjqrsimt4kuou6jl76svhbxgcvsho32d5whra" + }, + { + "/": "bafy2bzacebm5kwc2biyyaqswltrfgrk7cv22hcrfdkhckpqjq3awsu6pws4si" + }, + { + "/": "bafy2bzacec7pkm6xzcrotw3y5zdytbgy6udft2loqf4j2le62ruz3oulmanfa" + }, + { + "/": "bafy2bzacebpincfj5bktd6mkobriv5vwiagorvgweuo5yphn6z3ajzawv7q2y" + }, + { + "/": "bafy2bzacea6hjkpdhakn673z7lqrc5byioxre5ht554gm5zulpxpevj7dbnzo" + }, + { + "/": "bafy2bzacecxjdmz6t4h6gbcohruvmaktabhpvcxyet7tlj6bkmmbaovqrboki" + }, + { + "/": "bafy2bzaced6glm7pvr2jajenx5pkmjwee3c6y3qe2zolqhixbp6iujndqzj5e" + }, + { + "/": "bafy2bzacean2xfyr7i4tjsrqbgdiuqqc7z5wt7jsw6x3qomuebkspvjfxd7ke" + }, + { + "/": "bafy2bzacedsaz7ovgjkb7awf6s7y624bpw6js3i5lr5vas6wmkh4tirbnpphy" + }, + { + "/": "bafy2bzaceaaeyi44qw4cgie3dwkzysocj3a3xddrskwo7aqyg4h3xi4q7gjla" + }, + { + "/": "bafy2bzacedbgkhrms6hwivadwy25znnpamuzwjyib4ewgxrcejqzoq5sc5pme" + }, + { + "/": "bafy2bzaceddg2ogejnzovciqjxkgaqgg4a5pvarbfseqnjn3bjczq72ui7mw6" + }, + { + "/": "bafy2bzacec76cak2ft5t57g7eewzae2g4qlh4vdx5the64mhylguei4g2m676" + }, + { + "/": "bafy2bzaceapw3tme6fx7fg4xpfzmgkxt6bdfh2kpmvy3brpc4bxo236je62g2" + }, + { + "/": "bafy2bzacedqhopibbutecx5u6z6xcyomvzuw7fmpg2kfpfn6a3rmaoxomot2q" + }, + { + "/": "bafy2bzacecn7qvfkfcfpwvjnqk3rsviqjnacfdh644kyvkdfwkgk3xujubfm2" + }, + { + "/": "bafy2bzacebe4u63s7jvj3qt73pnulztu4jv6yq3ikulqcdtnm2hr2a43p34fa" + }, + { + "/": "bafy2bzacec42kl5w7mvbs3ic3ipih4q6eho6avhvhxxilc2jev33t6f2cytkk" + }, + { + "/": "bafy2bzacebd7tidwh6vy5lxpn3tv6i5yqn7s4rttaxrbttfdvwvtdirc6tesw" + }, + { + "/": "bafy2bzacebwd2ooq2oko7lhigoeup37tywatk2hsuhjuaa4x65f24arpkubcy" + }, + { + "/": "bafy2bzaceartfnukagy4cebtkanuj5quoh7mj2br3snghrxxopqy2h2vcvfnw" + }, + { + "/": "bafy2bzacedfxealgp3xme3o2jkuqz5ylykznec7epf3zevbf3m6n7tozltyao" + }, + { + "/": "bafy2bzacedeavfgbycmevol7khezw65nhuw3uma26fr6pmk7j6hlse2jnp3f4" + }, + { + "/": "bafy2bzacecv3nwgnz75og5kdjitqrfh4dsne3guxw6vt7ndlp3q53zo3quyto" + }, + { + "/": "bafy2bzacebapky35yjv7moo7ppjrk3k6e4qbmt6i26q7cfpgm3i4bkgt54i4k" + }, + { + "/": "bafy2bzacebz2j2dlm7p4d5cipaagzcxmcxovvetawp5uej33mzxyibyf2fqey" + }, + { + "/": "bafy2bzacebxtwc7mhhissdpk4ruxoklctk2yff2bygzrnfvdpedhx5of3ttma" + } + ] + } +} diff --git a/platform/filecoin/mocks/ChainGetTipSetByHeight.json b/platform/filecoin/mocks/ChainGetTipSetByHeight.json new file mode 100644 index 000000000..4838d132c --- /dev/null +++ b/platform/filecoin/mocks/ChainGetTipSetByHeight.json @@ -0,0 +1,196 @@ +{ + "jsonrpc": "2.0", + "result": { + "Cids": [ + { + "/": "bafy2bzaceca6n6sqyyfexclyo3yeinj3ihamd5whfpxnss6pzmdxs6obqh5mc" + } + ], + "Blocks": [ + { + "Miner": "f033130", + "Ticket": { + "VRFProof": "g0ei5BNIAWjWn24m22fh8iXY59stLoNr9TjP8aQyDbnEez87t+PLOjTcIKg18GcFDRuenomxVbdyXEn0XrhaeZ2G01cmUfveYDJG4CcIfuzX6Sh0FWiZYIhNOOoyPIiV" + }, + "ElectionProof": { + "WinCount": 1, + "VRFProof": "kTVIw/UGXzREwqiKFFTw/wkyg9yAc24A9YS5cK5tpt0F3Mmv45ezP6tjzu/OP1f4EUmuK4Z2KXLa6SganAX4RB6ueMELzgCsUvAJJaWbHeoeXG2HxZXixW8mA/wLopeD" + }, + "BeaconEntries": [ + { + "Round": 339434, + "Data": "kxqziKg0KKpF6BO/4+ONq0PuxWNE9yAYc8163CKzKmIW+IFUdFFfkxK/UYNpvtL/FGWYOIRmOq1l5jIwJ+yXtw+65cbNUdfXO5NbRws4HY6DsiN8stpuXIuujO237yup" + } + ], + "WinPoStProof": [ + { + "PoStProof": 3, + "ProofBytes": "qvj6xfDBYRDVI3YtfJxbMu17XI9pGpnd3Cx4zL6IZSafx2suJiEr0ZGVa2SO+TMzonqKAvSjSOwxrgPI45jeZy9nRYOO4VOPo5H3jGz/OwDcz1hRB2ldQLn9hWyyyaWECbUD77uhnxhR0VXFPpO7YSo/eS4h0phLY/x7PAlJE46B1ozdOuDNCx8HmJDmcfolhmX5qqtWKAyoPeBtfwhnSMZ1CS+wjMZBC8jo4M8HI2gtjQCZqlp3n3pKSlwEFwOE" + } + ], + "Parents": [ + { + "/": "bafy2bzaceb2oioogn5spogg5qd3s77h6y5nl65yg2ihtwsy7gz5ya5js2psfw" + }, + { + "/": "bafy2bzacecgvr4vq4owqyb2kosfohcz2tsjopa7iprikdruhqh6eacd5maopi" + }, + { + "/": "bafy2bzacecuyfvfsdbjydw6z2ymswcrnzcopetgwkz3ja6r252mrc3bidkgvy" + }, + { + "/": "bafy2bzacecpovgb6stxmpjagtyjnxbor375afxztmgr5z62b5dwlivwh4jq4q" + }, + { + "/": "bafy2bzacecplfcf3jpirxua4szvhbh3youjyec5u2ifeeha764lmsmqorl7rc" + } + ], + "ParentWeight": "5085326167", + "Height": 243590, + "ParentStateRoot": { + "/": "bafy2bzacedizpvzsmkr7lv5bl5zpp5y4fuyb5nz7dgdycbi4hbopiyiu534qe" + }, + "ParentMessageReceipts": { + "/": "bafy2bzacebsijpga2dovhvvkctky3zncdkhlfp2673hpbnc2vz7pd6r2agbgm" + }, + "Messages": { + "/": "bafy2bzacedpgiddoj7tht6yafgen3br7ozllj7ysghnzfxp6jae7l4v3a37eq" + }, + "BLSAggregate": { + "Type": 2, + "Data": "sctdQjn/f+NJGpMocEeElSkB1dR/9rb9TC8PF/IdqzqUWcjXrP8NgHsMtfUsJU1GEczsyWRX59axHy/Y7Roub2/o06WwfbMIb2jjKsMNr37+PeiR5rdqTZZTd3fL6uT7" + }, + "Timestamp": 1605614100, + "BlockSig": { + "Type": 2, + "Data": "koyrqh5EW89wU9TMKls7li0g+cZkmT2vgRuixgYDQuGOc+LvZbrACtdDPE3E9wIlDXu+l8YgWy3kP9eKqycxU7EptytrUCHTTOzB4TsJU82MQYsQe8wx/pmiUqo4g5NQ" + }, + "ForkSignaling": 0, + "ParentBaseFee": "957593361" + }, + { + "Miner": "f024563", + "Ticket": { + "VRFProof": "g5h6RT/d4RRi59X3Baio+e8Xv4XRIGSNiv6IaOFfKUxRfXgdKACLkEpKaSFfy320EyU3iVZlHj0ZDOhGdAJuguO3jKUTr2eAYSAJkbs4Ii1vR2+Vl5s3Se/ke8biyOAm" + }, + "ElectionProof": { + "WinCount": 1, + "VRFProof": "hKIZ8H1FJNZKj+1o95+MHpqg7U8r/8g/9WmDJXCfxjXv5ccNbZDkJRyzJF8eq72vEw+Z/HJ1AvLg4ZELa0JJuTacSdXd/p46k2Uvp8ksIuOuTGUYvTeARKNyqyzBSB/a" + }, + "BeaconEntries": [ + { + "Round": 339434, + "Data": "kxqziKg0KKpF6BO/4+ONq0PuxWNE9yAYc8163CKzKmIW+IFUdFFfkxK/UYNpvtL/FGWYOIRmOq1l5jIwJ+yXtw+65cbNUdfXO5NbRws4HY6DsiN8stpuXIuujO237yup" + } + ], + "WinPoStProof": [ + { + "PoStProof": 3, + "ProofBytes": "l0cnzfcm5mNz7D/G4SDcKlp1p5h5JD04Zm/LQCnIoJMTWZoPwl5WH81Gs16wWOQPtJv7GTYuXal7M1sgvDwidXleqm1Yf8HGvjLdzkd/7YNmNibsHCDI0VC+UDjK/Kr4ALtPyhii5p0MFRKer1y+NkQNbnh64ZUz42h+Q1lI1WVSqMIbJULGlJg+/RYjdgMkmKvY82e6sf0T0n7694QMXbo15rzSmEhkF+2qmj7qHBfNjjMgCMLDZ7A4uFmf/EH9" + } + ], + "Parents": [ + { + "/": "bafy2bzaceb2oioogn5spogg5qd3s77h6y5nl65yg2ihtwsy7gz5ya5js2psfw" + }, + { + "/": "bafy2bzacecgvr4vq4owqyb2kosfohcz2tsjopa7iprikdruhqh6eacd5maopi" + }, + { + "/": "bafy2bzacecuyfvfsdbjydw6z2ymswcrnzcopetgwkz3ja6r252mrc3bidkgvy" + }, + { + "/": "bafy2bzacecpovgb6stxmpjagtyjnxbor375afxztmgr5z62b5dwlivwh4jq4q" + }, + { + "/": "bafy2bzacecplfcf3jpirxua4szvhbh3youjyec5u2ifeeha764lmsmqorl7rc" + } + ], + "ParentWeight": "5085326167", + "Height": 243590, + "ParentStateRoot": { + "/": "bafy2bzacedizpvzsmkr7lv5bl5zpp5y4fuyb5nz7dgdycbi4hbopiyiu534qe" + }, + "ParentMessageReceipts": { + "/": "bafy2bzacebsijpga2dovhvvkctky3zncdkhlfp2673hpbnc2vz7pd6r2agbgm" + }, + "Messages": { + "/": "bafy2bzaceaute5p2f6muqyzaqarupxt3k3jb2wpzswnamnv2zkramjrkdcz26" + }, + "BLSAggregate": { + "Type": 2, + "Data": "uFZuhqr7pj08swYQiPCZDmiJnJBDsCxKmw1FSWYLgUBvkwPpwtSFaHj+W3o+hNYWEcZBf8spX5VArHaIt7B7W3CV2XUQlwzhptbX1K3mNfkCPiGMwB65owT/xh9O/cf7" + }, + "Timestamp": 1605614100, + "BlockSig": { + "Type": 2, + "Data": "kf6f9VTCnPX9rTzWDab8aF0OSGFfmVqH6xyL1zssyU7PwINIjQn58sP31E1sfSGfFmRmKGfv0GBa1XP9EfBZcyj7miTEe7fCLTIYaS3ZvtFLnHSmylJHSGp6H00fIzwv" + }, + "ForkSignaling": 0, + "ParentBaseFee": "957593361" + }, + { + "Miner": "f02490", + "Ticket": { + "VRFProof": "pUa1oaYhxCGlbJ5kRtV4gSh1q+ed39VKc6J45GGLa2G4ZpHDkB3YP3z7u95aq+YHCIa6WutJhSgTjCmgtS7R9shibMpgMAnq4V7V2pMe07gWKZ0DUAAIM/D7sM4XCTRv" + }, + "ElectionProof": { + "WinCount": 1, + "VRFProof": "k6UQkvSHV6sWXPKUB7KEQRh7m6n6cAIogKbVjBQHaR6e0ok3JA3tcVFh7jUX7ERpBsYoJonN4ctCIXT82B6iSwisa+yiX8/X2nKGVbmB1oaWB86jOZQc+lqUkefJrB/C" + }, + "BeaconEntries": [ + { + "Round": 339434, + "Data": "kxqziKg0KKpF6BO/4+ONq0PuxWNE9yAYc8163CKzKmIW+IFUdFFfkxK/UYNpvtL/FGWYOIRmOq1l5jIwJ+yXtw+65cbNUdfXO5NbRws4HY6DsiN8stpuXIuujO237yup" + } + ], + "WinPoStProof": [ + { + "PoStProof": 3, + "ProofBytes": "tCFxee4dl0/JELevW8wRY3ygztrR9Q3hlKu3Ehxi43WF1nKF2OxUFJgAyDRlr3DvgbttMAgQ9Sa9RUU6xZBIe6ZTs27GcNiVq99rqPgcYPMv1GFNfpz5lAJLvAODeBLhA04EcDbL9zmkfTN6nkMgKv6FSP1C2ghHB33A+qRXwVQ/WmiEb2g5rvC2X36Z9U+0kyR7ZO7Tr3/5R1J20Mlzt9gtDLyTwIlaa6xu4YzxRwcJi1461OpcOHoie/xhphk4" + } + ], + "Parents": [ + { + "/": "bafy2bzaceb2oioogn5spogg5qd3s77h6y5nl65yg2ihtwsy7gz5ya5js2psfw" + }, + { + "/": "bafy2bzacecgvr4vq4owqyb2kosfohcz2tsjopa7iprikdruhqh6eacd5maopi" + }, + { + "/": "bafy2bzacecuyfvfsdbjydw6z2ymswcrnzcopetgwkz3ja6r252mrc3bidkgvy" + }, + { + "/": "bafy2bzacecpovgb6stxmpjagtyjnxbor375afxztmgr5z62b5dwlivwh4jq4q" + }, + { + "/": "bafy2bzacecplfcf3jpirxua4szvhbh3youjyec5u2ifeeha764lmsmqorl7rc" + } + ], + "ParentWeight": "5085326167", + "Height": 243590, + "ParentStateRoot": { + "/": "bafy2bzacedizpvzsmkr7lv5bl5zpp5y4fuyb5nz7dgdycbi4hbopiyiu534qe" + }, + "ParentMessageReceipts": { + "/": "bafy2bzacebsijpga2dovhvvkctky3zncdkhlfp2673hpbnc2vz7pd6r2agbgm" + }, + "Messages": { + "/": "bafy2bzaceaz4aw5fdtispsrpmvjckzzpcc675kpdqsl4l7khlsd2w6gpvc36i" + }, + "BLSAggregate": { + "Type": 2, + "Data": "rdcE8jas3aeVtdZN9GMINJTvLeugBr6nD0+dVBblkk4jznyYhJJR9hA56Vi722AqGKDdFLoE/vonGKwhP51QMgv0Gcg95vOgaVtSOZyBQ4ODfy9uXVaAOtm0koZZTH7T" + }, + "Timestamp": 1605614100, + "BlockSig": { + "Type": 2, + "Data": "rTn6iXHp97b5w2ktP/0EXc5esfePPcjDnh7DVMEVkjUZ62SHrYSfGlsWrzkdtY0IBITY0p3w1j2+xZ7dC5gJ863H0nM0bI6edPkuwnsPe6PcTZ2jVmWg8iHiCGnSXnK6" + }, + "ForkSignaling": 0, + "ParentBaseFee": "957593361" + } + ], + "Height": 243590 + } +} diff --git a/platform/filecoin/mocks/ChainHead.json b/platform/filecoin/mocks/ChainHead.json new file mode 100644 index 000000000..471485b21 --- /dev/null +++ b/platform/filecoin/mocks/ChainHead.json @@ -0,0 +1,202 @@ +{ + "jsonrpc": "2.0", + "result": { + "Cids": [ + { + "/": "bafy2bzaceca6n6sqyyfexclyo3yeinj3ihamd5whfpxnss6pzmdxs6obqh5mc" + }, + { + "/": "bafy2bzacedi6lyer3xf4axumo2mgtwa52qw5kmtzt5ken3w6oo2hdhg63szoa" + }, + { + "/": "bafy2bzaceb3ppcax237vxf5vwq5uckmwz2x2z3k2zfnqbjcaudrg3byzcipyi" + } + ], + "Blocks": [ + { + "Miner": "f033130", + "Ticket": { + "VRFProof": "g0ei5BNIAWjWn24m22fh8iXY59stLoNr9TjP8aQyDbnEez87t+PLOjTcIKg18GcFDRuenomxVbdyXEn0XrhaeZ2G01cmUfveYDJG4CcIfuzX6Sh0FWiZYIhNOOoyPIiV" + }, + "ElectionProof": { + "WinCount": 1, + "VRFProof": "kTVIw/UGXzREwqiKFFTw/wkyg9yAc24A9YS5cK5tpt0F3Mmv45ezP6tjzu/OP1f4EUmuK4Z2KXLa6SganAX4RB6ueMELzgCsUvAJJaWbHeoeXG2HxZXixW8mA/wLopeD" + }, + "BeaconEntries": [ + { + "Round": 339434, + "Data": "kxqziKg0KKpF6BO/4+ONq0PuxWNE9yAYc8163CKzKmIW+IFUdFFfkxK/UYNpvtL/FGWYOIRmOq1l5jIwJ+yXtw+65cbNUdfXO5NbRws4HY6DsiN8stpuXIuujO237yup" + } + ], + "WinPoStProof": [ + { + "PoStProof": 3, + "ProofBytes": "qvj6xfDBYRDVI3YtfJxbMu17XI9pGpnd3Cx4zL6IZSafx2suJiEr0ZGVa2SO+TMzonqKAvSjSOwxrgPI45jeZy9nRYOO4VOPo5H3jGz/OwDcz1hRB2ldQLn9hWyyyaWECbUD77uhnxhR0VXFPpO7YSo/eS4h0phLY/x7PAlJE46B1ozdOuDNCx8HmJDmcfolhmX5qqtWKAyoPeBtfwhnSMZ1CS+wjMZBC8jo4M8HI2gtjQCZqlp3n3pKSlwEFwOE" + } + ], + "Parents": [ + { + "/": "bafy2bzaceb2oioogn5spogg5qd3s77h6y5nl65yg2ihtwsy7gz5ya5js2psfw" + }, + { + "/": "bafy2bzacecgvr4vq4owqyb2kosfohcz2tsjopa7iprikdruhqh6eacd5maopi" + }, + { + "/": "bafy2bzacecuyfvfsdbjydw6z2ymswcrnzcopetgwkz3ja6r252mrc3bidkgvy" + }, + { + "/": "bafy2bzacecpovgb6stxmpjagtyjnxbor375afxztmgr5z62b5dwlivwh4jq4q" + }, + { + "/": "bafy2bzacecplfcf3jpirxua4szvhbh3youjyec5u2ifeeha764lmsmqorl7rc" + } + ], + "ParentWeight": "5085326167", + "Height": 243590, + "ParentStateRoot": { + "/": "bafy2bzacedizpvzsmkr7lv5bl5zpp5y4fuyb5nz7dgdycbi4hbopiyiu534qe" + }, + "ParentMessageReceipts": { + "/": "bafy2bzacebsijpga2dovhvvkctky3zncdkhlfp2673hpbnc2vz7pd6r2agbgm" + }, + "Messages": { + "/": "bafy2bzacedpgiddoj7tht6yafgen3br7ozllj7ysghnzfxp6jae7l4v3a37eq" + }, + "BLSAggregate": { + "Type": 2, + "Data": "sctdQjn/f+NJGpMocEeElSkB1dR/9rb9TC8PF/IdqzqUWcjXrP8NgHsMtfUsJU1GEczsyWRX59axHy/Y7Roub2/o06WwfbMIb2jjKsMNr37+PeiR5rdqTZZTd3fL6uT7" + }, + "Timestamp": 1605614100, + "BlockSig": { + "Type": 2, + "Data": "koyrqh5EW89wU9TMKls7li0g+cZkmT2vgRuixgYDQuGOc+LvZbrACtdDPE3E9wIlDXu+l8YgWy3kP9eKqycxU7EptytrUCHTTOzB4TsJU82MQYsQe8wx/pmiUqo4g5NQ" + }, + "ForkSignaling": 0, + "ParentBaseFee": "957593361" + }, + { + "Miner": "f024563", + "Ticket": { + "VRFProof": "g5h6RT/d4RRi59X3Baio+e8Xv4XRIGSNiv6IaOFfKUxRfXgdKACLkEpKaSFfy320EyU3iVZlHj0ZDOhGdAJuguO3jKUTr2eAYSAJkbs4Ii1vR2+Vl5s3Se/ke8biyOAm" + }, + "ElectionProof": { + "WinCount": 1, + "VRFProof": "hKIZ8H1FJNZKj+1o95+MHpqg7U8r/8g/9WmDJXCfxjXv5ccNbZDkJRyzJF8eq72vEw+Z/HJ1AvLg4ZELa0JJuTacSdXd/p46k2Uvp8ksIuOuTGUYvTeARKNyqyzBSB/a" + }, + "BeaconEntries": [ + { + "Round": 339434, + "Data": "kxqziKg0KKpF6BO/4+ONq0PuxWNE9yAYc8163CKzKmIW+IFUdFFfkxK/UYNpvtL/FGWYOIRmOq1l5jIwJ+yXtw+65cbNUdfXO5NbRws4HY6DsiN8stpuXIuujO237yup" + } + ], + "WinPoStProof": [ + { + "PoStProof": 3, + "ProofBytes": "l0cnzfcm5mNz7D/G4SDcKlp1p5h5JD04Zm/LQCnIoJMTWZoPwl5WH81Gs16wWOQPtJv7GTYuXal7M1sgvDwidXleqm1Yf8HGvjLdzkd/7YNmNibsHCDI0VC+UDjK/Kr4ALtPyhii5p0MFRKer1y+NkQNbnh64ZUz42h+Q1lI1WVSqMIbJULGlJg+/RYjdgMkmKvY82e6sf0T0n7694QMXbo15rzSmEhkF+2qmj7qHBfNjjMgCMLDZ7A4uFmf/EH9" + } + ], + "Parents": [ + { + "/": "bafy2bzaceb2oioogn5spogg5qd3s77h6y5nl65yg2ihtwsy7gz5ya5js2psfw" + }, + { + "/": "bafy2bzacecgvr4vq4owqyb2kosfohcz2tsjopa7iprikdruhqh6eacd5maopi" + }, + { + "/": "bafy2bzacecuyfvfsdbjydw6z2ymswcrnzcopetgwkz3ja6r252mrc3bidkgvy" + }, + { + "/": "bafy2bzacecpovgb6stxmpjagtyjnxbor375afxztmgr5z62b5dwlivwh4jq4q" + }, + { + "/": "bafy2bzacecplfcf3jpirxua4szvhbh3youjyec5u2ifeeha764lmsmqorl7rc" + } + ], + "ParentWeight": "5085326167", + "Height": 243590, + "ParentStateRoot": { + "/": "bafy2bzacedizpvzsmkr7lv5bl5zpp5y4fuyb5nz7dgdycbi4hbopiyiu534qe" + }, + "ParentMessageReceipts": { + "/": "bafy2bzacebsijpga2dovhvvkctky3zncdkhlfp2673hpbnc2vz7pd6r2agbgm" + }, + "Messages": { + "/": "bafy2bzaceaute5p2f6muqyzaqarupxt3k3jb2wpzswnamnv2zkramjrkdcz26" + }, + "BLSAggregate": { + "Type": 2, + "Data": "uFZuhqr7pj08swYQiPCZDmiJnJBDsCxKmw1FSWYLgUBvkwPpwtSFaHj+W3o+hNYWEcZBf8spX5VArHaIt7B7W3CV2XUQlwzhptbX1K3mNfkCPiGMwB65owT/xh9O/cf7" + }, + "Timestamp": 1605614100, + "BlockSig": { + "Type": 2, + "Data": "kf6f9VTCnPX9rTzWDab8aF0OSGFfmVqH6xyL1zssyU7PwINIjQn58sP31E1sfSGfFmRmKGfv0GBa1XP9EfBZcyj7miTEe7fCLTIYaS3ZvtFLnHSmylJHSGp6H00fIzwv" + }, + "ForkSignaling": 0, + "ParentBaseFee": "957593361" + }, + { + "Miner": "f02490", + "Ticket": { + "VRFProof": "pUa1oaYhxCGlbJ5kRtV4gSh1q+ed39VKc6J45GGLa2G4ZpHDkB3YP3z7u95aq+YHCIa6WutJhSgTjCmgtS7R9shibMpgMAnq4V7V2pMe07gWKZ0DUAAIM/D7sM4XCTRv" + }, + "ElectionProof": { + "WinCount": 1, + "VRFProof": "k6UQkvSHV6sWXPKUB7KEQRh7m6n6cAIogKbVjBQHaR6e0ok3JA3tcVFh7jUX7ERpBsYoJonN4ctCIXT82B6iSwisa+yiX8/X2nKGVbmB1oaWB86jOZQc+lqUkefJrB/C" + }, + "BeaconEntries": [ + { + "Round": 339434, + "Data": "kxqziKg0KKpF6BO/4+ONq0PuxWNE9yAYc8163CKzKmIW+IFUdFFfkxK/UYNpvtL/FGWYOIRmOq1l5jIwJ+yXtw+65cbNUdfXO5NbRws4HY6DsiN8stpuXIuujO237yup" + } + ], + "WinPoStProof": [ + { + "PoStProof": 3, + "ProofBytes": "tCFxee4dl0/JELevW8wRY3ygztrR9Q3hlKu3Ehxi43WF1nKF2OxUFJgAyDRlr3DvgbttMAgQ9Sa9RUU6xZBIe6ZTs27GcNiVq99rqPgcYPMv1GFNfpz5lAJLvAODeBLhA04EcDbL9zmkfTN6nkMgKv6FSP1C2ghHB33A+qRXwVQ/WmiEb2g5rvC2X36Z9U+0kyR7ZO7Tr3/5R1J20Mlzt9gtDLyTwIlaa6xu4YzxRwcJi1461OpcOHoie/xhphk4" + } + ], + "Parents": [ + { + "/": "bafy2bzaceb2oioogn5spogg5qd3s77h6y5nl65yg2ihtwsy7gz5ya5js2psfw" + }, + { + "/": "bafy2bzacecgvr4vq4owqyb2kosfohcz2tsjopa7iprikdruhqh6eacd5maopi" + }, + { + "/": "bafy2bzacecuyfvfsdbjydw6z2ymswcrnzcopetgwkz3ja6r252mrc3bidkgvy" + }, + { + "/": "bafy2bzacecpovgb6stxmpjagtyjnxbor375afxztmgr5z62b5dwlivwh4jq4q" + }, + { + "/": "bafy2bzacecplfcf3jpirxua4szvhbh3youjyec5u2ifeeha764lmsmqorl7rc" + } + ], + "ParentWeight": "5085326167", + "Height": 243590, + "ParentStateRoot": { + "/": "bafy2bzacedizpvzsmkr7lv5bl5zpp5y4fuyb5nz7dgdycbi4hbopiyiu534qe" + }, + "ParentMessageReceipts": { + "/": "bafy2bzacebsijpga2dovhvvkctky3zncdkhlfp2673hpbnc2vz7pd6r2agbgm" + }, + "Messages": { + "/": "bafy2bzaceaz4aw5fdtispsrpmvjckzzpcc675kpdqsl4l7khlsd2w6gpvc36i" + }, + "BLSAggregate": { + "Type": 2, + "Data": "rdcE8jas3aeVtdZN9GMINJTvLeugBr6nD0+dVBblkk4jznyYhJJR9hA56Vi722AqGKDdFLoE/vonGKwhP51QMgv0Gcg95vOgaVtSOZyBQ4ODfy9uXVaAOtm0koZZTH7T" + }, + "Timestamp": 1605614100, + "BlockSig": { + "Type": 2, + "Data": "rTn6iXHp97b5w2ktP/0EXc5esfePPcjDnh7DVMEVkjUZ62SHrYSfGlsWrzkdtY0IBITY0p3w1j2+xZ7dC5gJ863H0nM0bI6edPkuwnsPe6PcTZ2jVmWg8iHiCGnSXnK6" + }, + "ForkSignaling": 0, + "ParentBaseFee": "957593361" + } + ], + "Height": 243590 + } +} diff --git a/platform/filecoin/mocks/response.json b/platform/filecoin/mocks/response.json new file mode 100644 index 000000000..9e8f1952b --- /dev/null +++ b/platform/filecoin/mocks/response.json @@ -0,0 +1,229 @@ +{ + "number": 243590, + "txs": [ + { + "id": "", + "coin": 461, + "from": "f13sb4pa34qzf35txnan4fqjfkwwqgldz6ekh5trq", + "to": "f029223", + "fee": "0", + "date": 1605614100, + "block": 243590, + "status": "completed", + "sequence": 246187, + "type": "transfer", + "memo": "", + "metadata": { "value": "0", "symbol": "FIL", "decimals": 18 } + }, + { + "id": "", + "coin": 461, + "from": "f13sb4pa34qzf35txnan4fqjfkwwqgldz6ekh5trq", + "to": "f026582", + "fee": "0", + "date": 1605614100, + "block": 243590, + "status": "completed", + "sequence": 246188, + "type": "transfer", + "memo": "", + "metadata": { "value": "0", "symbol": "FIL", "decimals": 18 } + }, + { + "id": "", + "coin": 461, + "from": "f13sb4pa34qzf35txnan4fqjfkwwqgldz6ekh5trq", + "to": "f029084", + "fee": "0", + "date": 1605614100, + "block": 243590, + "status": "completed", + "sequence": 246189, + "type": "transfer", + "memo": "", + "metadata": { "value": "0", "symbol": "FIL", "decimals": 18 } + }, + { + "id": "", + "coin": 461, + "from": "f13sb4pa34qzf35txnan4fqjfkwwqgldz6ekh5trq", + "to": "f026721", + "fee": "0", + "date": 1605614100, + "block": 243590, + "status": "completed", + "sequence": 246190, + "type": "transfer", + "memo": "", + "metadata": { "value": "0", "symbol": "FIL", "decimals": 18 } + }, + { + "id": "", + "coin": 461, + "from": "f13sb4pa34qzf35txnan4fqjfkwwqgldz6ekh5trq", + "to": "f027694", + "fee": "0", + "date": 1605614100, + "block": 243590, + "status": "completed", + "sequence": 246191, + "type": "transfer", + "memo": "", + "metadata": { "value": "0", "symbol": "FIL", "decimals": 18 } + }, + { + "id": "", + "coin": 461, + "from": "f13sb4pa34qzf35txnan4fqjfkwwqgldz6ekh5trq", + "to": "f028389", + "fee": "0", + "date": 1605614100, + "block": 243590, + "status": "completed", + "sequence": 246192, + "type": "transfer", + "memo": "", + "metadata": { "value": "0", "symbol": "FIL", "decimals": 18 } + }, + { + "id": "", + "coin": 461, + "from": "f13sb4pa34qzf35txnan4fqjfkwwqgldz6ekh5trq", + "to": "f027138", + "fee": "0", + "date": 1605614100, + "block": 243590, + "status": "completed", + "sequence": 246193, + "type": "transfer", + "memo": "", + "metadata": { "value": "0", "symbol": "FIL", "decimals": 18 } + }, + { + "id": "", + "coin": 461, + "from": "f13sb4pa34qzf35txnan4fqjfkwwqgldz6ekh5trq", + "to": "f028945", + "fee": "0", + "date": 1605614100, + "block": 243590, + "status": "completed", + "sequence": 246194, + "type": "transfer", + "memo": "", + "metadata": { "value": "0", "symbol": "FIL", "decimals": 18 } + }, + { + "id": "", + "coin": 461, + "from": "f13sb4pa34qzf35txnan4fqjfkwwqgldz6ekh5trq", + "to": "f028250", + "fee": "0", + "date": 1605614100, + "block": 243590, + "status": "completed", + "sequence": 246195, + "type": "transfer", + "memo": "", + "metadata": { "value": "0", "symbol": "FIL", "decimals": 18 } + }, + { + "id": "", + "coin": 461, + "from": "f13sb4pa34qzf35txnan4fqjfkwwqgldz6ekh5trq", + "to": "f027555", + "fee": "0", + "date": 1605614100, + "block": 243590, + "status": "completed", + "sequence": 246196, + "type": "transfer", + "memo": "", + "metadata": { "value": "0", "symbol": "FIL", "decimals": 18 } + }, + { + "id": "", + "coin": 461, + "from": "f13sb4pa34qzf35txnan4fqjfkwwqgldz6ekh5trq", + "to": "f026860", + "fee": "0", + "date": 1605614100, + "block": 243590, + "status": "completed", + "sequence": 246197, + "type": "transfer", + "memo": "", + "metadata": { "value": "0", "symbol": "FIL", "decimals": 18 } + }, + { + "id": "", + "coin": 461, + "from": "f13sb4pa34qzf35txnan4fqjfkwwqgldz6ekh5trq", + "to": "f028806", + "fee": "0", + "date": 1605614100, + "block": 243590, + "status": "completed", + "sequence": 246198, + "type": "transfer", + "memo": "", + "metadata": { "value": "0", "symbol": "FIL", "decimals": 18 } + }, + { + "id": "", + "coin": 461, + "from": "f13sb4pa34qzf35txnan4fqjfkwwqgldz6ekh5trq", + "to": "f026999", + "fee": "0", + "date": 1605614100, + "block": 243590, + "status": "completed", + "sequence": 246199, + "type": "transfer", + "memo": "", + "metadata": { "value": "0", "symbol": "FIL", "decimals": 18 } + }, + { + "id": "", + "coin": 461, + "from": "f13sb4pa34qzf35txnan4fqjfkwwqgldz6ekh5trq", + "to": "f028528", + "fee": "0", + "date": 1605614100, + "block": 243590, + "status": "completed", + "sequence": 246200, + "type": "transfer", + "memo": "", + "metadata": { "value": "0", "symbol": "FIL", "decimals": 18 } + }, + { + "id": "", + "coin": 461, + "from": "f13sb4pa34qzf35txnan4fqjfkwwqgldz6ekh5trq", + "to": "f028667", + "fee": "0", + "date": 1605614100, + "block": 243590, + "status": "completed", + "sequence": 246201, + "type": "transfer", + "memo": "", + "metadata": { "value": "0", "symbol": "FIL", "decimals": 18 } + }, + { + "id": "", + "coin": 461, + "from": "f1i5kvaeurfv27jncddyvcuzgegm4j46y5u7okcza", + "to": "f2mgv6khl6s6oukeyi3nm3ja67s7fl3cecy2stvny", + "fee": "0", + "date": 1605614100, + "block": 243590, + "status": "completed", + "sequence": 2, + "type": "transfer", + "memo": "", + "metadata": { "value": "0", "symbol": "FIL", "decimals": 18 } + } + ] +} diff --git a/platform/filecoin/rpc/client.go b/platform/filecoin/rpc/client.go new file mode 100644 index 000000000..321ca4149 --- /dev/null +++ b/platform/filecoin/rpc/client.go @@ -0,0 +1,42 @@ +package rpc + +import "github.com/trustwallet/golibs/client" + +type Client struct { + client.Request +} + +func (c Client) GetBlockHeight() (ChainHeadResponse, error) { + var result ChainHeadResponse + err := c.RpcCall(&result, "Filecoin.ChainHead", nil) + if err != nil { + return ChainHeadResponse{}, err + } + return result, nil +} + +func (c Client) GetTipSetByHeight(height int64) (ChainHeadResponse, error) { + var result ChainHeadResponse + params := []interface{}{ + height, nil, + } + err := c.RpcCall(&result, "Filecoin.ChainGetTipSetByHeight", params) + if err != nil { + return ChainHeadResponse{}, err + } + return result, nil +} + +func (c Client) GetBlockMessage(cid string) (BlockMessageResponse, error) { + var result BlockMessageResponse + params := []interface{}{ + map[string]interface{}{ + "/": cid, + }, + } + err := c.RpcCall(&result, "Filecoin.ChainGetBlockMessages", params) + if err != nil { + return BlockMessageResponse{}, err + } + return result, nil +} diff --git a/platform/filecoin/rpc/models.go b/platform/filecoin/rpc/models.go new file mode 100644 index 000000000..6da56df0b --- /dev/null +++ b/platform/filecoin/rpc/models.go @@ -0,0 +1,47 @@ +package rpc + +type ChainHeadResponse struct { + Cids []struct { + Cid string `json:"/"` + } `json:"Cids"` + Blocks []struct { + Timestamp int `json:"Timestamp"` + } + Height int `json:"Height"` +} + +type BlockMessageResponse struct { + SecpkMessages []SecpkMessage `json:"SecpkMessages"` +} + +type SecpkMessage struct { + Message Message `json:"Message"` +} + +type Message struct { + Version int `json:"Version"` + To string `json:"To"` + From string `json:"From"` + Nonce int `json:"Nonce"` + Value string `json:"Value"` + GasLimit int `json:"GasLimit"` + GasFeeCap string `json:"GasFeeCap"` + GasPremium string `json:"GasPremium"` + Method int `json:"Method"` + Params interface{} `json:"Params"` +} + +func (c ChainHeadResponse) GetCids() []string { + result := make([]string, 0, len(c.Cids)) + for _, cid := range c.Cids { + result = append(result, cid.Cid) + } + return result +} + +func (c ChainHeadResponse) GetTimestamp() int64 { + if len(c.Blocks) == 0 { + return 0 + } + return int64(c.Blocks[0].Timestamp) +} diff --git a/platform/filecoin/transaction.go b/platform/filecoin/transaction.go new file mode 100644 index 000000000..70e880bd7 --- /dev/null +++ b/platform/filecoin/transaction.go @@ -0,0 +1,53 @@ +package filecoin + +import ( + "github.com/trustwallet/blockatlas/platform/filecoin/explorer" + "github.com/trustwallet/golibs/types" +) + +const messageMethod = "Send" + +func (p *Platform) GetTxsByAddress(address string) (types.Txs, error) { + res, err := p.explorer.GetMessagesByAddress(address, types.TxPerPage) + if err != nil { + return nil, err + } + normalized := make(types.Txs, 0) + for _, message := range res.Messages { + // skip non transfer messages + if message.Method != messageMethod { + continue + } + normalized = append(normalized, p.NormalizeMessage(message, address)) + } + + return normalized, nil +} + +func (p *Platform) NormalizeMessage(message explorer.Message, address string) types.Tx { + status := types.StatusCompleted + if message.Receipt.ExitCode != 0 { + status = types.StatusError + } + direction := types.DirectionOutgoing + if message.From != address { + direction = types.DirectionIncoming + } + return types.Tx{ + ID: message.Cid, + Coin: p.Coin().ID, + From: message.From, + To: message.To, + Date: message.Timestamp, + Block: message.Height, + Status: status, + Sequence: message.Nonce, + Type: types.TxTransfer, + Direction: direction, + Meta: types.Transfer{ + Value: types.Amount(message.Value), + Symbol: p.Coin().Symbol, + Decimals: p.Coin().Decimals, + }, + } +} diff --git a/platform/filecoin/transaction_test.go b/platform/filecoin/transaction_test.go new file mode 100644 index 000000000..ce2334249 --- /dev/null +++ b/platform/filecoin/transaction_test.go @@ -0,0 +1,102 @@ +package filecoin + +import ( + "reflect" + "testing" + + "github.com/trustwallet/blockatlas/platform/filecoin/explorer" + "github.com/trustwallet/golibs/types" +) + +func TestPlatform_NormalizeMessage(t *testing.T) { + type args struct { + message explorer.Message + address string + } + tests := []struct { + name string + args args + want types.Tx + }{ + { + name: "Test transfer", + args: args{ + message: explorer.Message{ + Cid: "bafy2bzacectkidmsel5gn5qamrqhcgqgqefhdzlqukry3rc2ase4yqdbxazqi", + Height: 305641, + Timestamp: 1607475630, + From: "f1mdseaz4gkbz2cq2kf4q3xqbws5ongyt7vdbvzoa", + To: "f16hhfi2xkkmpsi4c5mmgwbkgk5wslfcaflefsqpy", + Nonce: 6, + Value: "298040241318833792", + Method: "Send", + Receipt: explorer.Receipt{ + ExitCode: 0, + }, + }, + address: "f16hhfi2xkkmpsi4c5mmgwbkgk5wslfcaflefsqpy", + }, + want: types.Tx{ + ID: "bafy2bzacectkidmsel5gn5qamrqhcgqgqefhdzlqukry3rc2ase4yqdbxazqi", + Coin: 461, + From: "f1mdseaz4gkbz2cq2kf4q3xqbws5ongyt7vdbvzoa", + To: "f16hhfi2xkkmpsi4c5mmgwbkgk5wslfcaflefsqpy", + Date: 1607475630, + Block: 305641, + Status: "completed", + Sequence: 6, + Type: "transfer", + Direction: "incoming", + Meta: types.Transfer{ + Value: "298040241318833792", + Symbol: "FIL", + Decimals: 18, + }, + }, + }, + { + name: "Test transfer failed", + args: args{ + message: explorer.Message{ + Cid: "bafy2bzacebgbszawdnrl7flgrb2ixt4f6lsb4jjqywv3bsekplpsiswexepha", + Height: 310103, + Timestamp: 1607609490, + From: "f16hhfi2xkkmpsi4c5mmgwbkgk5wslfcaflefsqpy", + To: "f1elvpho4c6iba6xrlok3773cxbvq32thlofezw5y", + Nonce: 23, + Value: "1000000000000000", + Method: "Send", + Receipt: explorer.Receipt{ + ExitCode: 7, + }, + }, + address: "f16hhfi2xkkmpsi4c5mmgwbkgk5wslfcaflefsqpy", + }, + want: types.Tx{ + ID: "bafy2bzacebgbszawdnrl7flgrb2ixt4f6lsb4jjqywv3bsekplpsiswexepha", + Coin: 461, + From: "f16hhfi2xkkmpsi4c5mmgwbkgk5wslfcaflefsqpy", + To: "f1elvpho4c6iba6xrlok3773cxbvq32thlofezw5y", + Date: 1607609490, + Block: 310103, + Status: "error", + Sequence: 23, + Type: "transfer", + Direction: "outgoing", + Meta: types.Transfer{ + Value: "1000000000000000", + Symbol: "FIL", + Decimals: 18, + }, + }, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + p := &Platform{} + if got := p.NormalizeMessage(tt.args.message, tt.args.address); !reflect.DeepEqual(got, tt.want) { + t.Errorf("Platform.NormalizeMessage() = %v, want %v", got, tt.want) + } + }) + } +} diff --git a/platform/fio/actor.go b/platform/fio/actor.go new file mode 100644 index 000000000..6fa8d5f69 --- /dev/null +++ b/platform/fio/actor.go @@ -0,0 +1,101 @@ +package fio + +import ( + "errors" + "github.com/btcsuite/btcutil/base58" +) + +func actorFromPublicKeyOrActor(addressOrActor string) string { + l := len(addressOrActor) + if l >= 51 && l <= 55 && addressOrActor[:3] == "FIO" { + // assume public key string + return actorFromPublicKey(addressOrActor) + } + if l <= 13 { + // assume actor + return addressOrActor + } + return "" +} + +func actorFromPublicKey(address string) string { + pkBytes, err := bytesFromPublicKeyString(address) + if err != nil { + return "" + } + return actorFromPublicKeyBytes(pkBytes) +} + +func actorFromPublicKeyBytes(pkBytes []byte) string { + shortenedKey := shortenKey(pkBytes) + name13 := getName(shortenedKey) + // trim to 12 characters + return name13[:12] +} + +func bytesFromPublicKeyString(address string) ([]byte, error) { + if address[:3] != "FIO" { + return nil, errors.New("Invalid FIO public key prefix") + } + array := base58.Decode(address[3:]) + if len(array) != 37 { + return nil, errors.New("Invalid FIO public key length") + } + return array, nil +} + +func mask12(len int) byte { + if len == 12 { + return 0x0f + } + return 0x1f +} + +func mask0(len int) byte { + if len == 0 { + return 0x0f + } + return 0x1f +} + +func shortenKey(addrKey []byte) uint64 { + var ( + res uint64 = 0 + i = 1 // Ignore key head + l = 0 + ) + for l <= 12 { + //assert(i < 33) + trimmedChar := uint64(addrKey[i] & mask12(l)) + if trimmedChar == 0 { + i++ + continue + } // Skip a zero and move to next + var shuffle byte = 0 + if l < 12 { + shuffle = byte(5*(12-l) - 1) + } + res = res | (trimmedChar << shuffle) + l++ + i++ + } + return res +} + +func getName(shortKey uint64) string { + var ( + charmap = ".12345abcdefghijklmnopqrstuvwxyz" + str [13]byte + tmp = shortKey + ) + for i := 0; i <= 12; i++ { + c := charmap[tmp&uint64(mask0(i))] + str[12-i] = c + if i == 0 { + tmp = tmp >> 4 + } else { + tmp = tmp >> 5 + } + } + return string(str[:]) +} diff --git a/platform/fio/actor_test.go b/platform/fio/actor_test.go new file mode 100644 index 000000000..3580b92ad --- /dev/null +++ b/platform/fio/actor_test.go @@ -0,0 +1,68 @@ +package fio + +import ( + "encoding/hex" + "testing" + + "github.com/stretchr/testify/assert" +) + +func TestActorFromPublicKey(t *testing.T) { + addrArr := []string{ + "FIO6cDpi7vPnvRwMEdXtLnAmFwygaQ8CzD7vqKLBJ2GfgtHBQ4PPy", + "FIO7uMZoeei5HtXAD24C4yCkpWWbf24bjYtrRNjWdmGCXHZccwuiE", + "FIO7bxrQUTbQ4mqcoefhWPz1aFieN4fA9RQAiozRz7FrUChHZ7Rb8", + "FIO6m1fMdTpRkRBnedvYshXCxLFiC5suRU8KDfx8xxtXp2hntxpnf", + "FIO7Q3XfQ2ocGP1zYst6Sfx5qrsiZ865Cu8So2atrub9JN94so7gt", + "FIO5kJKNHwctcfUM5XZyiWSqSTM5HTzznJP9F3ZdbhaQAHEVq575o", + "2odzomo2v4pe", // actor + "hhq2g4qgycfb", // actor + "FIO5kJKNHwctcfUM5XZyiWSqSTM5HTzznJP9F3ZdbhaQAHEVq575", // invalid length + "FIO5kJKNHwctcfUM5XZyiWSqSTM5H", // invalid length + "FIO5kJKNHwct", // assume actor + } + actorArr := []string{ + "2odzomo2v4pe", + "hhq2g4qgycfb", + "5kmx4qbqlpld", + "qdfejz2a5wpl", + "ezsmbcy2opod", + "ltwagbt4qpuk", + "2odzomo2v4pe", + "hhq2g4qgycfb", + "", + "", + "FIO5kJKNHwct", + } + for i := range addrArr { + assert.Equal(t, actorArr[i], actorFromPublicKeyOrActor(actorArr[i])) + } +} + +func TestBytesFromPublicKeyString(t *testing.T) { + { + pkBytes, err := bytesFromPublicKeyString("FIO5kJKNHwctcfUM5XZyiWSqSTM5HTzznJP9F3ZdbhaQAHEVq575o") + assert.Equal(t, nil, err) + assert.Equal(t, 37, len(pkBytes)) + assert.Equal(t, "0271195c66ec2799e436757a70cd8431d4b17733a097b18a5f7f1b6b085978ff0f343fc54e", hex.EncodeToString(pkBytes)) + } + { + pkBytes, err := bytesFromPublicKeyString("FIO6cDpi7vPnvRwMEdXtLnAmFwygaQ8CzD7vqKLBJ2GfgtHBQ4PPy") + assert.Equal(t, nil, err) + assert.Equal(t, "02e274495ff4d2f4027bc4d5ead805b0197f19efe526ba2c1c5545ba916d6088a7248a8bf4", hex.EncodeToString(pkBytes)) + } + { + pkBytes, err := bytesFromPublicKeyString("FIO6cDpi7vPnvRwMEdXtLnAmFwygaQ8CzD7vqKLBJ2GfgtHBQ4P") + assert.True(t, err != nil) + assert.Equal(t, 0, len(pkBytes)) + } +} + +func TestShortenKey(t *testing.T) { + pkBytes, _ := hex.DecodeString("02e274495ff4d2f4027bc4d5ead805b0197f19efe526ba2c1c5545ba916d6088a7248a8bf4") + assert.Equal(t, uint64(1518832697283783336), shortenKey(pkBytes)) +} + +func TestGetName(t *testing.T) { + assert.Equal(t, "2odzomo2v4pec", getName(uint64(1518832697283783336))) +} diff --git a/platform/fio/api.go b/platform/fio/api.go deleted file mode 100644 index 77b361fca..000000000 --- a/platform/fio/api.go +++ /dev/null @@ -1,24 +0,0 @@ -package fio - -import ( - "github.com/spf13/viper" - "github.com/trustwallet/blockatlas/coin" - "github.com/trustwallet/blockatlas/pkg/blockatlas" -) - -type Platform struct { - client Client -} - -func (p *Platform) Init() error { - p.client = Client{blockatlas.InitClient(viper.GetString("fio.api"))} - return nil -} - -func (p *Platform) Coin() coin.Coin { - return coin.Coins[coin.FIO] -} - -func (p *Platform) GetTxsByAddress(address string) (page blockatlas.TxPage, err error) { - return page, err -} diff --git a/platform/fio/base.go b/platform/fio/base.go new file mode 100644 index 000000000..1605417b7 --- /dev/null +++ b/platform/fio/base.go @@ -0,0 +1,21 @@ +package fio + +import ( + "github.com/trustwallet/golibs/client" + "github.com/trustwallet/golibs/coin" + "github.com/trustwallet/golibs/network/middleware" +) + +type Platform struct { + client Client +} + +func Init(api string) *Platform { + return &Platform{ + client: Client{client.InitJSONClient(api, middleware.SentryErrorHandler)}, + } +} + +func (p *Platform) Coin() coin.Coin { + return coin.Coins[coin.FIO] +} diff --git a/platform/fio/client.go b/platform/fio/client.go index 556d1cac3..4b64c4eb6 100644 --- a/platform/fio/client.go +++ b/platform/fio/client.go @@ -1,9 +1,22 @@ package fio -import ( - "github.com/trustwallet/blockatlas/pkg/blockatlas" -) +import "github.com/trustwallet/golibs/client" +// Client for FIO API type Client struct { - blockatlas.Request + client.Request +} + +func (c *Client) getTransactions(account string) (actions []Action, error error) { + var res GetActionsResponse + err := c.Post(&res, "v1/history/get_actions", GetActionsRequest{ + AccountName: account, + Pos: -1, // latest + Offset: -100, // 100 before last; use 100 because not all actions are transfers + Sort: "desc", + }) + if err != nil { + return nil, err + } + return res.Actions, nil } diff --git a/platform/fio/model.go b/platform/fio/model.go new file mode 100644 index 000000000..ee5ef15bb --- /dev/null +++ b/platform/fio/model.go @@ -0,0 +1,66 @@ +package fio + +// ActionDataTransfer (from get_actions) +type ActionDataTransfer struct { + From string `json:"from"` + To string `json:"to"` + Quantity string `json:"quantity"` + Memo string `json:"memo"` +} + +// ActionDataTrnsfiopubky (from get_actions) +type ActionDataTrnsfiopubky struct { + PayeePublicKey string `json:"payee_public_key"` + Amount int64 `json:"amount"` + MaxFee int64 `json:"max_fee"` + Actor string `json:"actor"` + TpID string `json:"tpid"` +} + +// ActionAct (from get_actions) +type ActionAct struct { + Account string `json:"account"` + Name string `json:"name"` + Data interface{} `json:"data"` // Structure of data is action-specific +} + +// ActionTrace +type ActionTrace struct { + Act ActionAct `json:"act"` + TrxID string `json:"trx_id"` +} + +// Action (from get_actions) +type Action struct { + ActionSeq uint64 `json:"account_action_seq"` + BlockNum uint64 `json:"block_num"` + BlockTime string `json:"block_time"` + ActionTrace ActionTrace `json:"action_trace"` +} + +// GetActionsRequest request struct for get_actions +// see https://github.com/EOSIO/eos/blob/master/plugins/history_plugin/include/eosio/history_plugin/history_plugin.hpp +type GetActionsRequest struct { + AccountName string `json:"account_name"` + Pos int32 `json:"pos"` + Offset int32 `json:"offset"` + Sort string `json:"sort"` // desc +} + +// GetActionsResponse request struct for get_actions +type GetActionsResponse struct { + Actions []Action `json:"actions"` +} + +// GetPubAddressRequest request struct for get_pub_address +type GetPubAddressRequest struct { + FioAddress string `json:"fio_address"` + TokenCode string `json:"token_code"` + ChainCode string `json:"chain_code"` +} + +// GetPubAddressResponse response struct for get_pub_address +type GetPubAddressResponse struct { + PublicAddress string `json:"public_address"` + Message string `json:"message"` +} diff --git a/platform/fio/transaction.go b/platform/fio/transaction.go new file mode 100644 index 000000000..cef228919 --- /dev/null +++ b/platform/fio/transaction.go @@ -0,0 +1,125 @@ +package fio + +import ( + "encoding/json" + "fmt" + "sort" + "strconv" + "strings" + "time" + + "errors" + + "github.com/trustwallet/golibs/types" +) + +const ( + contractToken = "fio.token" + contractTreasury = "fio.treasury" + actionTransfer = "transfer" + actionTransferPubkey = "trnsfiopubky" +) + +func (p *Platform) GetTxsByAddress(address string) (page types.Txs, err error) { + // take actor from address + account := actorFromPublicKeyOrActor(address) + actions, err := p.client.getTransactions(account) + if err != nil { + return nil, err + } + txs := make(types.Txs, 0) + for _, a := range actions { + tx, err := p.Normalize(&a, account) + if err != nil { + continue + } + txs = append(txs, tx) + } + txs = unique(txs) + sort.Sort(txs) + return txs, nil +} + +func (p *Platform) Normalize(action *Action, account string) (types.Tx, error) { + var ( + to, from, memo string + amount, fee types.Amount + sequence uint64 + ) + const dateFormat string = "2006-01-02T15:04:05" + + if action.ActionTrace.Act.Account == contractToken && + (action.ActionTrace.Act.Name == actionTransfer || action.ActionTrace.Act.Name == actionTransferPubkey) { + // convert to action-specific data + dataJSON, err := json.Marshal(action.ActionTrace.Act.Data) + if err != nil { + return types.Tx{}, errors.New("Unparseable Data field") + } + switch action.ActionTrace.Act.Name { + case actionTransfer: + var actionData ActionDataTransfer + if json.Unmarshal(dataJSON, &actionData) != nil { + return types.Tx{}, errors.New("Unparseable Data field") + } + if actionData.To == contractTreasury { + return types.Tx{}, errors.New("Skip tx sent to treasury, usually fee") + } + from = actionData.From + to = actionData.To + amountNum, err := strconv.ParseFloat(strings.Split(actionData.Quantity, " ")[0], 64) + if err == nil { + amount = types.Amount(strconv.Itoa(int(amountNum * 1000000000))) + } + // fee unknown + memo = actionData.Memo + sequence = action.ActionSeq + case actionTransferPubkey: + var actionData ActionDataTrnsfiopubky + if json.Unmarshal(dataJSON, &actionData) != nil { + return types.Tx{}, errors.New("Unparseable Data field") + } + from = actionData.Actor + to = actorFromPublicKeyOrActor(actionData.PayeePublicKey) + amount = types.Amount(strconv.FormatInt(actionData.Amount, 10)) + fee = types.Amount(strconv.FormatInt(actionData.MaxFee, 10)) + // not set sequence because it might be duplicated + } + date, _ := time.Parse(dateFormat, action.BlockTime) + tx := types.Tx{ + ID: action.ActionTrace.TrxID, + Coin: p.Coin().ID, + Date: date.Unix(), + From: from, + To: to, + Block: action.BlockNum, + Sequence: sequence, + Status: types.StatusCompleted, + Fee: fee, + Meta: types.Transfer{ + Value: amount, + Symbol: p.Coin().Symbol, + Decimals: p.Coin().Decimals, + }, + Memo: memo, + Type: types.TxTransfer, + } + tx.Direction = tx.GetTransactionDirection(account) + return tx, nil + } + return types.Tx{}, errors.New("Unknown action") +} + +func unique(txs types.Txs) types.Txs { + set := make(map[string]struct{}) + var result types.Txs + for _, tx := range txs { + id := fmt.Sprintf("%s-%d", tx.ID, tx.Sequence) + if _, ok := set[id]; ok { + continue + } else { + set[id] = struct{}{} + result = append(result, tx) + } + } + return result +} diff --git a/platform/harmony/api.go b/platform/harmony/api.go deleted file mode 100644 index 2197a3491..000000000 --- a/platform/harmony/api.go +++ /dev/null @@ -1,124 +0,0 @@ -package harmony - -import ( - "github.com/spf13/viper" - "github.com/trustwallet/blockatlas/coin" - "github.com/trustwallet/blockatlas/pkg/blockatlas" - "github.com/trustwallet/blockatlas/pkg/errors" - "github.com/trustwallet/blockatlas/pkg/numbers" - "strconv" -) - -type Platform struct { - client Client -} - -func (p *Platform) Init() error { - p.client = Client{blockatlas.InitClient(viper.GetString("harmony.api"))} - p.client.Headers["Content-Type"] = "application/json" - return nil -} - -func (p *Platform) Coin() coin.Coin { - return coin.Coins[coin.ONE] -} - -func (p *Platform) GetTxsByAddress(address string) (blockatlas.TxPage, error) { - result, err := p.client.GetTxsOfAddress(address) - if err != nil { - return blockatlas.TxPage{}, err - } - return NormalizeTxs(result.Transactions), err -} - -func (p *Platform) CurrentBlockNumber() (int64, error) { - return p.client.CurrentBlockNumber() -} - -func (p *Platform) GetBlockByNumber(num int64) (*blockatlas.Block, error) { - srcBlock, err := p.client.GetBlockByNumber(num) - if err != nil { - return nil, err - } - block := p.NormalizeBlock(&srcBlock) - return &block, nil -} - -func (p *Platform) NormalizeBlock(block *BlockInfo) blockatlas.Block { - blockNumber, err := hexToInt(block.Number) - if err != nil { - return blockatlas.Block{} - } - return blockatlas.Block{ - ID: block.Hash, - Number: int64(blockNumber), - Txs: NormalizeTxs(block.Transactions), - } -} - -func NormalizeTxs(txs []Transaction) blockatlas.TxPage { - normalizeTxs := make([]blockatlas.Tx, 0) - for _, srcTx := range txs { - normalized, isCorrect, err := NormalizeTx(&srcTx) - if !isCorrect || err != nil { - return []blockatlas.Tx{} - } - normalizeTxs = append(normalizeTxs, normalized) - } - return normalizeTxs -} - -func GetNormalizationError(err error) error { - return errors.E(err, errors.TypePlatformNormalize, errors.Params{"method": "Harmony_NormalizeTx"}).PushToSentry() -} - -func NormalizeTx(trx *Transaction) (tx blockatlas.Tx, b bool, err error) { - gasPrice, err := hexToInt(trx.GasPrice) - if err != nil { - return blockatlas.Tx{}, false, GetNormalizationError(err) - } - gas, err := hexToInt(trx.Gas) - if err != nil { - return blockatlas.Tx{}, false, GetNormalizationError(err) - } - fee := gas * gasPrice - literalFee := strconv.Itoa(int(fee)) - - literalValue, err := numbers.HexToDecimal(trx.Value) - if err != nil { - return blockatlas.Tx{}, false, GetNormalizationError(err) - } - - block, err := hexToInt(trx.BlockNumber) - if err != nil { - return blockatlas.Tx{}, false, GetNormalizationError(err) - } - - nonce, err := hexToInt(trx.Nonce) - if err != nil { - return blockatlas.Tx{}, false, GetNormalizationError(err) - } - - timestamp, err := hexToInt(trx.Timestamp) - if err != nil { - return blockatlas.Tx{}, false, GetNormalizationError(err) - } - - return blockatlas.Tx{ - ID: trx.Hash, - Coin: coin.ONE, - From: trx.From, - To: trx.To, - Fee: blockatlas.Amount(literalFee), - Status: blockatlas.StatusCompleted, - Sequence: nonce, - Date: int64(timestamp), - Type: blockatlas.TxTransfer, - Block: block, - Meta: blockatlas.Transfer{ - Value: blockatlas.Amount(literalValue), - Symbol: coin.Coins[coin.ONE].Symbol, - Decimals: coin.Coins[coin.ONE].Decimals, - }, - }, true, nil -} diff --git a/platform/harmony/api_test.go b/platform/harmony/api_test.go deleted file mode 100644 index 42b69f69e..000000000 --- a/platform/harmony/api_test.go +++ /dev/null @@ -1,78 +0,0 @@ -package harmony - -import ( - "bytes" - "encoding/json" - "github.com/trustwallet/blockatlas/coin" - "github.com/trustwallet/blockatlas/pkg/blockatlas" - "testing" -) - -const transferSrc = ` -{ - "blockHash": "0x0bde901cd3599aa082482777fd0a7fed3f02b7b5a9096b7ea7b2fcb8addaa05d", - "blockNumber": "0x12", - "from": "one103q7qe5t2505lypvltkqtddaef5tzfxwsse4z7", - "gas": "0x5208", - "gasPrice": "0x3b9aca00", - "hash": "0x230798fe22abff459b004675bf827a4089326a296fa4165d0c2ad27688e03e0c", - "input": "0x", - "nonce": "0x0", - "to": "one129r9pj3sk0re76f7zs3qz92rggmdgjhtwge62k", - "transactionIndex": "0x1", - "value": "0x16345785d8a0000", - "shardID": 0, - "toShardID": 0, - "v": "0x27", - "r": "0x57766aa1304e97f8b71a9fa54a61b61ce8ef9ad177fcb337dd81827aad184327", - "s": "0x3b3e5767899e8af5e75d62243a725371f08705b91e2305459e6fd8e8d2646651", - "timestamp": "0x5DF5234E" -} -` - -var transferDst = blockatlas.Tx{ - ID: "0x230798fe22abff459b004675bf827a4089326a296fa4165d0c2ad27688e03e0c", - Coin: coin.ONE, - From: "one103q7qe5t2505lypvltkqtddaef5tzfxwsse4z7", - To: "one129r9pj3sk0re76f7zs3qz92rggmdgjhtwge62k", - Fee: "21000000000000", - Date: 1576346446, - Block: 18, - Status: blockatlas.StatusCompleted, - Meta: blockatlas.Transfer{ - Value: "100000000000000000", - Symbol: "ONE", - Decimals: 18, - }, -} - -func TestNormalize(t *testing.T) { - var srcTx Transaction - err := json.Unmarshal([]byte(transferSrc), &srcTx) - if err != nil { - t.Error(err) - return - } - - resTx, isGood, err := NormalizeTx(&srcTx) - - if !isGood || err != nil { - t.Fatal() - } - - resJSON, err := json.Marshal(&resTx) - if err != nil { - t.Fatal(err) - } - - dstJSON, err := json.Marshal(&transferDst) - if err != nil { - t.Fatal(err) - } - - if !bytes.Equal(resJSON, dstJSON) { - println(string(resJSON)) - println(string(dstJSON)) - t.Error("tx don't equal") - } -} diff --git a/platform/harmony/base.go b/platform/harmony/base.go new file mode 100644 index 000000000..18b2b98eb --- /dev/null +++ b/platform/harmony/base.go @@ -0,0 +1,22 @@ +package harmony + +import ( + "github.com/trustwallet/golibs/client" + "github.com/trustwallet/golibs/coin" + "github.com/trustwallet/golibs/network/middleware" +) + +type Platform struct { + client Client +} + +func Init(api string) *Platform { + p := &Platform{ + client: Client{client.InitJSONClient(api, middleware.SentryErrorHandler)}, + } + return p +} + +func (p *Platform) Coin() coin.Coin { + return coin.Harmony() +} diff --git a/platform/harmony/block.go b/platform/harmony/block.go new file mode 100644 index 000000000..11f013115 --- /dev/null +++ b/platform/harmony/block.go @@ -0,0 +1,27 @@ +package harmony + +import "github.com/trustwallet/golibs/types" + +func (p *Platform) CurrentBlockNumber() (int64, error) { + return p.client.CurrentBlockNumber() +} + +func (p *Platform) GetBlockByNumber(num int64) (*types.Block, error) { + srcBlock, err := p.client.GetBlockByNumber(num) + if err != nil { + return nil, err + } + block := p.NormalizeBlock(&srcBlock) + return &block, nil +} + +func (p *Platform) NormalizeBlock(block *BlockInfo) types.Block { + blockNumber, err := hexToInt(block.Number) + if err != nil { + return types.Block{} + } + return types.Block{ + Number: int64(blockNumber), + Txs: NormalizeTxs(block.Transactions), + } +} diff --git a/platform/harmony/client.go b/platform/harmony/client.go index 67f48c6b6..4a074956d 100644 --- a/platform/harmony/client.go +++ b/platform/harmony/client.go @@ -2,13 +2,14 @@ package harmony import ( "fmt" - "github.com/trustwallet/blockatlas/pkg/blockatlas" - "github.com/trustwallet/blockatlas/pkg/numbers" "strconv" + + "github.com/trustwallet/golibs/client" + "github.com/trustwallet/golibs/numbers" ) type Client struct { - blockatlas.Request + client.Request } func (c *Client) GetTxsOfAddress(address string) (txPage *TxResult, err error) { @@ -41,6 +42,20 @@ func (c *Client) GetBlockByNumber(num int64) (info BlockInfo, err error) { return } +func (c *Client) GetBalance(address string) (string, error) { + var result string + err := rpcCallStub(c, &result, "hmy_getBalance", []interface{}{address, "latest"}) + + if err != nil { + return "0", err + } + balance, err := numbers.HexToDecimal(result) + if err != nil { + return "0", err + } + return balance, nil +} + func hexToInt(hex string) (uint64, error) { nonceStr, err := numbers.HexToDecimal(hex) if err != nil { @@ -48,3 +63,8 @@ func hexToInt(hex string) (uint64, error) { } return strconv.ParseUint(nonceStr, 10, 64) } + +// rpcCallStub is can be overwritten by the unit test +var rpcCallStub = func(c *Client, result interface{}, method string, params interface{}) error { + return c.RpcCall(result, method, params) +} diff --git a/platform/harmony/mocks/delegation.json b/platform/harmony/mocks/delegation.json new file mode 100644 index 000000000..bba639e7e --- /dev/null +++ b/platform/harmony/mocks/delegation.json @@ -0,0 +1,9 @@ +[ + { + "validator_address": "one1pdv9lrdwl0rg5vglh4xtyrv3wjk3wsqket7zxy", + "delegator_address": "one1pf75h0t4am90z8uv3y0dgunfqp4lj8wr3t5rsp", + "amount": 12345678900000000000, + "reward": 15854399877248931866418, + "Undelegations": [] + } +] diff --git a/platform/harmony/mocks/transfer.json b/platform/harmony/mocks/transfer.json new file mode 100644 index 000000000..898ac8de9 --- /dev/null +++ b/platform/harmony/mocks/transfer.json @@ -0,0 +1,19 @@ +{ + "blockHash": "0x0bde901cd3599aa082482777fd0a7fed3f02b7b5a9096b7ea7b2fcb8addaa05d", + "blockNumber": "0x12", + "from": "one103q7qe5t2505lypvltkqtddaef5tzfxwsse4z7", + "gas": "0x5208", + "gasPrice": "0x3b9aca00", + "hash": "0x230798fe22abff459b004675bf827a4089326a296fa4165d0c2ad27688e03e0c", + "input": "0x", + "nonce": "0x0", + "to": "one129r9pj3sk0re76f7zs3qz92rggmdgjhtwge62k", + "transactionIndex": "0x1", + "value": "0x16345785d8a0000", + "shardID": 0, + "toShardID": 0, + "v": "0x27", + "r": "0x57766aa1304e97f8b71a9fa54a61b61ce8ef9ad177fcb337dd81827aad184327", + "s": "0x3b3e5767899e8af5e75d62243a725371f08705b91e2305459e6fd8e8d2646651", + "timestamp": "0x5DF5234E" +} diff --git a/platform/harmony/mocks/validator.json b/platform/harmony/mocks/validator.json new file mode 100644 index 000000000..68f61ca0c --- /dev/null +++ b/platform/harmony/mocks/validator.json @@ -0,0 +1,65 @@ +{ + "validator": { + "bls-public-keys": [ + "29fb5d202e2f6f7955b425dc706fc0b29047067e51ba583fbb017c0f51186d5e1eaf6dd4059848be311ab5a49d625309" + ], + "last-epoch-in-committee": 18, + "min-self-delegation": 10999000000000000000000, + "max-total-delegation": 100000000000000000000000000, + "rate": "0.100000000000000000", + "max-rate": "0.100000000000000000", + "max-change-rate": "0.100000000000000000", + "update-height": 88, + "name": "sieemma node", + "identity": "sieemma node by ankr", + "website": "www.ankr.com", + "security-contact": "info@ankr.com", + "details": "This validator is launched from app.ankr.com", + "creation-height": 88, + "address": "one1v8pukmelacy3xdap773rpg5pax3tmu40wmwr2j", + "delegations": [ + { + "delegator-address": "one1v8pukmelacy3xdap773rpg5pax3tmu40wmwr2j", + "amount": 10999000000000000000000, + "reward": 2328233463148225437028, + "undelegations": [] + } + ] + }, + "current-epoch-performance": { + "current-epoch-signing-percent": { + "current-epoch-signed": 3, + "current-epoch-to-sign": 3, + "num-beacon-blocks-until-next-epoch": 37, + "current-epoch-signing-percentage": "1.000000000000000000" + } + }, + "metrics": { + "by-bls-key": [ + { + "key": { + "bls-public-key": "29fb5d202e2f6f7955b425dc706fc0b29047067e51ba583fbb017c0f51186d5e1eaf6dd4059848be311ab5a49d625309", + "group-percent": "0.056856187290969900", + "effective-stake": "85000000000000000000000.000000000000000000", + "earning-account": "one1v8pukmelacy3xdap773rpg5pax3tmu40wmwr2j", + "overall-percent": "0.018193979933110368", + "shard-id": 1 + }, + "earned-reward": 4478494623655913952 + } + ] + }, + "total-delegation": 10999000000000000000000, + "currently-in-committee": true, + "epos-status": "currently elected", + "epos-winning-stake": "85000000000000000000000.000000000000000000", + "booted-status": null, + "lifetime": { + "reward-accumulated": 2328233463148225437028, + "blocks": { + "to-sign": 525, + "signed": 504 + }, + "apr": "12.345" + } +} diff --git a/platform/harmony/transaction.go b/platform/harmony/transaction.go new file mode 100644 index 000000000..8f5fb9ca8 --- /dev/null +++ b/platform/harmony/transaction.go @@ -0,0 +1,82 @@ +package harmony + +import ( + "strconv" + + "github.com/trustwallet/golibs/coin" + "github.com/trustwallet/golibs/numbers" + "github.com/trustwallet/golibs/types" +) + +const Annual = 10 + +func (p *Platform) GetTxsByAddress(address string) (types.Txs, error) { + result, err := p.client.GetTxsOfAddress(address) + if err != nil { + return types.Txs{}, err + } + return NormalizeTxs(result.Transactions), err +} + +func NormalizeTxs(txs []Transaction) types.Txs { + normalizeTxs := make(types.Txs, 0) + for _, srcTx := range txs { + normalized, isCorrect, err := NormalizeTx(&srcTx) + if !isCorrect || err != nil { + return types.Txs{} + } + normalizeTxs = append(normalizeTxs, normalized) + } + return normalizeTxs +} + +func NormalizeTx(trx *Transaction) (tx types.Tx, b bool, err error) { + gasPrice, err := hexToInt(trx.GasPrice) + if err != nil { + return types.Tx{}, false, err + } + gas, err := hexToInt(trx.Gas) + if err != nil { + return types.Tx{}, false, err + } + fee := gas * gasPrice + literalFee := strconv.Itoa(int(fee)) + + literalValue, err := numbers.HexToDecimal(trx.Value) + if err != nil { + return types.Tx{}, false, err + } + + block, err := hexToInt(trx.BlockNumber) + if err != nil { + return types.Tx{}, false, err + } + + nonce, err := hexToInt(trx.Nonce) + if err != nil { + return types.Tx{}, false, err + } + + timestamp, err := hexToInt(trx.Timestamp) + if err != nil { + return types.Tx{}, false, err + } + + return types.Tx{ + ID: trx.Hash, + Coin: coin.HARMONY, + From: trx.From, + To: trx.To, + Fee: types.Amount(literalFee), + Status: types.StatusCompleted, + Sequence: nonce, + Date: int64(timestamp), + Type: types.TxTransfer, + Block: block, + Meta: types.Transfer{ + Value: types.Amount(literalValue), + Symbol: coin.Harmony().Symbol, + Decimals: coin.Harmony().Decimals, + }, + }, true, nil +} diff --git a/platform/harmony/transaction_test.go b/platform/harmony/transaction_test.go new file mode 100644 index 000000000..d9c524de8 --- /dev/null +++ b/platform/harmony/transaction_test.go @@ -0,0 +1,65 @@ +package harmony + +import ( + "reflect" + "testing" + + "github.com/trustwallet/golibs/coin" + "github.com/trustwallet/golibs/mock" + "github.com/trustwallet/golibs/types" +) + +func TestNormalizeTx(t *testing.T) { + type args struct { + filename string + } + tests := []struct { + name string + args args + wantTx types.Tx + wantB bool + wantErr bool + }{ + { + name: "Test normalize transaction", + args: args{ + filename: "transfer.json", + }, + wantTx: types.Tx{ + ID: "0x230798fe22abff459b004675bf827a4089326a296fa4165d0c2ad27688e03e0c", + Coin: coin.HARMONY, + From: "one103q7qe5t2505lypvltkqtddaef5tzfxwsse4z7", + To: "one129r9pj3sk0re76f7zs3qz92rggmdgjhtwge62k", + Fee: "21000000000000", + Date: 1576346446, + Block: 18, + Type: types.TxTransfer, + Status: types.StatusCompleted, + Meta: types.Transfer{ + Value: "100000000000000000", + Symbol: "ONE", + Decimals: 18, + }, + }, + wantB: true, + wantErr: false, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + var srcTx Transaction + _ = mock.JsonModelFromFilePath("mocks/"+tt.args.filename, &srcTx) + gotTx, gotB, err := NormalizeTx(&srcTx) + if (err != nil) != tt.wantErr { + t.Errorf("NormalizeTx() error = %v, wantErr %v", err, tt.wantErr) + return + } + if !reflect.DeepEqual(gotTx, tt.wantTx) { + t.Errorf("NormalizeTx() gotTx = %v, want %v", gotTx, tt.wantTx) + } + if gotB != tt.wantB { + t.Errorf("NormalizeTx() gotB = %v, want %v", gotB, tt.wantB) + } + }) + } +} diff --git a/platform/icon/api.go b/platform/icon/api.go deleted file mode 100644 index 06faf7226..000000000 --- a/platform/icon/api.go +++ /dev/null @@ -1,71 +0,0 @@ -package icon - -import ( - "github.com/spf13/viper" - "github.com/trustwallet/blockatlas/coin" - "github.com/trustwallet/blockatlas/pkg/blockatlas" - "github.com/trustwallet/blockatlas/pkg/errors" - "github.com/trustwallet/blockatlas/pkg/logger" - "github.com/trustwallet/blockatlas/pkg/numbers" - "time" -) - -type Platform struct { - client Client -} - -func (p *Platform) Init() error { - p.client = Client{blockatlas.InitClient(viper.GetString("icon.api"))} - return nil -} - -func (p *Platform) Coin() coin.Coin { - return coin.Coins[coin.ICX] -} - -func (p *Platform) GetTxsByAddress(address string) (blockatlas.TxPage, error) { - trxs, err := p.client.GetAddressTransactions(address) - if err != nil { - return nil, err - } - - nTrxs := make([]blockatlas.Tx, 0) - for _, trx := range trxs { - nTrx, ok := Normalize(&trx) - if !ok { - continue - } - nTrxs = append(nTrxs, nTrx) - } - - return nTrxs, nil -} - -// Normalize converts an Icon transaction into the generic model -func Normalize(trx *Tx) (tx blockatlas.Tx, b bool) { - date, err := time.Parse("2006-01-02T15:04:05.999Z0700", trx.CreateDate) - if err != nil { - err = errors.E(err, errors.TypePlatformUnmarshal).PushToSentry() - logger.Error(err) - return tx, false - } - fee := numbers.DecimalExp(string(trx.Fee), 18) - value := numbers.DecimalExp(string(trx.Amount), 18) - - return blockatlas.Tx{ - ID: trx.TxHash, - Coin: coin.ICX, - From: trx.FromAddr, - To: trx.ToAddr, - Fee: blockatlas.Amount(fee), - Status: blockatlas.StatusCompleted, - Date: date.Unix(), - Type: blockatlas.TxTransfer, - Block: trx.Height, - Meta: blockatlas.Transfer{ - Value: blockatlas.Amount(value), - Symbol: coin.Coins[coin.ICX].Symbol, - Decimals: coin.Coins[coin.ICX].Decimals, - }, - }, true -} diff --git a/platform/icon/api_test.go b/platform/icon/api_test.go deleted file mode 100644 index b6de316ba..000000000 --- a/platform/icon/api_test.go +++ /dev/null @@ -1,68 +0,0 @@ -package icon - -import ( - "bytes" - "encoding/json" - "github.com/trustwallet/blockatlas/coin" - "github.com/trustwallet/blockatlas/pkg/blockatlas" - "testing" -) - -const basicSrc = ` -{ - "txHash": "0x34b8b6ec3a52710c24074f5e298f4a9c67bb61a0a1dde20e695efaeb30ff3754", - "height": 357832, - "createDate": "2019-04-16T06:36:34.000+0000", - "fromAddr": "hx1b8959dd5c57d2c502e22ee0a887d33baec09091", - "toAddr": "cx334db6519871cb2bfd154cec0905ced4ea142de1", - "txType": "1", - "dataType": "call", - "amount": "0.00347", - "fee": "0.0017476", - "state": 1, - "targetContractAddr": "cx334db6519871cb2bfd154cec0905ced4ea142de1", - "id": 730841 -} -` - -var basicDst = blockatlas.Tx{ - ID: "0x34b8b6ec3a52710c24074f5e298f4a9c67bb61a0a1dde20e695efaeb30ff3754", - Coin: coin.ICX, - From: "hx1b8959dd5c57d2c502e22ee0a887d33baec09091", - To: "cx334db6519871cb2bfd154cec0905ced4ea142de1", - Fee: "1747600000000000", - Date: 1555396594, - Block: 357832, - Meta: blockatlas.Transfer{ - Value: "3470000000000000", - Symbol: "ICX", - Decimals: 18, - }, -} - -func TestNormalize(t *testing.T) { - var srcTx Tx - err := json.Unmarshal([]byte(basicSrc), &srcTx) - - if err != nil { - t.Error(err) - return - } - - tx, _ := Normalize(&srcTx) - resJSON, err := json.Marshal(&tx) - if err != nil { - t.Fatal(err) - } - - dstJSON, err := json.Marshal(&basicDst) - if err != nil { - t.Fatal(err) - } - - if !bytes.Equal(resJSON, dstJSON) { - println(string(resJSON)) - println(string(dstJSON)) - t.Error("Transactions not equal") - } -} diff --git a/platform/icon/base.go b/platform/icon/base.go new file mode 100644 index 000000000..8950fbdfd --- /dev/null +++ b/platform/icon/base.go @@ -0,0 +1,21 @@ +package icon + +import ( + "github.com/trustwallet/golibs/client" + "github.com/trustwallet/golibs/coin" + "github.com/trustwallet/golibs/network/middleware" +) + +type Platform struct { + client Client +} + +func Init(api string) *Platform { + return &Platform{ + client: Client{client.InitClient(api, middleware.SentryErrorHandler)}, + } +} + +func (p *Platform) Coin() coin.Coin { + return coin.Icon() +} diff --git a/platform/icon/client.go b/platform/icon/client.go index e94103f23..1484c06d4 100644 --- a/platform/icon/client.go +++ b/platform/icon/client.go @@ -1,19 +1,21 @@ package icon import ( - "github.com/trustwallet/blockatlas/pkg/blockatlas" "net/url" "strconv" + + "github.com/trustwallet/golibs/client" + "github.com/trustwallet/golibs/types" ) type Client struct { - blockatlas.Request + client.Request } func (c *Client) GetAddressTransactions(address string) ([]Tx, error) { query := url.Values{ "address": {address}, - "count": {strconv.FormatInt(blockatlas.TxPerPage, 10)}, + "count": {strconv.Itoa(types.TxPerPage)}, } var res Response err := c.Get(&res, "address/txList", query) diff --git a/platform/icon/mocks/transfer.json b/platform/icon/mocks/transfer.json new file mode 100644 index 000000000..b8a31426a --- /dev/null +++ b/platform/icon/mocks/transfer.json @@ -0,0 +1,14 @@ +{ + "txHash": "0x34b8b6ec3a52710c24074f5e298f4a9c67bb61a0a1dde20e695efaeb30ff3754", + "height": 357832, + "createDate": "2019-04-16T06:36:34.000+0000", + "fromAddr": "hx1b8959dd5c57d2c502e22ee0a887d33baec09091", + "toAddr": "cx334db6519871cb2bfd154cec0905ced4ea142de1", + "txType": "1", + "dataType": "call", + "amount": "0.00347", + "fee": "0.0017476", + "state": 1, + "targetContractAddr": "cx334db6519871cb2bfd154cec0905ced4ea142de1", + "id": 730841 +} diff --git a/platform/icon/transaction.go b/platform/icon/transaction.go new file mode 100644 index 000000000..6faabd66a --- /dev/null +++ b/platform/icon/transaction.go @@ -0,0 +1,56 @@ +package icon + +import ( + "time" + + log "github.com/sirupsen/logrus" + "github.com/trustwallet/golibs/coin" + "github.com/trustwallet/golibs/numbers" + "github.com/trustwallet/golibs/types" +) + +func (p *Platform) GetTxsByAddress(address string) (types.Txs, error) { + trxs, err := p.client.GetAddressTransactions(address) + if err != nil { + return nil, err + } + + nTrxs := make(types.Txs, 0) + for _, trx := range trxs { + nTrx, ok := Normalize(&trx) + if !ok { + continue + } + nTrxs = append(nTrxs, nTrx) + } + + return nTrxs, nil +} + +// Normalize converts an Icon transaction into the generic model +func Normalize(trx *Tx) (tx types.Tx, b bool) { + date, err := time.Parse("2006-01-02T15:04:05.999Z0700", trx.CreateDate) + if err != nil { + log.Error(err) + return tx, false + } + fee := numbers.DecimalExp(string(trx.Fee), 18) + value := numbers.DecimalExp(string(trx.Amount), 18) + + return types.Tx{ + ID: trx.TxHash, + Coin: coin.ICON, + From: trx.FromAddr, + To: trx.ToAddr, + Fee: types.Amount(fee), + Status: types.StatusCompleted, + Date: date.Unix(), + Type: types.TxTransfer, + Block: trx.Height, + Meta: types.Transfer{ + Value: types.Amount(value), + Symbol: coin.Icon().Symbol, + Decimals: coin.Icon().Decimals, + }, + }, true +} diff --git a/platform/icon/transaction_test.go b/platform/icon/transaction_test.go new file mode 100644 index 000000000..583ecba00 --- /dev/null +++ b/platform/icon/transaction_test.go @@ -0,0 +1,60 @@ +package icon + +import ( + "reflect" + "testing" + + "github.com/trustwallet/golibs/coin" + "github.com/trustwallet/golibs/mock" + "github.com/trustwallet/golibs/types" +) + +func TestNormalizeTx(t *testing.T) { + type args struct { + filename string + } + tests := []struct { + name string + args args + wantTx types.Tx + ok bool + }{ + { + name: "Test normalize transaction", + args: args{ + filename: "transfer.json", + }, + wantTx: types.Tx{ + ID: "0x34b8b6ec3a52710c24074f5e298f4a9c67bb61a0a1dde20e695efaeb30ff3754", + Coin: coin.ICON, + From: "hx1b8959dd5c57d2c502e22ee0a887d33baec09091", + To: "cx334db6519871cb2bfd154cec0905ced4ea142de1", + Fee: "1747600000000000", + Date: 1555396594, + Block: 357832, + Status: "completed", + Type: "transfer", + Meta: types.Transfer{ + Value: "3470000000000000", + Symbol: "ICX", + Decimals: 18, + }, + }, + ok: true, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + var srcTx Tx + _ = mock.JsonModelFromFilePath("mocks/"+tt.args.filename, &srcTx) + gotTx, ok := Normalize(&srcTx) + if ok != tt.ok { + t.Errorf("Normalize() ok = %v, wantOk %v", ok, tt.ok) + return + } + if !reflect.DeepEqual(gotTx, tt.wantTx) { + t.Errorf("Normalize() gotTx = %v, want %v", gotTx, tt.wantTx) + } + }) + } +} diff --git a/platform/iotex/api.go b/platform/iotex/api.go deleted file mode 100644 index 117aebc65..000000000 --- a/platform/iotex/api.go +++ /dev/null @@ -1,149 +0,0 @@ -package iotex - -import ( - "github.com/trustwallet/blockatlas/pkg/blockatlas" - "strconv" - "time" - - "github.com/spf13/viper" - "github.com/trustwallet/blockatlas/coin" -) - -type Platform struct { - client Client -} - -func (p *Platform) Init() error { - p.client = Client{blockatlas.InitClient(viper.GetString("iotex.api"))} - return nil -} - -func (p *Platform) Coin() coin.Coin { - return coin.Coins[coin.IOTX] -} - -func (p *Platform) CurrentBlockNumber() (int64, error) { - return p.client.GetLatestBlock() -} - -func (p *Platform) GetBlockByNumber(num int64) (*blockatlas.Block, error) { - var normalized []blockatlas.Tx - txs, err := p.client.GetTxsInBlock(num) - if err != nil { - return nil, err - } - - for _, action := range txs { - tx := Normalize(action) - if tx != nil { - normalized = append(normalized, *tx) - } - } - - return &blockatlas.Block{ - Number: num, - Txs: normalized, - }, nil -} - -func (p *Platform) GetTxsByAddress(address string) (blockatlas.TxPage, error) { - - txs := make([]blockatlas.Tx, 0) - var start int64 - - totalTrx, err := p.client.GetAddressTotalTransactions(address) - if err != nil { - return nil, err - } - - if totalTrx >= blockatlas.TxPerPage { - start = totalTrx - blockatlas.TxPerPage - } - - actions, err := p.client.GetTxsOfAddress(address, start) - if err != nil { - return nil, err - } - - for _, srcTx := range actions.ActionInfo { - tx := Normalize(srcTx) - if tx != nil { - txs = append(txs, *tx) - } - } - - return txs, nil -} - -// Normalize converts an Iotex transaction into the generic model -func Normalize(trx *ActionInfo) *blockatlas.Tx { - if trx.Action == nil { - return nil - } - if trx.Action.Core == nil { - return nil - } - if trx.Action.Core.Transfer == nil { - return nil - } - - date, err := time.Parse(time.RFC3339, trx.Timestamp) - if err != nil { - return nil - } - height, err := strconv.ParseInt(trx.BlkHeight, 10, 64) - if err != nil { - return nil - } - if height <= 0 { - return nil - } - nonce, err := strconv.ParseInt(trx.Action.Core.Nonce, 10, 64) - if err != nil { - return nil - } - - return &blockatlas.Tx{ - ID: trx.ActHash, - Coin: coin.IOTX, - From: trx.Sender, - To: trx.Action.Core.Transfer.Recipient, - Fee: blockatlas.Amount(trx.GasFee), - Date: date.Unix(), - Block: uint64(height), - Status: blockatlas.StatusCompleted, - Sequence: uint64(nonce), - Type: blockatlas.TxTransfer, - Meta: blockatlas.Transfer{ - Value: trx.Action.Core.Transfer.Amount, - Symbol: coin.Coins[coin.IOTX].Symbol, - Decimals: coin.Coins[coin.IOTX].Decimals, - }, - } -} - -func (p *Platform) GetValidators() (blockatlas.ValidatorPage, error) { - return p.client.GetValidators() -} - -func (p *Platform) GetDelegations(address string) (blockatlas.DelegationsPage, error) { - return p.client.GetDelegations(address) -} - -func (p *Platform) GetDetails() blockatlas.StakingDetails { - return blockatlas.StakingDetails{ - Reward: blockatlas.StakingReward{Annual: 0}, - MinimumAmount: blockatlas.Amount("100000000000000000000"), - LockTime: 259200, - Type: blockatlas.DelegationTypeDelegate, - } -} - -func (p *Platform) UndelegatedBalance(address string) (string, error) { - account, err := p.client.GetAccount(address) - if err != nil { - return "0", err - } - - return account.AccountMeta.Balance, nil -} diff --git a/platform/iotex/api_test.go b/platform/iotex/api_test.go deleted file mode 100644 index c74dde030..000000000 --- a/platform/iotex/api_test.go +++ /dev/null @@ -1,131 +0,0 @@ -package iotex - -import ( - "encoding/json" - "github.com/trustwallet/blockatlas/pkg/blockatlas" - "testing" - - "github.com/stretchr/testify/assert" - - "github.com/trustwallet/blockatlas/coin" -) - -const ( - transfer = ` -{ - "actionInfo": - [ - { - "action": - { - "core": - { - "version":1, - "nonce":"3", - "gasLimit":"10000", - "gasPrice":"1000000000000", - "transfer": - { - "amount":"21000000000000000000", - "recipient":"io1mwekae7qqwlr23220k5n9z3fmjxz72tuchra3m" - } - }, - "senderPubKey":"BKCXbZcntIxrdPFZdWratLOfKU2yUUc0LuF/ilB3JoQzd/mvXaUbPuBpIE/sUtxGo0YxcAcN0cylCo1EIPQwJqc=", - "signature":"V4JBmqjFU+UmdVKQZ1+2CVElZ8sUMz1m0wfJEE5J7hFAG72nD2oI0wrLnTGBM0CaD1BjNGJvELYKi/g5IvO3AgE=" - }, - "actHash":"109b75cb688a5347268cbf11b20fa90fd0a14e92a42ba735c046bbf1a6e66ad7", - "blkHash":"42ace162549ec8d44641d7da7184d1e12ebd4111b0d2888a2d97d88a7c4fa04b", - "blkHeight":"96202", - "sender":"io1mwekae7qqwlr23220k5n9z3fmjxz72tuchra3m", - "gasFee":"10000000000000000", - "timestamp":"2019-05-03T06:09:00Z" - }, - { - "action": - { - "core": - { - "version":1, - "nonce":"3", - "gasLimit":"10000", - "gasPrice":"1000000000000", - "transfer": - { - "amount":"21000000000000000000", - "recipient":"io1mwekae7qqwlr23220k5n9z3fmjxz72tuchra3m" - } - }, - "senderPubKey":"BKCXbZcntIxrdPFZdWratLOfKU2yUUc0LuF/ilB3JoQzd/mvXaUbPuBpIE/sUtxGo0YxcAcN0cylCo1EIPQwJqc=", - "signature":"V4JBmqjFU+UmdVKQZ1+2CVElZ8sUMz1m0wfJEE5J7hFAG72nD2oI0wrLnTGBM0CaD1BjNGJvELYKi/g5IvO3AgE=" - }, - "actHash":"109b75cb688a5347268cbf11b20fa90fd0a14e92a42ba735c046bbf1a6e66ad7", - "blkHash":"42ace162549ec8d44641d7da7184d1e12ebd4111b0d2888a2d97d88a7c4fa04b", - "blkHeight":"0", - "sender":"io1mwekae7qqwlr23220k5n9z3fmjxz72tuchra3m", - "gasFee":"10000000000000000", - "timestamp":"2019-05-03T06:09:00Z" - }, - { - "action": - { - "core": - { - "version":1, - "nonce":"3.1", - "gasLimit":"10000", - "gasPrice":"1000000000000", - "transfer": - { - "amount":"21000000000000000000", - "recipient":"io1mwekae7qqwlr23220k5n9z3fmjxz72tuchra3m" - } - }, - "senderPubKey":"BKCXbZcntIxrdPFZdWratLOfKU2yUUc0LuF/ilB3JoQzd/mvXaUbPuBpIE/sUtxGo0YxcAcN0cylCo1EIPQwJqc=", - "signature":"V4JBmqjFU+UmdVKQZ1+2CVElZ8sUMz1m0wfJEE5J7hFAG72nD2oI0wrLnTGBM0CaD1BjNGJvELYKi/g5IvO3AgE=" - }, - "actHash":"109b75cb688a5347268cbf11b20fa90fd0a14e92a42ba735c046bbf1a6e66ad7", - "blkHash":"42ace162549ec8d44641d7da7184d1e12ebd4111b0d2888a2d97d88a7c4fa04b", - "blkHeight":"96202", - "sender":"io1mwekae7qqwlr23220k5n9z3fmjxz72tuchra3m", - "gasFee":"10000000000000000", - "timestamp":"2019-05-03T06:09:00Z" - } - ] -} -` -) - -var expected = []*blockatlas.Tx{ - { - ID: "109b75cb688a5347268cbf11b20fa90fd0a14e92a42ba735c046bbf1a6e66ad7", - Coin: coin.IOTX, - From: "io1mwekae7qqwlr23220k5n9z3fmjxz72tuchra3m", - To: "io1mwekae7qqwlr23220k5n9z3fmjxz72tuchra3m", - Fee: blockatlas.Amount("10000000000000000"), - Date: int64(1556863740), - Block: 96202, - Status: blockatlas.StatusCompleted, - Sequence: uint64(3), - Type: blockatlas.TxTransfer, - Meta: blockatlas.Transfer{ - Value: blockatlas.Amount("21000000000000000000"), - Symbol: "IOTX", - Decimals: 18, - }, - }, - nil, - nil, -} - -func TestNormalize(t *testing.T) { - a := assert.New(t) - - var act Response - a.NoError(json.Unmarshal([]byte(transfer), &act)) - a.Equal(3, len(act.ActionInfo)) - - for i, v := range act.ActionInfo { - tx := Normalize(v) - a.Equal(expected[i], tx) - } -} diff --git a/platform/iotex/base.go b/platform/iotex/base.go new file mode 100644 index 000000000..e053e37a5 --- /dev/null +++ b/platform/iotex/base.go @@ -0,0 +1,21 @@ +package iotex + +import ( + "github.com/trustwallet/golibs/client" + "github.com/trustwallet/golibs/coin" + "github.com/trustwallet/golibs/network/middleware" +) + +type Platform struct { + client Client +} + +func Init(api string) *Platform { + return &Platform{ + client: Client{client.InitClient(api, middleware.SentryErrorHandler)}, + } +} + +func (p *Platform) Coin() coin.Coin { + return coin.Iotex() +} diff --git a/platform/iotex/block.go b/platform/iotex/block.go new file mode 100644 index 000000000..a0a3804e0 --- /dev/null +++ b/platform/iotex/block.go @@ -0,0 +1,27 @@ +package iotex + +import "github.com/trustwallet/golibs/types" + +func (p *Platform) CurrentBlockNumber() (int64, error) { + return p.client.GetLatestBlock() +} + +func (p *Platform) GetBlockByNumber(num int64) (*types.Block, error) { + var normalized types.Txs + txs, err := p.client.GetTxsInBlock(num) + if err != nil { + return nil, err + } + + for _, action := range txs { + tx := Normalize(action) + if tx != nil { + normalized = append(normalized, *tx) + } + } + + return &types.Block{ + Number: num, + Txs: normalized, + }, nil +} diff --git a/platform/iotex/client.go b/platform/iotex/client.go index fe00476e7..1143493a3 100644 --- a/platform/iotex/client.go +++ b/platform/iotex/client.go @@ -2,15 +2,16 @@ package iotex import ( "fmt" - "github.com/trustwallet/blockatlas/pkg/blockatlas" - "github.com/trustwallet/blockatlas/pkg/errors" - "github.com/trustwallet/blockatlas/pkg/logger" "net/url" "strconv" + + "github.com/trustwallet/blockatlas/pkg/blockatlas" + "github.com/trustwallet/golibs/client" + "github.com/trustwallet/golibs/types" ) type Client struct { - blockatlas.Request + client.Request } func (c *Client) GetLatestBlock() (int64, error) { @@ -21,7 +22,7 @@ func (c *Client) GetLatestBlock() (int64, error) { } b, err := strconv.ParseInt(chainMeta.Height, 10, 64) if err != nil { - return 0, errors.E(err, "ParseInt failed", errors.TypePlatformUnmarshal).PushToSentry() + return 0, err } return b, nil } @@ -40,11 +41,10 @@ func (c *Client) GetTxsOfAddress(address string, start int64) (*Response, error) var response Response err := c.Get(&response, "actions/addr/"+address, url.Values{ "start": {strconv.FormatInt(start, 10)}, - "count": {strconv.FormatInt(blockatlas.TxPerPage, 10)}, + "count": {strconv.Itoa(types.TxPerPage)}, }) if err != nil { - logger.Error(err, "IOTEX: Failed to get transactions for address", logger.Params{"address": address}) return nil, blockatlas.ErrSourceConn } return &response, err diff --git a/platform/iotex/mocks/transfer.json b/platform/iotex/mocks/transfer.json new file mode 100644 index 000000000..3f223135b --- /dev/null +++ b/platform/iotex/mocks/transfer.json @@ -0,0 +1,70 @@ +{ + "actionInfo": [ + { + "action": { + "core": { + "version": 1, + "nonce": "3", + "gasLimit": "10000", + "gasPrice": "1000000000000", + "transfer": { + "amount": "21000000000000000000", + "recipient": "io1mwekae7qqwlr23220k5n9z3fmjxz72tuchra3m" + } + }, + "senderPubKey": "BKCXbZcntIxrdPFZdWratLOfKU2yUUc0LuF/ilB3JoQzd/mvXaUbPuBpIE/sUtxGo0YxcAcN0cylCo1EIPQwJqc=", + "signature": "V4JBmqjFU+UmdVKQZ1+2CVElZ8sUMz1m0wfJEE5J7hFAG72nD2oI0wrLnTGBM0CaD1BjNGJvELYKi/g5IvO3AgE=" + }, + "actHash": "109b75cb688a5347268cbf11b20fa90fd0a14e92a42ba735c046bbf1a6e66ad7", + "blkHash": "42ace162549ec8d44641d7da7184d1e12ebd4111b0d2888a2d97d88a7c4fa04b", + "blkHeight": "96202", + "sender": "io1mwekae7qqwlr23220k5n9z3fmjxz72tuchra3m", + "gasFee": "10000000000000000", + "timestamp": "2019-05-03T06:09:00Z" + }, + { + "action": { + "core": { + "version": 1, + "nonce": "3", + "gasLimit": "10000", + "gasPrice": "1000000000000", + "transfer": { + "amount": "21000000000000000000", + "recipient": "io1mwekae7qqwlr23220k5n9z3fmjxz72tuchra3m" + } + }, + "senderPubKey": "BKCXbZcntIxrdPFZdWratLOfKU2yUUc0LuF/ilB3JoQzd/mvXaUbPuBpIE/sUtxGo0YxcAcN0cylCo1EIPQwJqc=", + "signature": "V4JBmqjFU+UmdVKQZ1+2CVElZ8sUMz1m0wfJEE5J7hFAG72nD2oI0wrLnTGBM0CaD1BjNGJvELYKi/g5IvO3AgE=" + }, + "actHash": "109b75cb688a5347268cbf11b20fa90fd0a14e92a42ba735c046bbf1a6e66ad7", + "blkHash": "42ace162549ec8d44641d7da7184d1e12ebd4111b0d2888a2d97d88a7c4fa04b", + "blkHeight": "0", + "sender": "io1mwekae7qqwlr23220k5n9z3fmjxz72tuchra3m", + "gasFee": "10000000000000000", + "timestamp": "2019-05-03T06:09:00Z" + }, + { + "action": { + "core": { + "version": 1, + "nonce": "3.1", + "gasLimit": "10000", + "gasPrice": "1000000000000", + "transfer": { + "amount": "21000000000000000000", + "recipient": "io1mwekae7qqwlr23220k5n9z3fmjxz72tuchra3m" + } + }, + "senderPubKey": "BKCXbZcntIxrdPFZdWratLOfKU2yUUc0LuF/ilB3JoQzd/mvXaUbPuBpIE/sUtxGo0YxcAcN0cylCo1EIPQwJqc=", + "signature": "V4JBmqjFU+UmdVKQZ1+2CVElZ8sUMz1m0wfJEE5J7hFAG72nD2oI0wrLnTGBM0CaD1BjNGJvELYKi/g5IvO3AgE=" + }, + "actHash": "109b75cb688a5347268cbf11b20fa90fd0a14e92a42ba735c046bbf1a6e66ad7", + "blkHash": "42ace162549ec8d44641d7da7184d1e12ebd4111b0d2888a2d97d88a7c4fa04b", + "blkHeight": "96202", + "sender": "io1mwekae7qqwlr23220k5n9z3fmjxz72tuchra3m", + "gasFee": "10000000000000000", + "timestamp": "2019-05-03T06:09:00Z" + } + ] +} diff --git a/platform/iotex/model.go b/platform/iotex/model.go index d616d8a5d..a15dd6573 100644 --- a/platform/iotex/model.go +++ b/platform/iotex/model.go @@ -1,8 +1,6 @@ package iotex -import ( - "github.com/trustwallet/blockatlas/pkg/blockatlas" -) +import "github.com/trustwallet/golibs/types" type Response struct { ActionInfo []*ActionInfo `json:"actionInfo"` @@ -39,8 +37,8 @@ type ActionCore struct { } type Transfer struct { - Amount blockatlas.Amount `json:"amount"` - Recipient string `json:"recipient"` + Amount types.Amount `json:"amount"` + Recipient string `json:"recipient"` } type ChainMeta struct { diff --git a/platform/iotex/stake.go b/platform/iotex/stake.go new file mode 100644 index 000000000..5ccbefbf7 --- /dev/null +++ b/platform/iotex/stake.go @@ -0,0 +1,45 @@ +package iotex + +import ( + "github.com/trustwallet/blockatlas/pkg/blockatlas" + "github.com/trustwallet/blockatlas/services/assets" + "github.com/trustwallet/golibs/types" +) + +func (p *Platform) GetActiveValidators() (blockatlas.StakeValidators, error) { + validators, err := assets.GetValidatorsMap(p) + if err != nil { + return nil, err + } + result := make(blockatlas.StakeValidators, 0, len(validators)) + for _, v := range validators { + result = append(result, v) + } + return result, nil +} + +func (p *Platform) GetValidators() (blockatlas.ValidatorPage, error) { + return p.client.GetValidators() +} + +func (p *Platform) GetDelegations(address string) (blockatlas.DelegationsPage, error) { + return p.client.GetDelegations(address) +} + +func (p *Platform) GetDetails() blockatlas.StakingDetails { + return blockatlas.StakingDetails{ + Reward: blockatlas.StakingReward{Annual: 0}, + MinimumAmount: types.Amount("100000000000000000000"), + LockTime: 259200, + Type: blockatlas.DelegationTypeDelegate, + } +} + +func (p *Platform) UndelegatedBalance(address string) (string, error) { + account, err := p.client.GetAccount(address) + if err != nil { + return "0", err + } + + return account.AccountMeta.Balance, nil +} diff --git a/platform/iotex/transaction.go b/platform/iotex/transaction.go new file mode 100644 index 000000000..e68640f89 --- /dev/null +++ b/platform/iotex/transaction.go @@ -0,0 +1,86 @@ +package iotex + +import ( + "strconv" + "time" + + "github.com/trustwallet/golibs/coin" + "github.com/trustwallet/golibs/types" +) + +func (p *Platform) GetTxsByAddress(address string) (types.Txs, error) { + txs := make(types.Txs, 0) + var start int64 + + totalTrx, err := p.client.GetAddressTotalTransactions(address) + if err != nil { + return nil, err + } + + if totalTrx >= types.TxPerPage { + start = totalTrx - types.TxPerPage + } + + actions, err := p.client.GetTxsOfAddress(address, start) + if err != nil { + return nil, err + } + + for _, srcTx := range actions.ActionInfo { + tx := Normalize(srcTx) + if tx != nil { + txs = append(txs, *tx) + } + } + + return txs, nil +} + +// Normalize converts an Iotex transaction into the generic model +func Normalize(trx *ActionInfo) *types.Tx { + if trx.Action == nil { + return nil + } + if trx.Action.Core == nil { + return nil + } + if trx.Action.Core.Transfer == nil { + return nil + } + + date, err := time.Parse(time.RFC3339, trx.Timestamp) + if err != nil { + return nil + } + height, err := strconv.ParseInt(trx.BlkHeight, 10, 64) + if err != nil { + return nil + } + if height <= 0 { + return nil + } + nonce, err := strconv.ParseInt(trx.Action.Core.Nonce, 10, 64) + if err != nil { + return nil + } + if trx.GasFee == "" { + trx.GasFee = "0" + } + return &types.Tx{ + ID: trx.ActHash, + Coin: coin.IOTEX, + From: trx.Sender, + To: trx.Action.Core.Transfer.Recipient, + Fee: types.Amount(trx.GasFee), + Date: date.Unix(), + Block: uint64(height), + Status: types.StatusCompleted, + Sequence: uint64(nonce), + Type: types.TxTransfer, + Meta: types.Transfer{ + Value: trx.Action.Core.Transfer.Amount, + Symbol: coin.Iotex().Symbol, + Decimals: coin.Iotex().Decimals, + }, + } +} diff --git a/platform/iotex/transaction_test.go b/platform/iotex/transaction_test.go new file mode 100644 index 000000000..66faf0ee2 --- /dev/null +++ b/platform/iotex/transaction_test.go @@ -0,0 +1,61 @@ +package iotex + +import ( + "reflect" + "testing" + + "github.com/trustwallet/golibs/coin" + "github.com/trustwallet/golibs/mock" + "github.com/trustwallet/golibs/types" +) + +func TestNormalize(t *testing.T) { + type args struct { + filename string + } + tests := []struct { + name string + args args + want []*types.Tx + }{ + { + name: "Test normalize actions", + args: args{ + filename: "transfer.json", + }, + want: []*types.Tx{ + { + ID: "109b75cb688a5347268cbf11b20fa90fd0a14e92a42ba735c046bbf1a6e66ad7", + Coin: coin.IOTEX, + From: "io1mwekae7qqwlr23220k5n9z3fmjxz72tuchra3m", + To: "io1mwekae7qqwlr23220k5n9z3fmjxz72tuchra3m", + Fee: types.Amount("10000000000000000"), + Date: int64(1556863740), + Block: 96202, + Status: types.StatusCompleted, + Sequence: uint64(3), + Type: types.TxTransfer, + Meta: types.Transfer{ + Value: types.Amount("21000000000000000000"), + Symbol: "IOTX", + Decimals: 18, + }, + }, + nil, + nil, + }, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + var response Response + _ = mock.JsonModelFromFilePath("mocks/"+tt.args.filename, &response) + for i, v := range response.ActionInfo { + if got := Normalize(v); !reflect.DeepEqual(got, tt.want[i]) { + t.Errorf("Normalize() = %v, want %v", got, tt.want[i]) + } + } + }) + } +} diff --git a/platform/kava/base.go b/platform/kava/base.go new file mode 100644 index 000000000..f7f580cdd --- /dev/null +++ b/platform/kava/base.go @@ -0,0 +1,23 @@ +package kava + +import ( + "github.com/trustwallet/golibs/client" + "github.com/trustwallet/golibs/coin" + "github.com/trustwallet/golibs/network/middleware" +) + +type Platform struct { + client Client + CoinIndex uint +} + +func Init(coin uint, api string) *Platform { + return &Platform{ + CoinIndex: coin, + client: Client{client.InitClient(api, middleware.SentryErrorHandler)}, + } +} + +func (p *Platform) Coin() coin.Coin { + return coin.Coins[p.CoinIndex] +} diff --git a/platform/kava/block.go b/platform/kava/block.go new file mode 100644 index 000000000..3732dd420 --- /dev/null +++ b/platform/kava/block.go @@ -0,0 +1,20 @@ +package kava + +import "github.com/trustwallet/golibs/types" + +func (p *Platform) GetBlockByNumber(num int64) (*types.Block, error) { + srcTxs, err := p.client.GetBlockByNumber(num) + if err != nil { + return nil, err + } + + txs := p.NormalizeTxs(srcTxs.Txs) + return &types.Block{ + Number: num, + Txs: txs, + }, nil +} + +func (p *Platform) CurrentBlockNumber() (int64, error) { + return p.client.CurrentBlockNumber() +} diff --git a/platform/kava/client.go b/platform/kava/client.go new file mode 100644 index 000000000..a1027bb35 --- /dev/null +++ b/platform/kava/client.go @@ -0,0 +1,90 @@ +package kava + +import ( + "fmt" + "net/url" + "strconv" + "time" + + "github.com/trustwallet/golibs/client" +) + +// Client - the HTTP client +type Client struct { + client.Request +} + +// GetAddrTxs - get all KAVA transactions for a given address +func (c *Client) GetAddrTxs(address, tag string, page int) (txs TxPage, err error) { + query := url.Values{ + tag: {address}, + "page": {strconv.Itoa(page)}, + "limit": {"25"}, + } + err = c.Get(&txs, "txs", query) + if err != nil { + return TxPage{}, err + } + return +} + +func (c *Client) GetValidators() (validators Validators, err error) { + query := url.Values{ + "status": {"bonded"}, + } + err = c.GetWithCache(&validators, "staking/validators", query, time.Minute*10) + return +} + +func (c *Client) GetBlockByNumber(num int64) (txs TxPage, err error) { + err = c.Get(&txs, "txs", url.Values{"tx.height": {strconv.FormatInt(num, 10)}}) + return +} + +func (c *Client) CurrentBlockNumber() (num int64, err error) { + var latest LasteBlock + err = c.Get(&latest, "blocks/latest", nil) + + if err != nil { + return num, err + } + + num, err = strconv.ParseInt(latest.Block.Header.Height, 10, 64) + if err != nil { + return num, err + } + return +} + +func (c *Client) GetPool() (result StakingPool, err error) { + return result, c.GetWithCache(&result, "staking/pool", nil, time.Minute*20) +} + +func (c *Client) GetInflation() (inflation Inflation, err error) { + err = c.GetWithCache(&inflation, "minting/inflation", nil, time.Minute*20) + return +} + +func (c *Client) GetDelegations(address string) (delegations Delegations, err error) { + path := fmt.Sprintf("staking/delegators/%s/delegations", address) + err = c.Get(&delegations, path, nil) + if err != nil { + return delegations, err + } + return +} + +func (c *Client) GetUnbondingDelegations(address string) (delegations UnbondingDelegations, err error) { + path := fmt.Sprintf("staking/delegators/%s/unbonding_delegations", address) + err = c.Get(&delegations, path, nil) + if err != nil { + return delegations, err + } + return +} + +func (c *Client) GetAccount(address string) (result AuthAccount, err error) { + path := fmt.Sprintf("auth/accounts/%s", address) + err = c.Get(&result, path, nil) + return +} diff --git a/platform/kava/model.go b/platform/kava/model.go new file mode 100644 index 000000000..cb69497a4 --- /dev/null +++ b/platform/kava/model.go @@ -0,0 +1,267 @@ +package kava + +import ( + "encoding/json" + "strconv" + "strings" +) + +type TxType string +type EventType string +type AttributeKey string +type DenomType string + +// Types of messages +const ( + MsgSend TxType = "cosmos-sdk/MsgSend" + MsgMultiSend TxType = "cosmos-sdk/MsgMultiSend" + MsgCreateValidator TxType = "cosmos-sdk/MsgCreateValidator" + MsgDelegate TxType = "cosmos-sdk/MsgDelegate" + MsgUndelegate TxType = "cosmos-sdk/MsgUndelegate" + MsgBeginRedelegate TxType = "cosmos-sdk/MsgBeginRedelegate" + MsgWithdrawDelegationReward TxType = "cosmos-sdk/MsgWithdrawDelegationReward" + MsgWithdrawValidatorCommission TxType = "cosmos-sdk/MsgWithdrawValidatorCommission" + MsgSubmitProposal TxType = "cosmos-sdk/MsgSubmitProposal" + MsgDeposit TxType = "cosmos-sdk/MsgDeposit" + MsgVote TxType = "cosmos-sdk/MsgVote" + TextProposal TxType = "cosmos-sdk/TextProposal" + MsgUnjail TxType = "cosmos-sdk/MsgUnjail" + + EventTransfer EventType = "transfer" + EventWithdrawRewards EventType = "withdraw_rewards" + + AttributeAmount AttributeKey = "amount" + AttributeValidator AttributeKey = "validator" + + DenomAtom DenomType = "uatom" + DenomKava DenomType = "ukava" +) + +// Tx - Base transaction object. Always returned as part of an array +type Tx struct { + Block string `json:"height"` + Code int `json:"code"` + Date string `json:"timestamp"` + ID string `json:"txhash"` + Data Data `json:"tx"` + Events Events `json:"events"` +} + +type TxPage struct { + PageTotal string `json:"page_total"` + Txs []Tx `json:"txs"` +} + +// Events +type Event struct { + Type EventType + Attributes Attributes `json:"Attributes"` +} + +type Events []*Event + +func (e Events) GetWithdrawRewardValue() string { + result := int64(0) + for _, att := range e { + if att.Type == EventWithdrawRewards { + result += att.Attributes.GetWithdrawRewardValue() + } + } + return strconv.FormatInt(result, 10) +} + +type Attribute struct { + Key AttributeKey `json:"key"` + Value string `json:"value"` +} + +type Attributes []Attribute + +func (a Attributes) GetWithdrawRewardValue() int64 { + result := int64(0) + for _, att := range a { + if att.Key == AttributeAmount { + idx := strings.IndexByte(att.Value, 'u') + if idx < 0 { + continue + } + value := att.Value[:idx] + v, err := strconv.ParseInt(value, 10, 64) + if err != nil { + continue + } + result += v + } + } + return result +} + +// Data - "tx" sub object +type Data struct { + Contents Contents `json:"value"` +} + +// Contents - amount, fee, and memo +type Contents struct { + Message []Message `json:"msg"` + Fee Fee `json:"fee"` + Memo string `json:"memo"` +} + +// Message - an array that holds multiple 'particulars' entries. Possibly used for multiple transfers in one transaction? +type Message struct { + Type TxType + Value interface{} +} + +// MessageValueTransfer - from, to, and amount +type MessageValueTransfer struct { + FromAddr string `json:"from_address"` + ToAddr string `json:"to_address"` + Amount []Amount `json:"amount,omitempty"` +} + +// MessageValueDelegate - from, to, and amount +type MessageValueDelegate struct { + DelegatorAddr string `json:"delegator_address"` + ValidatorAddr string `json:"validator_address"` + Amount Amount `json:"amount,omitempty"` +} + +// Fee - also references the "amount" struct +type Fee struct { + FeeAmount []Amount `json:"amount"` +} + +// Amount - the asset & quantity. Always seems to be enclosed in an array/list for some reason. +// Perhaps used for multiple tokens transferred in a single sender/reciever transfer? +type Amount struct { + Denom string `json:"denom"` + Quantity string `json:"amount"` +} + +// # Staking + +type CosmosCommission struct { + Commision CosmosCommissionRates `json:"commission_rates"` +} + +type CosmosCommissionRates struct { + Rate string `json:"rate"` +} + +type Validators struct { + Result []Validator `json:"result"` +} + +type Validator struct { + Status int `json:"status"` + Address string `json:"operator_address"` + Commission CosmosCommission `json:"commission"` +} + +type Inflation struct { + Result string `json:"result"` +} + +type Delegations struct { + List []Delegation `json:"result"` +} + +type Delegation struct { + DelegatorAddress string `json:"delegator_address"` + ValidatorAddress string `json:"validator_address"` + Shares string `json:"shares"` + Balance struct { + Denom string `json:"denom"` + Amount string `json:"amount"` + } `json:"balance"` +} + +func (d *Delegation) Value() string { + shares := strings.Split(d.Balance.Amount, ".") + if len(shares) > 0 { + return shares[0] + } + return d.Balance.Amount +} + +type UnbondingDelegations struct { + List []UnbondingDelegation `json:"result"` +} + +type UnbondingDelegation struct { + Delegation + Entries []UnbondingDelegationEntry `json:"entries"` +} + +type UnbondingDelegationEntry struct { + DelegatorAddress string `json:"creation_height"` + CompletionTime string `json:"completion_time"` + Balance string `json:"balance"` +} + +type StakingPool struct { + Pool Pool `json:"result"` +} + +type Pool struct { + NotBondedTokens string `json:"not_bonded_tokens"` + BondedTokens string `json:"bonded_tokens"` +} + +type LasteBlock struct { + Block Block `json:"block"` +} + +type Block struct { + Header BlockHeader `json:"header"` +} + +type BlockHeader struct { + Height string `json:"height"` +} + +//UnmarshalJSON reads different message types +func (m *Message) UnmarshalJSON(buf []byte) error { + var messageInternal struct { + Type TxType `json:"type"` + Value json.RawMessage `json:"value"` + } + + err := json.Unmarshal(buf, &messageInternal) + if err != nil { + return err + } + + m.Type = messageInternal.Type + + switch messageInternal.Type { + case MsgUndelegate, MsgDelegate, MsgWithdrawDelegationReward: + var msgDelegate MessageValueDelegate + err = json.Unmarshal(messageInternal.Value, &msgDelegate) + m.Value = msgDelegate + case MsgSend: + var msgTransfer MessageValueTransfer + err = json.Unmarshal(messageInternal.Value, &msgTransfer) + m.Value = msgTransfer + } + return err +} + +type AuthAccount struct { + Account Account `json:"result"` +} + +type Account struct { + Value AccountValue `json:"value"` +} + +type AccountValue struct { + Coins []Balance `json:"coins"` +} + +type Balance struct { + Denom DenomType `json:"denom"` + Amount string `json:"amount"` +} diff --git a/platform/kava/stake.go b/platform/kava/stake.go new file mode 100644 index 000000000..fdce7f112 --- /dev/null +++ b/platform/kava/stake.go @@ -0,0 +1,220 @@ +package kava + +import ( + "fmt" + "strconv" + "time" + + "github.com/trustwallet/blockatlas/pkg/blockatlas" + "github.com/trustwallet/blockatlas/services/assets" + "github.com/trustwallet/golibs/coin" + + log "github.com/sirupsen/logrus" +) + +const ( + lockTime = 1814400 // in seconds (21 days) + minimumAmount = "1" +) + +func (p *Platform) GetActiveValidators() (blockatlas.StakeValidators, error) { + validators, err := assets.GetValidatorsMap(p) + if err != nil { + return nil, err + } + result := make(blockatlas.StakeValidators, 0, len(validators)) + for _, v := range validators { + result = append(result, v) + } + return result, nil +} + +func (p *Platform) GetValidators() (blockatlas.ValidatorPage, error) { + results := make(blockatlas.ValidatorPage, 0) + validators, err := p.client.GetValidators() + if err != nil { + return nil, err + } + pool, err := p.client.GetPool() + if err != nil { + return nil, err + } + + inflation, err := p.client.GetInflation() + if err != nil { + return nil, err + } + inflationValue, err := strconv.ParseFloat(inflation.Result, 32) + if err != nil { + return nil, err + } + + for _, validator := range validators.Result { + results = append(results, normalizeValidator(validator, pool.Pool, inflationValue)) + } + + return results, nil +} + +func (p *Platform) GetDetails() blockatlas.StakingDetails { + apr := blockatlas.DefaultAnnualReward + validators, err := p.GetValidators() + if err == nil { + apr = blockatlas.FindHightestAPR(validators) + } + return blockatlas.StakingDetails{ + Reward: blockatlas.StakingReward{Annual: apr}, + MinimumAmount: minimumAmount, + LockTime: lockTime, + Type: blockatlas.DelegationTypeDelegate, + } +} + +func (p *Platform) GetDelegations(address string) (blockatlas.DelegationsPage, error) { + results := make(blockatlas.DelegationsPage, 0) + delegations, err := p.client.GetDelegations(address) + if err != nil { + return nil, err + } + unbondingDelegations, err := p.client.GetUnbondingDelegations(address) + if err != nil { + return nil, err + } + if delegations.List == nil && unbondingDelegations.List == nil { + return results, nil + } + validators, err := assets.GetValidatorsMap(p) + if err != nil { + return nil, err + } + results = append(results, NormalizeDelegations(delegations.List, validators)...) + results = append(results, NormalizeUnbondingDelegations(unbondingDelegations.List, validators)...) + + return results, nil +} + +func (p *Platform) UndelegatedBalance(address string) (string, error) { + account, err := p.client.GetAccount(address) + if err != nil { + return "0", err + } + for _, coin := range account.Account.Value.Coins { + if coin.Denom == p.Denom() { + return coin.Amount, nil + } + } + return "0", nil +} + +func NormalizeDelegations(delegations []Delegation, validators blockatlas.ValidatorMap) []blockatlas.Delegation { + results := make([]blockatlas.Delegation, 0) + for _, v := range delegations { + validator, ok := validators[v.ValidatorAddress] + if !ok { + log.WithFields( + log.Fields{"address": v.ValidatorAddress, "platform": "cosmos", "delegation": v.DelegatorAddress}, + ).Warn("Validator not found") + validator = getUnknownValidator(v.ValidatorAddress) + + } + delegation := blockatlas.Delegation{ + Delegator: validator, + Value: v.Value(), + Status: blockatlas.DelegationStatusActive, + } + results = append(results, delegation) + } + return results +} + +func NormalizeUnbondingDelegations(delegations []UnbondingDelegation, validators blockatlas.ValidatorMap) []blockatlas.Delegation { + results := make([]blockatlas.Delegation, 0) + for _, v := range delegations { + for _, entry := range v.Entries { + validator, ok := validators[v.ValidatorAddress] + if !ok { + log.WithFields( + log.Fields{"address": v.ValidatorAddress, "platform": "cosmos", "delegation": v.DelegatorAddress}, + ).Warn("Validator not found") + validator = getUnknownValidator(v.ValidatorAddress) + } + t, _ := time.Parse(time.RFC3339, entry.CompletionTime) + delegation := blockatlas.Delegation{ + Delegator: validator, + Value: entry.Balance, + Status: blockatlas.DelegationStatusPending, + Metadata: blockatlas.DelegationMetaDataPending{ + AvailableDate: uint(t.Unix()), + }, + } + results = append(results, delegation) + } + } + return results +} + +func normalizeValidator(v Validator, p Pool, inflation float64) (validator blockatlas.Validator) { + reward := CalculateAnnualReward(p, inflation, v) + return blockatlas.Validator{ + Status: v.Status == 2, + ID: v.Address, + Details: blockatlas.StakingDetails{ + Reward: blockatlas.StakingReward{Annual: reward}, + MinimumAmount: minimumAmount, + LockTime: lockTime, + Type: blockatlas.DelegationTypeDelegate, + }, + } +} + +func CalculateAnnualReward(p Pool, inflation float64, validator Validator) float64 { + if validator.Address == "kavavaloper1wu8m65vqazssv2rh8rthv532hzggfr3h9azwz9" { + fmt.Println(1) + } + notBondedTokens, err := strconv.ParseFloat(p.NotBondedTokens, 32) + if err != nil { + return 0 + } + + bondedTokens, err := strconv.ParseFloat(p.BondedTokens, 32) + if err != nil { + return 0 + } + + commission, err := strconv.ParseFloat(validator.Commission.Commision.Rate, 32) + if err != nil { + return 0 + } + result := (notBondedTokens + bondedTokens) / bondedTokens * inflation + return (result - (result * commission)) * 100 +} + +func (p *Platform) Denom() DenomType { + switch p.CoinIndex { + case coin.Cosmos().ID: + return DenomAtom + case coin.Kava().ID: + return DenomKava + default: + return DenomAtom + } +} + +func getUnknownValidator(address string) blockatlas.StakeValidator { + return blockatlas.StakeValidator{ + ID: address, + Status: false, + Info: blockatlas.StakeValidatorInfo{ + Name: "Decommissioned", + Description: "Decommissioned", + }, + Details: blockatlas.StakingDetails{ + Reward: blockatlas.StakingReward{ + Annual: 0, + }, + LockTime: lockTime, + MinimumAmount: minimumAmount, + Type: blockatlas.DelegationTypeDelegate, + }, + } +} diff --git a/platform/kava/stake_test.go b/platform/kava/stake_test.go new file mode 100644 index 000000000..958d23e6d --- /dev/null +++ b/platform/kava/stake_test.go @@ -0,0 +1,153 @@ +package kava + +import ( + "encoding/json" + "testing" + + "github.com/trustwallet/blockatlas/pkg/blockatlas" + + "github.com/stretchr/testify/assert" +) + +const validatorSrc = ` +{ + "operator_address": "cosmosvaloper1lktjhnzkpkz3ehrg8psvmwhafg56kfss3q3t8m", + "consensus_pubkey": "cosmosvalconspub1zcjduepqelcwpat987h9yq0ck6g9fsc8t0mththk547gwvk0w4wnkpl0stnspr3hdc", + "jailed": false, + "status": 2, + "tokens": "1557750969185", + "delegator_shares": "1557750969185.000000000000000000", + "description": { + "moniker": "Umbrella ☔", + "identity": "A530AC4D75991FE2", + "website": "https://umbrellavalidator.com", + "details": "One of the winners of Cosmos Game of Stakes, and HackAtom3." + }, + "unbonding_height": "0", + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.070400000000000000", + "max_rate": "1.000000000000000000", + "max_change_rate": "0.100000000000000000", + "update_time": "2019-08-05T07:10:23.689753607Z" + } + }, + "min_self_delegation": "1" +}` + +const delegationsSrc = ` +[ + { + "delegator_address": "cosmos135qla4294zxarqhhgxsx0sw56yssa3z0f78pm0", + "validator_address": "cosmosvaloper1qwl879nx9t6kef4supyazayf7vjhennyh568ys", + "shares": "109999.000001746056062372", + "balance": { + "denom": "ukava", + "amount": "109999" + } + } +]` + +const unbondingDelegationsSrc = ` +[ + { + "delegator_address": "cosmos135qla4294zxarqhhgxsx0sw56yssa3z0f78pm0", + "validator_address": "cosmosvaloper1qwl879nx9t6kef4supyazayf7vjhennyh568ys", + "entries": [ + { + "creation_height": "0", + "completion_time": "2020-01-01T06:54:18.441436491Z", + "initial_balance": "109999", + "balance": "109999" + } + ] + } +]` + +var stakingPool = Pool{"1222", "200"} + +var cosmosValidator = Validator{Commission: CosmosCommission{CosmosCommissionRates{Rate: "0.4"}}} + +var inflation = 0.7 + +func TestNormalizeValidator(t *testing.T) { + var v Validator + _ = json.Unmarshal([]byte(validatorSrc), &v) + expected := blockatlas.Validator{ + Status: true, + ID: v.Address, + Details: blockatlas.StakingDetails{ + Reward: blockatlas.StakingReward{Annual: 462.6619201898575}, + LockTime: lockTime, + MinimumAmount: minimumAmount, + Type: blockatlas.DelegationTypeDelegate, + }, + } + result := normalizeValidator(v, stakingPool, inflation) + assert.Equal(t, expected, result) +} + +func TestCalculateAnnualReward(t *testing.T) { + result := CalculateAnnualReward(Pool{"1222", "200"}, inflation, cosmosValidator) + assert.Equal(t, 298.61999703347686, result) +} + +var validator1 = blockatlas.StakeValidator{ + ID: "cosmosvaloper1qwl879nx9t6kef4supyazayf7vjhennyh568ys", + Status: true, + Info: blockatlas.StakeValidatorInfo{ + Name: "Certus One", + Description: "Stake and earn rewards with the most secure and stable validator. Winner of the Game of Stakes. Operated by Certus One Inc. By delegating, you confirm that you are aware of the risk of slashing and that Certus One Inc is not liable for any potential damages to your investment.", + Image: "https://assets.trustwalletapp.com/blockchains/cosmos/validators/assets/cosmosvaloper1qwl879nx9t6kef4supyazayf7vjhennyh568ys/logo.png", + Website: "https://certus.one", + }, + Details: blockatlas.StakingDetails{ + Reward: blockatlas.StakingReward{ + Annual: 9.259735525366604, + }, + LockTime: lockTime, + MinimumAmount: minimumAmount, + }, +} + +var validatorMap = blockatlas.ValidatorMap{ + "cosmosvaloper1qwl879nx9t6kef4supyazayf7vjhennyh568ys": validator1, +} + +func TestNormalizeDelegations(t *testing.T) { + var delegations []Delegation + err := json.Unmarshal([]byte(delegationsSrc), &delegations) + assert.NoError(t, err) + assert.NotNil(t, delegations) + + expected := []blockatlas.Delegation{ + { + Delegator: validator1, + Value: "109999", + Status: blockatlas.DelegationStatusActive, + }, + } + result := NormalizeDelegations(delegations, validatorMap) + assert.Equal(t, expected, result) +} + +func TestNormalizeUnbondingDelegations(t *testing.T) { + var delegations []UnbondingDelegation + err := json.Unmarshal([]byte(unbondingDelegationsSrc), &delegations) + assert.NoError(t, err) + assert.NotNil(t, delegations) + + expected := []blockatlas.Delegation{ + { + Delegator: validator1, + Value: "109999", + Status: blockatlas.DelegationStatusPending, + Metadata: blockatlas.DelegationMetaDataPending{ + AvailableDate: 1577861658, + }, + }, + } + result := NormalizeUnbondingDelegations(delegations, validatorMap) + assert.Equal(t, expected, result) +} diff --git a/platform/kava/transaction.go b/platform/kava/transaction.go new file mode 100644 index 000000000..931863b35 --- /dev/null +++ b/platform/kava/transaction.go @@ -0,0 +1,232 @@ +package kava + +import ( + "strconv" + "strings" + "sync" + "time" + + "github.com/trustwallet/golibs/numbers" + "github.com/trustwallet/golibs/types" +) + +const kavaDenom = "ukava" + +func (p *Platform) GetTxsByAddress(address string) (types.Txs, error) { + return p.GetTokenTxsByAddress(address, kavaDenom) +} + +func (p *Platform) GetTokenTxsByAddress(address, token string) (types.Txs, error) { + tagsList := []string{"transfer.recipient", "message.sender"} + var wg sync.WaitGroup + out := make(chan []Tx, len(tagsList)) + wg.Add(len(tagsList)) + for _, t := range tagsList { + go func(tag, addr string, wg *sync.WaitGroup) { + defer wg.Done() + page := 1 + txs, err := p.client.GetAddrTxs(addr, tag, page) + if err != nil { + return + } + // Condition when no more pages to paginate + if txs.PageTotal == "1" || txs.PageTotal == "0" { + out <- txs.Txs + return + } + + totalPages, err := strconv.Atoi(txs.PageTotal) + if err != nil { + return + } + // gaia does support sort option, paginate to get latest transactions by passing total pages page + // https://github.com/cosmos/gaia/blob/f61b391aee5d04364d2b5539692bbb187ad9b946/docs/resources/gaiacli.md#query-transactions + txs2, err := p.client.GetAddrTxs(addr, tag, totalPages) + if err != nil { + return + } + out <- txs2.Txs + }(t, address, &wg) + } + wg.Wait() + close(out) + srcTxs := make([]Tx, 0) + for r := range out { + filteredTxs := p.FilterTxsByDenom(r, token) + srcTxs = append(srcTxs, filteredTxs...) + } + return p.NormalizeTxs(srcTxs), nil +} + +func (p *Platform) FilterTxsByDenom(txs []Tx, denom string) []Tx { + filteredTxs := make([]Tx, 0) + for _, tx := range txs { + messages := tx.Data.Contents.Message + if len(messages) == 0 { + continue + } + var amount Amount + switch messages[0].Value.(type) { + case MessageValueTransfer: + amount = messages[0].Value.(MessageValueTransfer).Amount[0] + case MessageValueDelegate: + amount = messages[0].Value.(MessageValueDelegate).Amount + } + if amount.Denom == denom { + filteredTxs = append(filteredTxs, tx) + } + } + return filteredTxs +} + +// NormalizeTxs converts multiple Cosmos transactions +func (p *Platform) NormalizeTxs(srcTxs []Tx) types.Txs { + txMap := make(map[string]bool) + txs := make(types.Txs, 0) + for _, srcTx := range srcTxs { + _, ok := txMap[srcTx.ID] + if ok { + continue + } + normalisedInputTx, ok := p.Normalize(&srcTx) + if ok { + txMap[srcTx.ID] = true + txs = append(txs, normalisedInputTx) + } + } + return txs +} + +// Normalize converts an Cosmos transaction into the generic model +func (p *Platform) Normalize(srcTx *Tx) (tx types.Tx, ok bool) { + date, err := time.Parse("2006-01-02T15:04:05Z", srcTx.Date) + if err != nil { + return types.Tx{}, false + } + block, err := strconv.ParseUint(srcTx.Block, 10, 64) + if err != nil { + return types.Tx{}, false + } + // Sometimes fees can be null objects (in the case of no fees e.g. F044F91441C460EDCD90E0063A65356676B7B20684D94C731CF4FAB204035B41) + fee := "0" + if len(srcTx.Data.Contents.Fee.FeeAmount) > 0 { + qty := srcTx.Data.Contents.Fee.FeeAmount[0].Quantity + if len(qty) > 0 && qty != fee { + fee, err = numbers.DecimalToSatoshis(srcTx.Data.Contents.Fee.FeeAmount[0].Quantity) + if err != nil { + return types.Tx{}, false + } + } + } + + status := types.StatusCompleted + // https://github.com/cosmos/cosmos-sdk/blob/95ddc242ad024ca78a359a13122dade6f14fd676/types/errors/errors.go#L19 + if srcTx.Code > 0 { + status = types.StatusError + } + + tx = types.Tx{ + ID: srcTx.ID, + Coin: p.Coin().ID, + Date: date.Unix(), + Status: status, + Fee: types.Amount(fee), + Block: block, + Memo: srcTx.Data.Contents.Memo, + } + + if len(srcTx.Data.Contents.Message) == 0 { + return tx, false + } + + msg := srcTx.Data.Contents.Message[0] + switch msg.Value.(type) { + case MessageValueTransfer: + transfer := msg.Value.(MessageValueTransfer) + p.fillTransfer(&tx, transfer) + return tx, true + case MessageValueDelegate: + delegate := msg.Value.(MessageValueDelegate) + p.fillDelegate(&tx, delegate, srcTx.Events, msg.Type) + return tx, true + } + return tx, false +} + +func (p *Platform) fillTransfer(tx *types.Tx, transfer MessageValueTransfer) { + if len(transfer.Amount) == 0 { + return + } + amount := transfer.Amount[0] + value, err := numbers.DecimalToSatoshis(amount.Quantity) + if err != nil { + return + } + tx.From = transfer.FromAddr + tx.To = transfer.ToAddr + tx.Type = types.TxTransfer + tx.Meta = types.Transfer{ + Value: types.Amount(value), + Symbol: p.Coin().Symbol, + Decimals: p.Coin().Decimals, + } + switch { + case amount.Denom == kavaDenom: + tx.Type = types.TxTransfer + tx.Meta = types.Transfer{ + Value: types.Amount(value), + Symbol: p.Coin().Symbol, + Decimals: p.Coin().Decimals, + } + default: + tx.Type = types.TxNativeTokenTransfer + tx.Meta = types.NativeTokenTransfer{ + Decimals: p.Coin().Decimals, + From: tx.From, + Symbol: strings.ToUpper(amount.Denom), + Name: amount.Denom, + To: tx.To, + TokenID: amount.Denom, + Value: types.Amount(value), + } + } +} + +func (p *Platform) fillDelegate(tx *types.Tx, delegate MessageValueDelegate, events Events, msgType TxType) { + value := "" + if len(delegate.Amount.Quantity) > 0 { + var err error + value, err = numbers.DecimalToSatoshis(delegate.Amount.Quantity) + if err != nil { + return + } + } + tx.From = delegate.DelegatorAddr + tx.To = delegate.ValidatorAddr + tx.Type = types.TxAnyAction + + key := types.KeyStakeDelegate + title := types.KeyTitle("") + switch msgType { + case MsgDelegate: + tx.Direction = types.DirectionOutgoing + title = types.AnyActionDelegation + case MsgUndelegate: + tx.Direction = types.DirectionIncoming + title = types.AnyActionUndelegation + case MsgWithdrawDelegationReward: + tx.Direction = types.DirectionIncoming + title = types.AnyActionClaimRewards + key = types.KeyStakeClaimRewards + value = events.GetWithdrawRewardValue() + } + tx.Meta = types.AnyAction{ + Coin: p.Coin().ID, + Title: title, + Key: key, + Name: p.Coin().Name, + Symbol: p.Coin().Symbol, + Decimals: p.Coin().Decimals, + Value: types.Amount(value), + } +} diff --git a/platform/cosmos/api_test.go b/platform/kava/transaction_test.go similarity index 69% rename from platform/cosmos/api_test.go rename to platform/kava/transaction_test.go index c571ec9df..dc348453b 100644 --- a/platform/cosmos/api_test.go +++ b/platform/kava/transaction_test.go @@ -1,12 +1,13 @@ -package cosmos +package kava import ( "encoding/json" - "github.com/stretchr/testify/assert" - "github.com/trustwallet/blockatlas/pkg/blockatlas" "testing" - "github.com/trustwallet/blockatlas/coin" + "github.com/stretchr/testify/assert" + + "github.com/trustwallet/golibs/coin" + "github.com/trustwallet/golibs/types" ) const transferSrc = ` @@ -48,7 +49,7 @@ const transferSrc = ` "to_address": "cosmos1nynns8ex9fq6sjjfj8k79ymkdz4sqth06xexae", "amount": [ { - "denom": "uatom", + "denom": "ukava", "amount": "2271999999" } ] @@ -58,7 +59,7 @@ const transferSrc = ` "fee": { "amount": [ { - "denom": "uatom", + "denom": "ukava", "amount": "1" } ], @@ -118,7 +119,7 @@ const transferSrcKava = ` "to_address": "kava1z89utvygweg5l56fsk8ak7t6hh88fd0agl98n0", "amount": [ { - "denom": "uatom", + "denom": "ukava", "amount": "2271999999" } ] @@ -128,7 +129,7 @@ const transferSrcKava = ` "fee": { "amount": [ { - "denom": "uatom", + "denom": "ukava", "amount": "1" } ], @@ -149,6 +150,97 @@ const transferSrcKava = ` "timestamp": "2019-05-04T17:57:57Z" }` +const transferSrcKavaToken = ` +{ + "height": "645538", + "txhash": "514D43780335A1C516850FEE5692F59E9A9DF1D8D986FC62AC434BEB58EDB8E2", + "raw_log": "[{\"msg_index\":0,\"log\":\"\",\"events\":[{\"type\":\"message\",\"attributes\":[{\"key\":\"action\",\"value\":\"send\"},{\"key\":\"sender\",\"value\":\"kava1ys70jvnajkv88529ys6urjcyle3k2j9r24g6a7\"},{\"key\":\"module\",\"value\":\"bank\"}]},{\"type\":\"transfer\",\"attributes\":[{\"key\":\"recipient\",\"value\":\"kava1wj2swfmeakxdrlqemvpzx2a4ljux9l4xq6qmcn\"},{\"key\":\"sender\",\"value\":\"kava1ys70jvnajkv88529ys6urjcyle3k2j9r24g6a7\"},{\"key\":\"amount\",\"value\":\"10000000000hard\"}]}]}]", + "logs": [ + { + "msg_index": 0, + "log": "", + "events": [ + { + "type": "message", + "attributes": [ + { + "key": "action", + "value": "send" + }, + { + "key": "sender", + "value": "kava1ys70jvnajkv88529ys6urjcyle3k2j9r24g6a7" + }, + { + "key": "module", + "value": "bank" + } + ] + }, + { + "type": "transfer", + "attributes": [ + { + "key": "recipient", + "value": "kava1wj2swfmeakxdrlqemvpzx2a4ljux9l4xq6qmcn" + }, + { + "key": "sender", + "value": "kava1ys70jvnajkv88529ys6urjcyle3k2j9r24g6a7" + }, + { + "key": "amount", + "value": "10000000000hard" + } + ] + } + ] + } + ], + "gas_wanted": "200000", + "gas_used": "74794", + "tx": { + "type": "cosmos-sdk/StdTx", + "value": { + "msg": [ + { + "type": "cosmos-sdk/MsgSend", + "value": { + "from_address": "kava1ys70jvnajkv88529ys6urjcyle3k2j9r24g6a7", + "to_address": "kava1wj2swfmeakxdrlqemvpzx2a4ljux9l4xq6qmcn", + "amount": [ + { + "denom": "hard", + "amount": "10000000000" + } + ] + } + } + ], + "fee": { + "amount": [ + { + "denom": "ukava", + "amount": "30" + } + ], + "gas": "200000" +}, + "signatures": [ + { + "pub_key": { + "type": "tendermint/PubKeySecp256k1", + "value": "A/Uf73aHoxZXS7SvKweW4Ijo723YDLuhwhir6JSmVmWe" + }, + "signature": "Cuse3VunNLXi19GxASZD0fFMWeelEKe8DnC7nIYyS6FGqXzN+KP9hAdct7g9jczGT+4emVsQtiLvuM9Racrnyg==" + } + ], + "memo": "" +} +}, + "timestamp": "2020-12-19T10:49:24Z" +}` + const failedTransferSrc = ` { "height": "5552", @@ -168,7 +260,7 @@ const failedTransferSrc = ` "to_address": "cosmos1za4pu5gxm80fg6sx0956f88l2sx7jfg2vf7nlc", "amount": [ { - "denom": "uatom", + "denom": "ukava", "amount": "100000" } ] @@ -178,7 +270,7 @@ const failedTransferSrc = ` "fee": { "amount": [ { - "denom": "uatom", + "denom": "ukava", "amount": "2000" } ], @@ -237,7 +329,7 @@ const delegateSrc = ` "delegator_address":"cosmos1237l0vauhw78qtwq045jd24ay4urpec6r3xfn3", "validator_address":"cosmosvaloper12w6tynmjzq4l8zdla3v4x0jt8lt4rcz5gk7zg2", "amount":{ - "denom":"uatom", + "denom":"ukava", "amount":"49920" } } @@ -246,7 +338,7 @@ const delegateSrc = ` "fee":{ "amount":[ { - "denom":"uatom", + "denom":"ukava", "amount":"5000" } ], @@ -310,7 +402,7 @@ const unDelegateSrc = ` "delegator_address":"cosmos137rrp4p8n0nqcft0mwc62tdnyhhzf80knv5t94", "validator_address":"cosmosvaloper1te8nxpc2myjfrhaty0dnzdhs5ahdh5agzuym9v", "amount":{ - "denom":"uatom", + "denom":"ukava", "amount":"5100000000" } } @@ -319,7 +411,7 @@ const unDelegateSrc = ` "fee":{ "amount":[ { - "denom":"uatom", + "denom":"ukava", "amount":"5000" } ], @@ -375,7 +467,7 @@ const claimRewardSrc1 = ` "fee": { "amount": [ { - "denom": "uatom", + "denom": "ukava", "amount": "1000" } ], @@ -400,7 +492,7 @@ const claimRewardSrc1 = ` "attributes": [ { "key": "amount", - "value": "1138uatom" + "value": "1138ukava" }, { "key": "validator", @@ -408,7 +500,7 @@ const claimRewardSrc1 = ` }, { "key": "amount", - "value": "40612uatom" + "value": "40612ukava" }, { "key": "validator", @@ -416,7 +508,7 @@ const claimRewardSrc1 = ` }, { "key": "amount", - "value": "954uatom" + "value": "954ukava" }, { "key": "validator", @@ -424,7 +516,7 @@ const claimRewardSrc1 = ` }, { "key": "amount", - "value": "43574uatom" + "value": "43574ukava" }, { "key": "amount" @@ -457,7 +549,7 @@ const claimRewardSrc2 = ` "delegator_address": "cosmos1y6yvdel7zys8x60gz9067fjpcpygsn62ae9x46", "validator_address": "cosmosvaloper12w6tynmjzq4l8zdla3v4x0jt8lt4rcz5gk7zg2", "amount": { - "denom": "uatom", + "denom": "ukava", "amount": "2692326" } } @@ -466,7 +558,7 @@ const claimRewardSrc2 = ` "fee": { "amount": [ { - "denom": "uatom", + "denom": "ukava", "amount": "0" } ], @@ -512,7 +604,7 @@ const claimRewardSrc2 = ` }, { "key": "amount", - "value": "2692701uatom" + "value": "2692701ukava" } ] }, @@ -521,7 +613,7 @@ const claimRewardSrc2 = ` "attributes": [ { "key": "amount", - "value": "2692701uatom" + "value": "2692701ukava" }, { "key": "validator", @@ -532,24 +624,24 @@ const claimRewardSrc2 = ` ] }` -var transferDst = blockatlas.Tx{ +var transferDst = types.Tx{ ID: "E19B011D20D862DA0BEA7F24E3BC6DFF666EE6E044FCD9BD95B073478086DBB6", - Coin: coin.ATOM, + Coin: coin.COSMOS, From: "cosmos1rw62phusuv9vzraezr55k0vsqssvz6ed52zyrl", To: "cosmos1nynns8ex9fq6sjjfj8k79ymkdz4sqth06xexae", Fee: "1", Date: 1556992677, Block: 151980, - Status: blockatlas.StatusCompleted, - Type: blockatlas.TxTransfer, - Meta: blockatlas.Transfer{ + Status: types.StatusCompleted, + Type: types.TxTransfer, + Meta: types.Transfer{ Value: "2271999999", Symbol: coin.Cosmos().Symbol, Decimals: 6, }, } -var transferDstKava = blockatlas.Tx{ +var transferDstKava = types.Tx{ ID: "E19B011D20D862DA0BEA7F24E3BC6DFF666EE6E044FCD9BD95B073478086DBB6", Coin: coin.KAVA, From: "kava17wcggpjx007uc09s8y4hwrj8f228mlwe0n0upn", @@ -557,117 +649,138 @@ var transferDstKava = blockatlas.Tx{ Fee: "1", Date: 1556992677, Block: 151980, - Status: blockatlas.StatusCompleted, - Type: blockatlas.TxTransfer, - Meta: blockatlas.Transfer{ + Status: types.StatusCompleted, + Type: types.TxTransfer, + Meta: types.Transfer{ Value: "2271999999", Symbol: coin.Kava().Symbol, Decimals: 6, }, } -var delegateDst = blockatlas.Tx{ +var transferDstKavaToken = types.Tx{ + ID: "514D43780335A1C516850FEE5692F59E9A9DF1D8D986FC62AC434BEB58EDB8E2", + Coin: coin.KAVA, + From: "kava1ys70jvnajkv88529ys6urjcyle3k2j9r24g6a7", + To: "kava1wj2swfmeakxdrlqemvpzx2a4ljux9l4xq6qmcn", + Fee: "30", + Date: 1608374964, + Block: 645538, + Status: types.StatusCompleted, + Type: types.TxNativeTokenTransfer, + Meta: types.NativeTokenTransfer{ + Value: "10000000000", + Symbol: "HARD", + Decimals: 6, + From: "kava1ys70jvnajkv88529ys6urjcyle3k2j9r24g6a7", + To: "kava1wj2swfmeakxdrlqemvpzx2a4ljux9l4xq6qmcn", + TokenID: "hard", + Name: "hard", + }, +} + +var delegateDst = types.Tx{ ID: "11078091D1D5BD84F4275B6CEE02170428944DB0E8EEC37E980551435F6D04C7", - Coin: coin.ATOM, + Coin: coin.COSMOS, From: "cosmos1237l0vauhw78qtwq045jd24ay4urpec6r3xfn3", To: "cosmosvaloper12w6tynmjzq4l8zdla3v4x0jt8lt4rcz5gk7zg2", Fee: "5000", Date: 1564632616, Block: 1258202, - Status: blockatlas.StatusCompleted, - Type: blockatlas.TxAnyAction, - Direction: blockatlas.DirectionOutgoing, - Meta: blockatlas.AnyAction{ - Coin: coin.ATOM, - Title: blockatlas.AnyActionDelegation, - Key: blockatlas.KeyStakeDelegate, + Status: types.StatusCompleted, + Type: types.TxAnyAction, + Direction: types.DirectionOutgoing, + Meta: types.AnyAction{ + Coin: coin.COSMOS, + Title: types.AnyActionDelegation, + Key: types.KeyStakeDelegate, Name: coin.Cosmos().Name, - Symbol: coin.Coins[coin.ATOM].Symbol, - Decimals: coin.Coins[coin.ATOM].Decimals, + Symbol: coin.Coins[coin.COSMOS].Symbol, + Decimals: coin.Coins[coin.COSMOS].Decimals, Value: "49920", }, } -var unDelegateDst = blockatlas.Tx{ +var unDelegateDst = types.Tx{ ID: "A1EC36741FEF681F4A77B8F6032AD081100EE5ECB4CC76AEAC2174BC6B871CFE", - Coin: coin.ATOM, + Coin: coin.COSMOS, From: "cosmos137rrp4p8n0nqcft0mwc62tdnyhhzf80knv5t94", To: "cosmosvaloper1te8nxpc2myjfrhaty0dnzdhs5ahdh5agzuym9v", Fee: "5000", Date: 1564624521, Block: 1257037, - Status: blockatlas.StatusCompleted, - Type: blockatlas.TxAnyAction, - Direction: blockatlas.DirectionIncoming, - Meta: blockatlas.AnyAction{ - Coin: coin.ATOM, - Title: blockatlas.AnyActionUndelegation, - Key: blockatlas.KeyStakeDelegate, + Status: types.StatusCompleted, + Type: types.TxAnyAction, + Direction: types.DirectionIncoming, + Meta: types.AnyAction{ + Coin: coin.COSMOS, + Title: types.AnyActionUndelegation, + Key: types.KeyStakeDelegate, Name: coin.Cosmos().Name, - Symbol: coin.Coins[coin.ATOM].Symbol, - Decimals: coin.Coins[coin.ATOM].Decimals, + Symbol: coin.Coins[coin.COSMOS].Symbol, + Decimals: coin.Coins[coin.COSMOS].Decimals, Value: "5100000000", }, } -var claimRewardDst2 = blockatlas.Tx{ +var claimRewardDst2 = types.Tx{ ID: "082BA88EC055A7C343A353297EAC104CE87C659E0DDD84621C9AC3C284232800", - Coin: coin.ATOM, + Coin: coin.COSMOS, From: "cosmos1y6yvdel7zys8x60gz9067fjpcpygsn62ae9x46", To: "cosmosvaloper12w6tynmjzq4l8zdla3v4x0jt8lt4rcz5gk7zg2", Fee: "0", Date: 1576462863, Block: 54561, - Status: blockatlas.StatusCompleted, - Type: blockatlas.TxAnyAction, - Direction: blockatlas.DirectionIncoming, + Status: types.StatusCompleted, + Type: types.TxAnyAction, + Direction: types.DirectionIncoming, Memo: "复投", - Meta: blockatlas.AnyAction{ - Coin: coin.ATOM, - Title: blockatlas.AnyActionClaimRewards, - Key: blockatlas.KeyStakeClaimRewards, + Meta: types.AnyAction{ + Coin: coin.COSMOS, + Title: types.AnyActionClaimRewards, + Key: types.KeyStakeClaimRewards, Name: coin.Cosmos().Name, - Symbol: coin.Coins[coin.ATOM].Symbol, - Decimals: coin.Coins[coin.ATOM].Decimals, + Symbol: coin.Coins[coin.COSMOS].Symbol, + Decimals: coin.Coins[coin.COSMOS].Decimals, Value: "2692701", }, } -var claimRewardDst1 = blockatlas.Tx{ +var claimRewardDst1 = types.Tx{ ID: "C382DCFDC30E2DA294421DAEAD5862F118592A7B000EE91F6BEF8452A1F525D7", - Coin: coin.ATOM, + Coin: coin.COSMOS, From: "cosmos1cxehfdhfm96ljpktdxsj0k6xp9gtuheghwgqug", To: "cosmosvaloper1ptyzewnns2kn37ewtmv6ppsvhdnmeapvtfc9y5", Fee: "1000", Date: 1576638273, Block: 79678, - Status: blockatlas.StatusCompleted, - Type: blockatlas.TxAnyAction, - Direction: blockatlas.DirectionIncoming, + Status: types.StatusCompleted, + Type: types.TxAnyAction, + Direction: types.DirectionIncoming, Memo: "", - Meta: blockatlas.AnyAction{ - Coin: coin.ATOM, - Title: blockatlas.AnyActionClaimRewards, - Key: blockatlas.KeyStakeClaimRewards, + Meta: types.AnyAction{ + Coin: coin.COSMOS, + Title: types.AnyActionClaimRewards, + Key: types.KeyStakeClaimRewards, Name: coin.Cosmos().Name, - Symbol: coin.Coins[coin.ATOM].Symbol, - Decimals: coin.Coins[coin.ATOM].Decimals, + Symbol: coin.Coins[coin.COSMOS].Symbol, + Decimals: coin.Coins[coin.COSMOS].Decimals, Value: "86278", }, } -var failedTransferDst = blockatlas.Tx{ +var failedTransferDst = types.Tx{ ID: "5E78C65A8C1A6C8239EBBBBF2E42020E6ADBA8037EDEA83BF88E1A9159CF13B8", - Coin: coin.ATOM, + Coin: coin.COSMOS, From: "cosmos1shpfyt7psrff2ux7nznxvj6f7gq59fcqng5mku", To: "cosmos1za4pu5gxm80fg6sx0956f88l2sx7jfg2vf7nlc", Fee: "2000", Date: 1576120902, Block: 5552, - Status: blockatlas.StatusFailed, - Type: blockatlas.TxTransfer, + Status: types.StatusError, + Type: types.TxTransfer, Memo: "UniCoins registration rewards", - Meta: blockatlas.Transfer{ + Meta: types.Transfer{ Value: "100000", Symbol: coin.Cosmos().Symbol, Decimals: 6, @@ -678,12 +791,19 @@ type test struct { name string platform Platform Data string - want blockatlas.Tx + want types.Tx +} + +type filterTest struct { + name string + platform Platform + Data []string + want types.Txs } func TestNormalize(t *testing.T) { - cosmos := Platform{CoinIndex: coin.ATOM} + cosmos := Platform{CoinIndex: coin.COSMOS} kava := Platform{CoinIndex: coin.KAVA} tests := []test{ @@ -729,12 +849,58 @@ func TestNormalize(t *testing.T) { transferSrcKava, transferDstKava, }, + { + "test kava transfer token tx", + kava, + transferSrcKavaToken, + transferDstKavaToken, + }, } for _, tt := range tests { testNormalize(t, tt) } } +func TestFilterByDenom(t *testing.T) { + + kava := Platform{CoinIndex: coin.KAVA} + + test := filterTest{ + "test transfer tx", + kava, + []string{ + transferSrc, + delegateSrc, + unDelegateSrc, + claimRewardSrc1, + claimRewardSrc2, + failedTransferSrc, + transferSrcKava, + transferSrcKavaToken, + }, + types.Txs{transferDstKavaToken}, + } + + testFilter(t, test) +} + +func testFilter(t *testing.T, test filterTest) { + t.Run(test.name, func(t *testing.T) { + srcTxs := make([]Tx, 0) + for _, tx := range test.Data { + var srcTx Tx + err := json.Unmarshal([]byte(tx), &srcTx) + assert.Nil(t, err) + srcTxs = append(srcTxs, srcTx) + } + tx := test.platform.FilterTxsByDenom(srcTxs, "hard") + assert.Equal(t, len(test.want), len(tx), "length: filtered to expected 1 tx") + normalized, ok := test.platform.Normalize(&tx[0]) + assert.True(t, ok) + assert.Equal(t, test.want[0], normalized, "denom: filtered txs are equal") + }) +} + func testNormalize(t *testing.T, tt test) { t.Run(tt.name, func(t *testing.T) { var srcTx Tx diff --git a/platform/nano/base.go b/platform/nano/base.go new file mode 100644 index 000000000..ce657bab4 --- /dev/null +++ b/platform/nano/base.go @@ -0,0 +1,22 @@ +package nano + +import ( + "github.com/trustwallet/golibs/client" + "github.com/trustwallet/golibs/coin" + "github.com/trustwallet/golibs/network/middleware" +) + +type Platform struct { + client Client +} + +func Init(api string) *Platform { + p := &Platform{ + client: Client{client.InitJSONClient(api, middleware.SentryErrorHandler)}, + } + return p +} + +func (p *Platform) Coin() coin.Coin { + return coin.Coins[coin.NANO] +} diff --git a/platform/nano/client.go b/platform/nano/client.go index 9d8d86696..550fa723f 100644 --- a/platform/nano/client.go +++ b/platform/nano/client.go @@ -3,15 +3,16 @@ package nano import ( "strconv" - "github.com/trustwallet/blockatlas/pkg/blockatlas" + "github.com/trustwallet/golibs/client" + "github.com/trustwallet/golibs/types" ) type Client struct { - blockatlas.Request + client.Request } func (c *Client) GetAccountHistory(address string) (history AccountHistory, err error) { - count := strconv.Itoa(blockatlas.TxPerPage) + count := strconv.Itoa(types.TxPerPage) err = c.Post(&history, "", AccountHistoryRequest{Action: "account_history", Account: address, Count: count}) return } diff --git a/platform/nano/api.go b/platform/nano/transaction.go similarity index 51% rename from platform/nano/api.go rename to platform/nano/transaction.go index 95b57fecf..a84fa0b9a 100644 --- a/platform/nano/api.go +++ b/platform/nano/transaction.go @@ -4,28 +4,11 @@ import ( "encoding/json" "strconv" - "github.com/trustwallet/blockatlas/coin" - "github.com/trustwallet/blockatlas/pkg/blockatlas" - - "github.com/spf13/viper" + "github.com/trustwallet/golibs/types" ) -type Platform struct { - client Client -} - -func (p *Platform) Init() error { - p.client = Client{blockatlas.InitClient(viper.GetString("nano.api"))} - p.client.Headers["Content-Type"] = "application/json" - return nil -} - -func (p *Platform) Coin() coin.Coin { - return coin.Coins[coin.NANO] -} - -func (p *Platform) GetTxsByAddress(address string) (blockatlas.TxPage, error) { - normalized := make([]blockatlas.Tx, 0) +func (p *Platform) GetTxsByAddress(address string) (types.Txs, error) { + normalized := make(types.Txs, 0) history, err := p.client.GetAccountHistory(address) if err != nil { return normalized, err @@ -41,14 +24,17 @@ func (p *Platform) GetTxsByAddress(address string) (blockatlas.TxPage, error) { } for _, srcTx := range txs { - tx := p.Normalize(&srcTx, history.Account) + tx, err := p.Normalize(&srcTx, history.Account) + if err != nil { + continue + } normalized = append(normalized, tx) } return normalized, nil } -func (p *Platform) Normalize(srcTx *Transaction, account string) (tx blockatlas.Tx) { +func (p *Platform) Normalize(srcTx *Transaction, account string) (types.Tx, error) { var from string var to string @@ -60,14 +46,20 @@ func (p *Platform) Normalize(srcTx *Transaction, account string) (tx blockatlas. to = account } - status := blockatlas.StatusCompleted - height, _ := strconv.ParseUint(srcTx.Height, 10, 64) + status := types.StatusCompleted + height, err := strconv.ParseUint(srcTx.Height, 10, 64) + if err != nil { + return types.Tx{}, err + } if height == 0 { - status = blockatlas.StatusPending + status = types.StatusPending + } + timestamp, err := strconv.ParseInt(srcTx.LocalTimestamp, 10, 64) + if err != nil { + return types.Tx{}, err } - timestamp, _ := strconv.ParseInt(srcTx.LocalTimestamp, 10, 64) - tx = blockatlas.Tx{ + tx := types.Tx{ ID: srcTx.Hash, Coin: p.Coin().ID, Date: timestamp, @@ -76,11 +68,11 @@ func (p *Platform) Normalize(srcTx *Transaction, account string) (tx blockatlas. Block: height, Status: status, Fee: "0", - Meta: blockatlas.Transfer{ - Value: blockatlas.Amount(srcTx.Amount), + Meta: types.Transfer{ + Value: types.Amount(srcTx.Amount), Symbol: p.Coin().Symbol, Decimals: p.Coin().Decimals, }, } - return tx + return tx, nil } diff --git a/platform/nano/api_test.go b/platform/nano/transaction_test.go similarity index 83% rename from platform/nano/api_test.go rename to platform/nano/transaction_test.go index db0e92b7e..37d8690ed 100644 --- a/platform/nano/api_test.go +++ b/platform/nano/transaction_test.go @@ -4,7 +4,7 @@ import ( "reflect" "testing" - "github.com/trustwallet/blockatlas/pkg/blockatlas" + "github.com/trustwallet/golibs/types" ) func TestNormalize(t *testing.T) { @@ -16,7 +16,7 @@ func TestNormalize(t *testing.T) { tests := []struct { name string args args - wantTx blockatlas.Tx + wantTx types.Tx }{ { name: "Send", @@ -31,7 +31,7 @@ func TestNormalize(t *testing.T) { }, account: "nano_3ifzdoxn7keh7tn8zuwty1yr8k5pmaxoq6jpp3jidbjbfnz6hyanh89x6rwj", }, - wantTx: blockatlas.Tx{ + wantTx: types.Tx{ ID: "455C1A3E14E2A645EE4DFA120820614DE3A9876BA2673D0D38494396F3650227", Coin: 165, Date: 1573006938, @@ -40,8 +40,8 @@ func TestNormalize(t *testing.T) { Block: 4, Status: "completed", Fee: "0", - Meta: blockatlas.Transfer{ - Value: blockatlas.Amount("45000000000000000000000000000"), + Meta: types.Transfer{ + Value: types.Amount("45000000000000000000000000000"), Symbol: "NANO", Decimals: 30, }, @@ -60,7 +60,7 @@ func TestNormalize(t *testing.T) { }, account: "nano_3ifzdoxn7keh7tn8zuwty1yr8k5pmaxoq6jpp3jidbjbfnz6hyanh89x6rwj", }, - wantTx: blockatlas.Tx{ + wantTx: types.Tx{ ID: "5D6B19DE75D8C1BAF7D91FBDA71AFC5F0FED68D483DEC5A51F0767A2384D0DE2", Coin: 165, Date: 1570862429, @@ -69,8 +69,8 @@ func TestNormalize(t *testing.T) { Block: 1, Status: "completed", Fee: "0", - Meta: blockatlas.Transfer{ - Value: blockatlas.Amount("90000000000000000000000000000"), + Meta: types.Transfer{ + Value: types.Amount("90000000000000000000000000000"), Symbol: "NANO", Decimals: 30, }, @@ -79,7 +79,7 @@ func TestNormalize(t *testing.T) { } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - if gotTx := platform.Normalize(tt.args.srcTx, tt.args.account); !reflect.DeepEqual(gotTx, tt.wantTx) { + if gotTx, err := platform.Normalize(tt.args.srcTx, tt.args.account); !reflect.DeepEqual(gotTx, tt.wantTx) && err == nil { t.Errorf("Normalize() = %v, want %v", gotTx, tt.wantTx) } }) diff --git a/platform/near/base.go b/platform/near/base.go new file mode 100644 index 000000000..427c7927d --- /dev/null +++ b/platform/near/base.go @@ -0,0 +1,22 @@ +package near + +import ( + "github.com/trustwallet/golibs/client" + "github.com/trustwallet/golibs/coin" + "github.com/trustwallet/golibs/network/middleware" +) + +type Platform struct { + client Client +} + +func Init(api string) *Platform { + p := &Platform{ + client: Client{client.InitClient(api, middleware.SentryErrorHandler)}, + } + return p +} + +func (p *Platform) Coin() coin.Coin { + return coin.Coins[coin.NEAR] +} diff --git a/platform/near/client.go b/platform/near/client.go new file mode 100644 index 000000000..c289b3ea1 --- /dev/null +++ b/platform/near/client.go @@ -0,0 +1,7 @@ +package near + +import "github.com/trustwallet/golibs/client" + +type Client struct { + client.Request +} diff --git a/platform/near/transaction.go b/platform/near/transaction.go new file mode 100644 index 000000000..42a3a0e32 --- /dev/null +++ b/platform/near/transaction.go @@ -0,0 +1,8 @@ +package near + +import "github.com/trustwallet/golibs/types" + +func (p *Platform) GetTxsByAddress(address string) (types.Txs, error) { + normalized := make(types.Txs, 0) + return normalized, nil +} diff --git a/platform/nebulas/api.go b/platform/nebulas/api.go deleted file mode 100644 index 0a1f269eb..000000000 --- a/platform/nebulas/api.go +++ /dev/null @@ -1,76 +0,0 @@ -package nebulas - -import ( - "github.com/spf13/viper" - "github.com/trustwallet/blockatlas/coin" - "github.com/trustwallet/blockatlas/pkg/blockatlas" -) - -type Platform struct { - client Client -} - -func (p *Platform) Init() error { - p.client = Client{blockatlas.InitClient(viper.GetString("nebulas.api"))} - return nil -} - -func (p *Platform) Coin() coin.Coin { - return coin.Coins[coin.NAS] -} - -func (p *Platform) GetTxsByAddress(address string) (blockatlas.TxPage, error) { - txs, err := p.client.GetTxs(address, 1) - if err != nil { - return nil, err - } - - return NormalizeTxs(txs), nil -} - -func (p *Platform) CurrentBlockNumber() (int64, error) { - return p.client.GetLatestBlock() -} - -func (p *Platform) GetBlockByNumber(num int64) (*blockatlas.Block, error) { - txs, err := p.client.GetBlockByNumber(num) - if err != nil { - return nil, err - } - - return &blockatlas.Block{ - Number: num, - Txs: NormalizeTxs(txs), - }, nil -} - -func NormalizeTxs(txs []Transaction) []blockatlas.Tx { - normalizeTxs := make([]blockatlas.Tx, 0) - for _, srcTx := range txs { - normalizeTxs = append(normalizeTxs, NormalizeTx(srcTx)) - } - return normalizeTxs -} - -func NormalizeTx(srcTx Transaction) blockatlas.Tx { - var status = blockatlas.StatusCompleted - if srcTx.Status == 0 { - status = blockatlas.StatusFailed - } - return blockatlas.Tx{ - ID: srcTx.Hash, - Coin: coin.NAS, - From: srcTx.From.Hash, - To: srcTx.To.Hash, - Fee: blockatlas.Amount(srcTx.TxFee), - Date: int64(srcTx.Timestamp) / 1000, - Block: srcTx.Block.Height, - Status: status, - Sequence: srcTx.Nonce, - Meta: blockatlas.Transfer{ - Value: blockatlas.Amount(srcTx.Value), - Symbol: coin.Coins[coin.NAS].Symbol, - Decimals: coin.Coins[coin.NAS].Decimals, - }, - } -} diff --git a/platform/nebulas/api_test.go b/platform/nebulas/api_test.go deleted file mode 100644 index 4c6126a92..000000000 --- a/platform/nebulas/api_test.go +++ /dev/null @@ -1,84 +0,0 @@ -package nebulas - -import ( - "bytes" - "encoding/json" - "github.com/stretchr/testify/assert" - "github.com/trustwallet/blockatlas/coin" - "github.com/trustwallet/blockatlas/pkg/blockatlas" - "testing" -) - -const transferSrc = ` -{ - "hash": "96bd280d60447b7dbcdb3fa76a99856e0422a76304e9d01d0c87e1dfceb6d952", - "block": { - "height": 2848548 - }, - "from": { - "hash": "n1Yv9xJJcH4UjoJPVDGdUCL2CxK29asFuyV" - }, - "to": { - "hash": "n1TFrmLUDTe5ggQaWJiXHSqNSRzKYdaV6hQ" - }, - "value": "500000000000000000", - "nonce": 7, - "status": 1, - "timestamp": 1565213205000, - "type": "binary", - "currentTimestamp": 1565361175536, - "txFee": "400000000000000" -}` - -var transferDst = blockatlas.Tx{ - ID: "96bd280d60447b7dbcdb3fa76a99856e0422a76304e9d01d0c87e1dfceb6d952", - Coin: coin.NAS, - From: "n1Yv9xJJcH4UjoJPVDGdUCL2CxK29asFuyV", - To: "n1TFrmLUDTe5ggQaWJiXHSqNSRzKYdaV6hQ", - Fee: "400000000000000", - Sequence: 7, - Date: 1565213205, - Block: 2848548, - Status: blockatlas.StatusCompleted, - Meta: blockatlas.Transfer{ - Value: "500000000000000000", - Symbol: "NAS", - Decimals: 18, - }, -} - -func TestNormalize(t *testing.T) { - var srcTx Transaction - err := json.Unmarshal([]byte(transferSrc), &srcTx) - if err != nil { - t.Error(err) - return - } - - resTx := NormalizeTx(srcTx) - - resJSON, err := json.Marshal(&resTx) - if err != nil { - t.Fatal(err) - } - - dstJSON, err := json.Marshal(&transferDst) - if err != nil { - t.Fatal(err) - } - - if !bytes.Equal(resJSON, dstJSON) { - println(string(resJSON)) - println(string(dstJSON)) - t.Error("tx don't equal") - } -} - -func TestNormalizeTxs(t *testing.T) { - txs := []Transaction{ - Transaction{}, - Transaction{}, - } - - assert.Equal(t, 2, len(NormalizeTxs(txs))) -} diff --git a/platform/nebulas/base.go b/platform/nebulas/base.go new file mode 100644 index 000000000..341899467 --- /dev/null +++ b/platform/nebulas/base.go @@ -0,0 +1,21 @@ +package nebulas + +import ( + "github.com/trustwallet/golibs/client" + "github.com/trustwallet/golibs/coin" + "github.com/trustwallet/golibs/network/middleware" +) + +type Platform struct { + client Client +} + +func Init(api string) *Platform { + return &Platform{ + client: Client{client.InitClient(api, middleware.SentryErrorHandler)}, + } +} + +func (p *Platform) Coin() coin.Coin { + return coin.Nebulas() +} diff --git a/platform/nebulas/client.go b/platform/nebulas/client.go index d9ad319de..15790dbd8 100644 --- a/platform/nebulas/client.go +++ b/platform/nebulas/client.go @@ -1,15 +1,16 @@ package nebulas import ( - "github.com/trustwallet/blockatlas/pkg/blockatlas" "net/url" "strconv" + + "github.com/trustwallet/golibs/client" ) const TxTypeBinary = "binary" type Client struct { - blockatlas.Request + client.Request } func (c *Client) GetTxs(address string, page int) ([]Transaction, error) { diff --git a/platform/nebulas/mocks/transfer.json b/platform/nebulas/mocks/transfer.json new file mode 100644 index 000000000..f40d067d4 --- /dev/null +++ b/platform/nebulas/mocks/transfer.json @@ -0,0 +1,19 @@ +{ + "hash": "96bd280d60447b7dbcdb3fa76a99856e0422a76304e9d01d0c87e1dfceb6d952", + "block": { + "height": 2848548 + }, + "from": { + "hash": "n1Yv9xJJcH4UjoJPVDGdUCL2CxK29asFuyV" + }, + "to": { + "hash": "n1TFrmLUDTe5ggQaWJiXHSqNSRzKYdaV6hQ" + }, + "value": "500000000000000000", + "nonce": 7, + "status": 1, + "timestamp": 1565213205000, + "type": "binary", + "currentTimestamp": 1565361175536, + "txFee": "400000000000000" +} diff --git a/platform/nebulas/model.go b/platform/nebulas/model.go index 68ce55391..583370cd2 100644 --- a/platform/nebulas/model.go +++ b/platform/nebulas/model.go @@ -22,7 +22,7 @@ type Transaction struct { Nonce uint64 `json:"nonce"` Block Block `json:"block"` From Address `json:"from"` - To Address `json: "to"` + To Address `json:"to"` Timestamp int64 `json:"timestamp"` Status int32 `json:"status"` } diff --git a/platform/nebulas/transaction.go b/platform/nebulas/transaction.go new file mode 100644 index 000000000..4dcb6d042 --- /dev/null +++ b/platform/nebulas/transaction.go @@ -0,0 +1,62 @@ +package nebulas + +import ( + "github.com/trustwallet/golibs/coin" + "github.com/trustwallet/golibs/types" +) + +func (p *Platform) GetTxsByAddress(address string) (types.Txs, error) { + txs, err := p.client.GetTxs(address, 1) + if err != nil { + return nil, err + } + + return NormalizeTxs(txs), nil +} + +func (p *Platform) CurrentBlockNumber() (int64, error) { + return p.client.GetLatestBlock() +} + +func (p *Platform) GetBlockByNumber(num int64) (*types.Block, error) { + txs, err := p.client.GetBlockByNumber(num) + if err != nil { + return nil, err + } + + return &types.Block{ + Number: num, + Txs: NormalizeTxs(txs), + }, nil +} + +func NormalizeTxs(txs []Transaction) types.Txs { + normalizeTxs := make(types.Txs, 0) + for _, srcTx := range txs { + normalizeTxs = append(normalizeTxs, NormalizeTx(srcTx)) + } + return normalizeTxs +} + +func NormalizeTx(srcTx Transaction) types.Tx { + var status = types.StatusCompleted + if srcTx.Status == 0 { + status = types.StatusError + } + return types.Tx{ + ID: srcTx.Hash, + Coin: coin.NEBULAS, + From: srcTx.From.Hash, + To: srcTx.To.Hash, + Fee: types.Amount(srcTx.TxFee), + Date: int64(srcTx.Timestamp) / 1000, + Block: srcTx.Block.Height, + Status: status, + Sequence: srcTx.Nonce, + Meta: types.Transfer{ + Value: types.Amount(srcTx.Value), + Symbol: coin.Nebulas().Symbol, + Decimals: coin.Nebulas().Decimals, + }, + } +} diff --git a/platform/nebulas/transaction_test.go b/platform/nebulas/transaction_test.go new file mode 100644 index 000000000..f59eebdfb --- /dev/null +++ b/platform/nebulas/transaction_test.go @@ -0,0 +1,54 @@ +package nebulas + +import ( + "reflect" + "testing" + + "github.com/trustwallet/golibs/coin" + "github.com/trustwallet/golibs/mock" + "github.com/trustwallet/golibs/types" +) + +func TestNormalizeTx(t *testing.T) { + type args struct { + filename string + } + tests := []struct { + name string + args args + wantTx types.Tx + }{ + { + name: "Test normalize transaction", + args: args{ + filename: "transfer.json", + }, + wantTx: types.Tx{ + ID: "96bd280d60447b7dbcdb3fa76a99856e0422a76304e9d01d0c87e1dfceb6d952", + Coin: coin.NEBULAS, + From: "n1Yv9xJJcH4UjoJPVDGdUCL2CxK29asFuyV", + To: "n1TFrmLUDTe5ggQaWJiXHSqNSRzKYdaV6hQ", + Fee: "400000000000000", + Sequence: 7, + Date: 1565213205, + Block: 2848548, + Status: types.StatusCompleted, + Meta: types.Transfer{ + Value: "500000000000000000", + Symbol: "NAS", + Decimals: 18, + }, + }, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + var srcTx Transaction + _ = mock.JsonModelFromFilePath("mocks/"+tt.args.filename, &srcTx) + gotTx := NormalizeTx(srcTx) + if !reflect.DeepEqual(gotTx, tt.wantTx) { + t.Errorf("NormalizeTx() gotTx = %v, want %v", gotTx, tt.wantTx) + } + }) + } +} diff --git a/platform/nimiq/api.go b/platform/nimiq/api.go deleted file mode 100644 index 2d8ed6208..000000000 --- a/platform/nimiq/api.go +++ /dev/null @@ -1,77 +0,0 @@ -package nimiq - -import ( - "github.com/spf13/viper" - "github.com/trustwallet/blockatlas/coin" - "github.com/trustwallet/blockatlas/pkg/blockatlas" -) - -type Platform struct { - client Client -} - -func (p *Platform) Init() error { - p.client = Client{blockatlas.InitClient(viper.GetString("nimiq.api"))} - return nil -} - -func (p *Platform) Coin() coin.Coin { - return coin.Coins[coin.NIM] -} - -func (p *Platform) CurrentBlockNumber() (int64, error) { - return p.client.CurrentBlockNumber() -} - -func (p *Platform) GetBlockByNumber(num int64) (*blockatlas.Block, error) { - if srcBlock, err := p.client.GetBlockByNumber(num); err == nil { - block := NormalizeBlock(srcBlock) - return &block, nil - } else { - return nil, err - } -} - -func (p *Platform) GetTxsByAddress(address string) (blockatlas.TxPage, error) { - if srcTxs, err := p.client.GetTxsOfAddress(address, blockatlas.TxPerPage); err == nil { - return NormalizeTxs(srcTxs), err - } else { - return nil, err - } -} - -// NormalizeTx converts a Nimiq transaction into the generic model -func NormalizeTx(srcTx *Tx) blockatlas.Tx { - return blockatlas.Tx{ - ID: srcTx.Hash, - Coin: coin.NIM, - Date: srcTx.Timestamp, - From: srcTx.FromAddress, - To: srcTx.ToAddress, - Fee: srcTx.Fee, - Block: srcTx.BlockNumber, - Meta: blockatlas.Transfer{ - Value: srcTx.Value, - Symbol: coin.Coins[coin.NIM].Symbol, - Decimals: coin.Coins[coin.NIM].Decimals, - }, - } -} - -// NormalizeTxs converts multiple Nimiq transactions -func NormalizeTxs(srcTxs []Tx) []blockatlas.Tx { - txs := make([]blockatlas.Tx, len(srcTxs)) - for i, srcTx := range srcTxs { - txs[i] = NormalizeTx(&srcTx) - } - return txs -} - -// NormalizeBlock converts a Nimiq block into the generic model -func NormalizeBlock(srcBlock *Block) blockatlas.Block { - return blockatlas.Block{ - Number: srcBlock.Number, - ID: srcBlock.Hash, - Txs: NormalizeTxs(srcBlock.Txs), - } -} diff --git a/platform/nimiq/api_test.go b/platform/nimiq/api_test.go deleted file mode 100644 index 8699887b7..000000000 --- a/platform/nimiq/api_test.go +++ /dev/null @@ -1,69 +0,0 @@ -package nimiq - -import ( - "bytes" - "encoding/json" - "github.com/trustwallet/blockatlas/coin" - "github.com/trustwallet/blockatlas/pkg/blockatlas" - "testing" -) - -const basicSrc = ` -{ - "hash": "8b219949f4c1dfe9e7a9cdc5dbbc507e40dc16f44a1a5182ed6125c9a6891a50", - "blockHash": "ab36a0909c6ed5761a984ef261d9c3456b7c1aea6a52d531c5bf2518526a32e6", - "blockNumber": 252575, - "timestamp": 1538924505, - "confirmations": 271245, - "transactionIndex": 37, - "from": "4a88aaad038f9b8248865c4b9249efc554960e16", - "fromAddress": "NQ69 9A4A MB83 HXDQ 4J46 BH5R 4JFF QMA9 C3GN", - "to": "ad25610feb43d75307763d3f010822a757027429", - "toAddress": "NQ15 MLJN 23YB 8FBM 61TN 7LYG 2212 LVBG 4V19", - "value": 10000000000000, - "fee": 138, - "data": null, - "flags": 0 -} -` - -var basicDst = blockatlas.Tx{ - ID: "8b219949f4c1dfe9e7a9cdc5dbbc507e40dc16f44a1a5182ed6125c9a6891a50", - Coin: coin.NIM, - From: "NQ69 9A4A MB83 HXDQ 4J46 BH5R 4JFF QMA9 C3GN", - To: "NQ15 MLJN 23YB 8FBM 61TN 7LYG 2212 LVBG 4V19", - Fee: "138", - Date: 1538924505, - Block: 252575, - Meta: blockatlas.Transfer{ - Value: "10000000000000", - Symbol: "NIM", - Decimals: 5, - }, -} - -func TestNormalizeTx(t *testing.T) { - var srcTx Tx - err := json.Unmarshal([]byte(basicSrc), &srcTx) - if err != nil { - t.Error(err) - return - } - - tx := NormalizeTx(&srcTx) - resJSON, err := json.Marshal(&tx) - if err != nil { - t.Fatal(err) - } - - dstJSON, err := json.Marshal(&basicDst) - if err != nil { - t.Fatal(err) - } - - if !bytes.Equal(resJSON, dstJSON) { - println(string(resJSON)) - println(string(dstJSON)) - t.Error("basic: tx don't equal") - } -} diff --git a/platform/nimiq/base.go b/platform/nimiq/base.go new file mode 100644 index 000000000..690992cbf --- /dev/null +++ b/platform/nimiq/base.go @@ -0,0 +1,21 @@ +package nimiq + +import ( + "github.com/trustwallet/golibs/client" + "github.com/trustwallet/golibs/coin" + "github.com/trustwallet/golibs/network/middleware" +) + +type Platform struct { + client Client +} + +func Init(api string) *Platform { + return &Platform{ + client: Client{client.InitJSONClient(api, middleware.SentryErrorHandler)}, + } +} + +func (p *Platform) Coin() coin.Coin { + return coin.Nimiq() +} diff --git a/platform/nimiq/block.go b/platform/nimiq/block.go new file mode 100644 index 000000000..a4a49eb58 --- /dev/null +++ b/platform/nimiq/block.go @@ -0,0 +1,24 @@ +package nimiq + +import "github.com/trustwallet/golibs/types" + +func (p *Platform) CurrentBlockNumber() (int64, error) { + return p.client.CurrentBlockNumber() +} + +func (p *Platform) GetBlockByNumber(num int64) (*types.Block, error) { + srcBlock, err := p.client.GetBlockByNumber(num) + if err != nil { + return nil, err + } + block := NormalizeBlock(srcBlock) + return &block, nil +} + +// NormalizeBlock converts a Nimiq block into the generic model +func NormalizeBlock(srcBlock *Block) types.Block { + return types.Block{ + Number: srcBlock.Number, + Txs: NormalizeTxs(srcBlock.Txs), + } +} diff --git a/platform/nimiq/client.go b/platform/nimiq/client.go index c98c0a9da..7837a2bbe 100644 --- a/platform/nimiq/client.go +++ b/platform/nimiq/client.go @@ -1,16 +1,18 @@ package nimiq import ( - "github.com/trustwallet/blockatlas/pkg/blockatlas" "strconv" + + "github.com/trustwallet/golibs/client" + "github.com/trustwallet/golibs/types" ) type Client struct { - blockatlas.Request + client.Request } -func (c *Client) GetTxsOfAddress(address string, count int) (tx []Tx, err error) { - err = c.RpcCall(&tx, "getTransactionsByAddress", []string{address, strconv.Itoa(count)}) +func (c *Client) GetTxsOfAddress(address string) (tx []Tx, err error) { + err = c.RpcCall(&tx, "getTransactionsByAddress", []string{address, strconv.Itoa(types.TxPerPage)}) return } diff --git a/platform/nimiq/mocks/getTransactionsByAddress_50.json b/platform/nimiq/mocks/getTransactionsByAddress_50.json new file mode 100644 index 000000000..973f15bbe --- /dev/null +++ b/platform/nimiq/mocks/getTransactionsByAddress_50.json @@ -0,0 +1,62 @@ +[ + { + "hash": "61454a43916e075f0e0a830888db7a37e9ffc42503fa3cd2d9eb85fe8067e435", + "blockHash": "ec2c6712a977d62e95e0d43eca02bf4161c86197e576073429c0cdc6b9cc1ce1", + "blockNumber": 507486, + "timestamp": 1554283830, + "confirmations": 450839, + "from": "99643a627e867dae6cf10ca73b4aff0345d3b72e", + "fromAddress": "NQ76 K5J3 LQKX GRXS UT7H 1JKK NJPY 0D2V 7DRE", + "to": "0d609a98033b7b85ab5178c6050ef9ef82d9006e", + "toAddress": "NQ64 1MG9 M603 7DVQ BASH F330 A3PR VX1D J03E", + "value": 199400, + "fee": 300, + "data": null, + "flags": 0 + }, + { + "hash": "bc38ac8f4fa67222e38e6120073e327a1cc7c38b8419502f6fd5dc3699853296", + "blockHash": "58c6afb786829419c90bdcdaf0ab01630b36105affc1718e3d2e772d91d73621", + "blockNumber": 952271, + "timestamp": 1581094339, + "confirmations": 6054, + "from": "fdcc85a8e604f23c7d2cd3c13a5d18dc566a6e7c", + "fromAddress": "NQ02 YP68 BA76 0KR3 QY9C SF0K LP8Q THB6 LTKU", + "to": "99643a627e867dae6cf10ca73b4aff0345d3b72e", + "toAddress": "NQ76 K5J3 LQKX GRXS UT7H 1JKK NJPY 0D2V 7DRE", + "value": 100000, + "fee": 138, + "data": null, + "flags": 0 + }, + { + "hash": "54de2a0c420f9c145320c9a020decb106b0b8989fe4be147144af79dc13e8a1c", + "blockHash": "25b73d90dd38ff61f6c8d713671ba576f735fa3f544d0ea9a5f74f00aea082ff", + "blockNumber": 933566, + "timestamp": 1579965313, + "confirmations": 24759, + "from": "fdcc85a8e604f23c7d2cd3c13a5d18dc566a6e7c", + "fromAddress": "NQ02 YP68 BA76 0KR3 QY9C SF0K LP8Q THB6 LTKU", + "to": "99643a627e867dae6cf10ca73b4aff0345d3b72e", + "toAddress": "NQ76 K5J3 LQKX GRXS UT7H 1JKK NJPY 0D2V 7DRE", + "value": 100000, + "fee": 138, + "data": null, + "flags": 0 + }, + { + "hash": "874494dc2640876ad1417822e230304050ef37924b06ee84a8d8584935f2707b", + "blockHash": "c583c5ee1b375d46d07a1289de036b7e10c426184d8d85de7e6d6eec66681167", + "blockNumber": 591542, + "timestamp": 1559352602, + "confirmations": 366783, + "from": "fdcc85a8e604f23c7d2cd3c13a5d18dc566a6e7c", + "fromAddress": "NQ02 YP68 BA76 0KR3 QY9C SF0K LP8Q THB6 LTKU", + "to": "99643a627e867dae6cf10ca73b4aff0345d3b72e", + "toAddress": "NQ76 K5J3 LQKX GRXS UT7H 1JKK NJPY 0D2V 7DRE", + "value": 100000, + "fee": 138, + "data": null, + "flags": 0 + } +] diff --git a/platform/nimiq/mocks/pending_tx.json b/platform/nimiq/mocks/pending_tx.json new file mode 100644 index 000000000..56335f594 --- /dev/null +++ b/platform/nimiq/mocks/pending_tx.json @@ -0,0 +1,11 @@ +{ + "data": null, + "fee": 300, + "flags": 0, + "from": "d48182276127b149a9710e78c436fb4bc1c4dc0b", + "fromAddress": "NQ74 SJ0Q 49T1 4XQL KABH 1RUC 8DPT 9F0U 9P0B", + "hash": "79719d16f3f347cc98c35cd7a9af708cdce97de578b5135c5ae4393fd7920d61", + "to": "0a17218ffdc42385f45329ba4089919236dd2743", + "toAddress": "NQ97 18BJ 33YV QGHQ BV2K 56V4 12CH J8TD S9S3", + "value": 100000 +} diff --git a/platform/nimiq/mocks/tx.json b/platform/nimiq/mocks/tx.json new file mode 100644 index 000000000..cdbd29538 --- /dev/null +++ b/platform/nimiq/mocks/tx.json @@ -0,0 +1,16 @@ +{ + "hash": "8b219949f4c1dfe9e7a9cdc5dbbc507e40dc16f44a1a5182ed6125c9a6891a50", + "blockHash": "ab36a0909c6ed5761a984ef261d9c3456b7c1aea6a52d531c5bf2518526a32e6", + "blockNumber": 252575, + "timestamp": 1538924505, + "confirmations": 271245, + "transactionIndex": 37, + "from": "4a88aaad038f9b8248865c4b9249efc554960e16", + "fromAddress": "NQ69 9A4A MB83 HXDQ 4J46 BH5R 4JFF QMA9 C3GN", + "to": "ad25610feb43d75307763d3f010822a757027429", + "toAddress": "NQ15 MLJN 23YB 8FBM 61TN 7LYG 2212 LVBG 4V19", + "value": 10000000000000, + "fee": 138, + "data": null, + "flags": 0 +} diff --git a/platform/nimiq/model.go b/platform/nimiq/model.go index fcb3b8a88..b47c7f9fa 100644 --- a/platform/nimiq/model.go +++ b/platform/nimiq/model.go @@ -1,20 +1,22 @@ package nimiq import ( - "github.com/trustwallet/blockatlas/pkg/blockatlas" + "encoding/json" + + "github.com/trustwallet/golibs/types" ) type Tx struct { - Hash string `json:"hash"` - BlockHash string `json:"blockHash"` - BlockNumber uint64 `json:"blockNumber"` - Timestamp int64 `json:"timestamp"` - Confirmations int `json:"confirmations"` - TxIndex int `json:"transactionIndex"` - FromAddress string `json:"fromAddress"` - ToAddress string `json:"toAddress"` - Value blockatlas.Amount `json:"value"` - Fee blockatlas.Amount `json:"fee"` + Hash string `json:"hash"` + BlockHash string `json:"blockHash"` + BlockNumber uint64 `json:"blockNumber"` + Timestamp json.Number `json:"timestamp"` + Confirmations int `json:"confirmations"` + TxIndex int `json:"transactionIndex"` + FromAddress string `json:"fromAddress"` + ToAddress string `json:"toAddress"` + Value types.Amount `json:"value"` + Fee types.Amount `json:"fee"` } type Block struct { diff --git a/platform/nimiq/transaction.go b/platform/nimiq/transaction.go new file mode 100644 index 000000000..f2fd00bbe --- /dev/null +++ b/platform/nimiq/transaction.go @@ -0,0 +1,55 @@ +package nimiq + +import ( + "sort" + "time" + + "github.com/trustwallet/golibs/coin" + "github.com/trustwallet/golibs/types" +) + +func (p *Platform) GetTxsByAddress(address string) (types.Txs, error) { + srcTxs, err := p.client.GetTxsOfAddress(address) + if err != nil { + return nil, err + } + return NormalizeTxs(srcTxs), err +} + +// NormalizeTx converts a Nimiq transaction into the generic model +func NormalizeTx(srcTx *Tx) types.Tx { + date, err := srcTx.Timestamp.Int64() + // Pending transaction doesn't have a timestamp, we gonna use the current time + if err != nil || len(srcTx.BlockHash) == 0 { + date = time.Now().Unix() + } + return types.Tx{ + ID: srcTx.Hash, + Coin: coin.NIMIQ, + Date: date, + From: srcTx.FromAddress, + To: srcTx.ToAddress, + Fee: srcTx.Fee, + Block: srcTx.BlockNumber, + Meta: types.Transfer{ + Value: srcTx.Value, + Symbol: coin.Nimiq().Symbol, + Decimals: coin.Nimiq().Decimals, + }, + } +} + +// NormalizeTxs converts multiple Nimiq transactions +func NormalizeTxs(srcTxs []Tx) types.Txs { + sort.SliceStable(srcTxs, func(i, j int) bool { + return srcTxs[i].BlockNumber > srcTxs[j].BlockNumber + }) + if len(srcTxs) > types.TxPerPage { + srcTxs = srcTxs[:types.TxPerPage] + } + txs := make(types.Txs, len(srcTxs)) + for i, srcTx := range srcTxs { + txs[i] = NormalizeTx(&srcTx) + } + return txs +} diff --git a/platform/nimiq/transaction_test.go b/platform/nimiq/transaction_test.go new file mode 100644 index 000000000..f9a270942 --- /dev/null +++ b/platform/nimiq/transaction_test.go @@ -0,0 +1,92 @@ +package nimiq + +import ( + "encoding/json" + "fmt" + "math" + "sort" + "testing" + "time" + + "github.com/stretchr/testify/assert" + "github.com/trustwallet/golibs/coin" + "github.com/trustwallet/golibs/mock" + "github.com/trustwallet/golibs/types" +) + +var ( + basicSrc, _ = mock.JsonStringFromFilePath("mocks/" + "tx.json") + pendingSrc, _ = mock.JsonStringFromFilePath("mocks/" + "pending_tx.json") + basicDst = types.Tx{ + ID: "8b219949f4c1dfe9e7a9cdc5dbbc507e40dc16f44a1a5182ed6125c9a6891a50", + Coin: coin.NIMIQ, + From: "NQ69 9A4A MB83 HXDQ 4J46 BH5R 4JFF QMA9 C3GN", + To: "NQ15 MLJN 23YB 8FBM 61TN 7LYG 2212 LVBG 4V19", + Fee: "138", + Date: 1538924505, + Block: 252575, + Meta: types.Transfer{ + Value: "10000000000000", + Symbol: "NIM", + Decimals: 5, + }, + } + pendingDst = types.Tx{ + ID: "79719d16f3f347cc98c35cd7a9af708cdce97de578b5135c5ae4393fd7920d61", + Coin: coin.NIMIQ, + From: "NQ74 SJ0Q 49T1 4XQL KABH 1RUC 8DPT 9F0U 9P0B", + To: "NQ97 18BJ 33YV QGHQ BV2K 56V4 12CH J8TD S9S3", + Fee: "300", + Date: 666666, // special placholder value + Block: 0, + Meta: types.Transfer{ + Value: "100000", + Symbol: "NIM", + Decimals: 5, + }, + } +) + +func TestNormalizeTx1(t *testing.T) { + now := time.Now().Unix() + tests := []struct { + name string + srcTx string + want types.Tx + }{ + {"test transaction", basicSrc, basicDst}, + {"test pending transaction", pendingSrc, pendingDst}, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + var srcTx Tx + err := json.Unmarshal([]byte(tt.srcTx), &srcTx) + if err != nil { + fmt.Println(tt.srcTx) + t.Error(err) + return + } + got := NormalizeTx(&srcTx) + // special handling for current date, if around now, replace with special value + if math.Abs(float64(got.Date-now)) < 30 { + got.Date = 666666 + } + assert.Equal(t, tt.want, got) + }) + } +} + +func TestNormalizeTxs_Ordering(t *testing.T) { + var srcTxs []Tx + _ = mock.JsonModelFromFilePath("mocks/getTransactionsByAddress_50.json", &srcTxs) + txs := NormalizeTxs(srcTxs) + if len(txs) != 4 { + t.Fatalf("Unexpected count: %d", len(txs)) + } + sorted := sort.SliceIsSorted(txs, func(i, j int) bool { + return txs[i].Block > txs[j].Block + }) + if !sorted { + t.Fatal("Transactions not sorted") + } +} diff --git a/platform/oasis/base.go b/platform/oasis/base.go new file mode 100644 index 000000000..8c55d4837 --- /dev/null +++ b/platform/oasis/base.go @@ -0,0 +1,22 @@ +package oasis + +import ( + "github.com/trustwallet/golibs/client" + "github.com/trustwallet/golibs/coin" + "github.com/trustwallet/golibs/network/middleware" +) + +type Platform struct { + client Client +} + +func Init(api string) *Platform { + p := &Platform{ + client: Client{client.InitClient(api, middleware.SentryErrorHandler)}, + } + return p +} + +func (p *Platform) Coin() coin.Coin { + return coin.Oasis() +} diff --git a/platform/oasis/block.go b/platform/oasis/block.go new file mode 100644 index 000000000..b42e9eab5 --- /dev/null +++ b/platform/oasis/block.go @@ -0,0 +1,26 @@ +package oasis + +import ( + "github.com/trustwallet/golibs/types" +) + +func (p *Platform) CurrentBlockNumber() (int64, error) { + num, err := p.client.GetCurrentBlock() + if err != nil { + return 0, err + } + return num, nil +} + +func (p *Platform) GetBlockByNumber(num int64) (*types.Block, error) { + srcBlock, err := p.client.GetBlockByNumber(num) + if err == nil { + txs := NormalizeTxs(*srcBlock) + return &types.Block{ + Number: num, + Txs: txs, + }, nil + } + + return nil, err +} diff --git a/platform/oasis/client.go b/platform/oasis/client.go new file mode 100644 index 000000000..1f9db9609 --- /dev/null +++ b/platform/oasis/client.go @@ -0,0 +1,42 @@ +package oasis + +import ( + "github.com/trustwallet/golibs/client" +) + +type Client struct { + client.Request +} + +func (c *Client) GetCurrentBlock() (int64, error) { + var blk int64 + + err := c.Post(&blk, "block/tip", nil) + if err != nil { + return 0, err + } + + return blk, nil +} + +func (c *Client) GetBlockByNumber(num int64) (*[]Transaction, error) { + var txs []Transaction + + err := c.Post(&txs, "transactions/block", BlockRequest{BlockIdentifier: num}) + if err != nil { + return nil, err + } + + return &txs, nil +} + +func (c *Client) GetTrxOfAddress(address string) (*[]Transaction, error) { + var txs []Transaction + + err := c.Post(&txs, "transactions/address", TransactionsByAddressRequest{Address: address}) + if err != nil { + return nil, err + } + + return &txs, nil +} diff --git a/platform/oasis/mocks/tx_with_error.json b/platform/oasis/mocks/tx_with_error.json new file mode 100644 index 000000000..f0867f1a5 --- /dev/null +++ b/platform/oasis/mocks/tx_with_error.json @@ -0,0 +1,12 @@ +{ + "tx_hash": "6df10a2d114739ee6007fbd2ae0905b2ae81be6fc1d8ff6c5a9f404923263b84", + "from": "oasis1qrmp3lmcuvxhr9dq90mrrxe2yxzwfqw9xcvqujpu", + "to": "oasis1qqnv3peudzvekhulf8v3ht29z4cthkhy7gkxmph5", + "amount": "10", + "fee": "10", + "date": 1605774037000, + "block": 712027, + "success": false, + "error_message": "insufficient balance", + "sequence": 1 +} diff --git a/platform/oasis/mocks/tx_with_fee.json b/platform/oasis/mocks/tx_with_fee.json new file mode 100644 index 000000000..8ab1730db --- /dev/null +++ b/platform/oasis/mocks/tx_with_fee.json @@ -0,0 +1,11 @@ +{ + "tx_hash": "2b06966eaf27d830cc3c91fe2e38c0d26d38430cf8754be786f66a084ab127d2", + "from": "oasis1qp29h8ykmxet46eqzw0wennrmmy4al3xzv37m3ca", + "to": "oasis1qz9re9hc0k9qxrhvww7x9zrfv8x8jpr4kcr2twr2", + "amount": "1000000000", + "fee": "15000", + "date": 1605717688000, + "block": 702410, + "success": true, + "sequence": 1 +} diff --git a/platform/oasis/mocks/tx_without_fee.json b/platform/oasis/mocks/tx_without_fee.json new file mode 100644 index 000000000..192441189 --- /dev/null +++ b/platform/oasis/mocks/tx_without_fee.json @@ -0,0 +1,11 @@ +{ + "tx_hash": "a49afb8055ef3bbb4fca1e162886ab32b71c5a0d49555793342971237b031972", + "from": "oasis1qpcgnf84hnvvfvzup542rhc8kjyvqf4aqqlj5kqh", + "to": "oasis1qz9re9hc0k9qxrhvww7x9zrfv8x8jpr4kcr2twr2", + "amount": "170000000000", + "fee": "0", + "date": 1610472221000, + "block": 1502238, + "success": true, + "sequence": 5 +} diff --git a/platform/oasis/model.go b/platform/oasis/model.go new file mode 100644 index 000000000..2debfd034 --- /dev/null +++ b/platform/oasis/model.go @@ -0,0 +1,28 @@ +package oasis + +type Block struct { + Height int64 `json:"height"` + Hash string `json:"hash"` + Timestamp int64 `json:"timestamp"` +} + +type BlockRequest struct { + BlockIdentifier int64 `json:"block_identifier"` +} + +type Transaction struct { + Hash string `json:"tx_hash"` + From string `json:"from"` + To string `json:"to"` + Amount string `json:"amount"` + Fee string `json:"fee"` + Date int64 `json:"date"` + Block uint64 `json:"block"` + Success bool `json:"success"` + ErrorMsg string `json:"error_message,omitempty"` + Sequence uint64 `json:"sequence"` +} + +type TransactionsByAddressRequest struct { + Address string `json:"address"` +} diff --git a/platform/oasis/transaction.go b/platform/oasis/transaction.go new file mode 100644 index 000000000..a43e0073f --- /dev/null +++ b/platform/oasis/transaction.go @@ -0,0 +1,54 @@ +package oasis + +import ( + "github.com/trustwallet/golibs/coin" + "github.com/trustwallet/golibs/types" +) + +func (p *Platform) GetTxsByAddress(address string) (types.Txs, error) { + txs, err := p.client.GetTrxOfAddress(address) + if err != nil { + return nil, err + } + + return NormalizeTxs(*txs), nil +} + +func NormalizeTxs(srcTxs []Transaction) types.Txs { + var txs types.Txs + for _, srcTx := range srcTxs { + tx := NormalizeTx(srcTx) + txs = append(txs, tx) + } + return txs +} + +func NormalizeTx(srcTx Transaction) types.Tx { + symbol := coin.Coins[coin.OASIS].Symbol + decimals := coin.Coins[coin.OASIS].Decimals + + status := types.StatusCompleted + if !srcTx.Success { + status = types.StatusError + } + + nTx := types.Tx{ + ID: srcTx.Hash, + Coin: coin.OASIS, + From: srcTx.From, + To: srcTx.To, + Fee: types.Amount(srcTx.Fee), + Date: srcTx.Date, + Block: srcTx.Block, + Status: status, + Error: srcTx.ErrorMsg, + Sequence: srcTx.Sequence, + Meta: types.Transfer{ + Value: types.Amount(srcTx.Amount), + Symbol: symbol, + Decimals: decimals, + }, + } + + return nTx +} diff --git a/platform/oasis/transaction_test.go b/platform/oasis/transaction_test.go new file mode 100644 index 000000000..d22fd641b --- /dev/null +++ b/platform/oasis/transaction_test.go @@ -0,0 +1,90 @@ +package oasis + +import ( + "github.com/stretchr/testify/assert" + "github.com/trustwallet/golibs/coin" + "github.com/trustwallet/golibs/mock" + "github.com/trustwallet/golibs/types" + "testing" +) + +func TestNormalizeTx(t *testing.T) { + tests := []struct { + name string + filename string + wantTx types.Tx + }{ + { + name: "Test normalize successful transaction without fee", + filename: "tx_without_fee.json", + wantTx: types.Tx{ + ID: "a49afb8055ef3bbb4fca1e162886ab32b71c5a0d49555793342971237b031972", + Coin: coin.OASIS, + From: "oasis1qpcgnf84hnvvfvzup542rhc8kjyvqf4aqqlj5kqh", + To: "oasis1qz9re9hc0k9qxrhvww7x9zrfv8x8jpr4kcr2twr2", + Fee: "0", + Date: 1610472221000, + Block: 1502238, + Status: types.StatusCompleted, + Sequence: 5, + Meta: types.Transfer{ + Value: "170000000000", + Symbol: "ROSE", + Decimals: 9, + }, + }, + }, + { + name: "Test normalize successful transaction with fee", + filename: "tx_with_fee.json", + wantTx: types.Tx{ + ID: "2b06966eaf27d830cc3c91fe2e38c0d26d38430cf8754be786f66a084ab127d2", + Coin: coin.OASIS, + From: "oasis1qp29h8ykmxet46eqzw0wennrmmy4al3xzv37m3ca", + To: "oasis1qz9re9hc0k9qxrhvww7x9zrfv8x8jpr4kcr2twr2", + Fee: "15000", + Date: 1605717688000, + Block: 702410, + Status: types.StatusCompleted, + Sequence: 1, + Meta: types.Transfer{ + Value: "1000000000", + Symbol: "ROSE", + Decimals: 9, + }, + }, + }, + { + name: "Test normalize transaction with error", + filename: "tx_with_error.json", + wantTx: types.Tx{ + ID: "6df10a2d114739ee6007fbd2ae0905b2ae81be6fc1d8ff6c5a9f404923263b84", + Coin: coin.OASIS, + From: "oasis1qrmp3lmcuvxhr9dq90mrrxe2yxzwfqw9xcvqujpu", + To: "oasis1qqnv3peudzvekhulf8v3ht29z4cthkhy7gkxmph5", + Fee: "10", + Date: 1605774037000, + Block: 712027, + Status: types.StatusError, + Error: "insufficient balance", + Sequence: 1, + Meta: types.Transfer{ + Value: "10", + Symbol: "ROSE", + Decimals: 9, + }, + }, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + var srcTx Transaction + + err := mock.JsonModelFromFilePath("mocks/"+tt.filename, &srcTx) + assert.Nil(t, err) + + gotTx := NormalizeTx(srcTx) + assert.ObjectsAreEqual(gotTx, tt.wantTx) + }) + } +} diff --git a/platform/ontology/api.go b/platform/ontology/api.go deleted file mode 100644 index a09c42d96..000000000 --- a/platform/ontology/api.go +++ /dev/null @@ -1,128 +0,0 @@ -package ontology - -import ( - "github.com/spf13/viper" - "github.com/trustwallet/blockatlas/coin" - "github.com/trustwallet/blockatlas/pkg/blockatlas" - "github.com/trustwallet/blockatlas/pkg/logger" - "github.com/trustwallet/blockatlas/pkg/numbers" - "strings" -) - -type Platform struct { - client Client -} - -const ( - GovernanceContract = "AFmseVrdL9f9oyCzZefL9tG6UbviEH9ugK" - ONTAssetName = "ont" - ONGAssetName = "ong" -) - -func (p *Platform) Init() error { - p.client = Client{blockatlas.InitClient(viper.GetString("ontology.api"))} - return nil -} - -func (p *Platform) Coin() coin.Coin { - return coin.Coins[coin.ONT] -} - -func (p *Platform) GetTxsByAddress(address string) (blockatlas.TxPage, error) { - return p.GetTokenTxsByAddress(address, ONTAssetName) -} - -func (p *Platform) GetTokenTxsByAddress(address string, token string) (blockatlas.TxPage, error) { - txPage, err := p.client.GetTxsOfAddress(address, token) - if err != nil { - logger.Error(err, "Ontology: Failed to get transactions for address and token", - logger.Params{ - "address": address, - "token": token, - }) - return blockatlas.TxPage{}, err - } - - var txs []blockatlas.Tx - for _, srcTx := range txPage.Result.TxnList { - tx, ok := Normalize(&srcTx, token) - if !ok { - continue - } - txs = append(txs, tx) - } - - return txs, nil -} - -func Normalize(srcTx *Tx, assetName string) (tx blockatlas.Tx, ok bool) { - if len(srcTx.TransferList) < 1 { - return tx, false - } - transfer := srcTx.TransferList[0] - fee := numbers.DecimalExp(srcTx.Fee, 9) - var status blockatlas.Status - if srcTx.ConfirmFlag == 1 { - status = blockatlas.StatusCompleted - } else { - status = blockatlas.StatusFailed - } - - tx = blockatlas.Tx{ - ID: srcTx.TxnHash, - Coin: coin.ONT, - Fee: blockatlas.Amount(fee), - Date: srcTx.TxnTime, - Block: srcTx.Height, - Status: status, - } - - switch assetName { - case ONTAssetName: - normalizeONT(&tx, &transfer) - case ONGAssetName: - normalizeONG(&tx, &transfer) - default: // unsupported asset - return tx, false - } - - return tx, true -} - -func normalizeONT(tx *blockatlas.Tx, transfer *Transfer) { - i := strings.IndexRune(transfer.Amount, '.') - value := transfer.Amount[:i] - - tx.From = transfer.FromAddress - tx.To = transfer.ToAddress - tx.Type = blockatlas.TxTransfer - tx.Meta = blockatlas.Transfer{ - Value: blockatlas.Amount(value), - Symbol: coin.Coins[coin.ONT].Symbol, - Decimals: coin.Coins[coin.ONT].Decimals, - } -} - -func normalizeONG(tx *blockatlas.Tx, transfer *Transfer) { - var value string - if transfer.ToAddress == GovernanceContract { - value = "0" - } else { - value = numbers.DecimalExp(transfer.Amount, 9) - } - - from := transfer.FromAddress - to := transfer.ToAddress - tx.From = from - tx.To = to - tx.Type = blockatlas.TxNativeTokenTransfer - tx.Meta = blockatlas.NativeTokenTransfer{ - Name: "Ontology Gas", - Symbol: "ONG", - TokenID: "ong", - Decimals: 9, - Value: blockatlas.Amount(value), - From: from, - To: to, - } -} diff --git a/platform/ontology/api_test.go b/platform/ontology/api_test.go deleted file mode 100644 index 146f4756a..000000000 --- a/platform/ontology/api_test.go +++ /dev/null @@ -1,178 +0,0 @@ -package ontology - -import ( - "bytes" - "encoding/json" - "github.com/trustwallet/blockatlas/coin" - "github.com/trustwallet/blockatlas/pkg/blockatlas" - "testing" -) - -var srcOntTransfer = ` -{ - "TxnType": 209, - "ConfirmFlag": 1, - "Fee": "0.010000000", - "BlockIndex": 2, - "TransferList": [ - { - "FromAddress": "AUyL4TZ1zFEcSKDJrjFnD7vsq5iFZMZqT7", - "Amount": "2.000000000", - "ToAddress": "AQ9kzzHNLCcyrPwJuVMrSPgGzqmuQNVwMF", - "AssetName": "ont" - } - ], - "TxnTime": 1556952450, - "TxnHash": "4804e1be63ebe1715d6b4a039cc9d84b86cde74c8a8c8411578e6dcadc1e5405", - "Height": 3411115 -} -` - -var dstOntTransfer = blockatlas.Tx{ - ID: "4804e1be63ebe1715d6b4a039cc9d84b86cde74c8a8c8411578e6dcadc1e5405", - Coin: coin.ONT, - From: "AUyL4TZ1zFEcSKDJrjFnD7vsq5iFZMZqT7", - To: "AQ9kzzHNLCcyrPwJuVMrSPgGzqmuQNVwMF", - Fee: "10000000", - Date: 1556952450, - Type: "transfer", - Status: blockatlas.StatusCompleted, - Block: 3411115, - Meta: blockatlas.Transfer{ - Value: "2", - Symbol: "ONT", - Decimals: 0, - }, -} - -var srcOngTransfer1 = ` -{ - "TxnType": 209, - "ConfirmFlag": 1, - "Fee": "0.010000000", - "BlockIndex": 2, - "TransferList": [ - { - "FromAddress": "AUyL4TZ1zFEcSKDJrjFnD7vsq5iFZMZqT7", - "Amount": "0.010000000", - "ToAddress": "AFmseVrdL9f9oyCzZefL9tG6UbviEH9ugK", - "AssetName": "ong" - } - ], - "TxnTime": 1555341286, - "TxnHash": "f494d7aeae2b88d313465d1f5f588b213795b38988a0bef182d9d3c2012f6e6e", - "Height": 2863855 -} -` - -var dstOngTransfer1 = blockatlas.Tx{ - ID: "f494d7aeae2b88d313465d1f5f588b213795b38988a0bef182d9d3c2012f6e6e", - Coin: coin.ONT, - From: "AUyL4TZ1zFEcSKDJrjFnD7vsq5iFZMZqT7", - To: "AFmseVrdL9f9oyCzZefL9tG6UbviEH9ugK", - Fee: "10000000", - Date: 1555341286, - Type: blockatlas.TxNativeTokenTransfer, - Status: blockatlas.StatusCompleted, - Block: 2863855, - Meta: blockatlas.NativeTokenTransfer{ - Name: "Ontology Gas", - Symbol: "ONG", - TokenID: "ong", - Decimals: 9, - Value: "0", - From: "AUyL4TZ1zFEcSKDJrjFnD7vsq5iFZMZqT7", - To: "AFmseVrdL9f9oyCzZefL9tG6UbviEH9ugK", - }, -} - -var srcOngTransfer2 = ` -{ - "TxnType": 209, - "ConfirmFlag": 1, - "Fee": "0.010000000", - "BlockIndex": 1, - "TransferList": [ - { - "FromAddress": "AUyL4TZ1zFEcSKDJrjFnD7vsq5iFZMZqT7", - "Amount": "10.000000000", - "ToAddress": "AQ9kzzHNLCcyrPwJuVMrSPgGzqmuQNVwMF", - "AssetName": "ong" - }, - { - "FromAddress": "AUyL4TZ1zFEcSKDJrjFnD7vsq5iFZMZqT7", - "Amount": "0.010000000", - "ToAddress": "AFmseVrdL9f9oyCzZefL9tG6UbviEH9ugK", - "AssetName": "ong" - } - ], - "TxnTime": 1556952520, - "TxnHash": "eccbfd040925a22884d87e73f818f30ab42d06046460b86e9a042a1e9cba7561", - "Height": 3411141 -} -` -var dstOngTransfer = blockatlas.Tx{ - ID: "eccbfd040925a22884d87e73f818f30ab42d06046460b86e9a042a1e9cba7561", - Coin: coin.ONT, - From: "AUyL4TZ1zFEcSKDJrjFnD7vsq5iFZMZqT7", - To: "AQ9kzzHNLCcyrPwJuVMrSPgGzqmuQNVwMF", - Fee: "10000000", - Date: 1556952520, - Type: blockatlas.TxNativeTokenTransfer, - Status: blockatlas.StatusCompleted, - Block: 3411141, - Meta: blockatlas.NativeTokenTransfer{ - Name: "Ontology Gas", - Symbol: "ONG", - TokenID: "ong", - Decimals: 9, - Value: "10000000000", - From: "AUyL4TZ1zFEcSKDJrjFnD7vsq5iFZMZqT7", - To: "AQ9kzzHNLCcyrPwJuVMrSPgGzqmuQNVwMF", - }, -} - -func TestNormalize(t *testing.T) { - var tests = []struct { - Transaction string - AssetName string - Expected blockatlas.Tx - }{ - {srcOntTransfer, ONTAssetName, dstOntTransfer}, - {srcOngTransfer1, ONGAssetName, dstOngTransfer1}, - {srcOngTransfer2, ONGAssetName, dstOngTransfer}, - } - - for _, test := range tests { - var sourceTx Tx - - tErr := json.Unmarshal([]byte(test.Transaction), &sourceTx) - if tErr != nil { - t.Fatal("Ontology: Can't unmarshal transaction", tErr) - } - - var tx blockatlas.Tx - var ok bool - tx, ok = Normalize(&sourceTx, test.AssetName) - - if !ok { - t.Fatal("Ontology: Can't normalize transaction") - } - - actual, err := json.Marshal(&tx) - if err != nil { - t.Fatal(err) - } - - expected, err := json.Marshal(&test.Expected) - if err != nil { - t.Fatal(err) - } - - if !bytes.Equal(actual, expected) { - println(string(actual)) - println(string(expected)) - t.Error("Transactions not equal") - } - } -} diff --git a/platform/ontology/base.go b/platform/ontology/base.go new file mode 100644 index 000000000..6047ac590 --- /dev/null +++ b/platform/ontology/base.go @@ -0,0 +1,21 @@ +package ontology + +import ( + "github.com/trustwallet/golibs/client" + "github.com/trustwallet/golibs/coin" + "github.com/trustwallet/golibs/network/middleware" +) + +type Platform struct { + client Client +} + +func Init(api string) *Platform { + return &Platform{ + client: Client{client.InitClient(api, middleware.SentryErrorHandler)}, + } +} + +func (p *Platform) Coin() coin.Coin { + return coin.Ontology() +} diff --git a/platform/ontology/block.go b/platform/ontology/block.go new file mode 100644 index 000000000..482f37442 --- /dev/null +++ b/platform/ontology/block.go @@ -0,0 +1,34 @@ +package ontology + +import ( + "errors" + + "github.com/trustwallet/golibs/types" +) + +func (p *Platform) CurrentBlockNumber() (int64, error) { + block, err := p.client.CurrentBlockNumber() + if err != nil { + return 0, err + } + if len(block.Result.Records) == 0 { + return 0, errors.New("invalid block height result") + } + return block.Result.Records[0].Height, nil +} + +func (p *Platform) GetBlockByNumber(num int64) (*types.Block, error) { + blockOnt, err := p.client.GetBlockByNumber(num) + if err != nil { + return nil, err + } + txsRaw, err := p.getTxDetails(blockOnt.Result.Txs) + if err != nil { + return nil, err + } + txs := normalizeTxs(txsRaw, AssetAll) + return &types.Block{ + Number: num, + Txs: txs, + }, nil +} diff --git a/platform/ontology/client.go b/platform/ontology/client.go index 20eedee90..470ec6cef 100644 --- a/platform/ontology/client.go +++ b/platform/ontology/client.go @@ -2,18 +2,63 @@ package ontology import ( "fmt" - "github.com/trustwallet/blockatlas/pkg/blockatlas" + "net/url" + + "github.com/trustwallet/golibs/client" ) type Client struct { - blockatlas.Request + client.Request +} + +func (c *Client) GetBalances(address string) (balances BalancesResult, err error) { + path := fmt.Sprintf("v2/addresses/%s/native/balances", address) + err = c.Get(&balances, path, nil) + if err != nil || balances.Msg != MsgSuccess { + return balances, err + } + return } -// Explorer API max returned transactions per page -const TxPerPage = 20 +func (c *Client) GetTxsOfAddress(address string) (txPage TxsResult, err error) { + query := url.Values{"page_size": {"20"}, "page_number": {"1"}} + path := fmt.Sprintf("v2/addresses/%s/transactions", address) + err = c.Get(&txPage, path, query) + if err != nil || txPage.Msg != MsgSuccess { + return txPage, err + } + return +} -func (c *Client) GetTxsOfAddress(address, assetName string) (txPage *TxPage, err error) { - url := fmt.Sprintf("address/%s/%s/%d/1", address, assetName, TxPerPage) - err = c.Get(&txPage, url, nil) +func (c *Client) CurrentBlockNumber() (blocks BlockResult, err error) { + query := url.Values{"page_size": {"1"}, "page_number": {"1"}} + path := "v2/blocks" + err = c.Get(&blocks, path, query) + if err != nil || blocks.Msg != MsgSuccess { + return blocks, err + } return } + +func (c *Client) GetBlockByNumber(num int64) (block BlockResults, err error) { + path := fmt.Sprintf("v2/blocks/%d", num) + err = c.Get(&block, path, nil) + if err != nil || block.Msg != MsgSuccess { + return block, err + } + return +} + +func (c *Client) GetTxDetailsByHash(hash string) (Tx, error) { + path := fmt.Sprintf("v2/transactions/%s", hash) + var response TxResult + err := c.Get(&response, path, nil) + if err != nil || response.Msg != MsgSuccess { + return Tx{}, err + } + var ontTxV2 Tx + if response.Result.EventType == 3 { + ontTxV2 = response.Result + } + return ontTxV2, nil +} diff --git a/platform/ontology/mocks/block_response.json b/platform/ontology/mocks/block_response.json new file mode 100644 index 000000000..695272e3a --- /dev/null +++ b/platform/ontology/mocks/block_response.json @@ -0,0 +1,60 @@ +[ + { + "id": "266d9d7282a5601bf6cb8fc5368a76a2aa54f45731a063a699a692487bcbd0cb", + "coin": 1024, + "from": "AbEeCHUWpzQaxUN7G1a83N3P2XtVLuMLaE", + "to": "ASLbwuar3ZTbUbLPnCgjGUw2WHhMfvJJtx", + "fee": "10000000", + "date": 1580481541, + "block": 7707834, + "status": "completed", + "sequence": 0, + "type": "native_token_transfer", + "memo": "", + "metadata": { + "name": "Ontology Gas", + "symbol": "ONG", + "token_id": "ong", + "decimals": 9, + "value": "51000000000000", + "from": "AbEeCHUWpzQaxUN7G1a83N3P2XtVLuMLaE", + "to": "ASLbwuar3ZTbUbLPnCgjGUw2WHhMfvJJtx" + } + }, + { + "id": "2935268c5715f1f2015ba828681c39399dedbe7a24ed628ef7b85d9aac8045fd", + "coin": 1024, + "from": "ANdrA47zDXUu8MCkMdD3FYPmpSNGYeAvKz", + "to": "ASLbwuar3ZTbUbLPnCgjGUw2WHhMfvJJtx", + "fee": "10000000", + "date": 1580481541, + "block": 7707834, + "status": "completed", + "sequence": 0, + "type": "native_token_transfer", + "memo": "", + "metadata": { + "name": "Ontology Gas", + "symbol": "ONG", + "token_id": "ong", + "decimals": 9, + "value": "113200000000", + "from": "ANdrA47zDXUu8MCkMdD3FYPmpSNGYeAvKz", + "to": "ASLbwuar3ZTbUbLPnCgjGUw2WHhMfvJJtx" + } + }, + { + "id": "40976edc1306b0e5f55b90c8d3ca248bb544e5ebbadb02be6146ba0a0de402c3", + "coin": 1024, + "from": "Abg2gs6pfpQu82jXbm8EYGiipRBvf9ktVS", + "to": "ASLbwuar3ZTbUbLPnCgjGUw2WHhMfvJJtx", + "fee": "10000000", + "date": 1580481541, + "block": 7707834, + "status": "completed", + "sequence": 0, + "type": "transfer", + "memo": "", + "metadata": { "value": "10949", "symbol": "ONT", "decimals": 0 } + } +] diff --git a/platform/ontology/mocks/transfer_fee.json b/platform/ontology/mocks/transfer_fee.json new file mode 100644 index 000000000..aef03db36 --- /dev/null +++ b/platform/ontology/mocks/transfer_fee.json @@ -0,0 +1,18 @@ +{ + "tx_hash": "92a79aed526f31999e22d9e3912d4125d3f85ec3c63eede4b7dde4a041826095", + "tx_type": 209, + "tx_time": 1578902776, + "block_height": 7571071, + "fee": "0.01", + "block_index": 1, + "confirm_flag": 1, + "transfers": [ + { + "amount": "0.01", + "from_address": "ARFXGXSmgFT2h9EiS4D5fen127Lzi48Eij", + "to_address": "AFmseVrdL9f9oyCzZefL9tG6UbviEH9ugK", + "asset_name": "ong", + "contract_hash": "0200000000000000000000000000000000000000" + } + ] +} diff --git a/platform/ontology/mocks/transfer_ong.json b/platform/ontology/mocks/transfer_ong.json new file mode 100644 index 000000000..3586eeb83 --- /dev/null +++ b/platform/ontology/mocks/transfer_ong.json @@ -0,0 +1,18 @@ +{ + "tx_hash": "e5946ba02f56e17c3709db2bc91f43f76ee3a359006586024daa5c4ad8c54e78", + "tx_type": 209, + "tx_time": 1577631515, + "block_height": 7457989, + "fee": "0.01", + "block_index": 1, + "confirm_flag": 1, + "transfers": [ + { + "amount": "14.69", + "from_address": "ASLbwuar3ZTbUbLPnCgjGUw2WHhMfvJJtx", + "to_address": "ARFXGXSmgFT2h9EiS4D5fen127Lzi48Eij", + "asset_name": "ong", + "contract_hash": "0200000000000000000000000000000000000000" + } + ] +} diff --git a/platform/ontology/mocks/transfer_ont.json b/platform/ontology/mocks/transfer_ont.json new file mode 100644 index 000000000..77f8b5415 --- /dev/null +++ b/platform/ontology/mocks/transfer_ont.json @@ -0,0 +1,25 @@ +{ + "tx_hash": "ea0e5d8e389cb96760887094194ca359ac998b2f607be470a576861b91e2bf52", + "tx_type": 209, + "tx_time": 1578903628, + "block_height": 7571132, + "fee": "0.01", + "block_index": 1, + "confirm_flag": 1, + "transfers": [ + { + "amount": "5", + "from_address": "ARFXGXSmgFT2h9EiS4D5fen127Lzi48Eij", + "to_address": "ARFXGXSmgFT2h9EiS4D5fen127Lzi48Eij", + "asset_name": "ont", + "contract_hash": "0100000000000000000000000000000000000000" + }, + { + "amount": "0.01", + "from_address": "ARFXGXSmgFT2h9EiS4D5fen127Lzi48Eij", + "to_address": "AFmseVrdL9f9oyCzZefL9tG6UbviEH9ugK", + "asset_name": "ong", + "contract_hash": "0200000000000000000000000000000000000000" + } + ] +} diff --git a/platform/ontology/mocks/transfer_rewards.json b/platform/ontology/mocks/transfer_rewards.json new file mode 100644 index 000000000..b81ac4b7b --- /dev/null +++ b/platform/ontology/mocks/transfer_rewards.json @@ -0,0 +1,25 @@ +{ + "tx_hash": "d7554dcdf01f394b9107ff598df6d84e4c3b00ccf1e720b8c09abf085cbe4987", + "tx_type": 209, + "tx_time": 1579699532, + "block_height": 7644328, + "fee": "0.01", + "block_index": 1, + "confirm_flag": 1, + "transfers": [ + { + "amount": "0.03534404", + "from_address": "AFmseVrdL9f9oyCzZefL9tG6UbvhUMqNMV", + "to_address": "ARFXGXSmgFT2h9EiS4D5fen127Lzi48Eij", + "asset_name": "ong", + "contract_hash": "0200000000000000000000000000000000000000" + }, + { + "amount": "0.01", + "from_address": "ARFXGXSmgFT2h9EiS4D5fen127Lzi48Eij", + "to_address": "AFmseVrdL9f9oyCzZefL9tG6UbviEH9ugK", + "asset_name": "ong", + "contract_hash": "0200000000000000000000000000000000000000" + } + ] +} diff --git a/platform/ontology/model.go b/platform/ontology/model.go index 04d92937b..a5cd55a3c 100644 --- a/platform/ontology/model.go +++ b/platform/ontology/model.go @@ -1,27 +1,163 @@ package ontology -type TxPage struct { - Result Result `json:"Result"` +type AssetType string +type MsgType string +type Transfers []Transfer +type Balances []Balance + +const ( + GovernanceContract = "AFmseVrdL9f9oyCzZefL9tG6UbviEH9ugK" + ONGDecimals = 9 + + MsgSuccess MsgType = "SUCCESS" + + AssetONT AssetType = "ont" + AssetONG AssetType = "ong" + AssetAll AssetType = "all" +) + +type BaseResponse struct { + Code int `json:"code"` + Msg MsgType `json:"msg"` } -type Result struct { - TxnList []Tx `json:"TxnList"` +type BlockResults struct { + BaseResponse + Result Block `json:"result"` } -type Transfer struct { - Amount string `json:"Amount"` - FromAddress string `json:"FromAddress"` - ToAddress string `json:"ToAddress"` +type BlockResult struct { + BaseResponse + Result BlockRecords `json:"result"` +} + +type TxsResult struct { + BaseResponse + Result []Tx `json:"result"` +} + +type TxResult struct { + BaseResponse + Result Tx `json:"result"` +} + +type BalancesResult struct { + BaseResponse + Result Balances `json:"result"` +} + +type BlockRecords struct { + Total int64 `json:"total"` + Records []Block `json:"records"` +} + +type Block struct { + Height int64 `json:"block_height"` + Hash string `json:"block_hash"` + Txs []Tx `json:"txs"` } type Tx struct { - TxnHash string `json:"TxnHash"` - ConfirmFlag uint64 `json:"ConfirmFlag"` - TxnType uint64 `json:"TxnType"` - TxnTime int64 `json:"TxnTime"` - Height uint64 `json:"Height"` - Fee string `json:"Fee"` - BlockIndex uint64 `json:"BlockIndex"` - - TransferList []Transfer `json:"TransferList"` + Hash string `json:"tx_hash"` + ConfirmFlag uint64 `json:"confirm_flag"` + Time int64 `json:"tx_time"` + Height uint64 `json:"block_height"` + Fee string `json:"fee"` + BlockIndex uint64 `json:"block_index"` + EventType uint64 `json:"event_type,omitempty"` + Description string `json:"description,omitempty"` + Details Detail `json:"detail,omitempty"` + Transfers Transfers `json:"transfers,omitempty"` +} + +type Detail struct { + Transfers Transfers `json:"transfers"` +} + +type Transfer struct { + Amount string `json:"amount"` + FromAddress string `json:"from_address"` + ToAddress string `json:"to_address"` + AssetName AssetType `json:"asset_name"` + Description string `json:"description,omitempty"` +} + +type Balance struct { + Balance string `json:"balance"` + AssetName AssetType `json:"asset_name"` + AssetType string `json:"asset_type"` + ContractHash string `json:"contract_hash"` +} + +func (tf *Transfer) isFeeTransfer() bool { + if tf.AssetName != AssetONG { + return false + } + if tf.ToAddress != GovernanceContract { + return false + } + return true +} + +func (tfs Transfers) hasFeeTransfer() bool { + for _, tf := range tfs { + if tf.isFeeTransfer() { + return true + } + } + return false +} + +func (tx *Tx) getTransfers() Transfers { + return append(tx.Details.Transfers, tx.Transfers...) +} + +func (tfs Transfers) getTransfer(assetType AssetType) *Transfer { + for _, tf := range tfs { + if tf.isFeeTransfer() { + continue + } + if assetType != AssetAll && tf.AssetName != assetType { + continue + } + return &tf + } + return nil +} + +func (tfs Transfers) isClaimReward() bool { + // Claim Reward needs to have two transfers. + if len(tfs) < 2 { + return false + } + // Both transfers need to be ONG, one for reward and another one. + if tfs[0].AssetName != AssetONG || tfs[1].AssetName != AssetONG { + return false + } + // Avoid transactions for yourself + if tfs[0].ToAddress == tfs[0].FromAddress || tfs[1].ToAddress == tfs[1].FromAddress { + return false + } + // Verify if one of the transfers is a fee transfer. + if !tfs.hasFeeTransfer() { + return false + } + // The user need to pay a fee to get his reward + if tfs[1].isFeeTransfer() && tfs[0].ToAddress == tfs[1].FromAddress && tfs[1].ToAddress == GovernanceContract { + return true + } + if tfs[0].isFeeTransfer() && tfs[1].ToAddress == tfs[0].FromAddress && tfs[0].ToAddress == GovernanceContract { + return false + } + return false + +} + +func (bs Balances) getBalance(assetType AssetType) *Balance { + for _, b := range bs { + if b.AssetName == assetType { + return &b + } + } + return nil } diff --git a/platform/ontology/model_test.go b/platform/ontology/model_test.go new file mode 100644 index 000000000..b67322bf0 --- /dev/null +++ b/platform/ontology/model_test.go @@ -0,0 +1,211 @@ +package ontology + +import ( + "github.com/stretchr/testify/assert" + "reflect" + "testing" +) + +func TestTransfer_isFeeTransfer(t *testing.T) { + type fields struct { + ToAddress string + AssetName AssetType + } + tests := []struct { + name string + fields fields + want bool + }{ + {"test fee transfer", fields{ToAddress: GovernanceContract, AssetName: AssetONG}, true}, + {"test non fee transfer 1", fields{ToAddress: GovernanceContract, AssetName: AssetONT}, false}, + {"test non fee transfer 2", fields{ToAddress: "AUyL4TZ1zFEcSKDJrjFnD7vsq5iFZMZqT7", AssetName: AssetONG}, false}, + {"test non fee transfer 3", fields{ToAddress: "AUyL4TZ1zFEcSKDJrjFnD7vsq5iFZMZqT7", AssetName: AssetONT}, false}, + {"test invalid asset", fields{ToAddress: GovernanceContract, AssetName: "BNB"}, false}, + {"test empty", fields{ToAddress: "", AssetName: ""}, false}, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + tf := &Transfer{ + ToAddress: tt.fields.ToAddress, + AssetName: tt.fields.AssetName, + } + if got := tf.isFeeTransfer(); got != tt.want { + t.Errorf("isFeeTransfer() = %v, want %v", got, tt.want) + } + }) + } +} + +var ( + transfersClaims2 = Transfers{{ + Amount: "0.4", + FromAddress: "AFmseVrdL9f9oyCzZefL9tG6UbvhUMqNMV", + ToAddress: "AUyL4TZ1zFEcSKDJrjFnD7vsq5iFZMZqT7", + AssetName: "ong", + }, { + Amount: "0.01", + FromAddress: "AUyL4TZ1zFEcSKDJrjFnD7vsq5iFZMZqT7", + ToAddress: "AFmseVrdL9f9oyCzZefL9tG6UbviEH9ugK", + AssetName: "ong", + }} + transfersOngYourself = Transfers{{ + Amount: "0.02", + FromAddress: "AUyL4TZ1zFEcSKDJrjFnD7vsq5iFZMZqT7", + ToAddress: "AUyL4TZ1zFEcSKDJrjFnD7vsq5iFZMZqT7", + AssetName: "ong", + }, { + Amount: "0.01", + FromAddress: "AUyL4TZ1zFEcSKDJrjFnD7vsq5iFZMZqT7", + ToAddress: "AFmseVrdL9f9oyCzZefL9tG6UbviEH9ugK", + AssetName: "ong", + }} + transfersOng2 = Transfers{{ + Amount: "0.4", + FromAddress: "AUyL4TZ1zFEcSKDJrjFnD7vsq5iFZMZqT7", + ToAddress: "Abm1FqnU4qur9bviXmrD5YnNixXGvMsi9R", + AssetName: "ong", + }, { + Amount: "0.01", + FromAddress: "AUyL4TZ1zFEcSKDJrjFnD7vsq5iFZMZqT7", + ToAddress: "AFmseVrdL9f9oyCzZefL9tG6UbviEH9ugK", + AssetName: "ong", + }} + + transferFee = Transfer{ + Amount: "0.01", + FromAddress: "ARFXGXSmgFT2h9EiS4D5fen127Lzi48Eij", + ToAddress: "AFmseVrdL9f9oyCzZefL9tG6UbviEH9ugK", + AssetName: "ong", + } + transferOng = Transfer{ + Amount: "0.03534404", + FromAddress: "AFmseVrdL9f9oyCzZefL9tG6UbvhUMqNMV", + ToAddress: "ARFXGXSmgFT2h9EiS4D5fen127Lzi48Eij", + AssetName: "ong", + } + transferOnt = Transfer{ + Amount: "58", + FromAddress: "ARFXGXSmgFT2h9EiS4D5fen127Lzi48Eij", + ToAddress: "ARncJn1rr9hivokUWxzr915vS3usR6xdgJ", + AssetName: "ont", + } + transfersClaims1 = Transfers{transferOng, transferFee} + transfersOnt = Transfers{transferOnt, transferFee} + transfersOng1 = Transfers{transferOng} + transfersFee = Transfers{transferFee} +) + +func TestTransfers_getTransfer(t *testing.T) { + tests := []struct { + name string + tfs Transfers + asset AssetType + want *Transfer + }{ + {"Transfer Claims Asset Ong", transfersClaims1, AssetONG, &transferOng}, + {"Transfer Claims Asset Ont", transfersClaims1, AssetONT, nil}, + {"Transfer Claims Asset All", transfersClaims1, AssetAll, &transferOng}, + {"Transfer Ont Asset Ong", transfersOnt, AssetONG, nil}, + {"Transfer Ont Asset Ont", transfersOnt, AssetONT, &transferOnt}, + {"Transfer Ont Asset All", transfersOnt, AssetAll, &transferOnt}, + {"Transfer Ong Asset Ong", transfersOng1, AssetONG, &transferOng}, + {"Transfer Ong Asset Ont", transfersOng1, AssetONT, nil}, + {"Transfer Ong Asset All", transfersOng1, AssetAll, &transferOng}, + {"Transfer Fee Asset Ong", transfersFee, AssetONG, nil}, + {"Transfer Fee Asset Ont", transfersFee, AssetONT, nil}, + {"Transfer Fee Asset All", transfersFee, AssetAll, nil}, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + if got := tt.tfs.getTransfer(tt.asset); !reflect.DeepEqual(got, tt.want) { + t.Errorf("getTransfer() = %v, want %v", got, tt.want) + } + }) + } +} + +func TestTransfers_hasFeeTransfer(t *testing.T) { + tests := []struct { + name string + tfs Transfers + want bool + }{ + {"Transfer Claims 1", transfersClaims1, true}, + {"Transfer Calims 2", transfersClaims2, true}, + {"Transfer Ont", transfersOnt, true}, + {"Transfer Ong 1", transfersOng1, false}, + {"Transfer Ong 2", transfersOng2, true}, + {"Transfer Ong Yourself ", transfersOngYourself, true}, + {"Transfer Fee", transfersFee, true}, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + if got := tt.tfs.hasFeeTransfer(); got != tt.want { + t.Errorf("hasFeeTransfer() = %v, want %v", got, tt.want) + } + }) + } +} + +func TestTransfers_isClaimReward(t *testing.T) { + tests := []struct { + name string + tfs Transfers + want bool + }{ + {"Transfer Claims 1", transfersClaims1, true}, + {"Transfer Claims 2", transfersClaims2, true}, + {"Transfer Ont", transfersOnt, false}, + {"Transfer Ong 1", transfersOng1, false}, + {"Transfer Ong 2", transfersOng2, false}, + {"Transfer Ong Yourself", transfersOngYourself, false}, + {"Transfer Fee", transfersFee, false}, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + if got := tt.tfs.isClaimReward(); got != tt.want { + t.Errorf("isClaimReward() = %v, want %v", got, tt.want) + } + }) + } +} + +func TestBalances_getBalance(t *testing.T) { + tests := []struct { + name string + bs Balances + assetType AssetType + want *Balance + }{ + { + "test three assets", + Balances{{AssetName: AssetONT, Balance: "0"}, {AssetName: AssetONG, Balance: "1"}, {AssetName: AssetAll, Balance: "2"}}, + AssetONG, + &Balance{AssetName: AssetONG, Balance: "1"}, + }, + { + "test two assets", + Balances{{AssetName: AssetONT, Balance: "0"}, {AssetName: AssetONG, Balance: "1"}}, + AssetONT, + &Balance{AssetName: AssetONT, Balance: "0"}, + }, + { + "test invalid asset 1", + Balances{{AssetName: AssetONG, Balance: "0"}, {AssetName: AssetONG, Balance: "1"}, {AssetName: AssetAll, Balance: "2"}}, + AssetONT, + nil, + }, + { + "test invalid asset 2", + Balances{{AssetName: AssetONT, Balance: "0"}}, + AssetONG, + nil, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + got := tt.bs.getBalance(tt.assetType) + assert.EqualValues(t, tt.want, got) + }) + } +} diff --git a/platform/ontology/stake.go b/platform/ontology/stake.go new file mode 100644 index 000000000..d2b070471 --- /dev/null +++ b/platform/ontology/stake.go @@ -0,0 +1,52 @@ +package ontology + +import ( + "github.com/trustwallet/blockatlas/pkg/blockatlas" + "github.com/trustwallet/blockatlas/services/assets" +) + +const ( + // The current value comes from https://cryptoslate.com/coins/ontology + Annual = 4.45 +) + +func (p *Platform) GetActiveValidators() (blockatlas.StakeValidators, error) { + validators, err := assets.GetValidatorsMap(p) + if err != nil { + return nil, err + } + result := make(blockatlas.StakeValidators, 0, len(validators)) + for _, v := range validators { + result = append(result, v) + } + return result, nil +} + +func (p *Platform) GetDetails() blockatlas.StakingDetails { + return blockatlas.StakingDetails{ + Reward: blockatlas.StakingReward{Annual: Annual}, + MinimumAmount: "0", + LockTime: 0, + Type: blockatlas.DelegationTypeAuto, + } +} + +func (p *Platform) UndelegatedBalance(address string) (string, error) { + acc, err := p.client.GetBalances(address) + if err != nil { + return "0", err + } + balance := acc.Result.getBalance(AssetONT) + if balance == nil { + return "0", err + } + return balance.Balance, nil +} + +func (p *Platform) GetValidators() (blockatlas.ValidatorPage, error) { + return blockatlas.ValidatorPage{}, nil +} + +func (p *Platform) GetDelegations(address string) (blockatlas.DelegationsPage, error) { + return blockatlas.DelegationsPage{}, nil +} diff --git a/platform/ontology/transaction.go b/platform/ontology/transaction.go new file mode 100644 index 000000000..19ff782c2 --- /dev/null +++ b/platform/ontology/transaction.go @@ -0,0 +1,147 @@ +package ontology + +import ( + "errors" + "sync" + + "github.com/trustwallet/golibs/coin" + "github.com/trustwallet/golibs/numbers" + "github.com/trustwallet/golibs/types" +) + +func (p *Platform) GetTxsByAddress(address string) (types.Txs, error) { + return p.GetTokenTxsByAddress(address, string(AssetONT)) +} + +func (p *Platform) GetTokenTxsByAddress(address string, token string) (types.Txs, error) { + srcTxs, err := p.client.GetTxsOfAddress(address) + if err != nil { + return types.Txs{}, err + } + txPage := normalizeTxs(srcTxs.Result, AssetType(token)) + return txPage, nil +} + +func Normalize(srcTx *Tx, assetName AssetType) (tx types.Tx, ok bool) { + if len(srcTx.getTransfers()) < 1 { + return tx, false + } + fee := numbers.DecimalExp(srcTx.Fee, ONGDecimals) + status := types.StatusCompleted + if srcTx.ConfirmFlag != 1 { + status = types.StatusError + } + tx = types.Tx{ + ID: srcTx.Hash, + Coin: coin.ONTOLOGY, + Fee: types.Amount(fee), + Date: srcTx.Time, + Block: srcTx.Height, + Status: status, + Memo: "", + } + + switch assetName { + case AssetONT: + return normalizeONT(tx, srcTx.getTransfers()) + case AssetONG: + return normalizeONG(tx, srcTx.getTransfers()) + } + return tx, false +} + +func normalizeONT(tx types.Tx, transfers Transfers) (types.Tx, bool) { + transfer := transfers.getTransfer(AssetONT) + if transfer == nil { + return tx, false + } + tx.From = transfer.FromAddress + tx.To = transfer.ToAddress + tx.Type = types.TxTransfer + tx.Meta = types.Transfer{ + Value: types.Amount(transfer.Amount), + Symbol: coin.Ontology().Symbol, + Decimals: coin.Ontology().Decimals, + } + return tx, true +} + +func normalizeONG(tx types.Tx, transfers Transfers) (types.Tx, bool) { + transfer := transfers.getTransfer(AssetONG) + if transfer == nil { + return tx, false + } + from := transfer.FromAddress + to := transfer.ToAddress + tx.From = from + tx.To = to + value := numbers.DecimalExp(transfer.Amount, ONGDecimals) + if transfers.isClaimReward() { + tx.Type = types.TxAnyAction + tx.Meta = types.AnyAction{ + Coin: coin.Ontology().ID, + Name: "Ontology Gas", + Symbol: "ONG", + TokenID: string(AssetONG), + Decimals: ONGDecimals, + Value: types.Amount(value), + Title: types.AnyActionClaimRewards, + Key: types.KeyStakeClaimRewards, + } + return tx, true + } + tx.Type = types.TxNativeTokenTransfer + tx.Meta = types.NativeTokenTransfer{ + Name: "Ontology Gas", + Symbol: "ONG", + TokenID: string(AssetONG), + Decimals: ONGDecimals, + Value: types.Amount(value), + From: from, + To: to, + } + return tx, true +} + +func (p *Platform) getTxDetails(srcTx []Tx) ([]Tx, error) { + var wg sync.WaitGroup + txsOntV2Chan := make(chan Tx, len(srcTx)) + wg.Add(len(srcTx)) + for _, blockTxRaw := range srcTx { + go func(blockTxRaw Tx, wg *sync.WaitGroup) { + defer wg.Done() + txRaw, err := p.client.GetTxDetailsByHash(blockTxRaw.Hash) + if err == nil { + txsOntV2Chan <- txRaw + } + }(blockTxRaw, &wg) + } + wg.Wait() + close(txsOntV2Chan) + if len(txsOntV2Chan) != len(srcTx) { + return nil, errors.New("getTxDetails failed to call client.GetTxDetailsByHash http get or unmarshal") + } + var txsOntV2 []Tx + for tx := range txsOntV2Chan { + if len(tx.getTransfers()) > 0 { + txsOntV2 = append(txsOntV2, tx) + } + } + return txsOntV2, nil +} + +func normalizeTxs(srcTxs []Tx, assetType AssetType) types.Txs { + txs := make(types.Txs, 0) + for _, srcTx := range srcTxs { + transfer := srcTx.getTransfers().getTransfer(assetType) + if transfer == nil { + continue + } + tx, ok := Normalize(&srcTx, transfer.AssetName) + if !ok { + continue + } + txs = append(txs, tx) + } + return txs +} diff --git a/platform/ontology/transaction_test.go b/platform/ontology/transaction_test.go new file mode 100644 index 000000000..118911321 --- /dev/null +++ b/platform/ontology/transaction_test.go @@ -0,0 +1,205 @@ +package ontology + +import ( + "encoding/json" + "testing" + + "github.com/stretchr/testify/assert" + "github.com/trustwallet/golibs/coin" + "github.com/trustwallet/golibs/mock" + "github.com/trustwallet/golibs/types" +) + +var ( + srcOntTransfer, _ = mock.JsonStringFromFilePath("mocks/transfer_ont.json") + srcOngTransfer, _ = mock.JsonStringFromFilePath("mocks/transfer_ong.json") + srcRewardTransfer, _ = mock.JsonStringFromFilePath("mocks/transfer_rewards.json") + srcFeeTransfer, _ = mock.JsonStringFromFilePath("mocks/transfer_fee.json") + + dstOntTransfer = types.Tx{ + ID: "ea0e5d8e389cb96760887094194ca359ac998b2f607be470a576861b91e2bf52", + Coin: coin.ONTOLOGY, + From: "ARFXGXSmgFT2h9EiS4D5fen127Lzi48Eij", + To: "ARFXGXSmgFT2h9EiS4D5fen127Lzi48Eij", + Fee: "10000000", + Date: 1578903628, + Type: "transfer", + Status: types.StatusCompleted, + Block: 7571132, + Meta: types.Transfer{ + Value: "5", + Symbol: "ONT", + Decimals: 0, + }, + } + dstOngTransfer = types.Tx{ + ID: "e5946ba02f56e17c3709db2bc91f43f76ee3a359006586024daa5c4ad8c54e78", + Coin: coin.ONTOLOGY, + From: "ASLbwuar3ZTbUbLPnCgjGUw2WHhMfvJJtx", + To: "ARFXGXSmgFT2h9EiS4D5fen127Lzi48Eij", + Fee: "10000000", + Date: 1577631515, + Type: types.TxNativeTokenTransfer, + Status: types.StatusCompleted, + Block: 7457989, + Meta: types.NativeTokenTransfer{ + Name: "Ontology Gas", + Symbol: "ONG", + TokenID: "ong", + Decimals: 9, + Value: "14690000000", + From: "ASLbwuar3ZTbUbLPnCgjGUw2WHhMfvJJtx", + To: "ARFXGXSmgFT2h9EiS4D5fen127Lzi48Eij", + }, + } + dstRewardTransfer = types.Tx{ + ID: "d7554dcdf01f394b9107ff598df6d84e4c3b00ccf1e720b8c09abf085cbe4987", + Coin: coin.ONTOLOGY, + From: "AFmseVrdL9f9oyCzZefL9tG6UbvhUMqNMV", + To: "ARFXGXSmgFT2h9EiS4D5fen127Lzi48Eij", + Fee: "10000000", + Date: 1579699532, + Type: types.TxAnyAction, + Status: types.StatusCompleted, + Block: 7644328, + Meta: types.AnyAction{ + Coin: coin.Ontology().ID, + Name: "Ontology Gas", + Symbol: "ONG", + TokenID: "ong", + Decimals: 9, + Value: "35344040", + Title: types.AnyActionClaimRewards, + Key: types.KeyStakeClaimRewards, + }, + } +) + +func TestNormalize(t *testing.T) { + tests := []struct { + name string + Transaction string + AssetName AssetType + Expected types.Tx + wantErr bool + }{ + {"normalize ont", srcOntTransfer, AssetONT, dstOntTransfer, false}, + {"normalize ong", srcOngTransfer, AssetONG, dstOngTransfer, false}, + {"normalize claim reward", srcRewardTransfer, AssetONG, dstRewardTransfer, false}, + {"normalize fee", srcFeeTransfer, AssetONG, types.Tx{}, true}, + } + for _, test := range tests { + t.Run(test.name, func(t *testing.T) { + var sourceTx Tx + err := json.Unmarshal([]byte(test.Transaction), &sourceTx) + assert.Nil(t, err) + tx, ok := Normalize(&sourceTx, test.AssetName) + if test.wantErr { + assert.False(t, ok) + return + } + assert.True(t, ok) + assert.Equal(t, test.Expected, tx) + }) + } +} + +var ( + ontTxResp1 = TxResult{ + BaseResponse: BaseResponse{Code: 0, Msg: "SUCCESS"}, + Result: Tx{ + Hash: "266d9d7282a5601bf6cb8fc5368a76a2aa54f45731a063a699a692487bcbd0cb", + Time: 1580481541, + Height: 7707834, + Fee: "0.01", + Description: "transfer", + BlockIndex: 2, + ConfirmFlag: 1, + EventType: 3, + Details: Detail{ + Transfers: Transfers{ + { + Amount: "51000", + AssetName: "ong", + FromAddress: "AbEeCHUWpzQaxUN7G1a83N3P2XtVLuMLaE", + ToAddress: "ASLbwuar3ZTbUbLPnCgjGUw2WHhMfvJJtx", + }, + { + Amount: "0.01", + AssetName: "ong", + FromAddress: "ANKXUWXy6XrhQvqbjhKJPH9AnLa2CuEMRK", + ToAddress: "AFmseVrdL9f9oyCzZefL9tG6UbviEH9ugK", + }, + }, + }, + }, + } + + ontTxResp2 = TxResult{ + BaseResponse: BaseResponse{Code: 0, Msg: "SUCCESS"}, + Result: Tx{ + Hash: "2935268c5715f1f2015ba828681c39399dedbe7a24ed628ef7b85d9aac8045fd", + Time: 1580481541, + Height: 7707834, + Fee: "0.01", + Description: "transfer", + BlockIndex: 3, + ConfirmFlag: 1, + EventType: 3, + Details: Detail{ + Transfers: Transfers{ + { + Amount: "113.2", + AssetName: "ong", + FromAddress: "ANdrA47zDXUu8MCkMdD3FYPmpSNGYeAvKz", + ToAddress: "ASLbwuar3ZTbUbLPnCgjGUw2WHhMfvJJtx", + }, + { + Amount: "0.01", + AssetName: "ong", + FromAddress: "ANKXUWXy6XrhQvqbjhKJPH9AnLa2CuEMRK", + ToAddress: "AFmseVrdL9f9oyCzZefL9tG6UbviEH9ugK", + }, + }, + }, + }, + } + + ontTxResp3 = TxResult{ + BaseResponse: BaseResponse{Code: 0, Msg: "SUCCESS"}, + Result: Tx{ + Hash: "40976edc1306b0e5f55b90c8d3ca248bb544e5ebbadb02be6146ba0a0de402c3", + Time: 1580481541, + Height: 7707834, + Fee: "0.01", + Description: "transfer", + BlockIndex: 1, + ConfirmFlag: 1, + EventType: 3, + Details: Detail{ + Transfers: Transfers{ + { + Amount: "10949", + AssetName: "ont", + FromAddress: "Abg2gs6pfpQu82jXbm8EYGiipRBvf9ktVS", + ToAddress: "ASLbwuar3ZTbUbLPnCgjGUw2WHhMfvJJtx", + }, { + Amount: "0.01", + AssetName: "ong", + FromAddress: "ANKXUWXy6XrhQvqbjhKJPH9AnLa2CuEMRK", + ToAddress: "AFmseVrdL9f9oyCzZefL9tG6UbviEH9ugK", + }, + }, + }, + }, + } +) + +func TestNormalizeBlock(t *testing.T) { + block := normalizeTxs([]Tx{ontTxResp1.Result, ontTxResp2.Result, ontTxResp3.Result}, AssetAll) + var want types.Txs + _ = mock.JsonModelFromFilePath("mocks/block_response.json", &want) + lhs, _ := json.Marshal(block) + rhs, _ := json.Marshal(want) + assert.JSONEq(t, string(lhs), string(rhs)) +} diff --git a/platform/platform.go b/platform/platform.go new file mode 100644 index 000000000..13ac899ae --- /dev/null +++ b/platform/platform.go @@ -0,0 +1,110 @@ +package platform + +import ( + "github.com/trustwallet/blockatlas/config" + "github.com/trustwallet/blockatlas/platform/oasis" + + "github.com/trustwallet/blockatlas/platform/filecoin" + "github.com/trustwallet/blockatlas/platform/kava" + + "github.com/trustwallet/blockatlas/pkg/blockatlas" + "github.com/trustwallet/blockatlas/platform/aeternity" + "github.com/trustwallet/blockatlas/platform/aion" + "github.com/trustwallet/blockatlas/platform/algorand" + "github.com/trustwallet/blockatlas/platform/binance" + "github.com/trustwallet/blockatlas/platform/bitcoin" + "github.com/trustwallet/blockatlas/platform/cosmos" + "github.com/trustwallet/blockatlas/platform/elrond" + "github.com/trustwallet/blockatlas/platform/ethereum" + "github.com/trustwallet/blockatlas/platform/fio" + "github.com/trustwallet/blockatlas/platform/harmony" + "github.com/trustwallet/blockatlas/platform/icon" + "github.com/trustwallet/blockatlas/platform/iotex" + "github.com/trustwallet/blockatlas/platform/nano" + "github.com/trustwallet/blockatlas/platform/near" + "github.com/trustwallet/blockatlas/platform/nebulas" + "github.com/trustwallet/blockatlas/platform/nimiq" + "github.com/trustwallet/blockatlas/platform/ontology" + "github.com/trustwallet/blockatlas/platform/polkadot" + "github.com/trustwallet/blockatlas/platform/ripple" + "github.com/trustwallet/blockatlas/platform/solana" + "github.com/trustwallet/blockatlas/platform/stellar" + "github.com/trustwallet/blockatlas/platform/tezos" + "github.com/trustwallet/blockatlas/platform/theta" + "github.com/trustwallet/blockatlas/platform/tron" + "github.com/trustwallet/blockatlas/platform/vechain" + "github.com/trustwallet/blockatlas/platform/waves" + "github.com/trustwallet/blockatlas/platform/zilliqa" + "github.com/trustwallet/golibs/coin" +) + +const ( + allPlatformsHandle = "all" +) + +func GetHandle(coinId uint) string { + return coin.Coins[coinId].Handle +} + +func getAllHandlers() blockatlas.Platforms { + return blockatlas.Platforms{ + coin.Fio().Handle: fio.Init(config.Default.Fio.API), + coin.Aion().Handle: aion.Init(config.Default.Aion.API), + coin.Icon().Handle: icon.Init(config.Default.Icon.API), + coin.Tron().Handle: tron.Init(config.Default.Tron.API, config.Default.Tron.Key), + coin.Nano().Handle: nano.Init(config.Default.Nano.API), + coin.Nimiq().Handle: nimiq.Init(config.Default.Nimiq.API), + coin.Iotex().Handle: iotex.Init(config.Default.Iotex.API), + coin.Theta().Handle: theta.Init(config.Default.Theta.API, config.Default.Theta.Key), + coin.Waves().Handle: waves.Init(config.Default.Waves.API), + coin.Ripple().Handle: ripple.Init(config.Default.Ripple.API), + coin.Harmony().Handle: harmony.Init(config.Default.Harmony.API), + coin.Vechain().Handle: vechain.Init(config.Default.Vechain.API), + coin.Nebulas().Handle: nebulas.Init(config.Default.Nebulas.API), + coin.Ontology().Handle: ontology.Init(config.Default.Ontology.API), + coin.Algorand().Handle: algorand.Init(config.Default.Algorand.API, config.Default.Algorand.Key), + coin.Aeternity().Handle: aeternity.Init(config.Default.Aeternity.API), + coin.Solana().Handle: solana.Init(config.Default.Solana.API), + coin.Tezos().Handle: tezos.Init(config.Default.Tezos.API, config.Default.Tezos.RPC, config.Default.Tezos.Baker), + coin.Binance().Handle: binance.Init(config.Default.Binance.API, config.Default.Binance.Key, config.Default.Binance.StakingAPI), + coin.Zilliqa().Handle: zilliqa.Init(config.Default.Zilliqa.API, config.Default.Zilliqa.Key, config.Default.Zilliqa.RPC), + coin.Polkadot().Handle: polkadot.Init(coin.POLKADOT, config.Default.Polkadot.API), + coin.Stellar().Handle: stellar.Init(coin.STELLAR, config.Default.Stellar.API), + coin.Cosmos().Handle: cosmos.Init(coin.COSMOS, config.Default.Cosmos.API), + coin.Kava().Handle: kava.Init(coin.KAVA, config.Default.Kava.API), + coin.Bitcoin().Handle: bitcoin.Init(coin.BITCOIN, config.Default.Bitcoin.API), + coin.Litecoin().Handle: bitcoin.Init(coin.LITECOIN, config.Default.Litecoin.API), + coin.Bitcoincash().Handle: bitcoin.Init(coin.BITCOINCASH, config.Default.Bitcoincash.API), + coin.Zcash().Handle: bitcoin.Init(coin.ZCASH, config.Default.Zcash.API), + coin.Zcoin().Handle: bitcoin.Init(coin.ZCOIN, config.Default.Zcoin.API), + coin.Viacoin().Handle: bitcoin.Init(coin.VIACOIN, config.Default.Viacoin.API), + coin.Ravencoin().Handle: bitcoin.Init(coin.RAVENCOIN, config.Default.Ravencoin.API), + coin.Groestlcoin().Handle: bitcoin.Init(coin.GROESTLCOIN, config.Default.Groestlcoin.API), + coin.Zelcash().Handle: bitcoin.Init(coin.ZELCASH, config.Default.Zelcash.API), + coin.Decred().Handle: bitcoin.Init(coin.DECRED, config.Default.Decred.API), + coin.Digibyte().Handle: bitcoin.Init(coin.DIGIBYTE, config.Default.Digibyte.API), + coin.Dash().Handle: bitcoin.Init(coin.DASH, config.Default.Dash.API), + coin.Doge().Handle: bitcoin.Init(coin.DOGE, config.Default.Doge.API), + coin.Qtum().Handle: bitcoin.Init(coin.QTUM, config.Default.Qtum.API), + coin.Gochain().Handle: ethereum.InitWithBlockbook(coin.GOCHAIN, config.Default.Gochain.API), + coin.Thundertoken().Handle: ethereum.InitWithBlockbook(coin.THUNDERTOKEN, config.Default.Thundertoken.API), + coin.Classic().Handle: ethereum.InitWithBlockbook(coin.CLASSIC, config.Default.Classic.API), + coin.Poa().Handle: ethereum.InitWithBlockbook(coin.POA, config.Default.Poa.API), + coin.Callisto().Handle: ethereum.InitWithBlockbook(coin.CALLISTO, config.Default.Callisto.API), + coin.Wanchain().Handle: ethereum.InitWithBlockbook(coin.WANCHAIN, config.Default.Wanchain.API), + coin.Tomochain().Handle: ethereum.InitWithBlockbook(coin.TOMOCHAIN, config.Default.Tomochain.API), + coin.Smartchain().Handle: ethereum.InitWithBounce(coin.SMARTCHAIN, config.Default.Smartchain.API, config.Default.Smartchain.CollectionsAPI), + coin.Ethereum().Handle: ethereum.InitWithOpenSea(coin.ETHEREUM, config.Default.Ethereum.API, config.Default.Ethereum.CollectionsAPI, config.Default.Ethereum.CollectionsKey), + coin.Near().Handle: near.Init(config.Default.Near.API), + coin.Elrond().Handle: elrond.Init(coin.ELROND, config.Default.Elrond.API), + coin.Filecoin().Handle: filecoin.Init(config.Default.Filecoin.API, config.Default.Filecoin.Explorer), + coin.Oasis().Handle: oasis.Init(config.Default.Oasis.API), + } +} + +func getCollectionsHandlers() blockatlas.CollectionsAPIs { + return blockatlas.CollectionsAPIs{ + coin.ETHEREUM: ethereum.InitWithOpenSea(coin.ETHEREUM, config.Default.Ethereum.API, config.Default.Ethereum.CollectionsAPI, config.Default.Ethereum.CollectionsKey), + coin.SMARTCHAIN: ethereum.InitWithBounce(coin.SMARTCHAIN, config.Default.Smartchain.API, config.Default.Smartchain.CollectionsAPI), + } +} diff --git a/platform/polkadot/api.go b/platform/polkadot/api.go deleted file mode 100644 index 3233ba0f0..000000000 --- a/platform/polkadot/api.go +++ /dev/null @@ -1,155 +0,0 @@ -package polkadot - -import ( - "encoding/hex" - "encoding/json" - "fmt" - "github.com/trustwallet/blockatlas/pkg/numbers" - "strings" - - "github.com/spf13/viper" - "github.com/trustwallet/blockatlas/coin" - "github.com/trustwallet/blockatlas/pkg/blockatlas" -) - -type Platform struct { - client Client - CoinIndex uint -} - -var NetworkByteMap = map[string]byte{ - "DOT": 0x00, - "KSM": 0x02, -} - -func (p *Platform) Init() error { - p.client = Client{blockatlas.InitClient(viper.GetString(p.ConfigKey()))} - return nil -} - -func (p *Platform) Coin() coin.Coin { - return coin.Coins[p.CoinIndex] -} - -func (p *Platform) ConfigKey() string { - return fmt.Sprintf("%s.api", p.Coin().Handle) -} - -func (p *Platform) GetTxsByAddress(address string) (blockatlas.TxPage, error) { - transfers, err := p.client.GetTransfersOfAddress(address) - if err != nil { - return nil, err - } - - txs := make([]blockatlas.Tx, 0) - for _, srcTx := range transfers { - tx := p.NormalizeTransfer(&srcTx) - txs = append(txs, tx) - } - - return txs, nil -} - -func (p *Platform) CurrentBlockNumber() (int64, error) { - return p.client.GetCurrentBlock() -} - -func (p *Platform) GetBlockByNumber(num int64) (*blockatlas.Block, error) { - if srcBlock, err := p.client.GetBlockByNumber(num); err == nil { - txs := p.NormalizeExtrinsics(srcBlock) - return &blockatlas.Block{ - Number: num, - Txs: txs, - }, nil - } else { - return nil, err - } -} - -func (p *Platform) NormalizeTransfer(srcTx *Transfer) blockatlas.Tx { - decimals := p.Coin().Decimals - amount := strings.Split(numbers.DecimalExp(srcTx.Amount, int(decimals)), ".")[0] - status := blockatlas.StatusCompleted - if !srcTx.Success { - status = blockatlas.StatusFailed - } - result := blockatlas.Tx{ - ID: srcTx.Hash, - Coin: p.Coin().ID, - Date: int64(srcTx.Timestamp), - From: srcTx.From, - To: srcTx.To, - Fee: blockatlas.Amount(FeeTransfer), // API will return fee later - Block: srcTx.BlockNumber, - Status: status, - Meta: blockatlas.Transfer{ - Value: blockatlas.Amount(amount), - Symbol: p.Coin().Symbol, - Decimals: decimals, - }, - } - return result -} - -func (p *Platform) NormalizeExtrinsics(extrinsics []Extrinsic) []blockatlas.Tx { - txs := make([]blockatlas.Tx, 0) - for _, srcTx := range extrinsics { - tx := p.NormalizeExtrinsic(&srcTx) - if tx != nil { - txs = append(txs, *tx) - } - } - return txs -} - -func (p *Platform) NormalizeExtrinsic(srcTx *Extrinsic) *blockatlas.Tx { - var datas []CallData - err := json.Unmarshal([]byte(srcTx.Params), &datas) - if err != nil { - return nil - } - - var status blockatlas.Status - if !srcTx.Success { - status = blockatlas.StatusFailed - } else { - status = blockatlas.StatusCompleted - } - - result := blockatlas.Tx{ - ID: srcTx.Hash, - Coin: p.Coin().ID, - Date: int64(srcTx.Timestamp), - Block: srcTx.BlockNumber, - Status: status, - Sequence: srcTx.Nonce, - } - - decimals := p.Coin().Decimals - if srcTx.CallModule == ModuleBalances && - srcTx.CallModuleFunction == ModuleFunctionTransfer { - result.From = srcTx.AccountId - result.To = p.NormalizeAddress(datas[0].ValueRaw) - result.Fee = blockatlas.Amount(FeeTransfer) - result.Meta = blockatlas.Transfer{ - Value: blockatlas.Amount(fmt.Sprintf("%.0f", datas[1].Value.(float64))), - Symbol: p.Coin().Symbol, - Decimals: decimals, - } - } else { - // not supported yet - return nil - } - return &result -} - -func (p *Platform) NormalizeAddress(valueRaw string) string { - bytes, err := hex.DecodeString(valueRaw) - if err != nil { - return "" - } - if network, ok := NetworkByteMap[p.Coin().Symbol]; ok { - return PublicKeyToAddress(bytes[1:], network) - } - return "" -} diff --git a/platform/polkadot/api_test.go b/platform/polkadot/api_test.go deleted file mode 100644 index a167c64dd..000000000 --- a/platform/polkadot/api_test.go +++ /dev/null @@ -1,191 +0,0 @@ -package polkadot - -import ( - "reflect" - "testing" - - "github.com/trustwallet/blockatlas/coin" - "github.com/trustwallet/blockatlas/pkg/blockatlas" -) - -func TestNormalizeTransfer(t *testing.T) { - platform := Platform{CoinIndex: coin.KSM} - type args struct { - srcTx *Transfer - } - tests := []struct { - name string - args args - wantTx blockatlas.Tx - }{ - { - name: "Receive 1", - args: args{ - srcTx: &Transfer{ - From: "HKtMPUSoTC8Hts2uqcQVzPAuPRpecBt4XJ5Q1AT1GM3tp2r", - To: "CtwdfrhECFs3FpvCGoiE4hwRC4UsSiM8WL899HjRdQbfYZY", - Amount: "0.01", - Module: "balances", - Hash: "0x20cfbba19817e4b7a61e718d269de47e7067a24860fa978c2a8ead4c96a827c4", - Timestamp: 1577176992, - BlockNumber: 360298, - Success: true, - }, - }, - wantTx: blockatlas.Tx{ - ID: "0x20cfbba19817e4b7a61e718d269de47e7067a24860fa978c2a8ead4c96a827c4", - Coin: 434, - Date: 1577176992, - From: "HKtMPUSoTC8Hts2uqcQVzPAuPRpecBt4XJ5Q1AT1GM3tp2r", - To: "CtwdfrhECFs3FpvCGoiE4hwRC4UsSiM8WL899HjRdQbfYZY", - Block: 360298, - Status: "completed", - Fee: "100000000", - Meta: blockatlas.Transfer{ - Value: blockatlas.Amount("10000000000"), - Symbol: "KSM", - Decimals: 12, - }, - }, - }, - { - name: "Receive 2", - args: args{ - srcTx: &Transfer{ - From: "DbCNECPna3k6MXFWWNZa5jGsuWycqEE6zcUxZYkxhVofrFk", - To: "CtwdfrhECFs3FpvCGoiE4hwRC4UsSiM8WL899HjRdQbfYZY", - Amount: "210", - Module: "balances", - Hash: "0xe0be47f6ce0e62a218f197dd68599989376ee7e951d54c3c6146e2c5c5eacd1f", - Timestamp: 1575525432, - BlockNumber: 90672, - Success: true, - }, - }, - wantTx: blockatlas.Tx{ - ID: "0xe0be47f6ce0e62a218f197dd68599989376ee7e951d54c3c6146e2c5c5eacd1f", - Coin: 434, - Date: 1575525432, - From: "DbCNECPna3k6MXFWWNZa5jGsuWycqEE6zcUxZYkxhVofrFk", - To: "CtwdfrhECFs3FpvCGoiE4hwRC4UsSiM8WL899HjRdQbfYZY", - Block: 90672, - Status: "completed", - Fee: "100000000", - Meta: blockatlas.Transfer{ - Value: blockatlas.Amount("210000000000000"), - Symbol: "KSM", - Decimals: 12, - }, - }, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - if gotTx := platform.NormalizeTransfer(tt.args.srcTx); !reflect.DeepEqual(gotTx, tt.wantTx) { - t.Errorf("Normalize() = %v\n Want = %v", gotTx, tt.wantTx) - } - }) - } -} - -func TestNormalizeExtrinsic(t *testing.T) { - platform := Platform{CoinIndex: coin.KSM} - type args struct { - srcTx *Extrinsic - } - tests := []struct { - name string - args args - wantTx *blockatlas.Tx - }{ - { - name: "Transfer", - args: args{ - srcTx: &Extrinsic{ - Timestamp: 1577176992, - BlockNumber: 360298, - CallModuleFunction: "transfer", - CallModule: "balances", - Params: "[{\"name\":\"dest\",\"type\":\"Address\",\"value\":\"CtwdfrhECFs3FpvCGoiE4hwRC4UsSiM8WL899HjRdQbfYZY\",\"valueRaw\":\"ff0e33fdfb980e4499e5c3576e742a563b6a4fc0f6f598b1917fd7a6fe393ffc72\"},{\"name\":\"value\",\"type\":\"Compact\\u003cBalance\\u003e\",\"value\":10000000000,\"valueRaw\":\"0700e40b5402\"}]", - AccountId: "HKtMPUSoTC8Hts2uqcQVzPAuPRpecBt4XJ5Q1AT1GM3tp2r", - Nonce: 0, - Hash: "0x20cfbba19817e4b7a61e718d269de47e7067a24860fa978c2a8ead4c96a827c4", - Success: true, - }, - }, - wantTx: &blockatlas.Tx{ - ID: "0x20cfbba19817e4b7a61e718d269de47e7067a24860fa978c2a8ead4c96a827c4", - Coin: 434, - Date: 1577176992, - From: "HKtMPUSoTC8Hts2uqcQVzPAuPRpecBt4XJ5Q1AT1GM3tp2r", - To: "CtwdfrhECFs3FpvCGoiE4hwRC4UsSiM8WL899HjRdQbfYZY", - Block: 360298, - Status: "completed", - Fee: "100000000", - Meta: blockatlas.Transfer{ - Value: blockatlas.Amount("10000000000"), - Symbol: "KSM", - Decimals: 12, - }, - }, - }, - { - name: "Bond", - args: args{ - srcTx: &Extrinsic{ - Timestamp: 1577712822, - BlockNumber: 447444, - CallModuleFunction: "bond", - CallModule: "staking", - Params: "[{\"name\":\"controller\",\"type\":\"Address\",\"value\":\"b44024b9ac73ae8e2f6f6f72b5021a41963b2bc06f67181a040c40bcafb4127b\",\"valueRaw\":\"ffb44024b9ac73ae8e2f6f6f72b5021a41963b2bc06f67181a040c40bcafb4127b\"},{\"name\":\"value\",\"type\":\"Compact\\u003cBalanceOf\\u003e\",\"value\":100000000000,\"valueRaw\":\"0700e8764817\"},{\"name\":\"payee\",\"type\":\"RewardDestination\",\"value\":\"Staked\",\"valueRaw\":\"00\"}]", - AccountId: "b44024b9ac73ae8e2f6f6f72b5021a41963b2bc06f67181a040c40bcafb4127b", - Nonce: 1, - Hash: "0xeaaa9ca1a93854be0d3cccc7d7a36272e5663a40a296ab9b0451e0d43ee376ce", - Success: true, - }, - }, - wantTx: nil, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - if gotTx := platform.NormalizeExtrinsic(tt.args.srcTx); !reflect.DeepEqual(gotTx, tt.wantTx) { - t.Errorf("Normalize() = %v\n Want = %v", gotTx, tt.wantTx) - } - }) - } -} - -func TestNormalizeAddress(t *testing.T) { - platform := Platform{CoinIndex: coin.KSM} - type args struct { - valueRaw string - } - tests := []struct { - name string - args args - wantAddress string - }{ - { - name: "KSM address 1", - args: args{ - valueRaw: "ffe8e1b8de72651640e302b62dad1f643ec8b65a3647a7409b2896634db599ed60", - }, - wantAddress: "HqfgRXDgCQcV8KAuTAPGuA1r91iEzinmmNBPkR9kiKhifJq", - }, - { - name: "KSM address 2", - args: args{ - valueRaw: "ffe0b3fcccfe0283cc0f8c105c68b5690aab8c5c1692a868e55eaca836c8779085", - }, - wantAddress: "HewiDTQv92L2bVtkziZC8ASxrFUxr6ajQ62RXAnwQ8FDVmg", - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - if address := platform.NormalizeAddress(tt.args.valueRaw); address != tt.wantAddress { - t.Errorf("Normalize() = %v\n Want = %v", address, tt.wantAddress) - } - }) - } -} diff --git a/platform/polkadot/base.go b/platform/polkadot/base.go new file mode 100644 index 000000000..0d6cb9ab2 --- /dev/null +++ b/platform/polkadot/base.go @@ -0,0 +1,23 @@ +package polkadot + +import ( + "github.com/trustwallet/golibs/client" + "github.com/trustwallet/golibs/coin" + "github.com/trustwallet/golibs/network/middleware" +) + +type Platform struct { + client Client + CoinIndex uint +} + +func Init(coin uint, api string) *Platform { + return &Platform{ + CoinIndex: coin, + client: Client{client.InitJSONClient(api, middleware.SentryErrorHandler)}, + } +} + +func (p *Platform) Coin() coin.Coin { + return coin.Coins[p.CoinIndex] +} diff --git a/platform/polkadot/block.go b/platform/polkadot/block.go new file mode 100644 index 000000000..bbafaa1f5 --- /dev/null +++ b/platform/polkadot/block.go @@ -0,0 +1,19 @@ +package polkadot + +import "github.com/trustwallet/golibs/types" + +func (p *Platform) CurrentBlockNumber() (int64, error) { + return p.client.GetCurrentBlock() +} + +func (p *Platform) GetBlockByNumber(num int64) (*types.Block, error) { + if srcBlock, err := p.client.GetBlockByNumber(num); err == nil { + txs := p.NormalizeExtrinsics(srcBlock) + return &types.Block{ + Number: num, + Txs: txs, + }, nil + } else { + return nil, err + } +} diff --git a/platform/polkadot/client.go b/platform/polkadot/client.go index 1b5706f20..3a0ec2119 100644 --- a/platform/polkadot/client.go +++ b/platform/polkadot/client.go @@ -3,16 +3,17 @@ package polkadot import ( "strconv" - "github.com/trustwallet/blockatlas/pkg/blockatlas" + "github.com/trustwallet/golibs/client" + "github.com/trustwallet/golibs/types" ) type Client struct { - blockatlas.Request + client.Request } func (c *Client) GetTransfersOfAddress(address string) ([]Transfer, error) { var res SubscanResponse - err := c.Post(&res, "/scan/transfers", TransfersRequest{Address: address, Row: blockatlas.TxPerPage}) + err := c.Post(&res, "scan/transfers", TransfersRequest{Address: address, Row: types.TxPerPage}) if err != nil { return nil, err } @@ -21,7 +22,7 @@ func (c *Client) GetTransfersOfAddress(address string) ([]Transfer, error) { func (c *Client) GetExtrinsicsOfAddress(address string) ([]Extrinsic, error) { var res SubscanResponse - err := c.Post(&res, "/scan/extrinsics", TransfersRequest{Address: address, Row: blockatlas.TxPerPage}) + err := c.Post(&res, "scan/extrinsics", TransfersRequest{Address: address, Row: types.TxPerPage}) if err != nil { return nil, err } @@ -30,7 +31,7 @@ func (c *Client) GetExtrinsicsOfAddress(address string) ([]Extrinsic, error) { func (c *Client) GetCurrentBlock() (int64, error) { var res SubscanResponse - err := c.Post(&res, "/scan/metadata", nil) + err := c.Post(&res, "scan/metadata", nil) if err != nil { return 0, err } @@ -43,7 +44,7 @@ func (c *Client) GetCurrentBlock() (int64, error) { func (c *Client) GetBlockByNumber(number int64) ([]Extrinsic, error) { var res SubscanResponse - err := c.Post(&res, "/scan/block", BlockRequest{BlockNumber: number}) + err := c.Post(&res, "scan/block", BlockRequest{BlockNumber: number}) if err != nil { return nil, err } diff --git a/platform/polkadot/model.go b/platform/polkadot/model.go index 0fdfec36a..0973f4ffc 100644 --- a/platform/polkadot/model.go +++ b/platform/polkadot/model.go @@ -30,13 +30,13 @@ type Extrinsic struct { Nonce uint64 `json:"nonce"` Hash string `json:"extrinsic_hash"` Success bool `json:"success"` + Fee string `json:"fee"` } type CallData struct { - Name string `json:"name"` - Type string `json:"type"` - Value interface{} `json:"value"` - ValueRaw string `json:"valueRaw"` + Name string `json:"name"` + Type string `json:"type"` + Value string `json:"value"` } type TransfersRequest struct { diff --git a/platform/polkadot/transaction.go b/platform/polkadot/transaction.go new file mode 100644 index 000000000..bdd22c82e --- /dev/null +++ b/platform/polkadot/transaction.go @@ -0,0 +1,125 @@ +package polkadot + +import ( + "encoding/hex" + "encoding/json" + "strings" + + "github.com/trustwallet/golibs/numbers" + "github.com/trustwallet/golibs/types" +) + +var NetworkByteMap = map[string]byte{ + "DOT": 0x00, + "KSM": 0x02, +} + +func (p *Platform) GetTxsByAddress(address string) (types.Txs, error) { + transfers, err := p.client.GetTransfersOfAddress(address) + if err != nil { + return nil, err + } + + txs := make(types.Txs, 0) + for _, srcTx := range transfers { + tx := p.NormalizeTransfer(&srcTx) + txs = append(txs, tx) + } + + return txs, nil +} + +func (p *Platform) NormalizeTransfer(srcTx *Transfer) types.Tx { + decimals := p.Coin().Decimals + amount := strings.Split(numbers.DecimalExp(srcTx.Amount, int(decimals)), ".")[0] + status := types.StatusCompleted + if !srcTx.Success { + status = types.StatusError + } + result := types.Tx{ + ID: srcTx.Hash, + Coin: p.Coin().ID, + Date: int64(srcTx.Timestamp), + From: srcTx.From, + To: srcTx.To, + Fee: types.Amount(FeeTransfer), // API will return fee later + Block: srcTx.BlockNumber, + Status: status, + Meta: types.Transfer{ + Value: types.Amount(amount), + Symbol: p.Coin().Symbol, + Decimals: decimals, + }, + } + return result +} + +func (p *Platform) NormalizeExtrinsics(extrinsics []Extrinsic) types.Txs { + txs := make(types.Txs, 0) + for _, srcTx := range extrinsics { + tx := p.NormalizeExtrinsic(&srcTx) + if tx != nil { + txs = append(txs, *tx) + } + } + return txs +} + +func (p *Platform) NormalizeExtrinsic(srcTx *Extrinsic) *types.Tx { + var datas []CallData + err := json.Unmarshal([]byte(srcTx.Params), &datas) + if err != nil { + return nil + } + + // only supports balances::transfer + if srcTx.CallModule != ModuleBalances || srcTx.CallModuleFunction != ModuleFunctionTransfer { + return nil + } + + // check data types + if len(datas) < 2 || datas[0].Type != "Address" || datas[1].Type != "Compact" { + return nil + } + + to := p.NormalizeAddress(datas[0].Value) + if len(to) == 0 { + return nil + } + + status := types.StatusCompleted + if !srcTx.Success { + status = types.StatusError + } + + result := types.Tx{ + ID: srcTx.Hash, + Coin: p.Coin().ID, + From: srcTx.AccountId, + To: to, + Fee: types.Amount(srcTx.Fee), + Date: int64(srcTx.Timestamp), + Block: srcTx.BlockNumber, + Status: status, + Sequence: srcTx.Nonce, + + Meta: types.Transfer{ + Value: types.Amount(datas[1].Value), + Symbol: p.Coin().Symbol, + Decimals: p.Coin().Decimals, + }, + } + + return &result +} + +func (p *Platform) NormalizeAddress(valueRaw string) string { + bytes, err := hex.DecodeString(valueRaw) + if err != nil { + return "" + } + if network, ok := NetworkByteMap[p.Coin().Symbol]; ok && len(bytes) > 0 { + return PublicKeyToAddress(bytes[:], network) + } + return "" +} diff --git a/platform/polkadot/transaction_test.go b/platform/polkadot/transaction_test.go new file mode 100644 index 000000000..37bab42e2 --- /dev/null +++ b/platform/polkadot/transaction_test.go @@ -0,0 +1,276 @@ +package polkadot + +import ( + "reflect" + "testing" + + "github.com/trustwallet/golibs/coin" + "github.com/trustwallet/golibs/types" +) + +func TestNormalizeTransfer(t *testing.T) { + platform := Platform{CoinIndex: coin.KUSAMA} + type args struct { + srcTx *Transfer + } + tests := []struct { + name string + args args + wantTx types.Tx + }{ + { + name: "Receive 1", + args: args{ + srcTx: &Transfer{ + From: "HKtMPUSoTC8Hts2uqcQVzPAuPRpecBt4XJ5Q1AT1GM3tp2r", + To: "CtwdfrhECFs3FpvCGoiE4hwRC4UsSiM8WL899HjRdQbfYZY", + Amount: "0.01", + Module: "balances", + Hash: "0x20cfbba19817e4b7a61e718d269de47e7067a24860fa978c2a8ead4c96a827c4", + Timestamp: 1577176992, + BlockNumber: 360298, + Success: true, + }, + }, + wantTx: types.Tx{ + ID: "0x20cfbba19817e4b7a61e718d269de47e7067a24860fa978c2a8ead4c96a827c4", + Coin: 434, + Date: 1577176992, + From: "HKtMPUSoTC8Hts2uqcQVzPAuPRpecBt4XJ5Q1AT1GM3tp2r", + To: "CtwdfrhECFs3FpvCGoiE4hwRC4UsSiM8WL899HjRdQbfYZY", + Block: 360298, + Status: "completed", + Fee: "100000000", + Meta: types.Transfer{ + Value: types.Amount("10000000000"), + Symbol: "KSM", + Decimals: 12, + }, + }, + }, + { + name: "Receive 2", + args: args{ + srcTx: &Transfer{ + From: "DbCNECPna3k6MXFWWNZa5jGsuWycqEE6zcUxZYkxhVofrFk", + To: "CtwdfrhECFs3FpvCGoiE4hwRC4UsSiM8WL899HjRdQbfYZY", + Amount: "210", + Module: "balances", + Hash: "0xe0be47f6ce0e62a218f197dd68599989376ee7e951d54c3c6146e2c5c5eacd1f", + Timestamp: 1575525432, + BlockNumber: 90672, + Success: true, + }, + }, + wantTx: types.Tx{ + ID: "0xe0be47f6ce0e62a218f197dd68599989376ee7e951d54c3c6146e2c5c5eacd1f", + Coin: 434, + Date: 1575525432, + From: "DbCNECPna3k6MXFWWNZa5jGsuWycqEE6zcUxZYkxhVofrFk", + To: "CtwdfrhECFs3FpvCGoiE4hwRC4UsSiM8WL899HjRdQbfYZY", + Block: 90672, + Status: "completed", + Fee: "100000000", + Meta: types.Transfer{ + Value: types.Amount("210000000000000"), + Symbol: "KSM", + Decimals: 12, + }, + }, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + if gotTx := platform.NormalizeTransfer(tt.args.srcTx); !reflect.DeepEqual(gotTx, tt.wantTx) { + t.Errorf("Normalize() = %v\n Want = %v", gotTx, tt.wantTx) + } + }) + } +} + +func TestNormalizeExtrinsic(t *testing.T) { + type args struct { + platform Platform + srcTx *Extrinsic + } + tests := []struct { + name string + args args + wantTx *types.Tx + }{ + { + name: "Transfer KSM", + args: args{ + platform: Platform{CoinIndex: coin.KUSAMA}, + srcTx: &Extrinsic{ + Timestamp: 1577176992, + BlockNumber: 360298, + CallModuleFunction: "transfer", + CallModule: "balances", + Params: "[{\"name\":\"dest\",\"type\":\"Address\",\"value\":\"0e33fdfb980e4499e5c3576e742a563b6a4fc0f6f598b1917fd7a6fe393ffc72\",\"value_raw\":\"\"},{\"name\":\"value\",\"type\":\"Compact\\u003cBalance\\u003e\",\"value\":\"10000000000\",\"value_raw\":\"\"}]", + AccountId: "HKtMPUSoTC8Hts2uqcQVzPAuPRpecBt4XJ5Q1AT1GM3tp2r", + Nonce: 0, + Hash: "0x20cfbba19817e4b7a61e718d269de47e7067a24860fa978c2a8ead4c96a827c4", + Success: true, + Fee: "100000000", + }, + }, + wantTx: &types.Tx{ + ID: "0x20cfbba19817e4b7a61e718d269de47e7067a24860fa978c2a8ead4c96a827c4", + Coin: 434, + Date: 1577176992, + From: "HKtMPUSoTC8Hts2uqcQVzPAuPRpecBt4XJ5Q1AT1GM3tp2r", + To: "CtwdfrhECFs3FpvCGoiE4hwRC4UsSiM8WL899HjRdQbfYZY", + Fee: "100000000", + Block: 360298, + Status: "completed", + Sequence: 0, + Meta: types.Transfer{ + Value: types.Amount("10000000000"), + Symbol: "KSM", + Decimals: 12, + }, + }, + }, + { + name: "Transfer DOT", + args: args{ + platform: Platform{CoinIndex: coin.POLKADOT}, + srcTx: &Extrinsic{ + Timestamp: 1607035338, + BlockNumber: 2742892, + CallModuleFunction: "transfer", + CallModule: "balances", + Params: "[{\"name\":\"dest\",\"type\":\"Address\",\"value\":\"deb1bb215d2188d0934e803473f02b61b7990ffaea63a533a9917d5707f74d35\",\"value_raw\":\"\"},{\"name\":\"value\",\"type\":\"Compact\\u003cBalance\\u003e\",\"value\":\"16694000000\",\"value_raw\":\"\"}]", + AccountId: "13VELdVkrHf1UUH6TRYSuofJAHykL3MAw3sXG9HGR8YpgrBH", + Nonce: 1, + Hash: "0x17f92e09994e6885007bfdf4a0a5026f667e69ae94547c5c89b03d647541025e", + Success: true, + Fee: "153000000", + }, + }, + wantTx: &types.Tx{ + ID: "0x17f92e09994e6885007bfdf4a0a5026f667e69ae94547c5c89b03d647541025e", + Coin: 354, + Date: 1607035338, + From: "13VELdVkrHf1UUH6TRYSuofJAHykL3MAw3sXG9HGR8YpgrBH", + To: "162zRoDpEXQVCpPgJcoMMKZK6P8M9Ntu4myZ9ZBbDz6mqBzt", + Fee: "153000000", + Block: 2742892, + Status: "completed", + Sequence: 1, + Meta: types.Transfer{ + Value: types.Amount("16694000000"), + Symbol: "DOT", + Decimals: 10, + }, + }, + }, + { + name: "Bond", + args: args{ + platform: Platform{CoinIndex: coin.KUSAMA}, + srcTx: &Extrinsic{ + Timestamp: 1577712822, + BlockNumber: 447444, + CallModuleFunction: "bond", + CallModule: "staking", + Params: "[{\"name\":\"controller\",\"type\":\"Address\",\"value\":\"b44024b9ac73ae8e2f6f6f72b5021a41963b2bc06f67181a040c40bcafb4127b\",\"valueRaw\":\"ffb44024b9ac73ae8e2f6f6f72b5021a41963b2bc06f67181a040c40bcafb4127b\"},{\"name\":\"value\",\"type\":\"Compact\\u003cBalanceOf\\u003e\",\"value\":100000000000,\"valueRaw\":\"0700e8764817\"},{\"name\":\"payee\",\"type\":\"RewardDestination\",\"value\":\"Staked\",\"valueRaw\":\"00\"}]", + AccountId: "b44024b9ac73ae8e2f6f6f72b5021a41963b2bc06f67181a040c40bcafb4127b", + Nonce: 1, + Hash: "0xeaaa9ca1a93854be0d3cccc7d7a36272e5663a40a296ab9b0451e0d43ee376ce", + Success: true, + }, + }, + wantTx: nil, + }, + { + name: "Error Params", + args: args{ + platform: Platform{CoinIndex: coin.KUSAMA}, + srcTx: &Extrinsic{ + Timestamp: 1577712822, + BlockNumber: 447444, + CallModuleFunction: "set", + CallModule: "timestamp", + Params: "[{\"name\":\"now\",\"type\":\"Compact\\u003cMoment\\u003e\",\"value\":1580348178,\"valueRaw\":\"0b507e17f46f01\"}]", + AccountId: "b44024b9ac73ae8e2f6f6f72b5021a41963b2bc06f67181a040c40bcafb4127b", + Nonce: 1, + Hash: "0xeaaa9ca1a93854be0d3cccc7d7a36272e5663a40a296ab9b0451e0d43ee376ce", + Success: true, + }, + }, + wantTx: nil, + }, + { + name: "set_heads", + args: args{ + platform: Platform{CoinIndex: coin.KUSAMA}, + srcTx: &Extrinsic{ + Timestamp: 1577712822, + BlockNumber: 447444, + CallModuleFunction: "set_heads", + CallModule: "parachains", + Params: "[{\"name\":\"heads\",\"type\":\"Vec\\u003cAttestedCandidate\\u003e\",\"value\":[],\"valueRaw\":\"\"}]", + AccountId: "b44024b9ac73ae8e2f6f6f72b5021a41963b2bc06f67181a040c40bcafb4127b", + Nonce: 1, + Hash: "0xeaaa9ca1a93854be0d3cccc7d7a36272e5663a40a296ab9b0451e0d43ee376ce", + Success: true, + }, + }, + wantTx: nil, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + if gotTx := tt.args.platform.NormalizeExtrinsic(tt.args.srcTx); !reflect.DeepEqual(gotTx, tt.wantTx) { + t.Errorf("Normalize() = %v\n Want = %v", gotTx, tt.wantTx) + } + }) + } +} + +func TestNormalizeAddress(t *testing.T) { + + type args struct { + platform Platform + value string + } + tests := []struct { + name string + args args + wantAddress string + }{ + { + name: "KSM address 1", + args: args{ + platform: Platform{CoinIndex: coin.KUSAMA}, + value: "e8e1b8de72651640e302b62dad1f643ec8b65a3647a7409b2896634db599ed60", + }, + wantAddress: "HqfgRXDgCQcV8KAuTAPGuA1r91iEzinmmNBPkR9kiKhifJq", + }, + { + name: "KSM address 2", + args: args{ + platform: Platform{CoinIndex: coin.KUSAMA}, + value: "e0b3fcccfe0283cc0f8c105c68b5690aab8c5c1692a868e55eaca836c8779085", + }, + wantAddress: "HewiDTQv92L2bVtkziZC8ASxrFUxr6ajQ62RXAnwQ8FDVmg", + }, + { + name: "DOT address", + args: args{ + platform: Platform{CoinIndex: coin.POLKADOT}, + value: "e0b3fcccfe0283cc0f8c105c68b5690aab8c5c1692a868e55eaca836c8779085", + }, + wantAddress: "165dCENc9ZGsiUgxwvxWSKdbfsxtrUqYMWymC9tC1gwGfATj", + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + if address := tt.args.platform.NormalizeAddress(tt.args.value); address != tt.wantAddress { + t.Errorf("Normalize() = %v\n Want = %v", address, tt.wantAddress) + } + }) + } +} diff --git a/platform/registry.go b/platform/registry.go index 624c838fb..3b56d3cad 100644 --- a/platform/registry.go +++ b/platform/registry.go @@ -1,156 +1,81 @@ package platform import ( - "fmt" - - "github.com/trustwallet/blockatlas/platform/harmony" - + log "github.com/sirupsen/logrus" "github.com/trustwallet/blockatlas/pkg/blockatlas" - "github.com/trustwallet/blockatlas/pkg/logger" - "github.com/trustwallet/blockatlas/platform/algorand" - - "github.com/spf13/viper" - "github.com/trustwallet/blockatlas/coin" - "github.com/trustwallet/blockatlas/platform/aeternity" - "github.com/trustwallet/blockatlas/platform/aion" - "github.com/trustwallet/blockatlas/platform/binance" - "github.com/trustwallet/blockatlas/platform/bitcoin" - "github.com/trustwallet/blockatlas/platform/cosmos" - "github.com/trustwallet/blockatlas/platform/ethereum" - "github.com/trustwallet/blockatlas/platform/fio" - "github.com/trustwallet/blockatlas/platform/icon" - "github.com/trustwallet/blockatlas/platform/iotex" - "github.com/trustwallet/blockatlas/platform/nano" - "github.com/trustwallet/blockatlas/platform/nebulas" - "github.com/trustwallet/blockatlas/platform/nimiq" - "github.com/trustwallet/blockatlas/platform/ontology" - "github.com/trustwallet/blockatlas/platform/polkadot" - "github.com/trustwallet/blockatlas/platform/ripple" - "github.com/trustwallet/blockatlas/platform/stellar" - "github.com/trustwallet/blockatlas/platform/tezos" - "github.com/trustwallet/blockatlas/platform/theta" - "github.com/trustwallet/blockatlas/platform/tron" - "github.com/trustwallet/blockatlas/platform/vechain" - "github.com/trustwallet/blockatlas/platform/waves" - "github.com/trustwallet/blockatlas/platform/zilliqa" ) -var platformList = []blockatlas.Platform{ - &binance.Platform{}, - &nimiq.Platform{}, - &ripple.Platform{}, - &stellar.Platform{CoinIndex: coin.XLM}, - &stellar.Platform{CoinIndex: coin.KIN}, - ðereum.Platform{CoinIndex: coin.ETH}, - ðereum.Platform{CoinIndex: coin.ETC}, - ðereum.Platform{CoinIndex: coin.POA}, - ðereum.Platform{CoinIndex: coin.CLO}, - ðereum.Platform{CoinIndex: coin.GO}, - ðereum.Platform{CoinIndex: coin.WAN}, - ðereum.Platform{CoinIndex: coin.TOMO}, - ðereum.Platform{CoinIndex: coin.TT}, - &tezos.Platform{}, - &aion.Platform{}, - &cosmos.Platform{CoinIndex: coin.ATOM}, - &cosmos.Platform{CoinIndex: coin.KAVA}, - &icon.Platform{}, - &iotex.Platform{}, - &ontology.Platform{}, - &theta.Platform{}, - &tron.Platform{}, - &vechain.Platform{}, - &zilliqa.Platform{}, - &waves.Platform{}, - &aeternity.Platform{}, - &bitcoin.Platform{CoinIndex: coin.BTC}, - &bitcoin.Platform{CoinIndex: coin.LTC}, - &bitcoin.Platform{CoinIndex: coin.BCH}, - &bitcoin.Platform{CoinIndex: coin.DASH}, - &bitcoin.Platform{CoinIndex: coin.DOGE}, - &bitcoin.Platform{CoinIndex: coin.ZEC}, - &bitcoin.Platform{CoinIndex: coin.XZC}, - &bitcoin.Platform{CoinIndex: coin.VIA}, - &bitcoin.Platform{CoinIndex: coin.RVN}, - &bitcoin.Platform{CoinIndex: coin.QTUM}, - &bitcoin.Platform{CoinIndex: coin.GRS}, - &bitcoin.Platform{CoinIndex: coin.ZEL}, - &bitcoin.Platform{CoinIndex: coin.DCR}, - &bitcoin.Platform{CoinIndex: coin.DGB}, - &nebulas.Platform{}, - &fio.Platform{}, - &algorand.Platform{}, - &nano.Platform{}, - &harmony.Platform{}, - &polkadot.Platform{CoinIndex: coin.KSM}, -} +var ( + // Platforms contains all registered platforms by handle + Platforms map[string]blockatlas.Platform + + // BlockAPIs contain platforms with block services + BlockAPIs map[string]blockatlas.BlockAPI + + // TokensAPIs contain platforms with token services + TokensAPIs map[uint]blockatlas.TokensAPI + + // StakeAPIs contain platforms with staking services + StakeAPIs map[string]blockatlas.StakeAPI -// Platforms contains all registered platforms by handle -var Platforms map[string]blockatlas.Platform + // CollectionsAPIs contain platforms which collections services + CollectionsAPIs blockatlas.CollectionsAPIs +) -// BlockAPIs contain platforms with block services -var BlockAPIs map[string]blockatlas.BlockAPI +func getActivePlatforms(handles []string) []blockatlas.Platform { + if len(handles) == 0 { + log.WithFields(log.Fields{"ATLAS_PLATFORM": handles}). + Fatal("Please, use ATLAS_PLATFORM handle with non-empty value, see more at Readme. Example: all") + return nil + } -// StakeAPIs contain platforms with staking services -var StakeAPIs map[string]blockatlas.StakeAPI + allPlatforms := getAllHandlers() + log.WithFields(log.Fields{"handles": handles}).Info("Platform API setup with") -// CustomAPIs contain platforms with custom HTTP services -var CustomAPIs map[string]blockatlas.CustomAPI + platforms := make([]blockatlas.Platform, 0, len(handles)) -// NamingAPIs contain platforms which support naming services -var NamingAPIs map[uint64]blockatlas.NamingServiceAPI + for _, handle := range handles { + if handle == allPlatformsHandle { + return allPlatforms.GetPlatformList() + } + p, ok := allPlatforms[handle] + if ok { + platforms = append(platforms, p) + } + } + return platforms +} -// CollectionAPIs contain platforms which collections services -var CollectionAPIs map[uint]blockatlas.CollectionAPI +func Init(platformHandles []string) { + platformList := getActivePlatforms(platformHandles) -func Init() { Platforms = make(map[string]blockatlas.Platform) BlockAPIs = make(map[string]blockatlas.BlockAPI) + TokensAPIs = make(map[uint]blockatlas.TokensAPI) StakeAPIs = make(map[string]blockatlas.StakeAPI) - CustomAPIs = make(map[string]blockatlas.CustomAPI) - NamingAPIs = make(map[uint64]blockatlas.NamingServiceAPI) - CollectionAPIs = make(map[uint]blockatlas.CollectionAPI) for _, platform := range platformList { handle := platform.Coin().Handle - apiURL := fmt.Sprintf("%s.api", handle) - if !viper.IsSet(apiURL) { - continue - } - if viper.GetString(apiURL) == "" { - continue - } - - p := logger.Params{ + p := log.Fields{ "platform": handle, "coin": platform.Coin(), } if _, exists := Platforms[handle]; exists { - logger.Fatal("Duplicate handle", p) + log.WithFields(p).Fatal("Duplicate handle") } - - err := platform.Init() - if err != nil { - logger.Error("Failed to initialize API", err, p) - } - Platforms[handle] = platform - if blockAPI, ok := platform.(blockatlas.BlockAPI); ok { BlockAPIs[handle] = blockAPI } + if tokenAPI, ok := platform.(blockatlas.TokensAPI); ok { + TokensAPIs[platform.Coin().ID] = tokenAPI + } if stakeAPI, ok := platform.(blockatlas.StakeAPI); ok { StakeAPIs[handle] = stakeAPI } - if customAPI, ok := platform.(blockatlas.CustomAPI); ok { - CustomAPIs[handle] = customAPI - } - if namingAPI, ok := platform.(blockatlas.NamingServiceAPI); ok { - NamingAPIs[uint64(platform.Coin().ID)] = namingAPI - } - if collectionAPI, ok := platform.(blockatlas.CollectionAPI); ok { - CollectionAPIs[platform.Coin().ID] = collectionAPI - } } + + CollectionsAPIs = getCollectionsHandlers() } diff --git a/platform/ripple/api.go b/platform/ripple/api.go deleted file mode 100644 index 0a1e27629..000000000 --- a/platform/ripple/api.go +++ /dev/null @@ -1,107 +0,0 @@ -package ripple - -import ( - "github.com/spf13/viper" - "github.com/trustwallet/blockatlas/coin" - "github.com/trustwallet/blockatlas/pkg/blockatlas" - "strconv" - "time" -) - -type Platform struct { - client Client -} - -func (p *Platform) Init() error { - p.client = Client{blockatlas.InitClient(viper.GetString("ripple.api"))} - return nil -} - -func (p *Platform) Coin() coin.Coin { - return coin.Coins[coin.XRP] -} - -func (p *Platform) GetTxsByAddress(address string) (blockatlas.TxPage, error) { - s, err := p.client.GetTxsOfAddress(address) - if err != nil { - return nil, err - } - - txs := make([]blockatlas.Tx, 0) - for _, srcTx := range s { - tx, ok := NormalizeTx(&srcTx) - if !ok { - continue - } - txs = append(txs, tx) - } - - return txs, nil -} - -func (p *Platform) CurrentBlockNumber() (int64, error) { - return p.client.GetCurrentBlock() -} - -func (p *Platform) GetBlockByNumber(num int64) (*blockatlas.Block, error) { - if srcBlock, err := p.client.GetBlockByNumber(num); err == nil { - txs := NormalizeTxs(srcBlock) - return &blockatlas.Block{ - Number: num, - Txs: txs, - }, nil - } else { - return nil, err - } -} - -func NormalizeTxs(srcTxs []Tx) (txs []blockatlas.Tx) { - for _, srcTx := range srcTxs { - tx, ok := NormalizeTx(&srcTx) - if !ok || len(txs) >= blockatlas.TxPerPage { - continue - } - txs = append(txs, tx) - } - return -} - -// Normalize converts a Ripple transaction into the generic model -func NormalizeTx(srcTx *Tx) (blockatlas.Tx, bool) { - - date, err := time.Parse("2006-01-02T15:04:05-07:00", srcTx.Date) - var unix int64 - if err != nil { - unix = 0 - } else { - unix = date.Unix() - } - - v, vok := srcTx.Meta.DeliveredAmount.(string) - if !vok || len(v) == 0 { - return blockatlas.Tx{}, false - } - - if srcTx.Payment.TransactionType != "Payment" { - return blockatlas.Tx{}, false - } - - result := blockatlas.Tx{ - ID: srcTx.Hash, - Coin: coin.XRP, - Date: unix, - From: srcTx.Payment.Account, - To: srcTx.Payment.Destination, - Fee: srcTx.Payment.Fee, - Block: srcTx.LedgerIndex, - Meta: blockatlas.Transfer{ - Value: blockatlas.Amount(v), - Symbol: coin.Coins[coin.XRP].Symbol, - Decimals: coin.Coins[coin.XRP].Decimals, - }, - } - if srcTx.Payment.DestinationTag > 0 { - result.Memo = strconv.FormatInt(srcTx.Payment.DestinationTag, 10) - } - return result, true -} diff --git a/platform/ripple/api_test.go b/platform/ripple/api_test.go deleted file mode 100644 index e2f75498b..000000000 --- a/platform/ripple/api_test.go +++ /dev/null @@ -1,212 +0,0 @@ -package ripple - -import ( - "encoding/json" - "github.com/stretchr/testify/assert" - "github.com/trustwallet/blockatlas/pkg/blockatlas" - "testing" - - "github.com/trustwallet/blockatlas/coin" -) - -const paymentSrc = ` -{ - "hash": "40279A3DE51148BD41409DADF29DE8DCCD50F5AEE30840827B2C4C81C4E36505", - "ledger_index": 34698103, - "date": "2017-12-01T22:45:30+00:00", - "tx": { - "TransactionType": "Payment", - "Flags": 2147483648, - "Sequence": 21, - "LastLedgerSequence": 34698105, - "DestinationTag": 2500, - "Amount": "100000000", - "Fee": "3115", - "SigningPubKey": "03807050F9E271B2E49B0FF658362EF37DBFDD31435E610B6E11C52879DF8A9907", - "TxnSignature": "3045022100D14057AA2A868F54FC7CA2E44C8310D9A944446580EAA45936A75CFFDD00425602205CCBFACB55AB0F5B02659F1EBE619FC04DE75B0227C8EB148DC6D08CABBAB072", - "Account": "rGSxFjoqmWz54PycrgQBQ5dB6e7TUpMxzq", - "Destination": "rMQ98K56yXJbDGv49ZSmW51sLn94Xe1mu1", - "Memos": [ - { - "Memo": { - "MemoType": "636C69656E74", - "MemoFormat": "7274312E342E332D31332D6735383261336135" - } - } - ] - }, - "meta": { - "TransactionIndex": 20, - "TransactionResult": "tesSUCCESS", - "delivered_amount": "100000000" - } -} -` - -var paymentDst = blockatlas.Tx{ - ID: "40279A3DE51148BD41409DADF29DE8DCCD50F5AEE30840827B2C4C81C4E36505", - Coin: coin.XRP, - From: "rGSxFjoqmWz54PycrgQBQ5dB6e7TUpMxzq", - To: "rMQ98K56yXJbDGv49ZSmW51sLn94Xe1mu1", - Fee: "3115", - Date: 1512168330, - Block: 34698103, - Memo: "2500", - Meta: blockatlas.Transfer{ - Value: "100000000", - Symbol: "XRP", - Decimals: 6, - }, -} - -const paymentSrc2 = ` -{ - "hash":"3D8512E02414EF5A6BC00281D945735E85DED9EF739B1DCA9EABE04D9EEC72C1", - "ledger_index":49163909, - "date":"2019-08-06T17:58:01+00:00", - "tx":{ - "TransactionType":"Payment", - "Flags":2147614720, - "Sequence":115, - "DestinationTag":0, - "LastLedgerSequence":49163911, - "Amount":"1000000000", - "Fee":"120", - "SendMax":{ - "value":"0.001", - "currency":"USD", - "issuer":"rhub8VRN55s94qWKDv6jmDy1pUykJzF3wq" - }, - "SigningPubKey":"030E4853E7D0B0E2D3C1233EADCB1B1C35DE75AD4AECD94AC534B3057537753B94", - "TxnSignature":"3045022100EBBDDB5D2F59472463CA03429DDDED4F06648FF097662697CCFF3C5C9C36091202205367A18FE65F767D6C6D256B2F7058BBA3C5D35655AD881A94EFC4BA2C2422DF", - "Account":"raz97dHvnyBcnYTbXGYxhV8bGyr1aPrE5w", - "Destination":"rna8qC8Y9uLd2vzYtSEa1AJcdD3896zQ9S", - "Memos":[ - { - "Memo":{ - "MemoType":"636C69656E74", - "MemoData":"726D2D312E322E34" - } - } - ] - }, - "meta":{ - "TransactionIndex":24, - "DeliveredAmount":"3100", - "TransactionResult":"tesSUCCESS", - "delivered_amount":"3100" - } -} -` - -var paymentDst2 = blockatlas.Tx{ - ID: "3D8512E02414EF5A6BC00281D945735E85DED9EF739B1DCA9EABE04D9EEC72C1", - Coin: coin.XRP, - From: "raz97dHvnyBcnYTbXGYxhV8bGyr1aPrE5w", - To: "rna8qC8Y9uLd2vzYtSEa1AJcdD3896zQ9S", - Fee: "120", - Date: 1565114281, - Block: 49163909, - Memo: "", - Meta: blockatlas.Transfer{ - Value: "3100", - Symbol: "XRP", - Decimals: 6, - }, -} - -const paymentSrc3 = ` -{ - "hash":"3D8512E02414EF5A6BC00281D945735E85DED9EF739B1DCA9EABE04D9EEC72C1", - "ledger_index":49163909, - "date":"2019-08-06T17:58:01+00:00", - "tx":{ - "TransactionType": "SetRegularKey" - } -} -` - -const paymentSrc4 = ` -{ - "hash": "1D849E3A0041357EE373C7E17C9564F890047475492D9530B5F20A3BD6D95822", - "ledger_index": 49841027, - "date": "2019-09-06T01:48:32+00:00", - "tx": { - "TransactionType": "Payment", - "Flags": 2147942400, - "Sequence": 292765, - "LastLedgerSequence": 49841035, - "Amount": { - "value": "100000", - "currency": "ETH", - "issuer": "rJavT3eWaX9FubZFHtCvymJ6ZhSgJdMyNx" - }, - "Fee": "162", - "SendMax": "100000000000", - "Account": "r4NT6UfELQyoS689VLye22B3SfgvpM3nHY", - "Destination": "rJavT3eWaX9FubZFHtCvymJ6ZhSgJdMyNx" - }, - "meta": { - "TransactionIndex": 16, - "DeliveredAmount": { - "value": "533.92", - "currency": "ETH", - "issuer": "rJavT3eWaX9FubZFHtCvymJ6ZhSgJdMyNx" - }, - "TransactionResult": "tesSUCCESS", - "delivered_amount": { - "value": "533.92", - "currency": "ETH", - "issuer": "rJavT3eWaX9FubZFHtCvymJ6ZhSgJdMyNx" - } - } -} -` - -type test struct { - name string - apiResponse string - normalize bool - expected blockatlas.Tx -} - -func TestNormalize(t *testing.T) { - testNormalize(t, &test{ - name: "payment 1", - apiResponse: paymentSrc, - expected: paymentDst, - normalize: true, - }) - - testNormalize(t, &test{ - name: "payment 2", - apiResponse: paymentSrc2, - expected: paymentDst2, - normalize: true, - }) - - testNormalize(t, &test{ - name: "SetRegularKey transfer", - apiResponse: paymentSrc3, - expected: blockatlas.Tx{}, - normalize: false, - }) - - testNormalize(t, &test{ - name: "token transfer", - apiResponse: paymentSrc4, - expected: blockatlas.Tx{}, - normalize: false, - }) -} - -func testNormalize(t *testing.T, _test *test) { - t.Run(_test.name, func(t *testing.T) { - var payment Tx - err := json.Unmarshal([]byte(_test.apiResponse), &payment) - assert.Nil(t, err) - tx, ok := NormalizeTx(&payment) - assert.Equal(t, ok, _test.normalize, "tx could not be normalized") - assert.Equal(t, _test.expected, tx, "tx don't equal") - }) -} diff --git a/platform/ripple/base.go b/platform/ripple/base.go new file mode 100644 index 000000000..2f0111d86 --- /dev/null +++ b/platform/ripple/base.go @@ -0,0 +1,21 @@ +package ripple + +import ( + "github.com/trustwallet/golibs/client" + "github.com/trustwallet/golibs/coin" + "github.com/trustwallet/golibs/network/middleware" +) + +type Platform struct { + client Client +} + +func Init(api string) *Platform { + return &Platform{ + client: Client{client.InitClient(api, middleware.SentryErrorHandler)}, + } +} + +func (p *Platform) Coin() coin.Coin { + return coin.Ripple() +} diff --git a/platform/ripple/block.go b/platform/ripple/block.go new file mode 100644 index 000000000..0eecb9162 --- /dev/null +++ b/platform/ripple/block.go @@ -0,0 +1,19 @@ +package ripple + +import "github.com/trustwallet/golibs/types" + +func (p *Platform) CurrentBlockNumber() (int64, error) { + return p.client.GetCurrentBlock() +} + +func (p *Platform) GetBlockByNumber(num int64) (*types.Block, error) { + if srcBlock, err := p.client.GetBlockByNumber(num); err == nil { + txs := NormalizeTxs(srcBlock) + return &types.Block{ + Number: num, + Txs: txs, + }, nil + } else { + return nil, err + } +} diff --git a/platform/ripple/client.go b/platform/ripple/client.go index f4007c130..f297a74e9 100644 --- a/platform/ripple/client.go +++ b/platform/ripple/client.go @@ -2,28 +2,45 @@ package ripple import ( "fmt" - "github.com/trustwallet/blockatlas/pkg/blockatlas" "net/url" + + "github.com/trustwallet/golibs/client" ) type Client struct { - blockatlas.Request + client.Request } func (c *Client) GetTxsOfAddress(address string) ([]Tx, error) { + res, err := c.fetchTransactions(address, "true") + if err != nil { + return nil, err + } + + if res.Result == "error" { + res, err = c.fetchTransactions(address, "false") + if err != nil { + return nil, err + } + } + + return res.Transactions, nil +} + +func (c *Client) fetchTransactions(address, descending string) (Response, error) { query := url.Values{ - "type": {"Payment"}, - "result": {"tesSUCCESS"}, - "limit": {"200"}, + "type": {"Payment"}, + "descending": {descending}, + "limit": {"25"}, } uri := fmt.Sprintf("accounts/%s/transactions", url.PathEscape(address)) var res Response err := c.Get(&res, uri, query) if err != nil { - return nil, err + return Response{}, err } - return res.Transactions, nil + return res, nil } func (c *Client) GetCurrentBlock() (int64, error) { diff --git a/platform/ripple/mocks/payment.json b/platform/ripple/mocks/payment.json new file mode 100644 index 000000000..5d52f1574 --- /dev/null +++ b/platform/ripple/mocks/payment.json @@ -0,0 +1,31 @@ +{ + "hash": "40279A3DE51148BD41409DADF29DE8DCCD50F5AEE30840827B2C4C81C4E36505", + "ledger_index": 34698103, + "date": "2017-12-01T22:45:30+00:00", + "tx": { + "TransactionType": "Payment", + "Flags": 2147483648, + "Sequence": 21, + "LastLedgerSequence": 34698105, + "DestinationTag": 2500, + "Amount": "100000000", + "Fee": "3115", + "SigningPubKey": "03807050F9E271B2E49B0FF658362EF37DBFDD31435E610B6E11C52879DF8A9907", + "TxnSignature": "3045022100D14057AA2A868F54FC7CA2E44C8310D9A944446580EAA45936A75CFFDD00425602205CCBFACB55AB0F5B02659F1EBE619FC04DE75B0227C8EB148DC6D08CABBAB072", + "Account": "rGSxFjoqmWz54PycrgQBQ5dB6e7TUpMxzq", + "Destination": "rMQ98K56yXJbDGv49ZSmW51sLn94Xe1mu1", + "Memos": [ + { + "Memo": { + "MemoType": "636C69656E74", + "MemoFormat": "7274312E342E332D31332D6735383261336135" + } + } + ] + }, + "meta": { + "TransactionIndex": 20, + "TransactionResult": "tesSUCCESS", + "delivered_amount": "100000000" + } +} diff --git a/platform/ripple/mocks/payment_2.json b/platform/ripple/mocks/payment_2.json new file mode 100644 index 000000000..c6777b6f5 --- /dev/null +++ b/platform/ripple/mocks/payment_2.json @@ -0,0 +1,37 @@ +{ + "hash": "3D8512E02414EF5A6BC00281D945735E85DED9EF739B1DCA9EABE04D9EEC72C1", + "ledger_index": 49163909, + "date": "2019-08-06T17:58:01+00:00", + "tx": { + "TransactionType": "Payment", + "Flags": 2147614720, + "Sequence": 115, + "DestinationTag": 0, + "LastLedgerSequence": 49163911, + "Amount": "1000000000", + "Fee": "120", + "SendMax": { + "value": "0.001", + "currency": "USD", + "issuer": "rhub8VRN55s94qWKDv6jmDy1pUykJzF3wq" + }, + "SigningPubKey": "030E4853E7D0B0E2D3C1233EADCB1B1C35DE75AD4AECD94AC534B3057537753B94", + "TxnSignature": "3045022100EBBDDB5D2F59472463CA03429DDDED4F06648FF097662697CCFF3C5C9C36091202205367A18FE65F767D6C6D256B2F7058BBA3C5D35655AD881A94EFC4BA2C2422DF", + "Account": "raz97dHvnyBcnYTbXGYxhV8bGyr1aPrE5w", + "Destination": "rna8qC8Y9uLd2vzYtSEa1AJcdD3896zQ9S", + "Memos": [ + { + "Memo": { + "MemoType": "636C69656E74", + "MemoData": "726D2D312E322E34" + } + } + ] + }, + "meta": { + "TransactionIndex": 24, + "DeliveredAmount": "3100", + "TransactionResult": "tesSUCCESS", + "delivered_amount": "3100" + } +} diff --git a/platform/ripple/mocks/payment_3.json b/platform/ripple/mocks/payment_3.json new file mode 100644 index 000000000..30a71b642 --- /dev/null +++ b/platform/ripple/mocks/payment_3.json @@ -0,0 +1,8 @@ +{ + "hash": "3D8512E02414EF5A6BC00281D945735E85DED9EF739B1DCA9EABE04D9EEC72C1", + "ledger_index": 49163909, + "date": "2019-08-06T17:58:01+00:00", + "tx": { + "TransactionType": "SetRegularKey" + } +} diff --git a/platform/ripple/mocks/payment_4.json b/platform/ripple/mocks/payment_4.json new file mode 100644 index 000000000..d2e800771 --- /dev/null +++ b/platform/ripple/mocks/payment_4.json @@ -0,0 +1,34 @@ +{ + "hash": "1D849E3A0041357EE373C7E17C9564F890047475492D9530B5F20A3BD6D95822", + "ledger_index": 49841027, + "date": "2019-09-06T01:48:32+00:00", + "tx": { + "TransactionType": "Payment", + "Flags": 2147942400, + "Sequence": 292765, + "LastLedgerSequence": 49841035, + "Amount": { + "value": "100000", + "currency": "ETH", + "issuer": "rJavT3eWaX9FubZFHtCvymJ6ZhSgJdMyNx" + }, + "Fee": "162", + "SendMax": "100000000000", + "Account": "r4NT6UfELQyoS689VLye22B3SfgvpM3nHY", + "Destination": "rJavT3eWaX9FubZFHtCvymJ6ZhSgJdMyNx" + }, + "meta": { + "TransactionIndex": 16, + "DeliveredAmount": { + "value": "533.92", + "currency": "ETH", + "issuer": "rJavT3eWaX9FubZFHtCvymJ6ZhSgJdMyNx" + }, + "TransactionResult": "tesSUCCESS", + "delivered_amount": { + "value": "533.92", + "currency": "ETH", + "issuer": "rJavT3eWaX9FubZFHtCvymJ6ZhSgJdMyNx" + } + } +} diff --git a/platform/ripple/mocks/payment_failed.json b/platform/ripple/mocks/payment_failed.json new file mode 100644 index 000000000..1b65ce4ec --- /dev/null +++ b/platform/ripple/mocks/payment_failed.json @@ -0,0 +1,22 @@ +{ + "hash": "B9086F7EB895E943C4DDA9F1B582E6E7DE35F4FB91AD13C50AB74F854DC0EBE0", + "ledger_index": 53401154, + "date": "2020-02-13T10:47:52+00:00", + "tx": { + "TransactionType": "Payment", + "Flags": 2147483648, + "Sequence": 2102726, + "LastLedgerSequence": 53401182, + "Amount": "24999750000", + "Fee": "100000", + "SigningPubKey": "02C2EDA75565BA8D3CBD96FB28D53C9BE1B7A4DC1AF6FF1B2EBBD478D520BED52E", + "TxnSignature": "304502210081A1620F2106671FDFB9C0ABEB2976236693E6142E2B4CB7EA89338EA344BF8D02200EC9D2E2BE79C9E053F809802C426AFDC55B7BA5E01E3DF4B193F122740C39A3", + "Account": "rJb5KsHsDHF1YS5B5DU6QCkH5NsPaKQTcy", + "Destination": "rfHj5CuhajwdrzW2C8Y7EDXbx1QMiD5SXP" + }, + "meta": { + "TransactionIndex": 30, + "TransactionResult": "tefBAD_LEDGER", + "delivered_amount": "24999750000" + } +} diff --git a/platform/ripple/model.go b/platform/ripple/model.go index 18c542871..baa13d1bf 100644 --- a/platform/ripple/model.go +++ b/platform/ripple/model.go @@ -1,7 +1,14 @@ package ripple -import ( - "github.com/trustwallet/blockatlas/pkg/blockatlas" +import "github.com/trustwallet/golibs/types" + +type TransactionType string +type TransactionResult string + +const ( + transactionResultSuccess TransactionResult = "tesSUCCESS" + + transactionPayment TransactionType = "Payment" ) type Response struct { @@ -21,19 +28,20 @@ type Tx struct { } type Payment struct { - TransactionType string `json:"TransactionType"` - Flags uint64 `json:"Flags"` - Sequence uint64 `json:"Sequence"` - Fee blockatlas.Amount `json:"Fee"` - SigningPubKey string `json:"SigningPubKey"` - TxnSignature string `json:"TxnSignature"` - Account string `json:"Account"` - Destination string `json:"Destination"` - DestinationTag int64 `json:"DestinationTag,omitempty"` + TransactionType TransactionType `json:"TransactionType"` + Flags uint64 `json:"Flags"` + Sequence uint64 `json:"Sequence"` + Fee types.Amount `json:"Fee"` + SigningPubKey string `json:"SigningPubKey"` + TxnSignature string `json:"TxnSignature"` + Account string `json:"Account"` + Destination string `json:"Destination"` + DestinationTag int64 `json:"DestinationTag,omitempty"` } type Meta struct { - DeliveredAmount interface{} `json:"delivered_amount,omitempty"` + TransactionResult TransactionResult `json:"TransactionResult,omitempty"` + DeliveredAmount interface{} `json:"delivered_amount,omitempty"` } type DeliveredAmount struct { diff --git a/platform/ripple/transaction.go b/platform/ripple/transaction.go new file mode 100644 index 000000000..5b16fa207 --- /dev/null +++ b/platform/ripple/transaction.go @@ -0,0 +1,81 @@ +package ripple + +import ( + "strconv" + "time" + + "github.com/trustwallet/golibs/coin" + "github.com/trustwallet/golibs/types" +) + +func (p *Platform) GetTxsByAddress(address string) (types.Txs, error) { + s, err := p.client.GetTxsOfAddress(address) + if err != nil { + return nil, err + } + + txs := make(types.Txs, 0) + for _, srcTx := range s { + tx, ok := NormalizeTx(&srcTx) + if !ok { + continue + } + txs = append(txs, tx) + } + + return txs, nil +} + +func NormalizeTxs(srcTxs []Tx) (txs types.Txs) { + for _, srcTx := range srcTxs { + tx, ok := NormalizeTx(&srcTx) + if !ok || len(txs) >= types.TxPerPage { + continue + } + txs = append(txs, tx) + } + return +} + +// Normalize converts a Ripple transaction into the generic model +func NormalizeTx(srcTx *Tx) (types.Tx, bool) { + unix := int64(0) + date, err := time.Parse("2006-01-02T15:04:05-07:00", srcTx.Date) + if err == nil { + unix = date.Unix() + } + + v, vok := srcTx.Meta.DeliveredAmount.(string) + if !vok || len(v) == 0 { + return types.Tx{}, false + } + + if srcTx.Payment.TransactionType != transactionPayment { + return types.Tx{}, false + } + + status := types.StatusCompleted + if srcTx.Meta.TransactionResult != transactionResultSuccess { + status = types.StatusError + } + + result := types.Tx{ + ID: srcTx.Hash, + Coin: coin.RIPPLE, + Date: unix, + From: srcTx.Payment.Account, + To: srcTx.Payment.Destination, + Fee: srcTx.Payment.Fee, + Block: srcTx.LedgerIndex, + Status: status, + Meta: types.Transfer{ + Value: types.Amount(v), + Symbol: coin.Coins[coin.RIPPLE].Symbol, + Decimals: coin.Coins[coin.RIPPLE].Decimals, + }, + } + if srcTx.Payment.DestinationTag > 0 { + result.Memo = strconv.FormatInt(srcTx.Payment.DestinationTag, 10) + } + return result, true +} diff --git a/platform/ripple/transaction_test.go b/platform/ripple/transaction_test.go new file mode 100644 index 000000000..242a7d976 --- /dev/null +++ b/platform/ripple/transaction_test.go @@ -0,0 +1,122 @@ +package ripple + +import ( + "reflect" + "testing" + + "github.com/trustwallet/golibs/coin" + "github.com/trustwallet/golibs/mock" + "github.com/trustwallet/golibs/types" +) + +func TestNormalizeTx(t *testing.T) { + type args struct { + filename string + } + tests := []struct { + name string + args args + wantTx types.Tx + ok bool + }{ + { + name: "Test normalize payment", + args: args{ + filename: "payment.json", + }, + wantTx: types.Tx{ + ID: "40279A3DE51148BD41409DADF29DE8DCCD50F5AEE30840827B2C4C81C4E36505", + Coin: coin.RIPPLE, + From: "rGSxFjoqmWz54PycrgQBQ5dB6e7TUpMxzq", + To: "rMQ98K56yXJbDGv49ZSmW51sLn94Xe1mu1", + Fee: "3115", + Date: 1512168330, + Block: 34698103, + Memo: "2500", + Status: types.StatusCompleted, + Meta: types.Transfer{ + Value: "100000000", + Symbol: "XRP", + Decimals: 6, + }, + }, + ok: true, + }, + { + name: "Test normalize payment 2", + args: args{ + filename: "payment_2.json", + }, + wantTx: types.Tx{ + ID: "3D8512E02414EF5A6BC00281D945735E85DED9EF739B1DCA9EABE04D9EEC72C1", + Coin: coin.RIPPLE, + From: "raz97dHvnyBcnYTbXGYxhV8bGyr1aPrE5w", + To: "rna8qC8Y9uLd2vzYtSEa1AJcdD3896zQ9S", + Fee: "120", + Date: 1565114281, + Block: 49163909, + Memo: "", + Status: types.StatusCompleted, + Meta: types.Transfer{ + Value: "3100", + Symbol: "XRP", + Decimals: 6, + }, + }, + ok: true, + }, + { + name: "Test normalize failed payment", + args: args{ + filename: "payment_failed.json", + }, + wantTx: types.Tx{ + ID: "B9086F7EB895E943C4DDA9F1B582E6E7DE35F4FB91AD13C50AB74F854DC0EBE0", + Coin: coin.RIPPLE, + From: "rJb5KsHsDHF1YS5B5DU6QCkH5NsPaKQTcy", + To: "rfHj5CuhajwdrzW2C8Y7EDXbx1QMiD5SXP", + Fee: "100000", + Date: 1581590872, + Block: 53401154, + Memo: "", + Status: types.StatusError, + Meta: types.Transfer{ + Value: "24999750000", + Symbol: "XRP", + Decimals: 6, + }, + }, + ok: true, + }, + { + name: "Test normalize SetRegularKey transfer", + args: args{ + filename: "payment_3.json", + }, + wantTx: types.Tx{}, + ok: false, + }, + { + name: "Test normalize token transfer", + args: args{ + filename: "payment_4.json", + }, + wantTx: types.Tx{}, + ok: false, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + var srcTx Tx + _ = mock.JsonModelFromFilePath("mocks/"+tt.args.filename, &srcTx) + gotTx, err := NormalizeTx(&srcTx) + if err != tt.ok { + t.Errorf("NormalizeTx() error = %v, ok %v", err, tt.ok) + return + } + if !reflect.DeepEqual(gotTx, tt.wantTx) { + t.Errorf("NormalizeTx() gotTx = %v, want %v", gotTx, tt.wantTx) + } + }) + } +} diff --git a/platform/solana/base.go b/platform/solana/base.go new file mode 100644 index 000000000..fba50c047 --- /dev/null +++ b/platform/solana/base.go @@ -0,0 +1,19 @@ +package solana + +import ( + "github.com/trustwallet/golibs/client" + "github.com/trustwallet/golibs/coin" + "github.com/trustwallet/golibs/network/middleware" +) + +type Platform struct { + client Client +} + +func Init(api string) *Platform { + return &Platform{client: Client{client.InitJSONClient(api, middleware.SentryErrorHandler)}} +} + +func (p *Platform) Coin() coin.Coin { + return coin.Solana() +} diff --git a/platform/solana/block.go b/platform/solana/block.go new file mode 100644 index 000000000..4605f16b5 --- /dev/null +++ b/platform/solana/block.go @@ -0,0 +1,37 @@ +package solana + +import ( + "github.com/trustwallet/golibs/client" + "github.com/trustwallet/golibs/types" +) + +const ( + errorSkipped = -32009 +) + +func (p *Platform) CurrentBlockNumber() (int64, error) { + return p.client.GetLasteBlock() +} + +func (p *Platform) GetBlockByNumber(num int64) (*types.Block, error) { + block, err := p.client.GetTransactionsInBlock(num) + if err != nil { + // solana might skip some block which makes block number is not consecutive + rpcError, ok := err.(*client.RpcError) + if ok && rpcError.Code == errorSkipped { + return &types.Block{Number: num, Txs: types.Txs{}}, nil + } + return nil, err + } + + txs := make(types.Txs, 0) + for _, tx := range block.Transactions { + normalized, err := p.NormalizeTx(tx, uint64(num), block.BlockTime) + if err != nil { + continue + } + txs = append(txs, normalized) + } + + return &types.Block{Number: num, Txs: txs}, nil +} diff --git a/platform/solana/client.go b/platform/solana/client.go new file mode 100644 index 000000000..5d764db5f --- /dev/null +++ b/platform/solana/client.go @@ -0,0 +1,77 @@ +package solana + +import ( + "github.com/trustwallet/golibs/client" +) + +type Client struct { + client.Request +} + +func (c *Client) GetLasteBlock() (int64, error) { + var epoch EpochInfo + err := c.RpcCall(&epoch, "getEpochInfo", []string{}) + if err != nil { + return 0, err + } + return int64(epoch.BlockHeight), nil +} + +func (c *Client) GetEpochInfo() (epochInfo EpochInfo, err error) { + err = c.RpcCall(&epochInfo, "getEpochInfo", []string{}) + return +} + +func (c *Client) GetTransactionsByAddress(address string) ([]ConfirmedTransaction, error) { + var signatures []ConfirmedSignature + params := []interface{}{ + address, + map[string]interface{}{"limit": 25}, + } + err := c.RpcCall(&signatures, "getConfirmedSignaturesForAddress2", params) + if err != nil { + return nil, err + } + + return c.GetTransactionSignatures(signatures) +} + +func (c *Client) GetTransactionSignatures(signatures []ConfirmedSignature) ([]ConfirmedTransaction, error) { + var txs []ConfirmedTransaction + + // check empty + if len(signatures) == 0 { + return txs, nil + } + + // build batch request + requests := make(client.RpcRequests, 0) + for _, sig := range signatures { + requests = append(requests, &client.RpcRequest{ + Method: "getConfirmedTransaction", + Params: []string{ + sig.Signature, + "jsonParsed", + }, + }) + } + + responses, err := c.RpcBatchCall(requests) + if err != nil { + return txs, err + } + + // convert to ConfirmedTransaction + for _, response := range responses { + var tx ConfirmedTransaction + if err := response.GetObject(&tx); err == nil { + txs = append(txs, tx) + } + } + return txs, nil +} + +func (c *Client) GetTransactionsInBlock(num int64) (block Block, err error) { + err = c.RpcCall(&block, "getConfirmedBlock", []interface{}{num, "jsonParsed"}) + return +} diff --git a/platform/solana/mocks/GetTxsByAddress.json b/platform/solana/mocks/GetTxsByAddress.json new file mode 100644 index 000000000..c7bf25281 --- /dev/null +++ b/platform/solana/mocks/GetTxsByAddress.json @@ -0,0 +1,32 @@ +[ + { + "id": "4aQuuc4XFP7SQrZF4z3TsFyqdRHQBF37yxK8t1jQLL97JSwGadEvUFSM4GK6DtacWzid7VT7VTaqbfJfbzzsboYt", + "coin": 501, + "from": "HBYC51YrGFAZ8rM7Sj8e9uqKggpSrDYrinQDZzvMtqQp", + "to": "AHy6YZA8BsHgQfVkk7MbwpAN94iyN7Nf1zN4nPqUN32Q", + "fee": "5000", + "date": 1588062639, + "block": 5632752, + "status": "completed", + "sequence": 0, + "type": "transfer", + "direction": "incoming", + "memo": "", + "metadata": { "value": "1230000", "symbol": "SOL", "decimals": 9 } + }, + { + "id": "5QeLdXcC8GRh3KSs67Pq9sNE5uwFKkHt37crYLzcZ19ieh6RSEEGrS2r5eVXJiaXKb8M6FyKF45kHHmQRW2g1LYA", + "coin": 501, + "from": "AHy6YZA8BsHgQfVkk7MbwpAN94iyN7Nf1zN4nPqUN32Q", + "to": "HBYC51YrGFAZ8rM7Sj8e9uqKggpSrDYrinQDZzvMtqQp", + "fee": "5000", + "date": 1588026961, + "block": 5543556, + "status": "completed", + "sequence": 0, + "type": "transfer", + "direction": "outgoing", + "memo": "", + "metadata": { "value": "120000", "symbol": "SOL", "decimals": 9 } + } +] diff --git a/platform/solana/mocks/getConfirmedSignaturesForAddress2.json b/platform/solana/mocks/getConfirmedSignaturesForAddress2.json new file mode 100644 index 000000000..c48276582 --- /dev/null +++ b/platform/solana/mocks/getConfirmedSignaturesForAddress2.json @@ -0,0 +1,54 @@ +{ + "jsonrpc": "2.0", + "result": [ + { + "err": null, + "memo": null, + "signature": "4aQuuc4XFP7SQrZF4z3TsFyqdRHQBF37yxK8t1jQLL97JSwGadEvUFSM4GK6DtacWzid7VT7VTaqbfJfbzzsboYt", + "slot": 5632752 + }, + { + "err": null, + "memo": null, + "signature": "5QeLdXcC8GRh3KSs67Pq9sNE5uwFKkHt37crYLzcZ19ieh6RSEEGrS2r5eVXJiaXKb8M6FyKF45kHHmQRW2g1LYA", + "slot": 5543556 + }, + { + "err": null, + "memo": null, + "signature": "5Bk5b6ThBBqaPVacGjWbHSiXG58yUKi8NCyZq8Dye4iJMDZ4eoWKiPzdYLLL4VfQsJQuxvjjetZHxZ7rZiY4wsD8", + "slot": 5460244 + }, + { + "err": null, + "memo": null, + "signature": "33YpfYkBKoN2wxs27tkkhMMewxWHh9hTjDnJovz8wtB5Nshfjq4dWVSVAg7wNVrxi9yFJyNi3dNfpmfpxSk1bS85", + "slot": 5458444 + }, + { + "err": null, + "memo": null, + "signature": "5RJNtp3Upis48PuqrcTmm7gTgkMQfuEnrCauBCpPqBQZauu7PBdTefCk6zZeCHE9ESf3x9FwQvwHvXXsgXwRVJuu", + "slot": 3214148 + }, + { + "err": null, + "memo": null, + "signature": "4aCaxVsD3DwJeShU6ZzH9B8K1XCca2oqgEXkLfvXyabMTkvw1iYjjghbyZ9KdnHQqRDxcYDqGCmhZPVWiwQpBjAt", + "slot": 3194428 + }, + { + "err": null, + "memo": null, + "signature": "3Jt9Whbhd1y7gBaaJGrkFpG3nBStryfWqPRycZtte2tuRwCxDFsmoMtv1aoPaBS4yMsV6Xxbu1qX3NXMN8owNd2F", + "slot": 689909 + }, + { + "err": null, + "memo": null, + "signature": "3A4cvbLipNPA3NxYYgGAHXkWSSmwMSJi1k6NaT7wuxtr2dTbZEPLufbZ9qYTPwcifjTd3W26i3r2aP1pHi193HHH", + "slot": 493784 + } + ], + "id": 1 + } \ No newline at end of file diff --git a/platform/solana/mocks/getConfirmedTransaction.json b/platform/solana/mocks/getConfirmedTransaction.json new file mode 100644 index 000000000..ce54fc419 --- /dev/null +++ b/platform/solana/mocks/getConfirmedTransaction.json @@ -0,0 +1,240 @@ +[ + { + "jsonrpc": "2.0", + "result": { + "blockTime": 1588062639, + "meta": { + "err": null, + "fee": 5000, + "innerInstructions": null, + "logMessages": null, + "postBalances": [ + 3066455000, + 31395000, + 1 + ], + "preBalances": [ + 3067690000, + 30165000, + 1 + ], + "status": { + "Ok": null + } + }, + "slot": 5632752, + "transaction": { + "message": { + "accountKeys": [ + { + "pubkey": "HBYC51YrGFAZ8rM7Sj8e9uqKggpSrDYrinQDZzvMtqQp", + "signer": true, + "writable": true + }, + { + "pubkey": "AHy6YZA8BsHgQfVkk7MbwpAN94iyN7Nf1zN4nPqUN32Q", + "signer": false, + "writable": true + }, + { + "pubkey": "11111111111111111111111111111111", + "signer": false, + "writable": false + } + ], + "instructions": [ + { + "parsed": { + "info": { + "destination": "AHy6YZA8BsHgQfVkk7MbwpAN94iyN7Nf1zN4nPqUN32Q", + "lamports": 1230000, + "source": "HBYC51YrGFAZ8rM7Sj8e9uqKggpSrDYrinQDZzvMtqQp" + }, + "type": "transfer" + }, + "program": "system", + "programId": "11111111111111111111111111111111" + } + ], + "recentBlockhash": "9zjmFdQM4QEvPxjdqacu7aatBwkYzfFqkXqHaJBueD1f" + }, + "signatures": [ + "4aQuuc4XFP7SQrZF4z3TsFyqdRHQBF37yxK8t1jQLL97JSwGadEvUFSM4GK6DtacWzid7VT7VTaqbfJfbzzsboYt" + ] + } + }, + "id": 1 + }, + { + "jsonrpc": "2.0", + "result": { + "blockTime": 1588026961, + "meta": { + "err": null, + "fee": 5000, + "innerInstructions": null, + "logMessages": null, + "postBalances": [ + 30165000, + 3067690000, + 1 + ], + "preBalances": [ + 30290000, + 3067570000, + 1 + ], + "status": { + "Ok": null + } + }, + "slot": 5543556, + "transaction": { + "message": { + "accountKeys": [ + { + "pubkey": "AHy6YZA8BsHgQfVkk7MbwpAN94iyN7Nf1zN4nPqUN32Q", + "signer": true, + "writable": true + }, + { + "pubkey": "HBYC51YrGFAZ8rM7Sj8e9uqKggpSrDYrinQDZzvMtqQp", + "signer": false, + "writable": true + }, + { + "pubkey": "11111111111111111111111111111111", + "signer": false, + "writable": false + } + ], + "instructions": [ + { + "parsed": { + "info": { + "destination": "HBYC51YrGFAZ8rM7Sj8e9uqKggpSrDYrinQDZzvMtqQp", + "lamports": 120000, + "source": "AHy6YZA8BsHgQfVkk7MbwpAN94iyN7Nf1zN4nPqUN32Q" + }, + "type": "transfer" + }, + "program": "system", + "programId": "11111111111111111111111111111111" + } + ], + "recentBlockhash": "8u75QFEzBoj61tdiZFHQSTQnHzcagfTQAde2iijQp2r3" + }, + "signatures": [ + "5QeLdXcC8GRh3KSs67Pq9sNE5uwFKkHt37crYLzcZ19ieh6RSEEGrS2r5eVXJiaXKb8M6FyKF45kHHmQRW2g1LYA" + ] + } + }, + "id": 1 + }, + { + "jsonrpc": "2.0", + "result": { + "blockTime": 1613388458, + "meta": { + "err": { + "InstructionError": [ + 0, + { + "Custom": 0 + } + ] + }, + "fee": 5000, + "innerInstructions": [], + "logMessages": [ + "Program Vote111111111111111111111111111111111111111 invoke [1]", + "Program Vote111111111111111111111111111111111111111 failed: custom program error: 0x0" + ], + "postBalances": [ + 478775796520, + 26858640, + 1, + 1, + 1 + ], + "preBalances": [ + 478775801520, + 26858640, + 1, + 1, + 1 + ], + "status": { + "Err": { + "InstructionError": [ + 0, + { + "Custom": 0 + } + ] + } + } + }, + "slot": 52838310, + "transaction": { + "message": { + "accountKeys": [ + { + "pubkey": "D32cBNvo9qmMyMSJzWqDPQ3ujYFuW9HHNjVkwxspezQr", + "signer": true, + "writable": true + }, + { + "pubkey": "YT7i3TkDv9GpbQ5qEkL7dvb3fAXSuNKwCotw2MjrWxZ", + "signer": false, + "writable": true + }, + { + "pubkey": "SysvarS1otHashes111111111111111111111111111", + "signer": false, + "writable": false + }, + { + "pubkey": "SysvarC1ock11111111111111111111111111111111", + "signer": false, + "writable": false + }, + { + "pubkey": "Vote111111111111111111111111111111111111111", + "signer": false, + "writable": false + } + ], + "instructions": [ + { + "parsed": { + "info": { + "clockSysvar": "SysvarC1ock11111111111111111111111111111111", + "slotHashesSysvar": "SysvarS1otHashes111111111111111111111111111", + "vote": { + "hash": "A9Jg1smbeMVyssPKbeK3pAkMDfLkKgAfRMK5aFELJDsZ", + "slots": [ + 52838301, + 52838302 + ], + "timestamp": 1606944861 + }, + "voteAccount": "YT7i3TkDv9GpbQ5qEkL7dvb3fAXSuNKwCotw2MjrWxZ", + "voteAuthority": "D32cBNvo9qmMyMSJzWqDPQ3ujYFuW9HHNjVkwxspezQr" + }, + "type": "vote" + }, + "program": "vote", + "programId": "Vote111111111111111111111111111111111111111" + } + ], + "recentBlockhash": "3e9FDUaHg4t1KPsi8F4tf63Kxn5H5XU7BkQnVRmxjUKA" + }, + "signatures": [ + "29ku1FzyNHgx5BZ811uj82EEnZNG6JbPuCQJvy5zuXnBfy2zgAdUubpfwEz2CfojFzxuzghms6qq9afzrzSnavdD" + ] + } + }, + "id": 1 + } + ] \ No newline at end of file diff --git a/platform/solana/model.go b/platform/solana/model.go new file mode 100644 index 000000000..3bb94c7c1 --- /dev/null +++ b/platform/solana/model.go @@ -0,0 +1,69 @@ +package solana + +type EpochInfo struct { + AbsoluteSlot uint64 `json:"absoluteSlot"` + BlockHeight uint64 `json:"blockHeight"` + Epoch uint64 `json:"epoch"` + SlotIndex uint64 `json:"slotIndex"` + SlotsInEpoch uint64 `json:"slotsInEpoch"` +} + +type Block struct { + BlockTime int64 `json:"blockTime"` + Transactions []ConfirmedTransaction `json:"transactions"` +} + +type ConfirmedSignature struct { + Memo string `json:"memo"` + Signature string `json:"signature"` + Slot uint64 `json:"slot"` +} + +type ConfirmedTransaction struct { + Meta Meta `json:"meta"` + BlockTime int64 `json:"blockTime,omitempty"` + Slot uint64 `json:"slot,omitempty"` + Transaction Transaction `json:"transaction"` +} + +type Meta struct { + Err interface{} `json:"err"` + Fee uint64 `json:"fee"` +} + +type TransferInfo struct { + Destination string `json:"destination"` + Lamports uint64 `json:"lamports"` + Source string `json:"source"` +} + +type Parsed struct { + Info interface{} `json:"info"` + Type string `json:"type"` +} + +type TokenTransferInfo struct { + Destination string `json:"destination"` + Mint string `json:"mint"` + Source string `json:"source"` + TokenAmount TokenAmount `json:"tokenAmount"` +} + +type TokenAmount struct { + Amount string `json:"amount"` + Decimals uint `json:"decimals"` +} + +type Instruction struct { + Parsed interface{} `json:"parsed"` + Program string `json:"program"` +} + +type Message struct { + Instructions []Instruction `json:"instructions"` +} + +type Transaction struct { + Message Message `json:"message"` + Signatures []string `json:"signatures"` +} diff --git a/platform/solana/transaction.go b/platform/solana/transaction.go new file mode 100644 index 000000000..eeecf91f4 --- /dev/null +++ b/platform/solana/transaction.go @@ -0,0 +1,95 @@ +package solana + +import ( + "errors" + "fmt" + "strconv" + + "github.com/trustwallet/blockatlas/pkg/blockatlas" + "github.com/trustwallet/golibs/types" +) + +const ( + programSystem = "system" + programToken = "spl-token" + + instructionTransfer = "transfer" + // will support instructionTransferChecked later + // instructionTransferChecked = "transferChecked" +) + +func (p *Platform) GetTxsByAddress(address string) (types.Txs, error) { + results := make(types.Txs, 0) + txs, err := p.client.GetTransactionsByAddress(address) + if err != nil { + return results, err + } + for _, tx := range txs { + if tx.BlockTime == 0 { + continue + } + if normalized, err := p.NormalizeTx(tx, tx.Slot, tx.BlockTime); err == nil { + normalized.Direction = normalized.GetTransactionDirection(address) + results = append(results, normalized) + } + } + return results, nil +} + +func (p *Platform) NormalizeTx(tx ConfirmedTransaction, slot uint64, timestamp int64) (normalized types.Tx, err error) { + + // only check first instruction + if len(tx.Transaction.Message.Instructions) != 1 || len(tx.Transaction.Signatures) != 1 { + err = errors.New("not supported instructions/signatures count") + return + } + + // only supports transfer and token transfer + instruction := tx.Transaction.Message.Instructions[0] + + if instruction.Program != programSystem && instruction.Program != programToken { + err = fmt.Errorf("not supported program: %s", instruction.Program) + return + } + + var parsed Parsed + err = blockatlas.MapJsonObject(instruction.Parsed, &parsed) + + if err != nil { + return + } + + // tx status + status := types.StatusCompleted + if tx.Meta.Err != nil { + status = types.StatusError + } + + normalized = types.Tx{ + ID: tx.Transaction.Signatures[0], + Coin: p.Coin().ID, + Fee: types.Amount(strconv.FormatUint(tx.Meta.Fee, 10)), + Date: timestamp, + Block: slot, + Status: status, + } + + switch parsed.Type { + case instructionTransfer: + var transfer TransferInfo + err = blockatlas.MapJsonObject(parsed.Info, &transfer) + if err == nil { + normalized.From = transfer.Source + normalized.To = transfer.Destination + normalized.Type = types.TxTransfer + normalized.Meta = types.Transfer{ + Value: types.Amount(strconv.FormatUint(transfer.Lamports, 10)), + Symbol: p.Coin().Symbol, + Decimals: p.Coin().Decimals, + } + } + default: + err = fmt.Errorf("not supported type: %s", parsed.Type) + } + return +} diff --git a/platform/solana/transaction_test.go b/platform/solana/transaction_test.go new file mode 100644 index 000000000..2cea578f0 --- /dev/null +++ b/platform/solana/transaction_test.go @@ -0,0 +1,72 @@ +package solana + +import ( + "bytes" + "encoding/json" + "fmt" + "net/http" + "net/http/httptest" + "testing" + + "github.com/stretchr/testify/assert" + "github.com/trustwallet/golibs/client" + "github.com/trustwallet/golibs/mock" +) + +func TestPlatform_GetTxsByAddress(t *testing.T) { + wanted, err := mock.JsonStringFromFilePath("mocks/GetTxsByAddress.json") + if err != nil { + panic(err) + } + data := make(map[string]func(http.ResponseWriter, *http.Request)) + data["/"] = func(w http.ResponseWriter, req *http.Request) { + w.WriteHeader(http.StatusOK) + + var r client.RpcRequest + var rs []client.RpcRequest + var response string + + buf := new(bytes.Buffer) + _, err := buf.ReadFrom(req.Body) + if err != nil { + panic(err) + } + requestBody := buf.String() + + if err := json.Unmarshal([]byte(requestBody), &r); err == nil { + switch r.Method { + case "getConfirmedSignaturesForAddress2": + signatures, err := mock.JsonStringFromFilePath("mocks/getConfirmedSignaturesForAddress2.json") + if err != nil { + panic(err) + } + response = signatures + } + } else if err := json.Unmarshal([]byte(requestBody), &rs); err == nil { + switch rs[0].Method { + case "getConfirmedTransaction": + signatures, err := mock.JsonStringFromFilePath("mocks/getConfirmedTransaction.json") + if err != nil { + panic(err) + } + response = signatures + } + } else { + panic("not valid json rpc request") + } + + if _, err := fmt.Fprint(w, response); err != nil { + panic(err) + } + } + + server := httptest.NewServer(mock.CreateMockedAPI(data)) + defer server.Close() + + p := Init(server.URL) + txs, err := p.GetTxsByAddress("AHy6YZA8BsHgQfVkk7MbwpAN94iyN7Nf1zN4nPqUN32Q") + assert.Nil(t, err) + raw, err := json.Marshal(txs) + assert.Nil(t, err) + assert.JSONEq(t, wanted, string(raw)) +} diff --git a/platform/stellar/api.go b/platform/stellar/api.go deleted file mode 100644 index 8cb86ddcf..000000000 --- a/platform/stellar/api.go +++ /dev/null @@ -1,145 +0,0 @@ -package stellar - -import ( - "fmt" - "github.com/spf13/viper" - "github.com/trustwallet/blockatlas/coin" - "github.com/trustwallet/blockatlas/pkg/blockatlas" - "github.com/trustwallet/blockatlas/pkg/numbers" - "strconv" - "sync" - "time" -) - -type Platform struct { - client Client - CoinIndex uint -} - -func (p *Platform) Init() error { - handle := coin.Coins[p.CoinIndex].Handle - api := fmt.Sprintf("%s.api", handle) - p.client = Client{blockatlas.InitClient(viper.GetString(api))} - return nil -} - -func (p *Platform) Coin() coin.Coin { - return coin.Coins[p.CoinIndex] -} - -func (p *Platform) GetTxsByAddress(address string) (blockatlas.TxPage, error) { - payments, err := p.client.GetTxsOfAddress(address) - if err != nil { - return nil, err - } - - return p.NormalizePayments(payments), nil -} - -func (p *Platform) CurrentBlockNumber() (int64, error) { - return p.client.CurrentBlockNumber() -} - -func (p *Platform) GetBlockByNumber(num int64) (*blockatlas.Block, error) { - if srcBlock, err := p.client.GetBlockByNumber(num); err == nil { - block := p.NormalizeBlock(srcBlock) - return &block, nil - } else { - return nil, err - } -} - -func (p *Platform) NormalizeBlock(block *Block) blockatlas.Block { - return blockatlas.Block{ - ID: block.Ledger.Id, - Number: block.Ledger.Sequence, - Txs: p.NormalizePayments(block.Payments), - } -} - -func (p *Platform) NormalizePayments(payments []Payment) (txs []blockatlas.Tx) { - var ( - wg sync.WaitGroup - txsChan = make(chan blockatlas.Tx, len(payments)) - ) - - for _, payment := range payments { - wg.Add(1) - go func(pay Payment) { - defer wg.Done() - - txHash, err := p.client.GetTxHash(pay.TransactionHash) - if err != nil { - return - } - - tx, ok := Normalize(&pay, p.CoinIndex, txHash) - if !ok { - return - } - - txsChan <- tx - - }(payment) - } - wg.Wait() - close(txsChan) - - for tx := range txsChan { - txs = append(txs, tx) - } - - return -} - -// Normalize converts a Stellar-based transaction into the generic model -func Normalize(payment *Payment, nativeCoinIndex uint, hash TxHash) (tx blockatlas.Tx, ok bool) { - switch payment.Type { - case PaymentType: - if payment.AssetType != Native { - return tx, false - } - case CreateAccount: - break - default: - return tx, false - } - id, err := strconv.ParseUint(payment.ID, 10, 64) - if err != nil { - return tx, false - } - date, err := time.Parse("2006-01-02T15:04:05Z", payment.CreatedAt) - if err != nil { - return tx, false - } - var value, from, to string - if payment.Amount != "" { - value, err = numbers.DecimalToSatoshis(payment.Amount) - from = payment.From - to = payment.To - } else if payment.StartingBalance != "" { // When transfer to new account - value, err = numbers.DecimalToSatoshis(payment.StartingBalance) - from = payment.Funder - to = payment.Account - } else { - return tx, false - } - if err != nil { - return tx, false - } - return blockatlas.Tx{ - ID: payment.TransactionHash, - Coin: nativeCoinIndex, - From: from, - To: to, - Fee: FixedFee, - Date: date.Unix(), - Memo: hash.Memo, - Block: id, - Meta: blockatlas.Transfer{ - Value: blockatlas.Amount(value), - Symbol: coin.Coins[nativeCoinIndex].Symbol, - Decimals: coin.Coins[nativeCoinIndex].Decimals, - }, - }, true -} diff --git a/platform/stellar/api_test.go b/platform/stellar/api_test.go deleted file mode 100644 index 40feddee2..000000000 --- a/platform/stellar/api_test.go +++ /dev/null @@ -1,129 +0,0 @@ -package stellar - -import ( - "bytes" - "encoding/json" - "github.com/trustwallet/blockatlas/coin" - "github.com/trustwallet/blockatlas/pkg/blockatlas" - "testing" -) - -const createSrc = ` -{ - "id": "25002129911451649", - "paging_token": "25002129911451649", - "transaction_successful": true, - "source_account": "GBEZOC5U4TVH7ZY5N3FLYHTCZSI6VFGTULG7PBITLF5ZEBPJXFT46YZM", - "type": "create_account", - "type_i": 0, - "created_at": "2016-08-10T17:30:20Z", - "transaction_hash": "8b96cf3a660b85ef80b5a84c032cacdb93bb139cfe7e929b974ea9eaa0d29141", - "starting_balance": "47326939370.0000000", - "funder": "GBEZOC5U4TVH7ZY5N3FLYHTCZSI6VFGTULG7PBITLF5ZEBPJXFT46YZM", - "account": "GDKIJJIKXLOM2NRMPNQZUUYK24ZPVFC6426GZAEP3KUK6KEJLACCWNMX" -} -` - -var createDst = blockatlas.Tx{ - ID: "8b96cf3a660b85ef80b5a84c032cacdb93bb139cfe7e929b974ea9eaa0d29141", - Coin: coin.XLM, - From: "GBEZOC5U4TVH7ZY5N3FLYHTCZSI6VFGTULG7PBITLF5ZEBPJXFT46YZM", - To: "GDKIJJIKXLOM2NRMPNQZUUYK24ZPVFC6426GZAEP3KUK6KEJLACCWNMX", - Fee: "100", - Date: 1470850220, - Memo: "testing", - Block: 25002129911451649, - Meta: blockatlas.Transfer{ - Value: "473269393700000000", - Symbol: "XLM", - Decimals: 7, - }, -} - -const transferSrc = ` -{ - "id": "25008572362395649", - "paging_token": "25008572362395649", - "transaction_successful": true, - "source_account": "GDKIJJIKXLOM2NRMPNQZUUYK24ZPVFC6426GZAEP3KUK6KEJLACCWNMX", - "type": "payment", - "type_i": 1, - "created_at": "2016-08-10T19:39:01Z", - "transaction_hash": "a596dc910bae20b5bbe64aa7aa3f42acbd55769b98307878f5ad095e994bc9cf", - "asset_type": "native", - "from": "GDKIJJIKXLOM2NRMPNQZUUYK24ZPVFC6426GZAEP3KUK6KEJLACCWNMX", - "to": "GAX3BRBNB5WTJ2GNEFFH7A4CZKT2FORYABDDBZR5FIIT3P7FLS2EFOZZ", - "amount": "100000000.0000000" -} -` - -var transferDst = blockatlas.Tx{ - ID: "a596dc910bae20b5bbe64aa7aa3f42acbd55769b98307878f5ad095e994bc9cf", - Coin: coin.XLM, - From: "GDKIJJIKXLOM2NRMPNQZUUYK24ZPVFC6426GZAEP3KUK6KEJLACCWNMX", - To: "GAX3BRBNB5WTJ2GNEFFH7A4CZKT2FORYABDDBZR5FIIT3P7FLS2EFOZZ", - Fee: "100", - Date: 1470857941, - Memo: "testing", - Block: 25008572362395649, - Meta: blockatlas.Transfer{ - Value: blockatlas.Amount("1000000000000000"), - Symbol: "XLM", - Decimals: 7, - }, -} - -var hash = TxHash{ - Memo: "testing", -} - -type test struct { - name string - apiResponse string - hash TxHash - expected *blockatlas.Tx -} - -func TestNormalize(t *testing.T) { - testNormalize(t, &test{ - name: "create account", - apiResponse: createSrc, - hash: hash, - expected: &createDst, - }) - testNormalize(t, &test{ - name: "transfer", - apiResponse: transferSrc, - hash: hash, - expected: &transferDst, - }) -} - -func testNormalize(t *testing.T, _test *test) { - var payment Payment - err := json.Unmarshal([]byte(_test.apiResponse), &payment) - if err != nil { - t.Error(err) - return - } - tx, ok := Normalize(&payment, coin.XLM, _test.hash) - if !ok { - t.Errorf("%s: tx could not be normalized", _test.name) - } - - resJSON, err := json.Marshal(&tx) - if err != nil { - t.Fatal(err) - } - - dstJSON, err := json.Marshal(&_test.expected) - if err != nil { - t.Fatal(err) - } - - if !bytes.Equal(resJSON, dstJSON) { - println(string(resJSON)) - println(string(dstJSON)) - t.Error(_test.name + ": tx don't equal") - } -} diff --git a/platform/stellar/base.go b/platform/stellar/base.go new file mode 100644 index 000000000..8b3c9726b --- /dev/null +++ b/platform/stellar/base.go @@ -0,0 +1,23 @@ +package stellar + +import ( + "github.com/trustwallet/golibs/client" + "github.com/trustwallet/golibs/coin" + "github.com/trustwallet/golibs/network/middleware" +) + +type Platform struct { + client Client + CoinIndex uint +} + +func Init(coin uint, api string) *Platform { + return &Platform{ + CoinIndex: coin, + client: Client{client.InitClient(api, middleware.SentryErrorHandler)}, + } +} + +func (p *Platform) Coin() coin.Coin { + return coin.Coins[p.CoinIndex] +} diff --git a/platform/stellar/block.go b/platform/stellar/block.go new file mode 100644 index 000000000..60c40dc75 --- /dev/null +++ b/platform/stellar/block.go @@ -0,0 +1,22 @@ +package stellar + +import "github.com/trustwallet/golibs/types" + +func (p *Platform) CurrentBlockNumber() (int64, error) { + return p.client.CurrentBlockNumber() +} + +func (p *Platform) GetBlockByNumber(num int64) (*types.Block, error) { + if srcBlock, err := p.client.GetBlockByNumber(num); err == nil { + block := p.NormalizeBlock(srcBlock) + return &block, nil + } else { + return nil, err + } +} +func (p *Platform) NormalizeBlock(block *Block) types.Block { + return types.Block{ + Number: block.Ledger.Sequence, + Txs: p.NormalizePayments(block.Payments), + } +} diff --git a/platform/stellar/client.go b/platform/stellar/client.go index eb47350fb..85c468a5e 100644 --- a/platform/stellar/client.go +++ b/platform/stellar/client.go @@ -1,20 +1,22 @@ package stellar import ( + "errors" "fmt" - "github.com/trustwallet/blockatlas/pkg/blockatlas" - "github.com/trustwallet/blockatlas/pkg/errors" "net/url" + + "github.com/trustwallet/golibs/client" ) type Client struct { - blockatlas.Request + client.Request } func (c *Client) GetTxsOfAddress(address string) ([]Payment, error) { query := url.Values{ "order": {"desc"}, "limit": {"25"}, + "join": {"transactions"}, } path := fmt.Sprintf("accounts/%s/payments", url.PathEscape(address)) @@ -26,17 +28,6 @@ func (c *Client) GetTxsOfAddress(address string) ([]Payment, error) { return payments.Embedded.Records, nil } -func (c *Client) GetTxHash(id string) (TxHash, error) { - path := fmt.Sprintf("transactions/%s", id) - - var hash TxHash - err := c.Get(&hash, path, nil) - if err != nil { - return hash, err - } - return hash, nil -} - func (c *Client) CurrentBlockNumber() (int64, error) { query := url.Values{ "order": {"desc"}, @@ -49,7 +40,7 @@ func (c *Client) CurrentBlockNumber() (int64, error) { } if len(ledgers.Embedded.Records) == 0 { - return 0, errors.E("CurrentBlockNumber: Records is empty", errors.TypePlatformUnmarshal).PushToSentry() + return 0, errors.New("CurrentBlockNumber: Records is empty") } return ledgers.Embedded.Records[0].Sequence, nil } @@ -63,6 +54,7 @@ func (c *Client) GetBlockByNumber(num int64) (*Block, error) { query := url.Values{ "order": {"desc"}, "limit": {"100"}, + "join": {"transactions"}, } path := fmt.Sprintf("ledgers/%d/payments", num) diff --git a/platform/stellar/mocks/create_tx.json b/platform/stellar/mocks/create_tx.json new file mode 100644 index 000000000..e50548c10 --- /dev/null +++ b/platform/stellar/mocks/create_tx.json @@ -0,0 +1,13 @@ +{ + "id": "25002129911451649", + "paging_token": "25002129911451649", + "transaction_successful": true, + "source_account": "GBEZOC5U4TVH7ZY5N3FLYHTCZSI6VFGTULG7PBITLF5ZEBPJXFT46YZM", + "type": "create_account", + "type_i": 0, + "created_at": "2016-08-10T17:30:20Z", + "transaction_hash": "8b96cf3a660b85ef80b5a84c032cacdb93bb139cfe7e929b974ea9eaa0d29141", + "starting_balance": "47326939370.0000000", + "funder": "GBEZOC5U4TVH7ZY5N3FLYHTCZSI6VFGTULG7PBITLF5ZEBPJXFT46YZM", + "account": "GDKIJJIKXLOM2NRMPNQZUUYK24ZPVFC6426GZAEP3KUK6KEJLACCWNMX" +} diff --git a/platform/stellar/mocks/transfer_tx.json b/platform/stellar/mocks/transfer_tx.json new file mode 100644 index 000000000..53a9eba7b --- /dev/null +++ b/platform/stellar/mocks/transfer_tx.json @@ -0,0 +1,18 @@ +{ + "id": "25008572362395649", + "paging_token": "25008572362395649", + "transaction_successful": true, + "source_account": "GDKIJJIKXLOM2NRMPNQZUUYK24ZPVFC6426GZAEP3KUK6KEJLACCWNMX", + "type": "payment", + "type_i": 1, + "created_at": "2016-08-10T19:39:01Z", + "transaction_hash": "a596dc910bae20b5bbe64aa7aa3f42acbd55769b98307878f5ad095e994bc9cf", + "asset_type": "native", + "from": "GDKIJJIKXLOM2NRMPNQZUUYK24ZPVFC6426GZAEP3KUK6KEJLACCWNMX", + "to": "GAX3BRBNB5WTJ2GNEFFH7A4CZKT2FORYABDDBZR5FIIT3P7FLS2EFOZZ", + "amount": "100000000.0000000", + "transaction": { + "memo": "testing", + "ledger": 123 + } +} diff --git a/platform/stellar/model.go b/platform/stellar/model.go index 0d78d4785..af8d75f20 100644 --- a/platform/stellar/model.go +++ b/platform/stellar/model.go @@ -38,26 +38,23 @@ type Block struct { // Payment model returned by Horizon type Payment struct { - ID string `json:"id"` - Type string `json:"type"` - SourceAccount string `json:"source_account"` - CreatedAt string `json:"created_at"` - Account string `json:"account"` - Funder string `json:"funder"` - StartingBalance string `json:"starting_balance"` - Into string `json:"into"` - From string `json:"from"` - To string `json:"to"` - AssetType string `json:"asset_type"` - Amount string `json:"amount"` - TransactionHash string `json:"transaction_hash"` + ID string `json:"id"` + Type string `json:"type"` + SourceAccount string `json:"source_account"` + CreatedAt string `json:"created_at"` + Account string `json:"account"` + Funder string `json:"funder"` + StartingBalance string `json:"starting_balance"` + Into string `json:"into"` + From string `json:"from"` + To string `json:"to"` + AssetType string `json:"asset_type"` + Amount string `json:"amount"` + TransactionHash string `json:"transaction_hash"` + Transaction Transaction `json:"transaction"` } -type TxHash struct { - Memo string `json:"memo"` -} - -type Tuple struct { - Payment - TxHash +type Transaction struct { + Memo string `json:"memo"` + Ledger uint64 `json:"ledger"` } diff --git a/platform/stellar/transaction.go b/platform/stellar/transaction.go new file mode 100644 index 000000000..1177e8c37 --- /dev/null +++ b/platform/stellar/transaction.go @@ -0,0 +1,76 @@ +package stellar + +import ( + "time" + + "github.com/trustwallet/golibs/coin" + "github.com/trustwallet/golibs/numbers" + "github.com/trustwallet/golibs/types" +) + +func (p *Platform) GetTxsByAddress(address string) (types.Txs, error) { + payments, err := p.client.GetTxsOfAddress(address) + if err != nil { + return nil, err + } + + return p.NormalizePayments(payments), nil +} + +func (p *Platform) NormalizePayments(payments []Payment) types.Txs { + txs := make(types.Txs, 0, len(payments)) + for _, payment := range payments { + if tx, ok := Normalize(&payment, p.CoinIndex); ok { + txs = append(txs, tx) + } + } + return txs +} + +// Normalize converts a Stellar-based transaction into the generic model +func Normalize(payment *Payment, nativeCoinIndex uint) (tx types.Tx, ok bool) { + switch payment.Type { + case PaymentType: + if payment.AssetType != Native { + return tx, false + } + case CreateAccount: + break + default: + return tx, false + } + date, err := time.Parse("2006-01-02T15:04:05Z", payment.CreatedAt) + if err != nil { + return tx, false + } + var value, from, to string + if payment.Amount != "" { + value, err = numbers.DecimalToSatoshis(payment.Amount) + from = payment.From + to = payment.To + } else if payment.StartingBalance != "" { // When transfer to new account + value, err = numbers.DecimalToSatoshis(payment.StartingBalance) + from = payment.Funder + to = payment.Account + } else { + return tx, false + } + if err != nil { + return tx, false + } + return types.Tx{ + ID: payment.TransactionHash, + Coin: nativeCoinIndex, + From: from, + To: to, + Fee: FixedFee, + Date: date.Unix(), + Memo: payment.Transaction.Memo, + Block: payment.Transaction.Ledger, + Meta: types.Transfer{ + Value: types.Amount(value), + Symbol: coin.Coins[nativeCoinIndex].Symbol, + Decimals: coin.Coins[nativeCoinIndex].Decimals, + }, + }, true +} diff --git a/platform/stellar/transaction_test.go b/platform/stellar/transaction_test.go new file mode 100644 index 000000000..c25df6b62 --- /dev/null +++ b/platform/stellar/transaction_test.go @@ -0,0 +1,91 @@ +package stellar + +import ( + "encoding/json" + "testing" + + "github.com/stretchr/testify/assert" + "github.com/trustwallet/golibs/coin" + "github.com/trustwallet/golibs/mock" + "github.com/trustwallet/golibs/types" +) + +var ( + createSrc, _ = mock.JsonStringFromFilePath("mocks/" + "create_tx.json") + transferSrc, _ = mock.JsonStringFromFilePath("mocks/" + "transfer_tx.json") + + createDst = types.Tx{ + ID: "8b96cf3a660b85ef80b5a84c032cacdb93bb139cfe7e929b974ea9eaa0d29141", + Coin: coin.STELLAR, + From: "GBEZOC5U4TVH7ZY5N3FLYHTCZSI6VFGTULG7PBITLF5ZEBPJXFT46YZM", + To: "GDKIJJIKXLOM2NRMPNQZUUYK24ZPVFC6426GZAEP3KUK6KEJLACCWNMX", + Fee: "100", + Date: 1470850220, + Block: 0, + Meta: types.Transfer{ + Value: "473269393700000000", + Symbol: "XLM", + Decimals: 7, + }, + } + + transferDst = types.Tx{ + ID: "a596dc910bae20b5bbe64aa7aa3f42acbd55769b98307878f5ad095e994bc9cf", + Coin: coin.STELLAR, + From: "GDKIJJIKXLOM2NRMPNQZUUYK24ZPVFC6426GZAEP3KUK6KEJLACCWNMX", + To: "GAX3BRBNB5WTJ2GNEFFH7A4CZKT2FORYABDDBZR5FIIT3P7FLS2EFOZZ", + Fee: "100", + Date: 1470857941, + Memo: "testing", + Block: 123, + Meta: types.Transfer{ + Value: types.Amount("1000000000000000"), + Symbol: "XLM", + Decimals: 7, + }, + } +) + +type test struct { + name string + apiResponse string + expected *types.Tx +} + +func TestNormalize(t *testing.T) { + testNormalize(t, &test{ + name: "create account", + apiResponse: createSrc, + expected: &createDst, + }) + testNormalize(t, &test{ + name: "transfer", + apiResponse: transferSrc, + expected: &transferDst, + }) +} + +func testNormalize(t *testing.T, _test *test) { + var payment Payment + err := json.Unmarshal([]byte(_test.apiResponse), &payment) + if err != nil { + t.Error(err) + return + } + tx, ok := Normalize(&payment, coin.STELLAR) + if !ok { + t.Errorf("%s: tx could not be normalized", _test.name) + } + + _, err = json.Marshal(&tx) + if err != nil { + t.Fatal(err) + } + + _, err = json.Marshal(&_test.expected) + if err != nil { + t.Fatal(err) + } + + assert.Equal(t, tx, *_test.expected) +} diff --git a/platform/tezos/api.go b/platform/tezos/api.go deleted file mode 100644 index 6fb3532cb..000000000 --- a/platform/tezos/api.go +++ /dev/null @@ -1,192 +0,0 @@ -package tezos - -import ( - "github.com/spf13/viper" - "github.com/trustwallet/blockatlas/coin" - "github.com/trustwallet/blockatlas/pkg/blockatlas" - "github.com/trustwallet/blockatlas/pkg/errors" - services "github.com/trustwallet/blockatlas/services/assets" - "math" - "strconv" - "time" -) - -type Platform struct { - client Client - rpcClient RpcClient -} - -const Annual = 6.09 - -func (p *Platform) Init() error { - p.client = Client{blockatlas.InitClient(viper.GetString("tezos.api"))} - p.rpcClient = RpcClient{blockatlas.InitClient(viper.GetString("tezos.rpc"))} - return nil -} - -func (p *Platform) Coin() coin.Coin { - return coin.Coins[coin.XTZ] -} - -func (p *Platform) GetTxsByAddress(address string) (blockatlas.TxPage, error) { - s, err := p.client.GetTxsOfAddress(address) - if err != nil { - return nil, err - } - - txs := NormalizeTxs(s) - - return txs, nil -} - -func (p *Platform) CurrentBlockNumber() (int64, error) { - return p.client.GetCurrentBlock() -} - -func (p *Platform) GetBlockByNumber(num int64) (*blockatlas.Block, error) { - srcBlock, err := p.client.GetBlockByNumber(num) - if err != nil { - return nil, err - } - txs := NormalizeTxs(srcBlock) - return &blockatlas.Block{ - Number: num, - Txs: txs, - }, nil -} - -func (p *Platform) GetDelegations(address string) (blockatlas.DelegationsPage, error) { - account, err := p.client.GetAccount(address) - if err != nil { - return nil, err - } - if !account.IsDelegated { - return make(blockatlas.DelegationsPage, 0), nil - } - validators, err := services.GetValidatorsMap(p) - if err != nil { - return nil, err - } - return NormalizeDelegation(account, validators) -} - -func NormalizeDelegation(account Account, validators blockatlas.ValidatorMap) (blockatlas.DelegationsPage, error) { - validator, ok := validators[account.Delegate] - if !ok { - return nil, errors.E("Validator not found", - errors.Params{"Address": account.Address, "Delegate": account.Delegate, "Balance": account.Balance}) - } - balance := removeDecimals(account.Balance) - return blockatlas.DelegationsPage{ - { - Delegator: validator, - Value: balance, - Status: blockatlas.DelegationStatusActive, - }, - }, nil -} - -func NormalizeTxs(srcTxs []Tx) (txs []blockatlas.Tx) { - for _, srcTx := range srcTxs { - tx, ok := NormalizeTx(&srcTx) - if !ok { - continue - } - txs = append(txs, tx) - } - return txs -} - -func (p *Platform) GetValidators() (blockatlas.ValidatorPage, error) { - results := make(blockatlas.ValidatorPage, 0) - validators, err := p.rpcClient.GetValidators() - - if err != nil { - return results, err - } - - for _, v := range validators { - results = append(results, normalizeValidator(v)) - } - - return results, nil -} - -func (p *Platform) GetDetails() blockatlas.StakingDetails { - return getDetails() -} - -func (p *Platform) UndelegatedBalance(address string) (string, error) { - account, err := p.client.GetAccount(address) - if err != nil { - return "0", err - } - return removeDecimals(account.Balance), nil -} - -func getDetails() blockatlas.StakingDetails { - return blockatlas.StakingDetails{ - Reward: blockatlas.StakingReward{Annual: Annual}, - MinimumAmount: "0", - LockTime: 0, - Type: blockatlas.DelegationTypeDelegate, - } -} - -func normalizeValidator(v Validator) (validator blockatlas.Validator) { - // How to calculate Tezos APR? I have no idea. Tezos team does not know either. let's assume it's around 7% - no way to calculate in decentralized manner - // Delegation rewards distributed by the validators manually, it's up to them to do it. - - return blockatlas.Validator{ - Status: true, - ID: v.Address, - Details: getDetails(), - } -} - -// NormalizeTx converts a Tezos transaction into the generic model -func NormalizeTx(srcTx *Tx) (tx blockatlas.Tx, ok bool) { - unix := int64(0) - date, err := time.Parse("2006-01-02T15:04:05Z", srcTx.Time) - if err == nil { - unix = date.Unix() - } - - if srcTx.Type != "transaction" { - return tx, false - } - - var status blockatlas.Status - var errMsg string - if srcTx.Success && srcTx.Status == "applied" { - status = blockatlas.StatusCompleted - } else { - status = blockatlas.StatusFailed - errMsg = "transaction failed" - } - - volume := removeDecimals(srcTx.Volume) - return blockatlas.Tx{ - ID: srcTx.Hash, - Coin: coin.XTZ, - Date: unix, - From: srcTx.Sender, - To: srcTx.Receiver, - Fee: blockatlas.Amount(strconv.Itoa(srcTx.Fee)), - Block: srcTx.Height, - Meta: blockatlas.Transfer{ - Value: blockatlas.Amount(volume), - Symbol: coin.Coins[coin.XTZ].Symbol, - Decimals: coin.Coins[coin.XTZ].Decimals, - }, - Status: status, - Error: errMsg, - }, true -} - -func removeDecimals(volume float64) string { - decimals := coin.Coins[coin.XTZ].Decimals - d := math.Pow10(int(decimals)) - v := volume * d - return strconv.Itoa(int(v)) -} diff --git a/platform/tezos/api_test.go b/platform/tezos/api_test.go deleted file mode 100644 index 6431ba858..000000000 --- a/platform/tezos/api_test.go +++ /dev/null @@ -1,193 +0,0 @@ -package tezos - -import ( - "encoding/json" - "github.com/stretchr/testify/assert" - "github.com/trustwallet/blockatlas/coin" - "github.com/trustwallet/blockatlas/pkg/blockatlas" - "testing" -) - -const transferSrc = ` -{ - "ops": [ - { - "hash": "opN4YjaBwngT8Csz5gKzdwfm78cNquWwcHkjxfHqqstCAT5HWcM", - "type": "transaction", - "block": "BKq8skWbocNHvYw2af2erSvh9UYhPkofrWf1UBxDffhDZHEhUxw", - "time": "2018-07-04T12:43:27Z", - "height": 5442, - "status": "applied", - "is_success": true, - "is_contract": false, - "gas_limit": 200, - "gas_used": 100, - "gas_price": 0, - "volume": 1, - "fee": 0, - "sender": "tz1TcgvvzDD4hwHQHdPNGw6ZW9wkomwxaQkP", - "receiver": "tz1WCd2jm4uSt4vntk4vSuUWoZQGhLcDuR9q" - }, - { - "hash": "oo3aARP7Y271ZkNi6XqsZZHbzrV1sDwdqD8wrgvSBPaSRK2JDuj", - "type": "reveal", - "block": "BL3ET2QcAt7xNU2cnxjrY4iM3Wwe8UHLHCE85rhCiSP8zd26Qnk", - "time": "2018-07-04T12:50:27Z", - "height": 5449, - "status": "applied", - "is_success": true, - "is_contract": false, - "gas_limit": 0, - "gas_used": 0, - "gas_price": 0, - "volume": 0, - "fee": 0, - "data": "edpktthB79sCK3xQSekMfuhjHLLC593UW5CHyDR9CueVF68PS1K3ZH", - "sender": "tz1WCd2jm4uSt4vntk4vSuUWoZQGhLcDuR9q" - }, - { - "hash": "oo3aARP7Y271ZkNi6XqsZZHbzrV1sDwdqD8wrgvSBPaSRK2JDuj", - "type": "transaction", - "block": "BL3ET2QcAt7xNU2cnxjrY4iM3Wwe8UHLHCE85rhCiSP8zd26Qnk", - "time": "2018-07-04T12:50:27Z", - "height": 5449, - "status": "applied", - "is_success": true, - "is_contract": false, - "gas_limit": 360, - "gas_used": 260, - "gas_price": 0, - "volume": 1, - "fee": 0, - "sender": "tz1WCd2jm4uSt4vntk4vSuUWoZQGhLcDuR9q", - "receiver": "tz1TcgvvzDD4hwHQHdPNGw6ZW9wkomwxaQkP" - } - ] -} -` - -const validatorSrc = ` -[ - {"pkh":"tz2TSvNTh2epDMhZHrw73nV9piBX7kLZ9K9m","rolls":3726} -] -` - -func TestNormalize(t *testing.T) { - var srcOp Op - err := json.Unmarshal([]byte(transferSrc), &srcOp) - assert.NoError(t, err) - assert.NotNil(t, srcOp) - - expected := []blockatlas.Tx{ - { - ID: "opN4YjaBwngT8Csz5gKzdwfm78cNquWwcHkjxfHqqstCAT5HWcM", - Coin: coin.XTZ, - Date: 1530708207, - From: "tz1TcgvvzDD4hwHQHdPNGw6ZW9wkomwxaQkP", - To: "tz1WCd2jm4uSt4vntk4vSuUWoZQGhLcDuR9q", - Fee: "100", - Block: 5442, - Meta: blockatlas.Transfer{ - Value: blockatlas.Amount("1000000"), - Symbol: coin.Coins[coin.XTZ].Symbol, - Decimals: coin.Coins[coin.XTZ].Decimals, - }, - Status: "completed", - }, - { - ID: "oo3aARP7Y271ZkNi6XqsZZHbzrV1sDwdqD8wrgvSBPaSRK2JDuj", - Coin: coin.XTZ, - Date: 1530708627, - From: "tz1WCd2jm4uSt4vntk4vSuUWoZQGhLcDuR9q", - To: "tz1TcgvvzDD4hwHQHdPNGw6ZW9wkomwxaQkP", - Fee: "260", - Block: 5449, - Meta: blockatlas.Transfer{ - Value: blockatlas.Amount("1000000"), - Symbol: coin.Coins[coin.XTZ].Symbol, - Decimals: coin.Coins[coin.XTZ].Decimals, - }, - Status: "completed", - }, - } - result := NormalizeTxs(srcOp.Txs) - assert.Equal(t, result, expected) -} - -func TestNormalizeValidator(t *testing.T) { - var v Validator - _ = json.Unmarshal([]byte(validatorSrc), &v) - expected := blockatlas.Validator{ - Status: true, - ID: v.Address, - Details: blockatlas.StakingDetails{ - Reward: blockatlas.StakingReward{Annual: Annual}, - MinimumAmount: blockatlas.Amount("0"), - Type: blockatlas.DelegationTypeDelegate, - }, - } - result := normalizeValidator(v) - assert.Equal(t, result, expected) -} - -func Test_removeDecimals(t *testing.T) { - tests := []struct { - name string - volume float64 - want string - }{ - {"one float precision", 9.5, "9500000"}, - {"zero float precision", 9, "9000000"}, - {"five float precision", 9.00005, "9000050"}, - {"six float precision", 9.000005, "9000005"}, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - if got := removeDecimals(tt.volume); got != tt.want { - t.Errorf("removeDecimals() = %v, want %v", got, tt.want) - } - }) - } -} - -const accountSrc = ` -{ - "address": "tz1WDujRWCYjLBDfZieXW6insg5EUbg1rCRK", - "delegate": "tz2FCNBrERXtaTtNX6iimR1UJ5JSDxvdHM93", - "total_balance": 68995.611927, - "is_delegated": true -}` - -var validator1 = blockatlas.StakeValidator{ - ID: "tz2FCNBrERXtaTtNX6iimR1UJ5JSDxvdHM93", - Status: true, - Info: blockatlas.StakeValidatorInfo{ - Name: "stake.fish", - Description: "Leading validator for Proof of Stake blockchains. Stake your cryptocurrencies with us. We know validating.", - Image: "https://raw.githubusercontent.com/trustwallet/assets/master/blockchains/tezos/validators/assets/tz2fcnbrerxtattnx6iimr1uj5jsdxvdhm93/logo.png", - Website: "https://stake.fish/", - }, - Details: getDetails(), -} - -var validatorMap = blockatlas.ValidatorMap{ - "tz2FCNBrERXtaTtNX6iimR1UJ5JSDxvdHM93": validator1, -} - -func TestNormalizeDelegations(t *testing.T) { - var account Account - err := json.Unmarshal([]byte(accountSrc), &account) - assert.NoError(t, err) - assert.NotNil(t, account) - - expected := blockatlas.DelegationsPage{ - { - Delegator: validator1, - Value: "68995611927", - Status: blockatlas.DelegationStatusActive, - }, - } - result, err := NormalizeDelegation(account, validatorMap) - assert.NoError(t, err) - assert.Equal(t, result, expected) -} diff --git a/platform/tezos/baker.go b/platform/tezos/baker.go new file mode 100644 index 000000000..8ea61bd69 --- /dev/null +++ b/platform/tezos/baker.go @@ -0,0 +1,68 @@ +package tezos + +import ( + "math" + "strconv" + "time" + + "github.com/trustwallet/blockatlas/pkg/blockatlas" + "github.com/trustwallet/blockatlas/services/assets" + "github.com/trustwallet/golibs/client" + "github.com/trustwallet/golibs/coin" + "github.com/trustwallet/golibs/types" +) + +const ( + cacheTime = 1 * time.Hour +) + +type BakerClient struct { + client.Request +} + +func (c *BakerClient) GetBakers() (validators blockatlas.StakeValidators, err error) { + var bakers []Baker + err = c.GetWithCache(&bakers, "v2/bakers", nil, cacheTime) + if err != nil { + return + } + assetsValidators, err := assets.GetValidatorsInfo(coin.Tezos()) + if err != nil { + return + } + validatorMap := assetsValidators.ToMap() + for _, baker := range bakers { + if av, ok := validatorMap[baker.Address]; ok { + validators = append(validators, NormalizeStakeValidator(baker, av)) + } + } + return +} + +func NormalizeStakeValidator(baker Baker, assetValidator assets.AssetValidator) blockatlas.StakeValidator { + status := true + if baker.FreeSpace < 0 || baker.ServiceHealth != "active" || !baker.OpenForDelegation { + status = false + } + + amount := uint64(math.Ceil(baker.MinDelegation)) + + return blockatlas.StakeValidator{ + ID: baker.Address, + Status: status, + Info: blockatlas.StakeValidatorInfo{ + Name: assetValidator.Name, + Description: assetValidator.Description, + Website: assetValidator.Website, + Image: assets.GetImageURL(coin.Tezos(), baker.Address), + }, + Details: blockatlas.StakingDetails{ + Reward: blockatlas.StakingReward{ + Annual: math.Round(baker.EstimatedRoi*10000) / 100, + }, + LockTime: LockTime, + MinimumAmount: types.Amount(strconv.FormatUint(amount, 10)), + Type: blockatlas.DelegationTypeDelegate, + }, + } +} diff --git a/platform/tezos/baker_test.go b/platform/tezos/baker_test.go new file mode 100644 index 000000000..3bfcb8d01 --- /dev/null +++ b/platform/tezos/baker_test.go @@ -0,0 +1,137 @@ +package tezos + +import ( + "reflect" + "testing" + + "github.com/trustwallet/blockatlas/pkg/blockatlas" + "github.com/trustwallet/blockatlas/services/assets" +) + +func TestNormalizeStakeValidators(t *testing.T) { + tests := []struct { + name string + av assets.AssetValidator + baker Baker + validator blockatlas.StakeValidator + }{ + { + name: "Test normalize negative free space", + av: assets.AssetValidator{ + ID: "tz1fJHFn6sWEd3NnBPngACuw2dggTv6nQZ7g", + Name: "Baking Team from assets", + Description: "Baking team is full", + Website: "https://mytezosbaker.com/bakingteam", + }, + baker: Baker{ + Address: "tz1fJHFn6sWEd3NnBPngACuw2dggTv6nQZ7g", + Name: "Baking Team", + Logo: "https://services.tzkt.io/v1/avatars/tz1fJHFn6sWEd3NnBPngACuw2dggTv6nQZ7g", + FreeSpace: -54723.23208699998, + Fee: 0, + MinDelegation: 1000, + OpenForDelegation: true, + EstimatedRoi: 0.060643, + ServiceHealth: "active", + }, + validator: blockatlas.StakeValidator{ + ID: "tz1fJHFn6sWEd3NnBPngACuw2dggTv6nQZ7g", + Status: false, + Info: blockatlas.StakeValidatorInfo{ + Name: "Baking Team from assets", + Description: "Baking team is full", + Website: "https://mytezosbaker.com/bakingteam", + Image: "https://assets.trustwalletapp.com/blockchains/tezos/validators/assets/tz1fJHFn6sWEd3NnBPngACuw2dggTv6nQZ7g/logo.png", + }, + Details: blockatlas.StakingDetails{ + Reward: blockatlas.StakingReward{ + Annual: 6.06, + }, + MinimumAmount: "1000", + Type: "delegate", + }, + }, + }, + { + name: "Test normalize negative free space", + av: assets.AssetValidator{ + ID: "tz1gcna2xxZj2eNp1LaMyAhVJ49mEFj4FH26", + Name: "Exaion Baker", + Description: "Exaion is first French corporate to participate in the Tezos ecosystem as a corporate baker.", + Website: "https://www.edf.fr/en/the-edf-group", + }, + baker: Baker{ + Address: "tz1gcna2xxZj2eNp1LaMyAhVJ49mEFj4FH26", + Name: "Exaion Baker", + Logo: "https://services.tzkt.io/v1/avatars/tz1gcna2xxZj2eNp1LaMyAhVJ49mEFj4FH26", + FreeSpace: 7947.711756999997, + Fee: 0.04, + MinDelegation: 0, + OpenForDelegation: true, + EstimatedRoi: 0.058896, + ServiceHealth: "active", + }, + validator: blockatlas.StakeValidator{ + ID: "tz1gcna2xxZj2eNp1LaMyAhVJ49mEFj4FH26", + Status: true, + Info: blockatlas.StakeValidatorInfo{ + Name: "Exaion Baker", + Image: "https://assets.trustwalletapp.com/blockchains/tezos/validators/assets/tz1gcna2xxZj2eNp1LaMyAhVJ49mEFj4FH26/logo.png", + Description: "Exaion is first French corporate to participate in the Tezos ecosystem as a corporate baker.", + Website: "https://www.edf.fr/en/the-edf-group", + }, + Details: blockatlas.StakingDetails{ + Reward: blockatlas.StakingReward{ + Annual: 5.89, + }, + MinimumAmount: "0", + Type: "delegate", + }, + }, + }, + { + name: "Test", + av: assets.AssetValidator{ + ID: "tz1dbfppLAAxXZNtf2SDps7rch3qfUznKSoK", + Name: "Coinhouse", + Description: "The reliable and safe way to invest in cryptocurrencies", + Website: "https://www.coinhouse.com/", + }, + baker: Baker{ + Address: "tz1dbfppLAAxXZNtf2SDps7rch3qfUznKSoK", + Name: "Coinhouse", + Logo: "https://services.tzkt.io/v1/avatars/tz1dbfppLAAxXZNtf2SDps7rch3qfUznKSoK", + FreeSpace: 91005.65305700002, + Fee: 0.08, + MinDelegation: 0.1, + OpenForDelegation: false, + EstimatedRoi: 0.056598, + ServiceHealth: "active", + }, + validator: blockatlas.StakeValidator{ + ID: "tz1dbfppLAAxXZNtf2SDps7rch3qfUznKSoK", + Status: false, + Info: blockatlas.StakeValidatorInfo{ + Name: "Coinhouse", + Image: "https://assets.trustwalletapp.com/blockchains/tezos/validators/assets/tz1dbfppLAAxXZNtf2SDps7rch3qfUznKSoK/logo.png", + Description: "The reliable and safe way to invest in cryptocurrencies", + Website: "https://www.coinhouse.com/", + }, + Details: blockatlas.StakingDetails{ + Reward: blockatlas.StakingReward{ + Annual: 5.66, + }, + MinimumAmount: "1", + Type: "delegate", + }, + }, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + if gotValidator := NormalizeStakeValidator(tt.baker, tt.av); !reflect.DeepEqual(gotValidator, tt.validator) { + t.Errorf("NormalizeStakeValidators() = %v, want %v", gotValidator, tt.validator) + } + }) + } +} diff --git a/platform/tezos/base.go b/platform/tezos/base.go new file mode 100644 index 000000000..b06820874 --- /dev/null +++ b/platform/tezos/base.go @@ -0,0 +1,27 @@ +package tezos + +import ( + "github.com/trustwallet/golibs/client" + "github.com/trustwallet/golibs/coin" + "github.com/trustwallet/golibs/network/middleware" +) + +type Platform struct { + client Client + rpcClient RpcClient + bakerClient BakerClient +} + +func Init(api, rpc, baker string) *Platform { + p := &Platform{ + client: Client{client.InitClient(api, middleware.SentryErrorHandler)}, + rpcClient: RpcClient{client.InitClient(rpc, middleware.SentryErrorHandler)}, + bakerClient: BakerClient{client.InitClient(baker, middleware.SentryErrorHandler)}, + } + p.client.SetTimeout(35) + return p +} + +func (p *Platform) Coin() coin.Coin { + return coin.Tezos() +} diff --git a/platform/tezos/block.go b/platform/tezos/block.go new file mode 100644 index 000000000..ea23c438c --- /dev/null +++ b/platform/tezos/block.go @@ -0,0 +1,148 @@ +package tezos + +import ( + "encoding/json" + "fmt" + + "github.com/trustwallet/golibs/coin" + "github.com/trustwallet/golibs/types" + + "github.com/itchyny/timefmt-go" +) + +func (p *Platform) CurrentBlockNumber() (int64, error) { + return p.rpcClient.GetBlockHead() +} + +func (p *Platform) GetBlockByNumber(num int64) (*types.Block, error) { + block, err := p.rpcClient.GetBlockByNumber(num) + if err != nil { + return nil, err + } + + return ProcessRpcBlock(block, &p.rpcClient) +} + +func ProcessRpcBlock(block RpcBlock, rpcClient IRpcClient) (*types.Block, error) { + txs := types.Txs{} + + for _, ops := range block.Operations { + for _, op := range ops { + for _, content := range op.Contents { + if tx, err := mapTransaction(content); err == nil { + if !(tx.Kind == TxTypeDelegation || tx.Kind == TxTypeTransaction) { + continue + } + + balance := tx.Amount + if len(balance) == 0 { + account, err := rpcClient.GetAccountBalanceAtBlock(tx.Source, block.Header.Level) + if err != nil { + return nil, err + } + balance = account.Balance + } + + normalized, err := NormalizeRpcTransaction(tx, block.Header, balance) + if err != nil { + return nil, err + } + normalized.ID = op.Hash + txs = append(txs, normalized) + } + } + } + } + + return &types.Block{Number: block.Header.Level, Txs: txs}, nil +} + +func NormalizeRpcTransaction(tx RpcTransaction, header RpcBlockHeader, balance string) (types.Tx, error) { + + var to string + var txType types.TransactionType + switch tx.Kind { + case TxTypeTransaction: + to = tx.Destination + txType = types.TxTransfer + case TxTypeDelegation: + to = tx.Delegate + txType = types.TxAnyAction + default: + return types.Tx{}, fmt.Errorf("not supported operation kind: %s", tx.Kind) + } + + date, err := timefmt.Parse(header.Timestamp, "%Y-%m-%dT%H:%M:%SZ") + if err != nil { + return types.Tx{}, err + } + + metadata, err := mapMetadat(tx, balance) + if err != nil { + return types.Tx{}, err + } + + status := types.StatusCompleted + if tx.Metadata.OperationResult.Status != TxStatusApplied { + status = types.StatusError + } + + return types.Tx{ + Coin: coin.Tezos().ID, + From: tx.Source, + To: to, + Fee: types.Amount(tx.Fee), + Date: date.Unix(), + Block: uint64(header.Level), + Status: status, + Type: txType, + Meta: metadata, + }, nil +} + +func mapMetadat(tx RpcTransaction, balance string) (interface{}, error) { + coin := coin.Tezos() + + switch tx.Kind { + case TxTypeTransaction: + return types.Transfer{ + Value: types.Amount(balance), + Symbol: coin.Symbol, + Decimals: coin.Decimals, + }, nil + case TxTypeDelegation: + var title types.KeyTitle + if len(tx.Delegate) == 0 { + title = types.AnyActionUndelegation + } else { + title = types.AnyActionDelegation + } + + return types.AnyAction{ + Coin: coin.ID, + Title: title, + Key: types.KeyStakeDelegate, + Name: coin.Name, + Symbol: coin.Symbol, + Decimals: coin.Decimals, + Value: types.Amount(balance), + }, nil + default: + return nil, fmt.Errorf("not supported metadata for kind: %s", tx.Kind) + } +} + +func mapTransaction(content interface{}) (RpcTransaction, error) { + bytes, err := json.Marshal(content) + if err != nil { + return RpcTransaction{}, err + } + + var tx RpcTransaction + err = json.Unmarshal(bytes, &tx) + if err != nil { + return RpcTransaction{}, err + } + + return tx, nil +} diff --git a/platform/tezos/block_test.go b/platform/tezos/block_test.go new file mode 100644 index 000000000..967b498cf --- /dev/null +++ b/platform/tezos/block_test.go @@ -0,0 +1,149 @@ +package tezos + +import ( + "fmt" + "reflect" + "testing" + + "github.com/trustwallet/golibs/mock" + "github.com/trustwallet/golibs/types" +) + +func TestProcessRpcBlock(t *testing.T) { + type args struct { + filename string + } + tests := []struct { + name string + args args + want *types.Block + wantErr bool + }{ + { + name: "Test normalize block 1292516", + args: args{ + filename: "rpc_block_1292516.json", + }, + want: &types.Block{ + Number: 1292516, + Txs: types.Txs{ + { + ID: "oo25sEdAT3YDb83WNdMSxRv4E6V2Rt6Jc8msgTio7R4FBnAiFmj", + Coin: 1729, + From: "tz1SiPXX4MYGNJNDsRc7n8hkvUqFzg8xqF9m", + To: "tz1LGrjCS3Jj3YZyRx3mHMmEXRJVQeVnoYYi", + Fee: "2940", + Date: 1610065014, + Block: 1292516, + Status: "completed", + Sequence: 0, + Type: "transfer", + Memo: "", + Meta: types.Transfer{ + Value: "5278500000", + Symbol: "XTZ", + Decimals: 6, + }, + }, + { + ID: "ooPykS2pw28FveDV3FojeXmThtuCATDJdn93iFjrRxFaEytait2", + Coin: 1729, + From: "tz1MKCMt9dQDccykzripUGk5439BwEWthqx5", + To: "tz1S1Aew75hMrPUymqenKfHo8FspppXKpW7h", + Fee: "9008", + Date: 1610065014, + Block: 1292516, + Status: "completed", + Sequence: 0, + Type: "any_action", + Memo: "", + Meta: types.AnyAction{ + Coin: 1729, + Title: "Delegation", + Key: "stake_delegate", + Name: "Tezos", + Symbol: "XTZ", + Decimals: 6, + Value: "163965", + }, + }, + { + ID: "ooFFpMbVAJMkxNYFqxERDumptXS2kSEJQqTwoovVPinayJehB8f", + Coin: 1729, + From: "tz1YbzpfsfRtSiYJWcvpWEDHPNe3kkqEvY56", + To: "tz1L1c5YoQMaciYGB8gpzWoHbscBmtsTsknF", + Fee: "30000", + Date: 1610065014, + Block: 1292516, + Status: "completed", + Sequence: 0, + Type: "transfer", + Memo: "", + Meta: types.Transfer{ + Value: "290691675", + Symbol: "XTZ", + Decimals: 6, + }, + }, + { + ID: "opLbuEsuf9NmzgikvAG4sVaS7NJedzXHcz53iQPon6QurLP8Ztv", + Coin: 1729, + From: "tz1XbmS2Z3ya36JDqo1P1y3VU8t4RU2LJW6J", + To: "", + Fee: "2500", + Date: 1610065014, + Block: 1292516, + Status: "completed", + Sequence: 0, + Type: "any_action", + Memo: "", + Meta: types.AnyAction{ + Coin: 1729, + Title: "Undelegation", + Key: "stake_delegate", + Name: "Tezos", + Symbol: "XTZ", + Decimals: 6, + Value: "163965", + }, + }, + { + ID: "opNgBb87Cnpjr29Uc4CRuXpWgTfhPx2h76S5txrPJELa5XYiidZ", + Coin: 1729, + From: "tz1c5wM9826YcUNQ8a17z9eUYpKQ3oW3zfmJ", + To: "KT19kgnqC5VWoxktLRdRUERbyUPku9YioE8W", + Fee: "824", + Date: 1610065014, + Block: 1292516, + Status: "completed", + Sequence: 0, + Type: "transfer", + Memo: "", + Meta: types.Transfer{ + Value: "0", + Symbol: "XTZ", + Decimals: 6, + }, + }, + }, + }, + wantErr: false, + }, + } + for _, tt := range tests { + var block RpcBlock + _ = mock.JsonModelFromFilePath("mocks/"+tt.args.filename, &block) + rpcClient := &RpcClientMock{Balance: "163965"} + t.Run(tt.name, func(t *testing.T) { + got, err := ProcessRpcBlock(block, rpcClient) + fmt.Println(got) + if (err != nil) != tt.wantErr { + t.Errorf("ProcessRpcBlock() error = %v, wantErr %v", err, tt.wantErr) + return + } + if !reflect.DeepEqual(got, tt.want) { + t.Errorf("ProcessRpcBlock() = %v, \nwant %v", got, tt.want) + } + }) + } +} diff --git a/platform/tezos/client.go b/platform/tezos/client.go index c9b0add49..9d6eedba9 100644 --- a/platform/tezos/client.go +++ b/platform/tezos/client.go @@ -3,36 +3,21 @@ package tezos import ( "fmt" "net/url" + "strings" - "github.com/trustwallet/blockatlas/pkg/blockatlas" + "github.com/trustwallet/golibs/client" ) type Client struct { - blockatlas.Request + client.Request } -func (c *Client) GetTxsOfAddress(address string) ([]Tx, error) { - var account Op +func (c *Client) GetTxsOfAddress(address string, txType []string) (txs ExplorerAccount, err error) { path := fmt.Sprintf("account/%s/op", address) - err := c.Get(&account, path, url.Values{"limit": {"1000"}, "offset": {"0"}}) - return account.Txs, err -} - -func (c *Client) GetCurrentBlock() (int64, error) { - var head Head - err := c.Get(&head, "block/head", url.Values{"limit": {"1000"}, "offset": {"0"}}) - return head.Height, err -} - -func (c *Client) GetBlockByNumber(num int64) ([]Tx, error) { - var block Op - path := fmt.Sprintf("block/%d/op", num) - err := c.Get(&block, path, url.Values{"limit": {"1000"}, "offset": {"0"}}) - return block.Txs, err -} - -func (c *Client) GetAccount(address string) (result Account, err error) { - path := fmt.Sprintf("account/%s", address) - - return result, c.Get(&result, path, nil) + err = c.Get(&txs, path, url.Values{ + "order": {"desc"}, + "type": {strings.Join(txType, ",")}, + "limit": {"25"}, + }) + return } diff --git a/platform/tezos/mocks/account.json b/platform/tezos/mocks/account.json new file mode 100644 index 000000000..ef26566d2 --- /dev/null +++ b/platform/tezos/mocks/account.json @@ -0,0 +1,4 @@ +{ + "delegate": "tz2FCNBrERXtaTtNX6iimR1UJ5JSDxvdHM93", + "balance": "91237897" +} diff --git a/platform/tezos/mocks/delegation_response.json b/platform/tezos/mocks/delegation_response.json new file mode 100644 index 000000000..5cd933ea2 --- /dev/null +++ b/platform/tezos/mocks/delegation_response.json @@ -0,0 +1,483 @@ +{ + "balance": "19924380870", + "frozen_balance": "16854253212", + "frozen_balance_by_cycle": [ + { + "cycle": 240, + "deposit": "3072000000", + "fees": "15676", + "rewards": "90000000" + }, + { + "cycle": 241, + "deposit": "3328000000", + "fees": "621522", + "rewards": "95000000" + }, + { + "cycle": 242, + "deposit": "3648000000", + "fees": "4360", + "rewards": "101250000" + }, + { + "cycle": 243, + "deposit": "3392000000", + "fees": "28321", + "rewards": "125833333" + }, + { + "cycle": 244, + "deposit": "2816000000", + "fees": "0", + "rewards": "55000000" + }, + { "cycle": 245, "deposit": "128000000", "fees": "0", "rewards": "2500000" } + ], + "staking_balance": "163002104470", + "delegated_contracts": [ + "tz1YGsmfUfed8fmG4QLhGB1Y3gCMX44t1JTc", + "tz1WnfCXDniXhHzbXEPTQ1JSoyb7EzotYJs3", + "tz1RqtpgLw3uedpWaDVC5WAdvNfiUnsY7ZC5", + "tz1eLjmx4j7QLX2RabyS8Pf3sSe1U6H2UZji", + "tz1TYhMcdYah6QJWQbL853x4Rn6fSvtHhqDf", + "tz1XcmqCntUEzrpV6xcvw449Ro83KU5W3vv6", + "tz1QfbGBmr5dvha6agPcmsvnaz2EfcctW4ZJ", + "tz1bN4kotiEE7dAEsTGWpNTF2DnjJw9NNSoD", + "tz1hoj3Lw71qgsQf5a7cdhdU9crEH3mAAaNn", + "tz1SfvgWvSBxNsgta6UCmytMTPHzMsmjMB54", + "tz1ZsKynrRs8KNe3ao1ZMaKk6he6VUWtjcFU", + "tz1ZEKCiu7QspFVZL1svyr9vvir7tTm5CEdW", + "tz1gScW33c2EjpusjaPCm7r82QVZsALnNsXk", + "tz1TDnm46TxwLRbihJf2yTQLJGJYe6k7N3Kw", + "tz1NQCizMgAvmjhMJEidnTNPFEPHxA6XLY65", + "tz1dp6YqFkjoDZqrceSEC7cKFDEWbynyv7UV", + "tz1RctGdDVhQFoqL99bXJvYTwQNJWEL2Rx6Y", + "tz1hqd37vwxZcNeiNMrz6kpujusPRxcaFyhv", + "tz1crpuStZ66tv89kZMQbiGHk2C2RyD87o2S", + "tz1a45AtW3gs964AxC7X2sShAj9wsBGQjsWQ", + "tz1Xi1AtnoAv74PAQFDUY67TEjww1J2e6FaQ", + "tz1XqSWe3M9eEd2mueqEWmgKZLoYVJCRC92B", + "tz1Y5JZMUEsuX9oicG9AqXG8XWPHmKeWFrb8", + "tz1LVtuGkbCgEZsZhbzu1sonVg5xZyrrWqGD", + "tz1cfqx7H6qsXgsLTHFn7hWjdkU1SjpzpFyx", + "tz1SFMBqUwq6JJP1mQZfp8ae4GsfGSM8812Y", + "tz1LeU73Tm2eBcUV1prcHLjK1Pb7KgC8rPTu", + "tz1dMvyK57FBfUqzSenaWSoY1Rng77KxwTT8", + "tz1S382giorXLVdzw79LVcMj5MLJkYK8Ex8d", + "tz1TAscJC43xhPBNBESuNupw3FhLsfE4Ghxd", + "tz1eACKAsqr5faLgsE3ACdHeejrdM4igY2qj", + "tz1Ln7pr3Bf7Yxmnf57iEkgEUvo7PrMh3HJh", + "tz1XC1DbtQjUu2udaeVbSa3G2rrU9dJKmN6V", + "tz1PCa2Drre9MaJ5pcKpQHh8A75LDEYYA4rq", + "tz1S7SacT3Pe8EfDfMEnR7fdvDamZDiwVMoQ", + "tz1U6V2mWc6zd31yFXME5Xnoifo3PeHQhuJA", + "tz1V54Uhpp2i8pUVEFNcmhrkJqfDZhqb5F5C", + "tz1aTmVHkGBChKHfAqdJjjadkP4rz4MDjbJS", + "tz1dpijoKv5dCFT1BvtEmxy4YLcCsAc9ZGeh", + "tz1Mmv9StLbPu3jYVBDoKgNJTb3FD5wuA2vA", + "tz1PkJZs2Eb3ouLd9cTf4wSQ3n9aMz7YLGNR", + "tz1YpTsHeubr7WQaKu3Yfs3m1gKw5QP1MbdM", + "tz1ZP1EgEkNwB1nYA8bQdJ7YcttsbJuJCZLe", + "tz1Wh7XciNS6oUTW14bQ5PD7pQjqae2tNA8S", + "tz1bgRKKwMc4s8fxTDJrauCx3NoGLSRJ5B49", + "tz1URZ8CPFhzLz3UjQD9zUjTZY38XwGTCiKn", + "tz1KrUvC8nUGRnk4RXtqAFLsJj4cbtXjR5Wg", + "tz1f8eDjy48LDcWrrNTF3wwkGEjyXqDcoMro", + "tz1RStdCWJXpVVvYvAB5VZXgzrxPGoHpEhjK", + "tz1LWjsR3LiBDPyvuf7S1qJxaVKNZV9TSbaW", + "KT1DMboG5KtaPbMTaA2PeV8FqRcqbt9adzQE", + "tz1iq1eA7i2ogVCQ52g3zeSEqCrFTSVxhE2c", + "tz1Y9tfG6Gs5oFdLtcE9obQaxbwZyK8CTn6e", + "tz1XotDGePt679YtqexwfFvE9AutjdkvemH2", + "tz1LG4KEFVjp1MxSCXQWUSyoZpE4Nq3gbxHy", + "tz1TMRCpNgKAdp8GH3jXAVR3MuLMMPZBzevi", + "tz1hZY5ix3GTTUMAsv6anwD2817RspnnEb81", + "tz1gzPsf717fNkpFVQYuNAKBBQngqGx6CFJz", + "tz1TTxhXmRRdMAKdF7ykdyybgg1baD686JWs", + "tz1dPnbKhnmJo3J7S2rokMSmTtaWNGDeQuYa", + "tz1irRBG7qLAeo6URDn4bnUb9NByoLQUHN7K", + "tz1d9d9brjpFRrErRF8tT5StDve7svAQueTB", + "tz1SBRVFKJCaDnPRzHrn1Pc7NG61tqNY1HpM", + "tz1h4Ag9NixUomVaFo8MatDpEL84JEEs9oFx", + "tz1NVzxdVF2gy276bGAt3TFJHWUMtnS5BZrN", + "tz1Ytb5C7xDvWArsif3cEfWC7NpEiWkGVcW4", + "tz1WQ4w3WQUzReKAehyDKkVQjiVNJLuWoCrx", + "tz1StPqh4Jybs5yE4adLLBvrirwm7cuoEMC3", + "tz1f5yKJQwdEx1XbqUreT5E5MG2ddoP9sxG6", + "tz1hVxLkK7fDPCsgRytKyqSYoRGdPYkRAHK4", + "tz1Qs7gcTNMN759qBUukQmfA6cUeWzqtU7sq", + "tz1SsR67T1ykErBtVinVMCWhvwrUWBMkzxQu", + "tz1QD8a5kJBGHArP1DHECBzj4gbRPZuBGGL9", + "tz1inQ6S764Btu5HgHRGMg72Tee5UjQtri7y", + "tz1asvE47tkUoYPrb6HrVzkHVhfx3roZA56f", + "tz1ZqdsHNTeYLCw3Etw1BwMTRbU3Ji42HT4N", + "tz1Zd43K6xBnpddV2pv2PcbKPBXpYo6qAAxc", + "tz1YbEBGE1KQXAMLiQEnXVKLoNKVAmtQxJ2y", + "tz1QFhih66LJDFpm9T6a2gWdg7551k65C9ke", + "tz1T4RpJjC671WadSwA145zMZNSCmvcwGL5R", + "tz1Pibvp7EttcPX56CTvmxPsSLqwsDhd2fC1", + "tz1cFu4B4afDVkcojpv43h7wbv8169VA7mSU", + "tz1ixKgGdRoSzsp57qe5WXHLbeu2GRpXYmGW", + "KT1M6T4ft8UXXwFxa6QxRU3T1JDEKQBRK8Li", + "tz1csRh2tzRZw8dcuAm1LMCMUQBEq7N3EmY7", + "tz1gaz2QgwUTyZypSmMx72oUrraD1hZ4CWEB", + "tz1TpW2WB8Y9mYsDp2Lx4EoKcocyFWApScFy", + "tz1f9Hg7KF6xKLabL4UNLPdtJeohQbuJrVa2", + "tz1Q8Q7sT3r7pdGGyYEtX7v6jTxCwJ3bSdtJ", + "tz1iLAxh9M6xcaNMVhb5hGxZb9qvzBVwo5UT", + "tz1XXHuK4tMKJZBQDeDFCpzWdH4g26Q42gFW", + "tz1VvZYohqJvKzTKsRYcfuQuak6LYFao9hkD", + "KT1E6sM9KBpYWoK7ZxoxrcAzbngVhn9ZxkPw", + "tz1TuBtRJ5bGa7KRyhiZcoFiZTHXnuq4wz4X", + "tz1fQRtYbQqenvb171siK8KqScBZKHrsqKW4", + "tz1dn9tn4UqhwLiAShcaq63oiwzQ7X8aySTz", + "tz1Uvknh1VNhYYQbhFaP1rDU1GNtFpGWG98c", + "tz1ZosT8MD6tibQDYLbhfTm5Z9oQPL2f7LwP", + "tz1Yk9Mz6hSBrq7qWLUZKDqcuwyu19i7FS4Q", + "tz1i5wEnEp1Wf4WiL7dFxiTj81VSiDprGWyZ", + "tz1fQv9BGCjZC29DFPSmqNxkjFx2tLzRy9Kn", + "tz1M7TVpisBJfPkkjrfsnK7CZyRbVb2Vdooa", + "tz1TJ6ZPJVrAFZUNhReL9FnhzXXd86Hmtk3d", + "tz1hbeGj3krpLMdKMumeukTatZcDCG9RGnyT", + "tz1Xm41xUyqvV5caWkpx1ym2p8uTvJPKZMdw", + "tz1XZEpd7EnfzmjYKfRY2zrfEd4trBJWBybN", + "tz1QZAQoaXbLXW3WjYB8os5xjwe4mB62KjPi", + "tz1gd8XNS2Me4oRXq9XTkTX9kYumRM4Y6rXf", + "tz1aK1rKDWDSa31kB1SwP1tD3BvPTNQWXwwK", + "tz1Ui8BtvQpJpF155ppgMZSEpCKEDuLXNMX4", + "tz1ioGHFTom3ojBbcfgEb8mt1f1ceobVEcEq", + "tz1LxreKnQEFW2QB3dZDX1bNThcW8vmem4E8", + "tz1gu2wRjBfY7jpMokMDZGNZVBE5n98J65g4", + "tz1dfAqA9rhx1tFuu86FdhBwKMwaisVe1dEg", + "tz1ND2YvsV6mnWSUHA2bd1oUcTmshMbxYV1M", + "tz1aSBidSCjNqLcEk8BYvA43EenEZNtsvkuW", + "tz1e8Fk5whgxrPzTZAMiW2FbatdaABNt5hpX", + "tz1QeU3SH1pGYTWmKfZKovH2RiiqSnd3zFPo", + "tz1UkUgyb3Au9GeQx6YbcJJaafNDpgGRLDeV", + "tz1WPnZxticG6xGpHNhaV9kvU1PfgYiMXp7A", + "tz1LKVTXzQtDwQWXJpbe88Q2U5TceBrEJf5i", + "tz1X4tzFR73YRBBora46aevdGn3aqz5UzdrJ", + "tz1PouWF6hyoHmMYAGuwDBAXJKL4Z8yixEwq", + "tz1ib38e3VCZgvRxc2Gj6KtAgAv9FkWx3xt1", + "tz1Ndenm8uaonPs8oo7iqXQ6RRho6cG8GBd1", + "tz1WRAfQ4c98Lxz5k2j5QFwcaw31Z6zSuiza", + "tz1W7G8pgorMWDcWSsTpQLuQoKqVPk6MNTV5", + "tz1NY7t1otGmLV9VuhdApzsqwwqGEK6iLeyH", + "tz1MA5ywEYaPNzJWeLWBDfvAfZmryeFdrexy", + "tz1Rzq5gz824wG4gt4MPX13oKojnY3cJVTAB", + "KT1MmHkxDKy16ETe6CKY6Hs3SXGzAeMKHcmy", + "tz1aYL7YjKn8zFV8kCNMg5qjJTXQ5sPhnVQU", + "tz1Mqazkg2SgqB4ibXxpFudp2HVYEZ2s3t59", + "tz1X1o4zSNrnTDouETFM9AXQzamWcUkEj59n", + "tz1Qe9fqiQnizh5gzuURT3J24MQxd7A9qxTt", + "tz1UWyf2N1yCiEkfyCKdyMitKMAaUWACWpro", + "tz1LYCQsxVf2RdDEWcG5N1zY72XskyXevciC", + "tz1XD2yz8UQYGJ6BRb7h7wZp854fQXC9DQFm", + "tz1iiT4XbLvffTJbGhuiCg3ofaaNdLX2thSu", + "tz1YrCk1KZu9wwn9vCUYuZp8medpViizrZwK", + "tz1QPmsd6BS9CUAugcNGJP9me8V6qtEEYrV8", + "tz1adgGe3ghX6DH7kh1BAasaCGrf6ermGY53", + "tz1M7PNxBBCUx14jfdv5ZERWZWBhPJVjKHJD", + "tz1VcWpMRqd5xxoauw1urcnPQ2kZZxhbqgcv", + "tz1Y2nVkzQQmdVnDcuo6VDAgnBufoUHLXR3r", + "tz1bGvZzpjJZHzFJGQYWPVg4JQ7arsmX3CBW", + "tz1ZGn1qwM2Bg65xqNx37XB4ptSQnRh7LjED", + "tz1Pku546auwaUBm4Wht1zwZtfxg7ic81p6Z", + "tz1R5yUME8wSYtyZNpfWdoPZcQgNLtaUUvef", + "tz1b5HuS35FKB7qWvFuALXX6ZFspEWWJVjxP", + "tz1ihSZ12F2y6H778E6L4ciWzvX7rfPwmGQd", + "tz1T4yyuchdPqtZSbtsaBS3GLqLeUg8dJmb4", + "tz1LnRcJUtFBKcht4n2jo2PAJF1ufwAVa1nL", + "tz1iwdFtYWaicwc1dfJA6YmN7eRCX1RkaGuz", + "tz1aD3HxUFLSr6tmYuP7HKvx7t8WgKTY5pYs", + "tz1XJMJ7XjbHkkFkAWw9C8ocjfmkmTBXo5TG", + "tz1PfUUZ1YTRqP7qkjsSR1X7TCeYbRpnCfaj", + "tz1aLVDxteKdmBRaRMcQPQaEL2ExbDwQA7fP", + "tz1QoFWg86UsKYjtskkmBkz58mftgHLrvrci", + "tz1ZWbmnG1sb4KCkrjii1FoiJ1RcJEg7Tf5V", + "tz1VGrdEoiWdSpUFGZAbX6hxuQAJjEXqXvwW", + "tz1Q8gvcfGC74oaWx2Gb4TipRLb7aEfsWyAG", + "tz1QVsVf5VQfihDiBED7ZMn5Ai637z9GwfpB", + "tz1Nqf8Do6NFXncMzGhYasnif7iTJ8UgGHTn", + "tz1KotnQg3tbzTLxYJc9XW3dagmYjAMHzYV7", + "tz1QzMbAcThy4EX8ENvHZm2BVxQMmCY7wsUw", + "tz1YKTfdWtb6gzr26mRsLsGCNK8TBBVEHC1E", + "tz1egRyJLzTmC4aMUCRZLKEhtYd2MyD9f8RP", + "tz1NJFR2PLvbijMGGZ9LnW88CZxo1SSFxsxR", + "tz1fU6Zxx14MCEqfkSwDWRMqFmYmhygSJrcK", + "tz1aN9Gp5FXc7CQoR8MGSf3VUFohe6f9rFJ6", + "tz1KuQ5yDerio8tW294zHsYofWc8TQ3xnbaJ", + "tz1Yi1qojMoS2JhESiE4vAeo7dWUqQbnEQeL", + "tz1RxecATFfopVUvE9HS45rL6rgzGVg4cFG2", + "tz1hXRjun9ou7YN7sFKJJsgHPkGpdXzamzKY", + "tz1dWg4SYTFiYfPrDGBNCaNZunjCi9CyK8PU", + "tz1N7CRoQTrTjM6BG6PK4XfwnkEERKj1GgTt", + "tz1T8RkwAcBBwc9uCovercc6Qr326ezqtoij", + "tz1UkDYB4RgqBcRL7yYSikc8r6fpAeRVP9c4", + "tz1WLjJEwxQK3hbnZWkmEzGzQ988MdQVq1iB", + "tz1bLijXE1D8XxHjzK9wBK2udxNqXbHkMzFg", + "tz1VMWRzCPN9E7NLBfSHxFVzjZ2vxNPKRXCT", + "tz1eUfNmzeZWccsAV2ZzCovjMR4HSDH6eiiq", + "tz1VASv4WieYkgmUCeh2j5ftEw72NkkuCDje", + "tz1fZH9g6npSMZgSGzcaqegnuftJ1AcNEQ6F", + "tz1QGzvcCDezxV439D5cjRaTFXC8Y2bF6qTw", + "tz1PxPHvFdkGY7XkyuV2eUDYH3wxuerKiYiC", + "tz1YJUngcjMCStvP7MABMVBPyFkU3BupNymQ", + "tz1NoKTHMvzPooEbyeMHQBaia7Ekf8aTrv8g", + "tz1aQHYPPW8dq7ucWUccV74cEyzt6AiMjrfj", + "tz1dpCdky48ELUbjrzY89Uy4fTukmmJdr9tJ", + "tz1SQcKWYJCatD4jVFRNtR8UVBmtZT5VAM3x", + "tz1a6rVyLh6z7akANZsBuxSb2g9gNthXuFM1", + "tz1eNv53m15QQhKYyREahAx6LCK9YYczEUPe", + "tz1Z5Lgu8CDhbWNdyEzXkCC2TrkHrSDVwMWp", + "tz1Prq1iQE4xMn3JqwK6rMaJXoGjS9sfWM3L", + "tz1hxtCEcD7idQJEDiJEq37vBkoRcwF6KC2X", + "tz1ZTmAakWGa9fefwoaomG7wFPQhPXepyxdT", + "tz1dXKPAsBG4DG6oKki84UVTBYw5doTGbu95", + "tz1ZGCukFkDD5ns2aA8HuKGrE68DVmbhLvvs", + "tz1cvSwVukfoTNS16f1Y12mHYqsrnCK2z7ZM", + "tz1PV34FXaBY5mqLLyjG8TdzNCo5SUz51d1a", + "tz1KxhXker6qezyPyzpLcTVXxAadWuaRMB8Y", + "tz1cZmvFJgdJfUoBF2USegkoEq653qx3KgxB", + "tz1M8NxQupHMQ5uW1k25wCYYdxMWojKfiVNa", + "tz1eqnkA7YZS5uVhH42WfZkwkECTxCkUqKJG", + "tz1Z2ERSqjQjTtGdv6XZJ9ZoffxAQVCLHrLM", + "tz1iXW4XFVvg1QS6bGhuPo1VCGT6WTgEaoA5", + "tz1VMDp7io6vgXo8jsLcgbsUB6Vc9mdAw69x", + "tz1edVs2PENzexqcwWv22pwu4HfcgXbKcV4R", + "tz1LSUEVASTpic9FawaAMtZgR39LSYmPYcLM", + "tz1REnhE8TEzXdcWSRrzBYPWuveyY61Pe79R", + "tz1TrDkd3wtJcYnXZiB1kdoHtDJ61eP4QMA2", + "tz1fKL8yNKW98UGCE5duxSyM11QqzFBvQW36", + "tz1dPXJpxXqqLeoCs3X4GfribJKfyFVH1Jta", + "tz1NhzBdBcokEFPuzfdMrjihST3WU1F7uTGe", + "tz1crd1XnXNsCfgXVaHzYpsAe6XBEuhcYRF5", + "tz1N7T11AEwWAoqE6pYyU8ZYcdfBnMyPmr4X", + "tz1f5V7ijjQ8WBN5UUAnQvGcdXg7cAPxGCUu", + "KT1Vhqza4MMuELxENaiBYc6UB7syRpaZ12LF", + "tz1g81GLa2GeT6AgQ3CxtYBdwD3kwMLR1Hpt", + "tz1ifm8828dvFuS8wbwqCGhyoGKoXMAkpqbz", + "tz1ZfX2axfXid7Bnt2BiSv6QonweVFuuaAhM", + "tz1aJtqVgev1Jrc4utBfgZDj83ZFLjJKiZJu", + "tz1TyyjZ9adDW6rranHNXQVqEMp4Zb2rhegW", + "tz1iZS4BRLqyLbWbyyKt3e9gvAa6MJnDM2qj", + "tz1XM3wst4ioyMBHdkCVMdo3nfqYzb6zqbpn", + "tz1g54U8WwX4h7sVAfwNAMfmN191E1nYD42V", + "tz1ifvWnxwudcmQptnvbb5aRyDyWLLdUJmv3", + "tz1RDNwx22yxJ5x24ZxsrqFtA4bXY4gtwm4Q", + "tz1YvE23HCvxMNPqWsgQyYMw8Rm2UeMnPCMs", + "tz1dYeNiX8ayqUAc1SzDnr1iy259L5Djf1Rg", + "tz1Xrk1gZ6UGs2zr1RBCgexckHpS8CjgtdX2", + "tz1cp2AxYptGFABzTbnEWo62Rhixc5HKpjFu", + "tz1SCWJXrAiGQmoBPMLGifjrbTi7HnKgEDdu", + "tz1fxbW6z9xts7LnbXqvcdoqwp13rBavG6hP", + "tz1imF1LwtUxRojZSK6povb8mePfxQyk7UiF", + "tz1faBfWwvmovgkngNv2v4bW313jrepqdjAW", + "tz1XPjXcjWvqiNC4erXakoCiMY9Xx3omBRvZ", + "tz1iuPqyGQepHBWiVgTTdndbpnfkqckQb94n", + "tz1Kuu9FQu6L4bkNwLt39BGWAMSfDefWMCR7", + "tz1eEea8fmMweaMGbtUSa3AVWE8pgC7WM5Ym", + "tz1ceedKUzespKvmnaZApaXXcZTDJdVjenBa", + "tz1QbVugeaLaXJXqgD9s1gAYMwAJkW9rTgn3", + "tz1NqVdJps7ppiy5EbahVuAmDw1iKjhHsXG9", + "tz1UJ6u1bGV182edaXg5uPdbJq1qHR6xdJSZ", + "tz1fQiLH4SyuXumvKejsnQZgdnJ33J3kCqk6", + "tz1SBTErzCAU6o85X4xTdRzzCHQ79JkmGgRx", + "KT1UXH1LJ33HSaEvzW1Pk92tLbGEdsqcN93q", + "tz1iRk79QEsJ6Lj5F7pGaTAiQKTYw9RSUqzU", + "tz1ZKvoYkCB8otTqdWp1Mm3WvemXMQCSpsgT", + "tz1R6esD6XuzJ7hrC3ngrWdafh9FFJ9NV3oT", + "tz1bsVgtu9zggDAMvHWPWZET1wMEMTfzDTL1", + "tz1ivnzrqG3bpXuDchcS5KCpQMvEvB14Wxw2", + "tz1MaKRHHCaUqfaY8SgiHBzNNgvUF8EiB9RE", + "tz1LN4xvgHB9dqiuc9fqco1ZEwDueXDgDw8T", + "tz1i55Li1zdF52PXSKGavRjmE6pCpSgmA5To", + "tz1V9wpVevfkEfNe2JnsBGuzQKJfpGzvs6vB", + "tz1dGRzqFXkur4d4HEr5q5ULSTpxtT8a8y3t", + "tz1QVCn1BYxpeWSVsu6ZvoSm1vMwFs3U49ZV", + "tz1Ltc6HqhjcMEXGnW8wSaqEJfi4kse77oHS", + "tz1LzvmQDVt7iTDevkAu6TZAd6LkhYaw5i8W", + "tz1cGaQgUitUa9TYfDdgAKLY5zyh5GUVHPzs", + "tz1YMFNXmBU81a3hkDAf5w6oADRPuieefX4i", + "tz1QMMwLkiHSRxXMP2LUuLfvw4HCq2c5JfMk", + "tz1UYdeecJh8w5EoraCHT1TgKA1bL4jGaDWJ", + "tz1Lor69x8DPG9AJ5xSthwVqQ8XtqLvnSofa", + "tz1NUHJF4PcYq1QbN3sW7RX76b81r96hKKoz", + "tz1YEhhVsJTQkxcgD24tQEjfhBKETkdBip9H", + "tz1SVDQFfuBiQV8qbhjw5YGxxVWFkPvEmodP", + "tz1hjZuttQSUcSbkg47i1izUMykXCcdqq1zx", + "tz1fF85RhHDzszowsTj9KGwcFwfDjfWqX7UM", + "tz1LsXSAtqk2UaAi5UqPgnxiMSx5aNarTiZt", + "tz1ZMLcTZuhe1FrCtbbTyiEp4r7PBbQZ52HQ", + "tz1dLBPNqqKTEqWEMqyzh64jdTVMoaZij9sm", + "tz1VvsF4iSFq7KVV4YFznaN7ZQYSNqcrQbyS", + "tz1ZbdR5gF7VrGT81o2Ny4c9UVfCc7gzB8En", + "tz1gC8bBi8dJKzEn97fvc1cp31qBctXUHfPv", + "tz1WsYZt814Mg9brcP2scWD9CcCywj8NnRBQ", + "tz1fv4smnQUbKXARxBKkUh5tQtADqFMKKQDJ", + "tz1i3UYmtRdoDwcHFSRV2e3Tk47fchbwUMwT", + "tz1XGjuyXeeCK3EuHYnSVMqqeJj41aNDzGDG", + "tz1SgfF5YhWA7Y1L5kEwv5cgRTbLm998fJC5", + "tz1SoikxCAviVXxs3pdc8UArM6unU1mffMHV", + "tz1NnvH3F8SfaB39KvD7Wyep1ytDCXjPoCJ4", + "tz1VCjP2P3sBtCLQXKkDG6xRyz1o6Sh4cngZ", + "tz1YqLMuu5gqPcWZjGAaCY4cHgKFW1bUYeKR", + "tz1Nev8pcv8qZDK2q2Ps4isYMtcJpXWaGcUa", + "tz1RrEVWkWxxQY5uLuBbVU2WR9W3EFtU8iKf", + "tz1dfc5ei2TSihvEpFnyTTb9nuQbDWvEEEvN", + "tz1iGL8vPK2DNvYf67FrqdsTDyXCtpBMbgkC", + "tz1YXFAkEgAbgy5Mrsr2DnPhbuq2WnBhnDCa", + "tz1SJLqfbEyGJ21wfhMJvxgu2EjQ346o22mZ", + "tz1NwPTbuzs8s6mrGEJisP9CaXC458jjzzPF", + "tz1VGdetQxEuDWGQYE5BDREBvpzQY9javJyp", + "tz1awa88jNvcsmbBHXbGLk6fcqEycYZecic8", + "tz1dJKVHdNapMkayYcmHFVYutVXXHx5mTKri", + "tz1NneEsPdJRrDgse4TzLpRqvbksphYBXBMY", + "tz1gtGWmzyGZTz7D1BheVa4ooocxjwamba4R", + "tz1VXvbmwHskMRHcbcCLi6bihPt5KNtMgVeX", + "tz1T5MBz5WXy4mCrdVHy19zrFDa3uu5vuKG3", + "tz1TH3yto3yViq21nG84zmcTmuvRfVgfMRGf", + "tz1eJ7HaiQu85aNYwXnYByr4voQJe65wWTzv", + "tz1Vz1XhyYidM2zjSZoN2H5Ku3a4ctHVvGm7", + "tz1MVTqQAvvurF7Abs4vBmPUoSFtqPuXacmv", + "tz1hFFvzPH5DxuHA4ivQvrtEX92FGntGMRBi", + "tz1fmLPPwGznV4R6vFyW8sswUZYwcYLJeYAp", + "tz1N6Xh2h2K4unzgXv1XitABtA3eB26wDAUD", + "tz1iGEPSzjQN8PzT5FrGUzhRQnx59hVzeXn8", + "KT1Prk9xaXSd7uz4NzWQfZ8bWyY4csVvox5w", + "tz1et74jh4CLmpfmvYCG5398iygUkdL962fy", + "KT1PHojJp48asdfyvT9kMmnsEzB6cdUGpwFf", + "tz1fNt7sqTh21sekaMdsPTQvjYsC1SduMagV", + "tz1idn8cD2bFaftnFzvJ2gik9wGuWKDGmhsP", + "tz1Qz93toMBURzKyjbECFe8YKAwARu8t1C3C", + "KT1FBMtK4T7K5UC3nuc8YRG3wnQK3oaCH9Uo", + "tz1Ly6UMQm3NCmDQ2udu6WvPCJGqauhR9FWk", + "tz1epXpov9hcoRUaGVJ222t67udd3vV6jn35", + "tz1ZVR7QMhJWCKEhp4SdynXNnikdxTs5XxQT", + "KT1KRdu1hDLtDRufZqNMU2z42uKrXhmsmzJd", + "tz1ivo3rkUgJQ1Nbe4VEhNetCREAvbGZwi25", + "tz1UBQvZkovRpZwML86qTpL59gedS1FeWpRw", + "tz1d9CzUNaFMmsnUZTihrz6wDA8ZP3GvAKbj", + "tz1MZHrRbLDMczK4xtJP1BrRdoYnoMq6c3P7", + "tz1Rw3VKh9yAWLWaQMhzWoRRQoEouGTCzgV7", + "tz1iABqHT2J4XKEnHp8JYJNiXEJtFg8r9RbC", + "tz1fxdeeUWT6YG5aSQcaJVU5sbeFCQYKCvPX", + "tz1dNA8PnEfRgV4ZqrX3i43Lh7Rxpx9bwy78", + "tz1MEEdk9w54LTcHz1oSkwAY9UUSepg8WrFG", + "tz1Zgo1nWvejNmjhzqEYPoRc57JhWrKhetAH", + "tz1gk9E28K1b6xQNw2wFLG9WERwzKDDwVNT9", + "tz1ftbRcC92jdKCTj91Qor9EkoJUcwqFFvH4", + "tz1hjorZSyLWMvupoBgWZsKbDFyca4B6wK36", + "tz1YNktyxUEzwpKq6QaWafka5CeKokJAEqi5", + "tz1KiuNcJNJ451967gXPwSDLvQmXryMvgTmL", + "tz1XDqZ4z2d5sRLkywYRwEMBQH5hHzaCaRre", + "tz1aQNn7eMC7kP1EyQetvocKS4TXmzEd5Gaw", + "tz1fnBJmAxoJbfAaMcCar3Aa8MFFH69dKYJv", + "tz1cZwxsasN1KorL8hYJPBy7gaBdNtsbjNvm", + "tz1b5qJrAgViKFPM5BdLeVasrxest7EWnf5z", + "tz1h87YTFnTCHKHTUEG2BxWq7DSRf861U8e6", + "tz1LPjWu1P11x1aizsD9wmqzey7ob66vvymg", + "tz1NBmAeLwsXxLcvAwJXM4nS199qkFcH4313", + "tz1cPL3YSMFiRC2yiMvSr7RLPVg5H5XhNvgW", + "tz1ZzGYssgyWGEZYVgCpMiYA1eBMWxRVrrqP", + "tz1ZgEQPeGYXeMLePL5sgR94RrRxwbsyK85z", + "tz1NcRjeevWE6E5B1pBsDexSB3cPJDTpQ9UL", + "tz1dBhoxSAU58V43Kvb7hG71iRxsfzmj7Z2y", + "tz1UwEDdQfpdcnYtfU7BRqXGPXbeaJmXk63c", + "tz1cpiGQS4rjtqnbndrbRnihtUjKH8aa1yHf", + "tz1eBdroBUqaUQ4h4xYXB26z67L8cj6ZyLsx", + "tz1Lk6U6erqH6EEuqMqk6u8gjqtJybZTirDs", + "tz1iAeHTDNZSwJjXaqbRyfyp96ych9j36tW1", + "tz1PDpbmvvBbFcEzctGfNt9mvvVTgTWxGGPZ", + "tz1RkXsWMgAtz85cD4iBckPC8xUFf3fPUFw2", + "tz1LcGrFcHLS9jgmWij4u7EWJDRrnU4xhVGL", + "tz1R752LZLPkJ1dhMs49zJqDcRZMic7nvL6g", + "tz1bpSiotWsQCz7jLjU4FV5K9PCZ79jinbs5", + "tz1bbsn8DMXJMEW7gVeuBbpMFBf65dq3VTtv", + "tz1V7aymCngroTZBxraVxp5kRtLh8qFRLcMN", + "tz1WxVo86ucoAE5RwCUe3tHTVV7r2GwRRvMN", + "tz1VXY3dXhE1s5huXnyFT7vfXgNroR5hTdjr", + "tz1LrYXWJ8Z3eKLSAYfCUaoZjpaqNrTqEd8w", + "tz1ZdYg6spcG9yk4ZXHHLcgNL2p8Y5wyhWYp", + "tz1PSqayN9mB1Wxk9SMjcGixX5PX9zRvtLZ8", + "tz1Pnke8YsfcDZfcqpZwpyFxLFCzEnSG9ews", + "tz1Qcgog1zYs6evgGP6aNEpGvDnCa7rAPvx5", + "tz1R5S8M9FAHs3eYjKY9ci3RD6iBgV8QCiLM", + "tz1iwGHsJu1Mq3eGGj2dmp5xj7N9kqxvuJzy", + "tz1TiEvTkhsuF5drB6Q9gDAQ3ejjp9GkMjdw", + "tz1LQPiugXCFuDit9232iqWGfj41PQGaCKvV", + "tz1TkAAz3CXdKiN4T8jAqxfWCBddQ39Vcewf", + "tz1ViczpurHDugWPgYzh5sE7Y7CDUB6qxseX", + "tz1NMf4uWqQNaVLFLjztKMpYphGdGSPu89pu", + "tz1ViNQrnj5aPjhZ9EQ1UuFcH6UUALqo3EUU", + "tz1Zqneq8GbnQ1G3g1Jnh9Vv4qGMnzLXbt3s", + "tz1dHH1xpCwZXE66WWK4SKDPLzF1JHX5KC96", + "tz1aXL6EouwJR3yMDK9jgD7zL5tpM12Vx3RY", + "tz1gtaaw2gzQjJmx8R17BRpYdkR9haE7i811", + "tz1aj98BzdTbicVFrqSYeAFjRwHGmRAwo2J6", + "tz1TS2ByHGPAgDb2AYv3bQWakG1tiH7uPwQb", + "tz1Q1t1xazVvEgN1dmxPCDXt8hqK9BY6qF5T", + "tz1fYzKUnmF873zvfcyUaX6yvRHbNTqakkSw", + "tz1g81md3cSqEtozkZggJnvRUNbMCbFHETqL", + "tz1bENLm1iQRnPsybc6HvrfR3W2nvuGErdFK", + "tz1TktVVrHESq3mdw6hpohXQFjbpGkdERsKT", + "tz1YSQ3PA5t3drYuAXYX5VE2mRcK143vjkKJ", + "tz1VFsJNozUp4mmtpv98bS2Q3B72qXWagDsq", + "tz1W47pyCkjpiWRAHmR9rHTmM5a1Yf9dtzkB", + "tz1Td2RL3zTSRZFac1SaXVxcXeAXHzTATsAU", + "KT1Tvqr6CTN3Lj2usqGPNG5Uog8JdgnDnhps", + "KT1CStwHYoGYzXENQamy2nc251enF5wk7Yjy", + "tz1UZuJ7Ae3m3rhsBjig955Fcy8vyfPYTDEr", + "tz1Qs9UZiWESjBJAA1SkqDm4eMDm78wo1QpN", + "tz1ZeovPMP8hy3PaJDg7AC8HP3rjNKpfRFes", + "tz1dkzioZTg4E3yVShiX1hdpAkE84wYhzRL8", + "KT1QhJRX8884Ccb9EKpNNFsbB27P6sRoqo4t", + "tz1Ww975VPEgcZdiTQGahABVkMf8yrcZb9A3", + "tz1RBv1smMW4xtTWG53fkzRZJGPmMotNJTEE", + "tz1cQD5tsef53FPzMmN5kLoLjvLD7VAGGQU5", + "tz1SUwahJKb5V9dxwk8N8quQWc5bQ1Zm6cva", + "tz1ciLo5K3g1pHPJKjEQp4WNvu6e9bxDtmwT", + "tz1ZTv3NVL4ry3qHZdmo7Y4rLjciHRcmptbA", + "tz1Z8TYYJsQgCqvvMtDo9Z56CzAtdVEi88NA", + "tz1hqbwdkxsh2MNaqoPVNycWA6cu1EKonKy8", + "tz1M4QhH1WQqrQWtsnDvyAqtfm3S7UcFAb78", + "tz1hxJteiSNWfmj12WdmHaPsdGtbZxZn1W9H", + "tz1cEnJ8Cu9AJcrfg9tajTmBEyTXPJM4teKP", + "tz1eSjS3Q2Rc36o2hHMRNX5pErtfGQRH9spH", + "tz1W7XN1Si3eGg4b6a7opsZ8EKjdiYVvmtfR", + "tz1gwyEjft79QrS5RKgLM3WozabfFeXn5kSC", + "tz1avdpHLEVbCKJPbFRD8pqySrZjPT64meHC", + "tz1NjziRqzmncVzU3CHXyo5BSVsn5CwXrUxS", + "tz1diyBGHXh6QR88Ps8guLmv8yCyyYTSoYjK", + "tz1RNVWP9MqtDSukfN9xZjNibKUMyq9ih2m1", + "tz1N1wThWmdxubf8y18ySS4KG69tR7icTHLn", + "tz1P96NympEyX7h4K5az2H8qr5vi7HyYGd7T", + "tz1Y7Ft4jEFvKE3dAHMUSwz9W3gXAWvN2ADR", + "tz1ND1DoSpPTtyooQQLxfNq7w8FR9dw9ZzuR", + "tz1SuBRZzrE98AeHRMy25zbNxwQfT5Wv1Cpp", + "tz1Q8HLHCFUFQVn38UeiSCNJUQsZxF2d6vtp", + "tz1TJrVZoozuTqzdeMakTnJQEogvm4q2531m", + "tz1TnfvKsMQajLzijg2EoKpE5yBGmXDiRQ1K", + "tz1gzg3UU6UMjVMGrcuetgnQ6btdVUGxYfyP", + "tz1KwcHHYUT7kMKeY6zXwUAq9Kuj3ryeX1iy", + "tz1WXuFmAiWqreKWY465FEps1Ei2XrAyHGGt", + "tz1TZafuJ3eWM3d3mckARNaP2oxBNyjLQVG6", + "tz1N7mPBeSrRsAgcukmRj2Twp6fvNshT1Uyc", + "tz1gFFSNHfQeNED9wYqThHMJZm5CNe6sFEUE", + "tz1L5xtPTd4XceH85n9W8vB3TjK45XGt63hC", + "tz1h6rqcMhAoEG2cMhiPjdJoemaHenY9mH7L", + "tz1bK9XE8khrUn7VxmEuNzF6FidGqpjTTXDs", + "tz1NUZw2MUG2AmSrtwTF3qdAUwgqBfnAGyu2", + "tz1ichwjUoGrUSawDKP6wMVLghJNX196aEBi", + "tz1UEEsxKrP1FH3RtUFt2esg7UdFQ74VeasS", + "tz1aNF6AiXu5uG6LENhYvJMwqYJc1bKTRuKr", + "KT1AG7uQwt3VX6JZah9KbD8n4sYSyaTUNqB3", + "tz1byac5DY5hA7dJ3uPvWvYAsWcAcdAGy953", + "tz1abWuJnBvT9o5TWzkEA2u3BbQ2mqFNoX3e", + "tz1Qin5ErcHtxtZV1njJ3cmzjw6GghWsEGGc" + ], + "delegated_balance": "143547306933", + "deactivated": false, + "grace_period": 251 +} diff --git a/platform/tezos/mocks/rpc_block_1292516.json b/platform/tezos/mocks/rpc_block_1292516.json new file mode 100644 index 000000000..0ce432d8f --- /dev/null +++ b/platform/tezos/mocks/rpc_block_1292516.json @@ -0,0 +1,1154 @@ +{ + "protocol": "PsDELPH1Kxsxt8f9eWbxQeRxkjfbxoqM52jvs5Y5fBxWWh4ifpo", + "chain_id": "NetXdQprcVkpaWU", + "hash": "BLgbDJqfRXCYL7e4FQkDqqxR9istymAYh3V6yGnZEfoa4EYhDJw", + "header": { + "level": 1292516, + "proto": 7, + "predecessor": "BMQNTsyxPQU24bBVgfZSQpshrhYdTZoXBq5K15opDaVQ5fJBqhC", + "timestamp": "2021-01-08T00:16:54Z", + "validation_pass": 4, + "operations_hash": "LLoapCgveRMpGZTfYmsu5AMPiUMqKk6WoKU7nX9cDEJ22jTwr8R2j", + "fitness": [ + "01", + "000000000009b8e4" + ], + "context": "CoVfQGE41eiTzwjQSgq3VQQBAniKoTFJN1GKRwE1Rk2vU8Mqzozq", + "priority": 0, + "proof_of_work_nonce": "e69b63f1d8e70100", + "signature": "sigQ4L61R9DeFV1JspU81ECRZtBp3gMAFLQY8rBpuxbVsLsUPo1prkHDHEuoztFU9aSuy7H5r9U68CTMrbEteUygN2kz7Ef4" + }, + "metadata": { + "protocol": "PsDELPH1Kxsxt8f9eWbxQeRxkjfbxoqM52jvs5Y5fBxWWh4ifpo", + "next_protocol": "PsDELPH1Kxsxt8f9eWbxQeRxkjfbxoqM52jvs5Y5fBxWWh4ifpo", + "test_chain_status": { + "status": "running", + "chain_id": "NetXbKBPL76Ndcj", + "genesis": "BLjzqqoRoF16U6u1BsZupCEYCEsCfgKhtfFWZ2FJr2wdV1uCJPe", + "protocol": "PtEdoTezd3RHSC31mpxxo1npxFjoWWcFgQtxapi51Z8TLu6v6Uq", + "expiration": "2021-01-20T08:08:04Z" + }, + "max_operations_ttl": 60, + "max_operation_data_length": 16384, + "max_block_header_length": 238, + "max_operation_list_length": [ + { + "max_size": 32768, + "max_op": 32 + }, + { + "max_size": 32768 + }, + { + "max_size": 135168, + "max_op": 132 + }, + { + "max_size": 524288 + } + ], + "baker": "tz1irJKkXS2DBWkU1NnmFQx1c1L7pbGg4yhk", + "level": { + "level": 1292516, + "level_position": 1292515, + "cycle": 315, + "cycle_position": 2275, + "voting_period": 39, + "voting_period_position": 14563, + "expected_commitment": false + }, + "voting_period_kind": "testing", + "nonce_hash": null, + "consumed_gas": "10252559", + "deactivated": [], + "balance_updates": [ + { + "kind": "contract", + "contract": "tz1irJKkXS2DBWkU1NnmFQx1c1L7pbGg4yhk", + "change": "-512000000" + }, + { + "kind": "freezer", + "category": "deposits", + "delegate": "tz1irJKkXS2DBWkU1NnmFQx1c1L7pbGg4yhk", + "cycle": 315, + "change": "512000000" + }, + { + "kind": "freezer", + "category": "rewards", + "delegate": "tz1irJKkXS2DBWkU1NnmFQx1c1L7pbGg4yhk", + "cycle": 315, + "change": "40000000" + } + ] + }, + "operations": [ + [ + { + "protocol": "PsDELPH1Kxsxt8f9eWbxQeRxkjfbxoqM52jvs5Y5fBxWWh4ifpo", + "chain_id": "NetXdQprcVkpaWU", + "hash": "opHLT62KF7GKrK26xo7MB3rtC4PyYodrUjzwc8kFfKFEKsbxBHh", + "branch": "BMQNTsyxPQU24bBVgfZSQpshrhYdTZoXBq5K15opDaVQ5fJBqhC", + "contents": [ + { + "kind": "endorsement", + "level": 1292515, + "metadata": { + "balance_updates": [ + { + "kind": "contract", + "contract": "tz1LBEKXaxQbd5Gtzbc1ATCwc3pppu81aWGc", + "change": "-64000000" + }, + { + "kind": "freezer", + "category": "deposits", + "delegate": "tz1LBEKXaxQbd5Gtzbc1ATCwc3pppu81aWGc", + "cycle": 315, + "change": "64000000" + }, + { + "kind": "freezer", + "category": "rewards", + "delegate": "tz1LBEKXaxQbd5Gtzbc1ATCwc3pppu81aWGc", + "cycle": 315, + "change": "1250000" + } + ], + "delegate": "tz1LBEKXaxQbd5Gtzbc1ATCwc3pppu81aWGc", + "slots": [ + 26 + ] + } + } + ], + "signature": "sigkHkptuXLXoJE5rDgB1r4wjHP9iMh3m9H8soexwQSQiRNgEkqLKULiu82f6DczzYNaPv3mAdBPVBUDW1Yo1yYMNSVt9p13" + }, + { + "protocol": "PsDELPH1Kxsxt8f9eWbxQeRxkjfbxoqM52jvs5Y5fBxWWh4ifpo", + "chain_id": "NetXdQprcVkpaWU", + "hash": "op7EWp6L9ShsDg9JeJ2xSVryQ8WYE3AdWn8t2R72haLTigqcpfc", + "branch": "BMQNTsyxPQU24bBVgfZSQpshrhYdTZoXBq5K15opDaVQ5fJBqhC", + "contents": [ + { + "kind": "endorsement", + "level": 1292515, + "metadata": { + "balance_updates": [ + { + "kind": "contract", + "contract": "tz1LcuQHNVQEWP2fZjk1QYZGNrfLDwrT3SyZ", + "change": "-64000000" + }, + { + "kind": "freezer", + "category": "deposits", + "delegate": "tz1LcuQHNVQEWP2fZjk1QYZGNrfLDwrT3SyZ", + "cycle": 315, + "change": "64000000" + }, + { + "kind": "freezer", + "category": "rewards", + "delegate": "tz1LcuQHNVQEWP2fZjk1QYZGNrfLDwrT3SyZ", + "cycle": 315, + "change": "1250000" + } + ], + "delegate": "tz1LcuQHNVQEWP2fZjk1QYZGNrfLDwrT3SyZ", + "slots": [ + 4 + ] + } + } + ], + "signature": "sigNrvASXxs5EQYnxbb1Fsk3pmHWQwx5jEtXLt2cHKRxraewWPeGeh9z3LXjtbXj53xUFBrjm6ir3781Urg6DgZZanF2ci38" + }, + { + "protocol": "PsDELPH1Kxsxt8f9eWbxQeRxkjfbxoqM52jvs5Y5fBxWWh4ifpo", + "chain_id": "NetXdQprcVkpaWU", + "hash": "ont1RcGeWmfFSWkXksXZgdfzYviM6nxy6PTo1B4zniTqc3joNZL", + "branch": "BMQNTsyxPQU24bBVgfZSQpshrhYdTZoXBq5K15opDaVQ5fJBqhC", + "contents": [ + { + "kind": "endorsement", + "level": 1292515, + "metadata": { + "balance_updates": [ + { + "kind": "contract", + "contract": "tz1MGTFJXpQmtxLi8QJ7AuVRgM2L2Qfn9w9i", + "change": "-64000000" + }, + { + "kind": "freezer", + "category": "deposits", + "delegate": "tz1MGTFJXpQmtxLi8QJ7AuVRgM2L2Qfn9w9i", + "cycle": 315, + "change": "64000000" + }, + { + "kind": "freezer", + "category": "rewards", + "delegate": "tz1MGTFJXpQmtxLi8QJ7AuVRgM2L2Qfn9w9i", + "cycle": 315, + "change": "1250000" + } + ], + "delegate": "tz1MGTFJXpQmtxLi8QJ7AuVRgM2L2Qfn9w9i", + "slots": [ + 24 + ] + } + } + ], + "signature": "sigaU5DLRT5aNVJriDu6KaVpqn4GQPZLyNZAmN3z68xnYZprM8JbsWdViAGrExXgi6AE1ivSSez3XgkAMkas46kM9aob7Juk" + }, + { + "protocol": "PsDELPH1Kxsxt8f9eWbxQeRxkjfbxoqM52jvs5Y5fBxWWh4ifpo", + "chain_id": "NetXdQprcVkpaWU", + "hash": "oni3KonGeSuWTZFN1gL9QzfJQUuECH5WBAaZbkXkb8mYZ2Wi12c", + "branch": "BMQNTsyxPQU24bBVgfZSQpshrhYdTZoXBq5K15opDaVQ5fJBqhC", + "contents": [ + { + "kind": "endorsement", + "level": 1292515, + "metadata": { + "balance_updates": [ + { + "kind": "contract", + "contract": "tz1eEnQhbwf6trb8Q8mPb2RaPkNk2rN7BKi8", + "change": "-128000000" + }, + { + "kind": "freezer", + "category": "deposits", + "delegate": "tz1eEnQhbwf6trb8Q8mPb2RaPkNk2rN7BKi8", + "cycle": 315, + "change": "128000000" + }, + { + "kind": "freezer", + "category": "rewards", + "delegate": "tz1eEnQhbwf6trb8Q8mPb2RaPkNk2rN7BKi8", + "cycle": 315, + "change": "2500000" + } + ], + "delegate": "tz1eEnQhbwf6trb8Q8mPb2RaPkNk2rN7BKi8", + "slots": [ + 14, + 5 + ] + } + } + ], + "signature": "sigecQ7WZ6DKDi7vf9grAipamFD4oByJeNRZgeHbBqNSmRyhjuiYoaK7XkqzQ9CnghuJFWfJh2JuCLYz2Xi97itvriU5FScD" + }, + { + "protocol": "PsDELPH1Kxsxt8f9eWbxQeRxkjfbxoqM52jvs5Y5fBxWWh4ifpo", + "chain_id": "NetXdQprcVkpaWU", + "hash": "ooQf7pyd4rX38P6stjrz7cgiESZ3hvhkivEv3N9iweUmihiHEZp", + "branch": "BMQNTsyxPQU24bBVgfZSQpshrhYdTZoXBq5K15opDaVQ5fJBqhC", + "contents": [ + { + "kind": "endorsement", + "level": 1292515, + "metadata": { + "balance_updates": [ + { + "kind": "contract", + "contract": "tz2FCNBrERXtaTtNX6iimR1UJ5JSDxvdHM93", + "change": "-64000000" + }, + { + "kind": "freezer", + "category": "deposits", + "delegate": "tz2FCNBrERXtaTtNX6iimR1UJ5JSDxvdHM93", + "cycle": 315, + "change": "64000000" + }, + { + "kind": "freezer", + "category": "rewards", + "delegate": "tz2FCNBrERXtaTtNX6iimR1UJ5JSDxvdHM93", + "cycle": 315, + "change": "1250000" + } + ], + "delegate": "tz2FCNBrERXtaTtNX6iimR1UJ5JSDxvdHM93", + "slots": [ + 16 + ] + } + } + ], + "signature": "sigrGKAuAKGjLMkHcaNF4vHZJiCYEtaGhT5TWgmiEYGZEgRMnbx2YAYB2agYssCW9EAdPmorgRGQUvFNxdh1ErR8fDPJTKAq" + }, + { + "protocol": "PsDELPH1Kxsxt8f9eWbxQeRxkjfbxoqM52jvs5Y5fBxWWh4ifpo", + "chain_id": "NetXdQprcVkpaWU", + "hash": "ooUYKCanX3vJccWTsdc6bmCxLJy72oTwfaK7Hs1ro5SQxpsJNaN", + "branch": "BMQNTsyxPQU24bBVgfZSQpshrhYdTZoXBq5K15opDaVQ5fJBqhC", + "contents": [ + { + "kind": "endorsement", + "level": 1292515, + "metadata": { + "balance_updates": [ + { + "kind": "contract", + "contract": "tz1WCd2jm4uSt4vntk4vSuUWoZQGhLcDuR9q", + "change": "-64000000" + }, + { + "kind": "freezer", + "category": "deposits", + "delegate": "tz1WCd2jm4uSt4vntk4vSuUWoZQGhLcDuR9q", + "cycle": 315, + "change": "64000000" + }, + { + "kind": "freezer", + "category": "rewards", + "delegate": "tz1WCd2jm4uSt4vntk4vSuUWoZQGhLcDuR9q", + "cycle": 315, + "change": "1250000" + } + ], + "delegate": "tz1WCd2jm4uSt4vntk4vSuUWoZQGhLcDuR9q", + "slots": [ + 1 + ] + } + } + ], + "signature": "sigT9K4qPf5C58GfTEy3rEnupij2bjwL5GP5o8XLBSZePKCrvoB882FoQZyuraxgdCdW69JkGSGtMZbP1iwyNoeZVcq7pTQE" + }, + { + "protocol": "PsDELPH1Kxsxt8f9eWbxQeRxkjfbxoqM52jvs5Y5fBxWWh4ifpo", + "chain_id": "NetXdQprcVkpaWU", + "hash": "ooXUxXEazWx581aJaXESkRQJmmpTJyCvXsS5qZs5eN9Rwne6CuB", + "branch": "BMQNTsyxPQU24bBVgfZSQpshrhYdTZoXBq5K15opDaVQ5fJBqhC", + "contents": [ + { + "kind": "endorsement", + "level": 1292515, + "metadata": { + "balance_updates": [ + { + "kind": "contract", + "contract": "tz1YhNsiRRU8aHNGg7NK3uuP6UDAyacJernB", + "change": "-64000000" + }, + { + "kind": "freezer", + "category": "deposits", + "delegate": "tz1YhNsiRRU8aHNGg7NK3uuP6UDAyacJernB", + "cycle": 315, + "change": "64000000" + }, + { + "kind": "freezer", + "category": "rewards", + "delegate": "tz1YhNsiRRU8aHNGg7NK3uuP6UDAyacJernB", + "cycle": 315, + "change": "1250000" + } + ], + "delegate": "tz1YhNsiRRU8aHNGg7NK3uuP6UDAyacJernB", + "slots": [ + 8 + ] + } + } + ], + "signature": "sigQahH6yGcrjmp27BSvRTyLeSoX1dBAg8hKjvcxey7EyHZUTr4h4WfC26XMzNwV7fqPQstJSLQ7kLMaweMm1iAqJdiPEwC9" + }, + { + "protocol": "PsDELPH1Kxsxt8f9eWbxQeRxkjfbxoqM52jvs5Y5fBxWWh4ifpo", + "chain_id": "NetXdQprcVkpaWU", + "hash": "oo6AxrjAi5BogkuUjibw652m2zso7FwDci5iYpxZefaSLnbUZzn", + "branch": "BMQNTsyxPQU24bBVgfZSQpshrhYdTZoXBq5K15opDaVQ5fJBqhC", + "contents": [ + { + "kind": "endorsement", + "level": 1292515, + "metadata": { + "balance_updates": [ + { + "kind": "contract", + "contract": "tz1VmiY38m3y95HqQLjMwqnMS7sdMfGomzKi", + "change": "-64000000" + }, + { + "kind": "freezer", + "category": "deposits", + "delegate": "tz1VmiY38m3y95HqQLjMwqnMS7sdMfGomzKi", + "cycle": 315, + "change": "64000000" + }, + { + "kind": "freezer", + "category": "rewards", + "delegate": "tz1VmiY38m3y95HqQLjMwqnMS7sdMfGomzKi", + "cycle": 315, + "change": "1250000" + } + ], + "delegate": "tz1VmiY38m3y95HqQLjMwqnMS7sdMfGomzKi", + "slots": [ + 18 + ] + } + } + ], + "signature": "sigkcBaWP9hDxughJm189p6NVSKJuuXTqA4vUVjJDSPYLNRSSNbErbgX3miiFXeT8A3Mn6bByX5zTa55xBbj7eWqA5j6DDoa" + }, + { + "protocol": "PsDELPH1Kxsxt8f9eWbxQeRxkjfbxoqM52jvs5Y5fBxWWh4ifpo", + "chain_id": "NetXdQprcVkpaWU", + "hash": "oof6obQhnjWYF2zCa3TJKTYVRf6LBFqhNw1K8Bamum7FYKyPMuj", + "branch": "BMQNTsyxPQU24bBVgfZSQpshrhYdTZoXBq5K15opDaVQ5fJBqhC", + "contents": [ + { + "kind": "endorsement", + "level": 1292515, + "metadata": { + "balance_updates": [ + { + "kind": "contract", + "contract": "tz1irJKkXS2DBWkU1NnmFQx1c1L7pbGg4yhk", + "change": "-384000000" + }, + { + "kind": "freezer", + "category": "deposits", + "delegate": "tz1irJKkXS2DBWkU1NnmFQx1c1L7pbGg4yhk", + "cycle": 315, + "change": "384000000" + }, + { + "kind": "freezer", + "category": "rewards", + "delegate": "tz1irJKkXS2DBWkU1NnmFQx1c1L7pbGg4yhk", + "cycle": 315, + "change": "7500000" + } + ], + "delegate": "tz1irJKkXS2DBWkU1NnmFQx1c1L7pbGg4yhk", + "slots": [ + 31, + 28, + 23, + 15, + 7, + 3 + ] + } + } + ], + "signature": "sigfaMBbxsFN6ycsDjMJnE9h3nFRhapYVzZNwyHorRX26o7cCK8KxL73s4qLBxcpd1UxVQpbc2Tn2a52bwSaadUAE7jeYyhP" + }, + { + "protocol": "PsDELPH1Kxsxt8f9eWbxQeRxkjfbxoqM52jvs5Y5fBxWWh4ifpo", + "chain_id": "NetXdQprcVkpaWU", + "hash": "opWsXTj7bu6J3djS92rkm6WhzXzWHUgv4FdLuC8Y37BEeF4NpR2", + "branch": "BMQNTsyxPQU24bBVgfZSQpshrhYdTZoXBq5K15opDaVQ5fJBqhC", + "contents": [ + { + "kind": "endorsement", + "level": 1292515, + "metadata": { + "balance_updates": [ + { + "kind": "contract", + "contract": "tz1gfArv665EUkSg2ojMBzcbfwuPxAvqPvjo", + "change": "-128000000" + }, + { + "kind": "freezer", + "category": "deposits", + "delegate": "tz1gfArv665EUkSg2ojMBzcbfwuPxAvqPvjo", + "cycle": 315, + "change": "128000000" + }, + { + "kind": "freezer", + "category": "rewards", + "delegate": "tz1gfArv665EUkSg2ojMBzcbfwuPxAvqPvjo", + "cycle": 315, + "change": "2500000" + } + ], + "delegate": "tz1gfArv665EUkSg2ojMBzcbfwuPxAvqPvjo", + "slots": [ + 21, + 10 + ] + } + } + ], + "signature": "sigmhF5F43MsFWJzBf3WZ9C9iVNvQccvcoMMe9qvsD78gEo6cfSpV5VgfQF1rnFQADEnpHYiZ27mzRj153DebiEpje9ssMZ8" + }, + { + "protocol": "PsDELPH1Kxsxt8f9eWbxQeRxkjfbxoqM52jvs5Y5fBxWWh4ifpo", + "chain_id": "NetXdQprcVkpaWU", + "hash": "oo6rDhNZRSPwxWYLHHPdYXzr8i5YQMYwCtFaCm7Rmac6tqzFtjb", + "branch": "BMQNTsyxPQU24bBVgfZSQpshrhYdTZoXBq5K15opDaVQ5fJBqhC", + "contents": [ + { + "kind": "endorsement", + "level": 1292515, + "metadata": { + "balance_updates": [ + { + "kind": "contract", + "contract": "tz3adcvQaKXTCg12zbninqo3q8ptKKtDFTLv", + "change": "-64000000" + }, + { + "kind": "freezer", + "category": "deposits", + "delegate": "tz3adcvQaKXTCg12zbninqo3q8ptKKtDFTLv", + "cycle": 315, + "change": "64000000" + }, + { + "kind": "freezer", + "category": "rewards", + "delegate": "tz3adcvQaKXTCg12zbninqo3q8ptKKtDFTLv", + "cycle": 315, + "change": "1250000" + } + ], + "delegate": "tz3adcvQaKXTCg12zbninqo3q8ptKKtDFTLv", + "slots": [ + 19 + ] + } + } + ], + "signature": "sigkoSk5yS8w9bhAQFJdmxLhvg4ojvteTdNwDjYH7xSjyiyJKzQYiUfHNwgCg6KDcF9sdmiH7Am4zQbEKvivS3V33q6L9zvQ" + }, + { + "protocol": "PsDELPH1Kxsxt8f9eWbxQeRxkjfbxoqM52jvs5Y5fBxWWh4ifpo", + "chain_id": "NetXdQprcVkpaWU", + "hash": "ongTApNddtKjxcibvoLYo6hBVQB8ADMnygWdAxUWPZ5FhEkVtRc", + "branch": "BMQNTsyxPQU24bBVgfZSQpshrhYdTZoXBq5K15opDaVQ5fJBqhC", + "contents": [ + { + "kind": "endorsement", + "level": 1292515, + "metadata": { + "balance_updates": [ + { + "kind": "contract", + "contract": "tz1Ldzz6k1BHdhuKvAtMRX7h5kJSMHESMHLC", + "change": "-64000000" + }, + { + "kind": "freezer", + "category": "deposits", + "delegate": "tz1Ldzz6k1BHdhuKvAtMRX7h5kJSMHESMHLC", + "cycle": 315, + "change": "64000000" + }, + { + "kind": "freezer", + "category": "rewards", + "delegate": "tz1Ldzz6k1BHdhuKvAtMRX7h5kJSMHESMHLC", + "cycle": 315, + "change": "1250000" + } + ], + "delegate": "tz1Ldzz6k1BHdhuKvAtMRX7h5kJSMHESMHLC", + "slots": [ + 17 + ] + } + } + ], + "signature": "sigShgwQLVRmz3tSeBFAVF5xMF9nrYfCVNqzcdi1kj1dpHcHxvuCNj3dY1Ey3jUk68FhyoQjNv9QD4auAEYcECEFJSfBhfqi" + }, + { + "protocol": "PsDELPH1Kxsxt8f9eWbxQeRxkjfbxoqM52jvs5Y5fBxWWh4ifpo", + "chain_id": "NetXdQprcVkpaWU", + "hash": "ooGhj6ojVWczDFVdR7eUgvbEiTKAzA5mxa84v5bKtLDaz3qSBBc", + "branch": "BMQNTsyxPQU24bBVgfZSQpshrhYdTZoXBq5K15opDaVQ5fJBqhC", + "contents": [ + { + "kind": "endorsement", + "level": 1292515, + "metadata": { + "balance_updates": [ + { + "kind": "contract", + "contract": "tz3UoffC7FG7zfpmvmjUmUeAaHvzdcUvAj6r", + "change": "-64000000" + }, + { + "kind": "freezer", + "category": "deposits", + "delegate": "tz3UoffC7FG7zfpmvmjUmUeAaHvzdcUvAj6r", + "cycle": 315, + "change": "64000000" + }, + { + "kind": "freezer", + "category": "rewards", + "delegate": "tz3UoffC7FG7zfpmvmjUmUeAaHvzdcUvAj6r", + "cycle": 315, + "change": "1250000" + } + ], + "delegate": "tz3UoffC7FG7zfpmvmjUmUeAaHvzdcUvAj6r", + "slots": [ + 25 + ] + } + } + ], + "signature": "siggXjKBYBkFyQgJxZaB8NBQcFn1nNLvr5jxvMBu68bPwasjSkBQNLZBLYbapx7Ff1qLGnNzJ1CrTwToYdaiLCdMGgjZEVaf" + }, + { + "protocol": "PsDELPH1Kxsxt8f9eWbxQeRxkjfbxoqM52jvs5Y5fBxWWh4ifpo", + "chain_id": "NetXdQprcVkpaWU", + "hash": "opZbhKntXP3gdqoXhULZGH1Weg4jbNaFfGEmJ8ygE7XQxaaxWV4", + "branch": "BMQNTsyxPQU24bBVgfZSQpshrhYdTZoXBq5K15opDaVQ5fJBqhC", + "contents": [ + { + "kind": "endorsement", + "level": 1292515, + "metadata": { + "balance_updates": [ + { + "kind": "contract", + "contract": "tz3NExpXn9aPNZPorRE4SdjJ2RGrfbJgMAaV", + "change": "-256000000" + }, + { + "kind": "freezer", + "category": "deposits", + "delegate": "tz3NExpXn9aPNZPorRE4SdjJ2RGrfbJgMAaV", + "cycle": 315, + "change": "256000000" + }, + { + "kind": "freezer", + "category": "rewards", + "delegate": "tz3NExpXn9aPNZPorRE4SdjJ2RGrfbJgMAaV", + "cycle": 315, + "change": "5000000" + } + ], + "delegate": "tz3NExpXn9aPNZPorRE4SdjJ2RGrfbJgMAaV", + "slots": [ + 30, + 27, + 12, + 2 + ] + } + } + ], + "signature": "sigUZ8f6oav8XWD6bxkbcvQusfMmH9Z4wuynhnHHaiX68mrzqQxDDsxFpRC6hAac1X2aK1UKqQGmxj9dBZATRbjPz637yRTf" + }, + { + "protocol": "PsDELPH1Kxsxt8f9eWbxQeRxkjfbxoqM52jvs5Y5fBxWWh4ifpo", + "chain_id": "NetXdQprcVkpaWU", + "hash": "ooLowfcbB9v82VkHCpTRgNyoVZnycXpWrNttMvpLiRZJZD3osKZ", + "branch": "BMQNTsyxPQU24bBVgfZSQpshrhYdTZoXBq5K15opDaVQ5fJBqhC", + "contents": [ + { + "kind": "endorsement", + "level": 1292515, + "metadata": { + "balance_updates": [ + { + "kind": "contract", + "contract": "tz1MXFrtZoaXckE41bjUCSjAjAap3AFDSr3N", + "change": "-128000000" + }, + { + "kind": "freezer", + "category": "deposits", + "delegate": "tz1MXFrtZoaXckE41bjUCSjAjAap3AFDSr3N", + "cycle": 315, + "change": "128000000" + }, + { + "kind": "freezer", + "category": "rewards", + "delegate": "tz1MXFrtZoaXckE41bjUCSjAjAap3AFDSr3N", + "cycle": 315, + "change": "2500000" + } + ], + "delegate": "tz1MXFrtZoaXckE41bjUCSjAjAap3AFDSr3N", + "slots": [ + 9, + 6 + ] + } + } + ], + "signature": "sigkW3z2d8VfDkLmce13BoPyRNjPSX1896oRRFnu79khg6oRLLefytWJc4S1TLJxonBbXbmkTRNFDbrXz9yMLNZUER56LDAN" + }, + { + "protocol": "PsDELPH1Kxsxt8f9eWbxQeRxkjfbxoqM52jvs5Y5fBxWWh4ifpo", + "chain_id": "NetXdQprcVkpaWU", + "hash": "opFdTB2KuvM4QWni6Y7CDTXYq9GXbqGJzCYLZRPgJat49iE7Hbm", + "branch": "BMQNTsyxPQU24bBVgfZSQpshrhYdTZoXBq5K15opDaVQ5fJBqhC", + "contents": [ + { + "kind": "endorsement", + "level": 1292515, + "metadata": { + "balance_updates": [ + { + "kind": "contract", + "contract": "tz3RDC3Jdn4j15J7bBHZd29EUee9gVB1CxD9", + "change": "-128000000" + }, + { + "kind": "freezer", + "category": "deposits", + "delegate": "tz3RDC3Jdn4j15J7bBHZd29EUee9gVB1CxD9", + "cycle": 315, + "change": "128000000" + }, + { + "kind": "freezer", + "category": "rewards", + "delegate": "tz3RDC3Jdn4j15J7bBHZd29EUee9gVB1CxD9", + "cycle": 315, + "change": "2500000" + } + ], + "delegate": "tz3RDC3Jdn4j15J7bBHZd29EUee9gVB1CxD9", + "slots": [ + 29, + 11 + ] + } + } + ], + "signature": "sigbDVnYyYn7NQS6KvufAhabostdJn7nmLhLgL2ZwmQEQc6HFWKYChuv3SqEfy7oTFcNtKjezKX5q3wd4vvhNCkJHbE5puRj" + }, + { + "protocol": "PsDELPH1Kxsxt8f9eWbxQeRxkjfbxoqM52jvs5Y5fBxWWh4ifpo", + "chain_id": "NetXdQprcVkpaWU", + "hash": "oo1izHJH2vjuMu7vM8xnxxvTtwDdyuXfxAyhB5Mr6kKnV7rvF9X", + "branch": "BMQNTsyxPQU24bBVgfZSQpshrhYdTZoXBq5K15opDaVQ5fJBqhC", + "contents": [ + { + "kind": "endorsement", + "level": 1292515, + "metadata": { + "balance_updates": [ + { + "kind": "contract", + "contract": "tz3bvNMQ95vfAYtG8193ymshqjSvmxiCUuR5", + "change": "-64000000" + }, + { + "kind": "freezer", + "category": "deposits", + "delegate": "tz3bvNMQ95vfAYtG8193ymshqjSvmxiCUuR5", + "cycle": 315, + "change": "64000000" + }, + { + "kind": "freezer", + "category": "rewards", + "delegate": "tz3bvNMQ95vfAYtG8193ymshqjSvmxiCUuR5", + "cycle": 315, + "change": "1250000" + } + ], + "delegate": "tz3bvNMQ95vfAYtG8193ymshqjSvmxiCUuR5", + "slots": [ + 20 + ] + } + } + ], + "signature": "sigtg2nhv9sXBwpDiVnxmcaRztNNdLctPbzGP7SssfLZqrPFZ4jYrEra7CjuRNEEyjzNCpZx7C2zzPvranTTkX87f8msmBou" + }, + { + "protocol": "PsDELPH1Kxsxt8f9eWbxQeRxkjfbxoqM52jvs5Y5fBxWWh4ifpo", + "chain_id": "NetXdQprcVkpaWU", + "hash": "onxZ3XHmTEKWGSDRWuLvfzC5z2UFm4aYCU4XNkudzZ9Uwj8yEZ9", + "branch": "BMQNTsyxPQU24bBVgfZSQpshrhYdTZoXBq5K15opDaVQ5fJBqhC", + "contents": [ + { + "kind": "endorsement", + "level": 1292515, + "metadata": { + "balance_updates": [ + { + "kind": "contract", + "contract": "tz3bTdwZinP8U1JmSweNzVKhmwafqWmFWRfk", + "change": "-64000000" + }, + { + "kind": "freezer", + "category": "deposits", + "delegate": "tz3bTdwZinP8U1JmSweNzVKhmwafqWmFWRfk", + "cycle": 315, + "change": "64000000" + }, + { + "kind": "freezer", + "category": "rewards", + "delegate": "tz3bTdwZinP8U1JmSweNzVKhmwafqWmFWRfk", + "cycle": 315, + "change": "1250000" + } + ], + "delegate": "tz3bTdwZinP8U1JmSweNzVKhmwafqWmFWRfk", + "slots": [ + 0 + ] + } + } + ], + "signature": "sigj3q9Y5Ek1GAYJWqMYAjHh31vdxyPq844dfE96mBHS5mqQcYtH4mDmLP5SpphZ2TBUyepdDizfWhbJEXBHVVAQ2pWddYzZ" + }, + { + "protocol": "PsDELPH1Kxsxt8f9eWbxQeRxkjfbxoqM52jvs5Y5fBxWWh4ifpo", + "chain_id": "NetXdQprcVkpaWU", + "hash": "oocdLLz42VJAqKxohMUZq4aYNUEB75Ca9yadktVDGJTsxakjX2x", + "branch": "BMQNTsyxPQU24bBVgfZSQpshrhYdTZoXBq5K15opDaVQ5fJBqhC", + "contents": [ + { + "kind": "endorsement", + "level": 1292515, + "metadata": { + "balance_updates": [ + { + "kind": "contract", + "contract": "tz3RB4aoyjov4KEVRbuhvQ1CKJgBJMWhaeB8", + "change": "-128000000" + }, + { + "kind": "freezer", + "category": "deposits", + "delegate": "tz3RB4aoyjov4KEVRbuhvQ1CKJgBJMWhaeB8", + "cycle": 315, + "change": "128000000" + }, + { + "kind": "freezer", + "category": "rewards", + "delegate": "tz3RB4aoyjov4KEVRbuhvQ1CKJgBJMWhaeB8", + "cycle": 315, + "change": "2500000" + } + ], + "delegate": "tz3RB4aoyjov4KEVRbuhvQ1CKJgBJMWhaeB8", + "slots": [ + 22, + 13 + ] + } + } + ], + "signature": "sigs2jRm2CnqKvZAADPALAqmmQuhUeyoMXrNRYECQhCRtBR9ChzaVH6DzsTYyoAcnr15Nh4EC8H7tTsoKqfVxS2n4juEEC2q" + } + ], + [], + [], + [ + { + "protocol": "PsDELPH1Kxsxt8f9eWbxQeRxkjfbxoqM52jvs5Y5fBxWWh4ifpo", + "chain_id": "NetXdQprcVkpaWU", + "hash": "oo25sEdAT3YDb83WNdMSxRv4E6V2Rt6Jc8msgTio7R4FBnAiFmj", + "branch": "BLKdyZ3g3apF7bS2iWiKGbURiUQRu5MnngqUH9YB4cbLtpXKvD3", + "contents": [ + { + "kind": "transaction", + "source": "tz1SiPXX4MYGNJNDsRc7n8hkvUqFzg8xqF9m", + "fee": "2940", + "counter": "2173287", + "gas_limit": "15400", + "storage_limit": "300", + "amount": "5278500000", + "destination": "tz1LGrjCS3Jj3YZyRx3mHMmEXRJVQeVnoYYi", + "metadata": { + "balance_updates": [ + { + "kind": "contract", + "contract": "tz1SiPXX4MYGNJNDsRc7n8hkvUqFzg8xqF9m", + "change": "-2940" + }, + { + "kind": "freezer", + "category": "fees", + "delegate": "tz1irJKkXS2DBWkU1NnmFQx1c1L7pbGg4yhk", + "cycle": 315, + "change": "2940" + } + ], + "operation_result": { + "status": "applied", + "balance_updates": [ + { + "kind": "contract", + "contract": "tz1SiPXX4MYGNJNDsRc7n8hkvUqFzg8xqF9m", + "change": "-5278500000" + }, + { + "kind": "contract", + "contract": "tz1LGrjCS3Jj3YZyRx3mHMmEXRJVQeVnoYYi", + "change": "5278500000" + } + ], + "consumed_gas": "1427", + "consumed_milligas": "1427000" + } + } + } + ], + "signature": "sigcBCi9WMmTnKZ9SkJeBsepWoBvTGfPyhVRc77ukTLnYGuXRTdrtjg647umQcbCGji2QD5Qm8U6KVTeodv8vhmYV3X8K5Lp" + }, + { + "protocol": "PsDELPH1Kxsxt8f9eWbxQeRxkjfbxoqM52jvs5Y5fBxWWh4ifpo", + "chain_id": "NetXdQprcVkpaWU", + "hash": "ooPykS2pw28FveDV3FojeXmThtuCATDJdn93iFjrRxFaEytait2", + "branch": "BLKdyZ3g3apF7bS2iWiKGbURiUQRu5MnngqUH9YB4cbLtpXKvD3", + "contents": [ + { + "kind": "delegation", + "source": "tz1MKCMt9dQDccykzripUGk5439BwEWthqx5", + "fee": "9008", + "counter": "3419875", + "gas_limit": "18136", + "storage_limit": "257", + "delegate": "tz1S1Aew75hMrPUymqenKfHo8FspppXKpW7h", + "metadata": { + "balance_updates": [ + { + "kind": "contract", + "contract": "tz1MKCMt9dQDccykzripUGk5439BwEWthqx5", + "change": "-9008" + }, + { + "kind": "freezer", + "category": "fees", + "delegate": "tz1irJKkXS2DBWkU1NnmFQx1c1L7pbGg4yhk", + "cycle": 315, + "change": "9008" + } + ], + "operation_result": { + "status": "applied", + "consumed_gas": "1000", + "consumed_milligas": "1000000" + } + } + } + ], + "signature": "sigXUYjE4Pmj712QvZ25rkTew6j61SeUv7wDuZXuKY71VAf5M5g9B4Hi3aAvsYiKMGmtSqnf48RQLb3MVfwocQXSJY8JzDbx" + }, + { + "protocol": "PsDELPH1Kxsxt8f9eWbxQeRxkjfbxoqM52jvs5Y5fBxWWh4ifpo", + "chain_id": "NetXdQprcVkpaWU", + "hash": "ooFFpMbVAJMkxNYFqxERDumptXS2kSEJQqTwoovVPinayJehB8f", + "branch": "BMQNTsyxPQU24bBVgfZSQpshrhYdTZoXBq5K15opDaVQ5fJBqhC", + "contents": [ + { + "kind": "transaction", + "source": "tz1YbzpfsfRtSiYJWcvpWEDHPNe3kkqEvY56", + "fee": "30000", + "counter": "3790318", + "gas_limit": "18000", + "storage_limit": "257", + "amount": "290691675", + "destination": "tz1L1c5YoQMaciYGB8gpzWoHbscBmtsTsknF", + "metadata": { + "balance_updates": [ + { + "kind": "contract", + "contract": "tz1YbzpfsfRtSiYJWcvpWEDHPNe3kkqEvY56", + "change": "-30000" + }, + { + "kind": "freezer", + "category": "fees", + "delegate": "tz1irJKkXS2DBWkU1NnmFQx1c1L7pbGg4yhk", + "cycle": 315, + "change": "30000" + } + ], + "operation_result": { + "status": "applied", + "balance_updates": [ + { + "kind": "contract", + "contract": "tz1YbzpfsfRtSiYJWcvpWEDHPNe3kkqEvY56", + "change": "-290691675" + }, + { + "kind": "contract", + "contract": "tz1L1c5YoQMaciYGB8gpzWoHbscBmtsTsknF", + "change": "290691675" + } + ], + "consumed_gas": "1827", + "consumed_milligas": "1827000" + } + } + } + ], + "signature": "sigr2d12s1X4umxZGVYwrpbhSRTSBryo8pbHXHxumHrcSimcuePKkzVdtnvxm8xU74aFBKtjzxzvGDaaXrQhN85S2PULLJGu" + }, + { + "protocol": "PsDELPH1Kxsxt8f9eWbxQeRxkjfbxoqM52jvs5Y5fBxWWh4ifpo", + "chain_id": "NetXdQprcVkpaWU", + "hash": "opLbuEsuf9NmzgikvAG4sVaS7NJedzXHcz53iQPon6QurLP8Ztv", + "branch": "BMQNTsyxPQU24bBVgfZSQpshrhYdTZoXBq5K15opDaVQ5fJBqhC", + "contents": [ + { + "kind": "delegation", + "source": "tz1XbmS2Z3ya36JDqo1P1y3VU8t4RU2LJW6J", + "fee": "2500", + "counter": "5375544", + "gas_limit": "18136", + "storage_limit": "257", + "metadata": { + "balance_updates": [ + { + "kind": "contract", + "contract": "tz1XbmS2Z3ya36JDqo1P1y3VU8t4RU2LJW6J", + "change": "-2500" + }, + { + "kind": "freezer", + "category": "fees", + "delegate": "tz1irJKkXS2DBWkU1NnmFQx1c1L7pbGg4yhk", + "cycle": 315, + "change": "2500" + } + ], + "operation_result": { + "status": "applied", + "consumed_gas": "1000", + "consumed_milligas": "1000000" + } + } + } + ], + "signature": "sigt3eD7T3RrqUqqxcUy4aBoZNuRzjAECc2WXaJWjBYRk5sbRRMxHBnonq2zjXtkZcYhnY1VrkjbPwccc816eeNG2EcbLdif" + }, + { + "protocol": "PsDELPH1Kxsxt8f9eWbxQeRxkjfbxoqM52jvs5Y5fBxWWh4ifpo", + "chain_id": "NetXdQprcVkpaWU", + "hash": "opNgBb87Cnpjr29Uc4CRuXpWgTfhPx2h76S5txrPJELa5XYiidZ", + "branch": "BLKdyZ3g3apF7bS2iWiKGbURiUQRu5MnngqUH9YB4cbLtpXKvD3", + "contents": [ + { + "kind": "transaction", + "source": "tz1c5wM9826YcUNQ8a17z9eUYpKQ3oW3zfmJ", + "fee": "824", + "counter": "5988504", + "gas_limit": "5104", + "storage_limit": "0", + "amount": "0", + "destination": "KT19kgnqC5VWoxktLRdRUERbyUPku9YioE8W", + "parameters": { + "entrypoint": "update_value", + "value": { + "prim": "Pair", + "args": [ + { + "string": "2021-01-08T00:15:00Z" + }, + { + "prim": "Pair", + "args": [ + { + "int": "253" + }, + { + "prim": "Pair", + "args": [ + { + "int": "88" + }, + { + "int": "224" + } + ] + } + ] + } + ] + } + }, + "metadata": { + "balance_updates": [ + { + "kind": "contract", + "contract": "tz1c5wM9826YcUNQ8a17z9eUYpKQ3oW3zfmJ", + "change": "-824" + }, + { + "kind": "freezer", + "category": "fees", + "delegate": "tz1irJKkXS2DBWkU1NnmFQx1c1L7pbGg4yhk", + "cycle": 315, + "change": "824" + } + ], + "operation_result": { + "status": "applied", + "storage": { + "prim": "Pair", + "args": [ + { + "prim": "Pair", + "args": [ + { + "int": "1610064900" + }, + { + "prim": "Pair", + "args": [ + { + "int": "253" + }, + { + "prim": "Pair", + "args": [ + { + "int": "88" + }, + { + "int": "224" + } + ] + } + ] + } + ] + }, + { + "bytes": "0000b4685dc0a9a5cc28942065288413ce5bea2f76a0" + } + ] + }, + "consumed_gas": "4904", + "consumed_milligas": "4903559", + "storage_size": "621" + } + } + } + ], + "signature": "sigkWvegrNtN149DWqPVJB4Fi2gw3BcowmAF3bW8CNXi6iq8ML6DD9fLw71PFZnVkQJPpR9pvfwBP89wpNfA4gXmLDftgGj5" + } + ] + ] +} diff --git a/platform/tezos/mocks/validator.json b/platform/tezos/mocks/validator.json new file mode 100644 index 000000000..01568a018 --- /dev/null +++ b/platform/tezos/mocks/validator.json @@ -0,0 +1 @@ +[{ "pkh": "tz2TSvNTh2epDMhZHrw73nV9piBX7kLZ9K9m", "rolls": 3726 }] diff --git a/platform/tezos/model.go b/platform/tezos/model.go index de4153386..6181eb385 100644 --- a/platform/tezos/model.go +++ b/platform/tezos/model.go @@ -1,35 +1,140 @@ package tezos -type Op struct { - Txs []Tx `json:"ops"` +import ( + "fmt" + "time" + + "github.com/trustwallet/golibs/types" +) + +const ( + TxTypeTransaction string = "transaction" + TxTypeDelegation string = "delegation" + + TxStatusApplied string = "applied" +) + +type ( + Account struct { + Balance string `json:"balance"` + Delegate string `json:"delegate"` + } + + AccountBalance struct { + Balance string `json:"balance"` + } + + ExplorerAccount struct { + Transactions []Transaction `json:"ops"` + } + + Transaction struct { + Delegate string `json:"delegate"` // Current delegate (may be self when registered as delegate). + Errors []Error `json:"errors"` // Operation status applied, failed, backtracked, skipped. + Fee float64 `json:"fee"` // Total fee paid (and frozen) by all operations. + Hash string `json:"hash"` // Operation hash. + Height uint64 `json:"height"` + IsSuccess bool `json:"is_success"` // Flag indicating operation was successfully applied. + Receiver string `json:"receiver"` + Sender string `json:"sender"` + Stat string `json:"status"` // Operation status applied, failed, backtracked, skipped. + Time string `json:"time"` // Block time at which the operation was included on-chain e.g: 2019-09-28T13:10:51Z + Type string `json:"type"` // Operation type, one of activate_account, double_baking_evidence, double_endorsement_evidence, seed_nonce_revelation, transaction, origination, delegation, reveal, endorsement, proposals, ballot. + Volume float64 `json:"volume"` + } + + Error struct { + ID string `json:"id"` + Kind string `json:"kind"` + } + + Validator struct { + Address string `json:"pkh"` + } + + ActivityValidatorInfo struct { + Deactivated bool `json:"deactivated"` + } + + Baker struct { + Address string `json:"address"` + Name string `json:"name"` + Logo string `json:"logo"` + FreeSpace float64 `json:"freeSpace"` + Fee float64 `json:"fee"` + MinDelegation float64 `json:"minDelegation"` + OpenForDelegation bool `json:"openForDelegation"` + EstimatedRoi float64 `json:"estimatedRoi"` + ServiceHealth string `json:"serviceHealth"` + } +) + +func (t *Transaction) Status() types.Status { + switch t.Stat { + case TxStatusApplied: + return types.StatusCompleted + default: + return types.StatusError + } } -// Tx is a Tezos blockchain transaction -type Tx struct { - Hash string `json:"hash"` - BlockHash string `json:"block"` - Status string `json:"status"` - Success bool `json:"is_success"` - Time string `json:"time"` - Height uint64 `json:"height"` - Type string `json:"type"` - Sender string `json:"sender"` - Volume float64 `json:"volume"` - Receiver string `json:"receiver"` - Fee int `json:"gas_used"` +func (t *Transaction) ErrorMsg() string { + if !t.IsSuccess && len(t.Errors) > 0 { + return fmt.Sprintf("%s %s", t.Errors[0].ID, t.Errors[0].Kind) + } else { + return "" + } } -type Validator struct { - Address string `json:"pkh"` +func (t *Transaction) Title(address string) (types.KeyTitle, bool) { + if t.Type == TxTypeDelegation { + if address == t.Sender && t.Delegate != "" && t.Receiver == "" { + return types.AnyActionDelegation, true + } + + if address == t.Sender && t.Delegate == "" && t.Receiver != "" { + return types.AnyActionUndelegation, true + } + } + + return "unsupported title", false } -type Head struct { - Height int64 `json:"height"` +func (t *Transaction) BlockTimestamp() int64 { + unix := int64(0) + date, err := time.Parse(time.RFC3339, t.Time) + if err == nil { + unix = date.Unix() + } + return unix +} + +func (t *Transaction) TransferType() (types.TransactionType, bool) { + switch t.Type { + case TxTypeTransaction: + return types.TxTransfer, true + case TxTypeDelegation: + return types.TxAnyAction, true + default: + return "unsupported type", false + } +} + +func (t *Transaction) Direction(address string) types.Direction { + if t.Sender == address && t.Receiver == address { + return types.DirectionSelf + } + if t.Sender == address && t.Receiver != address { + return types.DirectionOutgoing + } + + return types.DirectionIncoming } -type Account struct { - Address string `json:"address"` - Delegate string `json:"delegate"` - Balance float64 `json:"total_balance"` - IsDelegated bool `json:"is_delegated"` +func (t *Transaction) GetReceiver() string { + if t.Receiver != "" { + return t.Receiver + } else { + return t.Delegate + } } diff --git a/platform/tezos/model_test.go b/platform/tezos/model_test.go new file mode 100644 index 000000000..951b70977 --- /dev/null +++ b/platform/tezos/model_test.go @@ -0,0 +1,151 @@ +package tezos + +import ( + "testing" + + "github.com/stretchr/testify/assert" + "github.com/trustwallet/golibs/types" +) + +var ( + addr1 = "tz1WDujRWCYjLBDfZieXW6insg5EUbg1rCRK" + addr2 = "tz1egbN6RK2bM5vt4aAZw6r9j4nL8z49bPdS" +) + +func TestTransaction_Status(t *testing.T) { + testStatus := []struct { + name string + in Transaction + out types.Status + }{ + {"Status completed", Transaction{Stat: "applied"}, types.StatusCompleted}, + {"Status error", Transaction{Stat: "failed"}, types.StatusError}, + {"Status error", Transaction{Stat: ""}, types.StatusError}, + {"Status error", Transaction{Stat: "something else"}, types.StatusError}, + } + + for _, tt := range testStatus { + t.Run(tt.name, func(t *testing.T) { + assert.Equal(t, tt.out, tt.in.Status()) + }) + } + + testsError := []struct { + name string + in Transaction + out string + }{ + {"Error present", Transaction{IsSuccess: false, Errors: []Error{{"unchanged", "temporary"}}}, "unchanged temporary"}, + {"Error no", Transaction{IsSuccess: true}, ""}, + } + + for _, tt := range testsError { + t.Run(tt.name, func(t *testing.T) { + assert.Equal(t, tt.out, tt.in.ErrorMsg()) + }) + } + + testsTitle := []struct { + name string + address string + in Transaction + out types.KeyTitle + }{ + {"Delegation title", addr1, Transaction{Sender: addr1, Delegate: addr2, Receiver: "", Type: TxTypeDelegation}, types.AnyActionDelegation}, + {"Undelegation title", addr1, Transaction{Sender: addr1, Delegate: "", Receiver: addr2, Type: TxTypeDelegation}, types.AnyActionUndelegation}, + {"Unsupported title", addr1, Transaction{Sender: addr1, Delegate: addr1, Receiver: addr1}, "unsupported title"}, + {"Unsupported title", addr1, Transaction{Sender: addr1, Delegate: addr2, Receiver: addr1}, "unsupported title"}, + {"Unsupported title", addr1, Transaction{Sender: addr1, Delegate: addr1, Receiver: addr2}, "unsupported title"}, + {"Unsupported title", addr1, Transaction{Sender: addr1, Delegate: addr2, Receiver: addr2}, "unsupported title"}, + } + + for _, tt := range testsTitle { + t.Run(tt.name, func(t *testing.T) { + title, _ := tt.in.Title(tt.address) + assert.Equal(t, tt.out, title) + }) + } + + testsBlockTimestamp := []struct { + name string + in Transaction + out int64 + }{ + {"Delegation", Transaction{Time: "2020-02-04T12:27:59Z"}, 1580819279}, + } + + for _, tt := range testsBlockTimestamp { + t.Run(tt.name, func(t *testing.T) { + assert.Equal(t, tt.out, tt.in.BlockTimestamp()) + }) + } + + testsTransferType := []struct { + name string + in Transaction + out types.TransactionType + }{ + {"Type should be transaction", Transaction{Type: "transaction"}, types.TxTransfer}, + {"Type should be delegation", Transaction{Type: "delegation"}, types.TxAnyAction}, + {"Type unsupported", Transaction{Type: "bake"}, "unsupported type"}, + } + + for _, tt := range testsTransferType { + t.Run(tt.name, func(t *testing.T) { + transferType, _ := tt.in.TransferType() + assert.Equal(t, tt.out, transferType) + }) + } + + testsDirection := []struct { + name string + in Transaction + out types.Direction + address string + }{ + {"Direction self", Transaction{Sender: addr1, Receiver: addr1}, types.DirectionSelf, addr1}, + {"Direction outgoing", Transaction{Sender: addr1, Receiver: addr2}, types.DirectionOutgoing, addr1}, + {"Direction incoming", Transaction{Sender: addr2, Receiver: addr1}, types.DirectionIncoming, addr1}, + } + + for _, tt := range testsDirection { + t.Run(tt.name, func(t *testing.T) { + assert.Equal(t, tt.out, tt.in.Direction(tt.address)) + }) + } + + testsNormalize := []struct { + name string + in Transaction + out types.Tx + address string + }{ + {"Normalize XTZ transfer", tezosTransfer, normalizedTezosTransfer, addr1}, + } + + for _, tt := range testsNormalize { + t.Run(tt.name, func(t *testing.T) { + normalized, ok := NormalizeTx(tt.in, tt.address) + if !ok { + assert.False(t, ok, "issue to normalize") + } + assert.Equal(t, tt.out, normalized) + }) + } + + testsGetReceiver := []struct { + name string + in Transaction + out string + }{ + {"Should get receiver when no delegate", Transaction{Receiver: addr1, Delegate: ""}, addr1}, + {"Should get receiver when delegate", Transaction{Receiver: "", Delegate: addr1}, addr1}, + } + + for _, tt := range testsGetReceiver { + t.Run(tt.name, func(t *testing.T) { + assert.Equal(t, tt.out, tt.in.GetReceiver()) + }) + } + +} diff --git a/platform/tezos/rpc.go b/platform/tezos/rpc.go index 338f4ab65..b0f271f96 100644 --- a/platform/tezos/rpc.go +++ b/platform/tezos/rpc.go @@ -1,19 +1,74 @@ package tezos import ( - "github.com/trustwallet/blockatlas/pkg/blockatlas" - "github.com/trustwallet/blockatlas/pkg/logger" + "fmt" + "strconv" + "time" + + "github.com/trustwallet/golibs/client" ) +type IRpcClient interface { + GetAccountBalanceAtBlock(address string, block int64) (account AccountBalance, err error) +} + type RpcClient struct { - blockatlas.Request + client.Request +} + +type PeriodType string + +const ( + TestingPeriodType PeriodType = "testing" +) + +func (c *RpcClient) GetBlockHead() (int64, error) { + var head RpcBlockHeader + err := c.Get(&head, "chains/main/blocks/head/header", nil) + if err != nil { + return 0, err + } + return int64(head.Level), nil +} + +func (c *RpcClient) GetBlockByNumber(num int64) (block RpcBlock, err error) { + err = c.Get(&block, fmt.Sprintf("chains/main/blocks/%d", num), nil) + return +} + +func (c *RpcClient) GetValidators(blockID string) (validators []Validator, err error) { + err = c.Get(&validators, fmt.Sprintf("chains/main/blocks/%s/votes/listings", blockID), nil) + return +} + +func (c *RpcClient) GetPeriodType() (periodType PeriodType, err error) { + err = c.Get(&periodType, "chains/main/blocks/head/votes/current_period_kind", nil) + return +} + +func (c *RpcClient) GetAccount(address string) (account Account, err error) { + err = c.Get(&account, "chains/main/blocks/head/context/contracts/"+address, nil) + return +} + +func (c *RpcClient) GetAccountBalanceAtBlock(address string, block int64) (account AccountBalance, err error) { + var head string + if block == 0 { + head = "head" + } else { + head = strconv.FormatInt(block, 10) + } + path := fmt.Sprintf("chains/main/blocks/%s/context/contracts/%s", head, address) + err = c.Get(&account, path, nil) + return } -func (c *RpcClient) GetValidators() (validators []Validator, err error) { - err = c.Get(&validators, "chains/main/blocks/head~32768/votes/listings", nil) +func (c *RpcClient) fetchValidatorActivityInfo(id string) (ActivityValidatorInfo, error) { + var info ActivityValidatorInfo + path := fmt.Sprintf("/chains/main/blocks/head/context/delegates/%s", id) + err := c.GetWithCache(&info, path, nil, time.Minute*5) if err != nil { - logger.Error(err, "Tezos: Failed to get validators for address") - return validators, err + return ActivityValidatorInfo{}, err } - return validators, err + return info, nil } diff --git a/platform/tezos/rpc_mock.go b/platform/tezos/rpc_mock.go new file mode 100644 index 000000000..9847ca83d --- /dev/null +++ b/platform/tezos/rpc_mock.go @@ -0,0 +1,9 @@ +package tezos + +type RpcClientMock struct { + Balance string +} + +func (r *RpcClientMock) GetAccountBalanceAtBlock(address string, block int64) (account AccountBalance, err error) { + return AccountBalance{Balance: r.Balance}, nil +} diff --git a/platform/tezos/rpc_model.go b/platform/tezos/rpc_model.go new file mode 100644 index 000000000..067699f2a --- /dev/null +++ b/platform/tezos/rpc_model.go @@ -0,0 +1,39 @@ +package tezos + +type RpcBlockHeader struct { + Level int64 `json:"level"` + Timestamp string `json:"timestamp"` +} + +type RpcOperationContent struct { + Hash string `json:"hash"` + Contents []interface{} `json:"contents"` +} + +type RpcTransaction struct { + Kind string `json:"kind"` + Source string `json:"source"` + Fee string `json:"fee"` + Counter string `json:"counter"` + GasLimit string `json:"gas_limit"` + StorageLimit string `json:"storage_limit"` + Amount string `json:"amount,omitempty"` + Destination string `json:"destination,omitempty"` + Delegate string `json:"delegate,omitempty"` + Metadata RpcMetadata `json:"metadata"` +} + +type RpcOperationContents []RpcOperationContent + +type RpcBlock struct { + Header RpcBlockHeader `json:"header"` + Operations []RpcOperationContents `json:"operations"` +} + +type RpcMetadata struct { + OperationResult OperationResult `json:"operation_result"` +} + +type OperationResult struct { + Status string `json:"status"` +} diff --git a/platform/tezos/stake.go b/platform/tezos/stake.go new file mode 100644 index 000000000..ba02919c5 --- /dev/null +++ b/platform/tezos/stake.go @@ -0,0 +1,144 @@ +package tezos + +import ( + log "github.com/sirupsen/logrus" + "github.com/trustwallet/blockatlas/pkg/blockatlas" +) + +const ( + Annual = 6.09 + LockTime = 0 + MinimumStakeAmount = "0" +) + +func (p *Platform) GetActiveValidators() (blockatlas.StakeValidators, error) { + validators, err := p.bakerClient.GetBakers() + if err != nil { + return nil, err + } + result := make(blockatlas.StakeValidators, 0, len(validators)) + for _, v := range validators { + if p.isValidatorActive(v.ID) { + result = append(result, v) + } + } + return result, nil +} + +func (p *Platform) isValidatorActive(id string) bool { + res, err := p.rpcClient.fetchValidatorActivityInfo(id) + if err != nil { + log.Error("Tezos activity validator " + err.Error()) + return false + } + return !res.Deactivated +} + +func (p *Platform) GetDelegations(address string) (blockatlas.DelegationsPage, error) { + account, err := p.rpcClient.GetAccount(address) + if err != nil { + return nil, err + } + if len(account.Delegate) == 0 { + return make(blockatlas.DelegationsPage, 0), nil + } + + validators, err := p.bakerClient.GetBakers() + if err != nil { + return nil, err + } + return NormalizeDelegation(account, validators.ToMap()) +} + +func NormalizeDelegation(account Account, validators blockatlas.ValidatorMap) (blockatlas.DelegationsPage, error) { + validator, ok := validators[account.Delegate] + if !ok { + log.WithFields(log.Fields{"platform": "tezos", "delegation": account.Delegate}).Warn("Validator not found") + validator = getUnknownValidator(account.Delegate) + } + return blockatlas.DelegationsPage{ + { + Delegator: validator, + Value: account.Balance, + Status: blockatlas.DelegationStatusActive, + }, + }, nil +} + +func (p *Platform) GetValidators() (blockatlas.ValidatorPage, error) { + results := make(blockatlas.ValidatorPage, 0) + + validators, err := p.getCurrentValidators() + if err != nil { + return results, err + } + + for _, v := range validators { + results = append(results, normalizeValidator(v)) + } + return results, nil +} + +func (p *Platform) getCurrentValidators() (validators []Validator, err error) { + periodType, err := p.rpcClient.GetPeriodType() + if err != nil { + return validators, err + } + + switch periodType { + case TestingPeriodType: + return p.rpcClient.GetValidators("head~32768") + default: + return p.rpcClient.GetValidators("head") + } +} + +func (p *Platform) GetDetails() blockatlas.StakingDetails { + return getDetails() +} + +func (p *Platform) UndelegatedBalance(address string) (string, error) { + account, err := p.rpcClient.GetAccount(address) + if err != nil { + return "0", err + } + return account.Balance, nil +} + +func getDetails() blockatlas.StakingDetails { + return blockatlas.StakingDetails{ + Reward: blockatlas.StakingReward{Annual: Annual}, + MinimumAmount: MinimumStakeAmount, + LockTime: LockTime, + Type: blockatlas.DelegationTypeDelegate, + } +} + +func normalizeValidator(v Validator) (validator blockatlas.Validator) { + // How to calculate Tezos APR? I have no idea. Tezos team does not know either. let's assume it's around 7% - no way to calculate in decentralized manner + // Delegation rewards distributed by the validators manually, it's up to them to do it. + return blockatlas.Validator{ + Status: true, + ID: v.Address, + Details: getDetails(), + } +} + +func getUnknownValidator(address string) blockatlas.StakeValidator { + return blockatlas.StakeValidator{ + ID: address, + Status: false, + Info: blockatlas.StakeValidatorInfo{ + Name: "Decommissioned", + Description: "Decommissioned", + }, + Details: blockatlas.StakingDetails{ + Reward: blockatlas.StakingReward{ + Annual: Annual, + }, + LockTime: LockTime, + MinimumAmount: MinimumStakeAmount, + Type: blockatlas.DelegationTypeDelegate, + }, + } +} diff --git a/platform/tezos/stake_test.go b/platform/tezos/stake_test.go new file mode 100644 index 000000000..008929406 --- /dev/null +++ b/platform/tezos/stake_test.go @@ -0,0 +1,96 @@ +package tezos + +import ( + "encoding/json" + "fmt" + "net/http" + "net/http/httptest" + "testing" + + "github.com/stretchr/testify/assert" + + "github.com/trustwallet/blockatlas/pkg/blockatlas" + "github.com/trustwallet/golibs/mock" + "github.com/trustwallet/golibs/types" +) + +var ( + accountSrc, _ = mock.JsonStringFromFilePath("mocks/" + "account.json") + validatorSrc, _ = mock.JsonStringFromFilePath("mocks/" + "validator.json") + mockedTezosResponse, _ = mock.JsonStringFromFilePath("mocks/" + "delegation_response.json") + + validator = blockatlas.Validator{ + Status: true, + ID: "tz2TSvNTh2epDMhZHrw73nV9piBX7kLZ9K9m", + Details: blockatlas.StakingDetails{ + Reward: blockatlas.StakingReward{Annual: Annual}, + MinimumAmount: types.Amount("0"), + Type: blockatlas.DelegationTypeDelegate, + }, + } + + stakeValidator = blockatlas.StakeValidator{ + ID: "tz2FCNBrERXtaTtNX6iimR1UJ5JSDxvdHM93", + Status: true, + Info: blockatlas.StakeValidatorInfo{ + Name: "stake.fish", + Description: "Leading validator for Proof of Stake blockchains. Stake your cryptocurrencies with us. We know validating.", + Image: "https://assets.trustwalletapp.com/blockchains/tezos/validators/assets/tz2fcnbrerxtattnx6iimr1uj5jsdxvdhm93/logo.png", + Website: "https://stake.fish/", + }, + Details: getDetails(), + } + + validatorMap = blockatlas.ValidatorMap{ + "tz2FCNBrERXtaTtNX6iimR1UJ5JSDxvdHM93": stakeValidator, + } + + delegationsBalance = "91237897" + + delegation = blockatlas.DelegationsPage{ + { + Delegator: stakeValidator, + Value: delegationsBalance, + Status: blockatlas.DelegationStatusActive, + }, + } +) + +func TestNormalizeValidator(t *testing.T) { + var v []Validator + err := json.Unmarshal([]byte(validatorSrc), &v) + assert.Nil(t, err) + result := normalizeValidator(v[0]) + assert.Equal(t, validator, result) +} + +func TestNormalizeDelegations(t *testing.T) { + var account Account + err := json.Unmarshal([]byte(accountSrc), &account) + assert.NoError(t, err) + assert.NotNil(t, account) + result, err := NormalizeDelegation(account, validatorMap) + assert.NoError(t, err) + assert.Equal(t, delegation, result) +} + +func TestPlatform_isValidatorActive(t *testing.T) { + server := httptest.NewServer(createMockedAPI()) + defer server.Close() + + p := Init(server.URL, server.URL, server.URL) + assert.True(t, p.isValidatorActive("tz1V3yg82mcrPJbegqVCPn6bC8w1CSTRp3f8")) +} + +func createMockedAPI() http.Handler { + r := http.NewServeMux() + + r.HandleFunc("/chains/main/blocks/head/context/delegates/tz1V3yg82mcrPJbegqVCPn6bC8w1CSTRp3f8", func(w http.ResponseWriter, r *http.Request) { + w.WriteHeader(http.StatusOK) + if _, err := fmt.Fprint(w, mockedTezosResponse); err != nil { + panic(err) + } + }) + + return r +} diff --git a/platform/tezos/transaction.go b/platform/tezos/transaction.go new file mode 100644 index 000000000..28222d47f --- /dev/null +++ b/platform/tezos/transaction.go @@ -0,0 +1,80 @@ +package tezos + +import ( + "github.com/trustwallet/golibs/coin" + "github.com/trustwallet/golibs/numbers" + "github.com/trustwallet/golibs/types" +) + +func (p *Platform) GetTxsByAddress(address string) (types.Txs, error) { + txTypes := []string{TxTypeTransaction, TxTypeDelegation} + txs, err := p.client.GetTxsOfAddress(address, txTypes) + if err != nil { + return nil, err + } + + return NormalizeTxs(txs.Transactions, address), nil +} + +func NormalizeTxs(srcTxs []Transaction, address string) (txs types.Txs) { + for _, srcTx := range srcTxs { + tx, ok := NormalizeTx(srcTx, address) + if !ok { + continue + } + txs = append(txs, tx) + } + return txs +} + +// NormalizeTx converts a Tezos transaction into the generic model +func NormalizeTx(srcTx Transaction, address string) (types.Tx, bool) { + var tx types.Tx + tt, ok := srcTx.TransferType() + if !ok { + return tx, false + } + + tx = types.Tx{ + Block: srcTx.Height, + Coin: coin.TEZOS, + Date: srcTx.BlockTimestamp(), + Error: srcTx.ErrorMsg(), + Fee: types.Amount(numbers.DecimalExp(numbers.Float64toString(srcTx.Fee), 6)), + From: srcTx.Sender, + ID: srcTx.Hash, + Status: srcTx.Status(), + To: srcTx.GetReceiver(), + Type: tt, + } + if address != "" { + tx.Direction = srcTx.Direction(address) + } + + value := types.Amount(numbers.DecimalExp(numbers.Float64toString(srcTx.Volume), 6)) + switch tt { + case types.TxAnyAction: + title, ok := srcTx.Title(address) + if !ok { + return tx, false + } + tx.Meta = types.AnyAction{ + Coin: coin.Tezos().ID, + Title: title, + Key: types.KeyStakeDelegate, + Name: coin.Tezos().Name, + Symbol: coin.Tezos().Symbol, + Decimals: coin.Tezos().Decimals, + Value: value, + } + case types.TxTransfer: + tx.Meta = types.Transfer{ + Value: value, + Symbol: coin.Tezos().Symbol, + Decimals: coin.Tezos().Decimals, + } + default: + return types.Tx{}, false + } + return tx, true +} diff --git a/platform/tezos/transaction_test.go b/platform/tezos/transaction_test.go new file mode 100644 index 000000000..d986741dc --- /dev/null +++ b/platform/tezos/transaction_test.go @@ -0,0 +1,63 @@ +package tezos + +import ( + "testing" + + "github.com/stretchr/testify/assert" + "github.com/trustwallet/golibs/types" +) + +var ( + tezosTransfer = Transaction{ + Hash: "op6GzJ3a3wGJTu4KuD2WNCVJdwEU5WKDXV6EyjsBYMEjyPQWozF", + Type: "transaction", + Time: "2020-02-28T12:59:06Z", + Height: 843988, + Stat: "applied", + IsSuccess: true, + Volume: 0.000001, + Fee: 0.0015, + Sender: addr1, + Receiver: addr1, + //Errors: {{ID: "proto.005-PsBabyM1.delegate.unchanged"}, Kind: "temporary"} + } + + normalizedTezosTransfer = types.Tx{ + ID: "op6GzJ3a3wGJTu4KuD2WNCVJdwEU5WKDXV6EyjsBYMEjyPQWozF", + Coin: 1729, + From: addr1, + To: addr1, + Fee: "1500", + Date: 1582894746, + Block: 843988, + Status: "completed", + Type: "transfer", + Direction: "yourself", + Memo: "", + Meta: types.Transfer{ + Value: "1", + Symbol: "XTZ", + Decimals: 6, + }, + } +) + +func TestNormalizeTx(t *testing.T) { + tests := []struct { + name string + in Transaction + out types.Tx + address string + }{ + {"Normalize XTZ transfer", tezosTransfer, normalizedTezosTransfer, addr1}, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + normalized, ok := NormalizeTx(tt.in, tt.address) + if !ok { + assert.False(t, ok, "issue to normalize") + } + assert.Equal(t, tt.out, normalized) + }) + } +} diff --git a/platform/theta/api.go b/platform/theta/api.go deleted file mode 100644 index 9697ff107..000000000 --- a/platform/theta/api.go +++ /dev/null @@ -1,103 +0,0 @@ -package theta - -import ( - "github.com/spf13/viper" - "github.com/trustwallet/blockatlas/coin" - "github.com/trustwallet/blockatlas/pkg/blockatlas" - "strconv" -) - -type Platform struct { - client Client -} - -func (p *Platform) Init() error { - p.client = Client{blockatlas.InitClient(viper.GetString("theta.api"))} - return nil -} - -func (p *Platform) Coin() coin.Coin { - return coin.Coins[coin.THETA] -} - -func (p *Platform) GetTxsByAddress(address string) (blockatlas.TxPage, error) { - // Endpoint supports queries without token query parameter - return p.GetTokenTxsByAddress(address, "") -} - -func (p *Platform) GetTokenTxsByAddress(address string, token string) (blockatlas.TxPage, error) { - trx, err := p.client.FetchAddressTransactions(address) - if err != nil { - return nil, err - } - - var txs []blockatlas.Tx - for _, tr := range trx { - if tr.Type != SendTransaction { - continue - } - tx, ok := Normalize(&tr, address, token) - if !ok { - continue - } - txs = append(txs, tx) - } - - return txs, nil -} - -func Normalize(trx *Tx, address, token string) (tx blockatlas.Tx, ok bool) { - time, _ := strconv.ParseInt(trx.Timestamp, 10, 64) - block, _ := strconv.ParseUint(trx.BlockHeight, 10, 64) - - tx = blockatlas.Tx{ - ID: trx.Hash, - Coin: coin.THETA, - Fee: blockatlas.Amount(trx.Data.Fee.Tfuelwei), - Date: time, - Block: block, - Sequence: block, - } - - input := trx.Data.Inputs[0] - output := trx.Data.Outputs[0] - sequence, _ := strconv.ParseUint(input.Sequence, 10, 64) - - // Condition for transfer THETA trnafer - if address != "" && token == "" && output.Coins.Tfuelwei == "0" { - tx.From = input.Address - tx.To = output.Address - tx.Sequence = sequence - tx.Type = blockatlas.TxTransfer - tx.Meta = blockatlas.Transfer{ - Value: blockatlas.Amount(output.Coins.Thetawei), - Symbol: coin.Coins[coin.THETA].Symbol, - Decimals: coin.Coins[coin.THETA].Decimals, - } - - return tx, true - } - - // Condition for transfer Theta Fuel (TFUEL) - if address != "" && token == "tfuel" && output.Coins.Thetawei == "0" { - from := input.Address - to := output.Address - tx.From = from - tx.To = to - tx.Sequence = sequence - tx.Type = blockatlas.TxNativeTokenTransfer - tx.Meta = blockatlas.NativeTokenTransfer{ - Name: "Theta Fuel", - Symbol: "TFUEL", - TokenID: "tfuel", - Decimals: 18, - Value: blockatlas.Amount(output.Coins.Tfuelwei), - From: from, - To: to, - } - - return tx, true - } - - return tx, false -} diff --git a/platform/theta/api_test.go b/platform/theta/api_test.go deleted file mode 100644 index 130c177be..000000000 --- a/platform/theta/api_test.go +++ /dev/null @@ -1,162 +0,0 @@ -package theta - -import ( - "bytes" - "encoding/json" - "github.com/trustwallet/blockatlas/coin" - "github.com/trustwallet/blockatlas/pkg/blockatlas" - "testing" -) - -var transferReceipt = `{ - "hash": "0x413d8423fd1e6df99fc57f425dfd58c791c877657b364c62c15905ade5114a70", - "data": { - "fee": { - "thetawei": "0", - "tfuelwei": "2000000000000" - }, - "inputs": [ - { - "address": "0xac0eeb6ee3e32e2c74e14ac74155063e4f4f981f", - "coins": { - "thetawei": "4000000000000000000", - "tfuelwei": "2000000000000" - }, - "sequence": "43" - } - ], - "outputs": [ - { - "address": "0x0a7d7141e9abe5d1c760cffa1129c6eb94f35a2a", - "coins": { - "thetawei": "4000000000000000000", - "tfuelwei": "0" - } - } - ] - }, - "number": 7785228, - "block_height": "700321", - "timestamp": "1557136781", - "status": "finalized" -}` - -var tFuelTransfer = ` -{ - "hash": "0x558cb5ec877119c2c84a677277efb5b3059adb830c6e74971b3dbe93221b7132", - "type": 2, - "data": { - "fee": { - "thetawei": "0", - "tfuelwei": "2000000000000" - }, - "inputs": [ - { - "address": "0xac0eeb6ee3e32e2c74e14ac74155063e4f4f981f", - "coins": { - "thetawei": "0", - "tfuelwei": "44326000000000000" - }, - "sequence": "44" - } - ], - "outputs": [ - { - "address": "0x0a7d7141e9abe5d1c760cffa1129c6eb94f35a2a", - "coins": { - "thetawei": "0", - "tfuelwei": "44324000000000000" - } - } - ] - }, - "number": 7785266, - "block_height": "700327", - "timestamp": "1557136821", - "status": "finalized" -} -` - -var expectedTransferTrx = blockatlas.Tx{ - ID: "0x413d8423fd1e6df99fc57f425dfd58c791c877657b364c62c15905ade5114a70", - Coin: coin.THETA, - From: "0xac0eeb6ee3e32e2c74e14ac74155063e4f4f981f", - To: "0x0a7d7141e9abe5d1c760cffa1129c6eb94f35a2a", - Fee: "2000000000000", - Date: 1557136781, - Type: "transfer", - Status: blockatlas.StatusCompleted, - Block: 700321, - Sequence: 43, - Meta: blockatlas.Transfer{ - Value: "4000000000000000000", - Symbol: "THETA", - Decimals: 18, - }, -} - -var expectedTfuelTransfer = blockatlas.Tx{ - ID: "0x558cb5ec877119c2c84a677277efb5b3059adb830c6e74971b3dbe93221b7132", - Coin: coin.THETA, - From: "0xac0eeb6ee3e32e2c74e14ac74155063e4f4f981f", - To: "0x0a7d7141e9abe5d1c760cffa1129c6eb94f35a2a", - Fee: "2000000000000", - Date: 1557136821, - Type: blockatlas.TxNativeTokenTransfer, - Status: blockatlas.StatusCompleted, - Sequence: 44, - Block: 700327, - Meta: blockatlas.NativeTokenTransfer{ - Name: "Theta Fuel", - Symbol: "TFUEL", - TokenID: "tfuel", - Decimals: 18, - Value: "44324000000000000", - From: "0xac0eeb6ee3e32e2c74e14ac74155063e4f4f981f", - To: "0x0a7d7141e9abe5d1c760cffa1129c6eb94f35a2a", - }, -} - -func TestNormalize(t *testing.T) { - var tests = []struct { - Transaction string - Address string - Token string - Expected blockatlas.Tx - }{ - {transferReceipt, "0xac0eeb6ee3e32e2c74e14ac74155063e4f4f981f", "", expectedTransferTrx}, - {tFuelTransfer, "0xac0eeb6ee3e32e2c74e14ac74155063e4f4f981f", "tfuel", expectedTfuelTransfer}, - } - - for _, test := range tests { - var trx Tx - - tErr := json.Unmarshal([]byte(test.Transaction), &trx) - if tErr != nil { - t.Fatal("THETA: Can't unmarshal transaction", tErr) - } - - var readyTx blockatlas.Tx - normTx, ok := Normalize(&trx, test.Address, test.Token) - if !ok { - t.Fatal("THETA: Can't normalize transaction", readyTx) - } - readyTx = normTx - - actual, err := json.Marshal(&readyTx) - if err != nil { - t.Fatal(err) - } - - expected, err := json.Marshal(&test.Expected) - if err != nil { - t.Fatal(err) - } - - if !bytes.Equal(actual, expected) { - println(string(actual)) - println(string(expected)) - t.Error("Transactions not equal") - } - } -} diff --git a/platform/theta/base.go b/platform/theta/base.go new file mode 100644 index 000000000..4cdc41325 --- /dev/null +++ b/platform/theta/base.go @@ -0,0 +1,23 @@ +package theta + +import ( + "github.com/trustwallet/golibs/client" + "github.com/trustwallet/golibs/coin" + "github.com/trustwallet/golibs/network/middleware" +) + +type Platform struct { + client Client +} + +func Init(api, key string) *Platform { + request := client.InitClient(api, middleware.SentryErrorHandler) + request.Headers = map[string]string{"x-api-token": key} + return &Platform{ + client: Client{request}, + } +} + +func (p *Platform) Coin() coin.Coin { + return coin.Coins[coin.THETA] +} diff --git a/platform/theta/client.go b/platform/theta/client.go index 54653e582..45f48eb43 100644 --- a/platform/theta/client.go +++ b/platform/theta/client.go @@ -2,12 +2,13 @@ package theta import ( "fmt" - "github.com/trustwallet/blockatlas/pkg/blockatlas" "net/url" + + "github.com/trustwallet/golibs/client" ) type Client struct { - blockatlas.Request + client.Request } func (c *Client) FetchAddressTransactions(address string) ([]Tx, error) { diff --git a/platform/theta/mocks/tfuel_transfer.json b/platform/theta/mocks/tfuel_transfer.json new file mode 100644 index 000000000..ac9e15fb6 --- /dev/null +++ b/platform/theta/mocks/tfuel_transfer.json @@ -0,0 +1,33 @@ +{ + "hash": "0x558cb5ec877119c2c84a677277efb5b3059adb830c6e74971b3dbe93221b7132", + "type": 2, + "data": { + "fee": { + "thetawei": "0", + "tfuelwei": "2000000000000" + }, + "inputs": [ + { + "address": "0x0a7d7141e9abe5d1c760cffa1129c6eb94f35a2a", + "coins": { + "thetawei": "0", + "tfuelwei": "44326000000000000" + }, + "sequence": "44" + } + ], + "outputs": [ + { + "address": "0xac0eeb6ee3e32e2c74e14ac74155063e4f4f981f", + "coins": { + "thetawei": "0", + "tfuelwei": "44324000000000000" + } + } + ] + }, + "number": 7785266, + "block_height": "700327", + "timestamp": "1557136821", + "status": "finalized" +} diff --git a/platform/theta/mocks/theta_transfer.json b/platform/theta/mocks/theta_transfer.json new file mode 100644 index 000000000..cf4b05c98 --- /dev/null +++ b/platform/theta/mocks/theta_transfer.json @@ -0,0 +1,32 @@ +{ + "hash": "0x413d8423fd1e6df99fc57f425dfd58c791c877657b364c62c15905ade5114a70", + "data": { + "fee": { + "thetawei": "0", + "tfuelwei": "2000000000000" + }, + "inputs": [ + { + "address": "0xac0eeb6ee3e32e2c74e14ac74155063e4f4f981f", + "coins": { + "thetawei": "4000000000000000000", + "tfuelwei": "2000000000000" + }, + "sequence": "43" + } + ], + "outputs": [ + { + "address": "0x0a7d7141e9abe5d1c760cffa1129c6eb94f35a2a", + "coins": { + "thetawei": "4000000000000000000", + "tfuelwei": "0" + } + } + ] + }, + "number": 7785228, + "block_height": "700321", + "timestamp": "1557136781", + "status": "finalized" +} diff --git a/platform/theta/model.go b/platform/theta/model.go index b6dce25a9..0211caee4 100644 --- a/platform/theta/model.go +++ b/platform/theta/model.go @@ -20,7 +20,7 @@ type Tx struct { type Data struct { Fee Fee `json:"fee"` - Inputs []Inputs `json:"inputs"` + Inputs []Input `json:"inputs"` Outputs []Output `json:"outputs"` } @@ -29,7 +29,7 @@ type Fee struct { Tfuelwei string `json:"tfuelwei"` } -type Inputs struct { +type Input struct { Address string `json:"address"` Sequence string `json:"sequence"` } diff --git a/platform/theta/transaction.go b/platform/theta/transaction.go new file mode 100644 index 000000000..80027659a --- /dev/null +++ b/platform/theta/transaction.go @@ -0,0 +1,128 @@ +package theta + +import ( + "fmt" + "strconv" + "strings" + + "github.com/trustwallet/golibs/coin" + "github.com/trustwallet/golibs/types" +) + +func (p *Platform) GetTxsByAddress(address string) (types.Txs, error) { + // Endpoint supports queries without token query parameter + return p.GetTokenTxsByAddress(address, "") +} + +func (p *Platform) GetTokenTxsByAddress(address, token string) (types.Txs, error) { + trx, err := p.client.FetchAddressTransactions(address) + if err != nil { + return nil, err + } + + var txs types.Txs + for _, tr := range trx { + if tr.Type != SendTransaction { + continue + } + tx, ok := Normalize(&tr, address, token) + if !ok { + continue + } + txs = append(txs, tx) + } + + return txs, nil +} + +func Normalize(trx *Tx, address, token string) (tx types.Tx, ok bool) { + time, _ := strconv.ParseInt(trx.Timestamp, 10, 64) + block, _ := strconv.ParseUint(trx.BlockHeight, 10, 64) + + tx = types.Tx{ + ID: trx.Hash, + Coin: coin.THETA, + Fee: types.Amount(trx.Data.Fee.Tfuelwei), + Date: time, + Block: block, + Sequence: block, + } + inputs := trx.Data.Inputs + outputs := trx.Data.Outputs + + // Doesn't support multisend + if len(inputs) == 0 && len(outputs) == 0 { + return tx, false + } + + input := inputs[0] + output := outputs[0] + sequence, _ := strconv.ParseUint(input.Sequence, 10, 64) + + // Condition for transfer THETA transfer + if address != "" && token == "" && output.Coins.Tfuelwei == "0" { + direction, err := getDirection(address, input, output) + if err != nil { + return tx, false + } + tx.From = input.Address + tx.To = output.Address + tx.Sequence = sequence + tx.Direction = direction + tx.Type = types.TxTransfer + tx.Meta = types.Transfer{ + Value: types.Amount(output.Coins.Thetawei), + Symbol: coin.Coins[coin.THETA].Symbol, + Decimals: coin.Coins[coin.THETA].Decimals, + } + + return tx, true + } + + // Condition for transfer Theta Fuel (TFUEL) + if address != "" && token == "tfuel" && output.Coins.Thetawei == "0" { + from := input.Address + to := output.Address + direction, err := getDirection(address, input, output) + if err != nil { + return tx, false + } + + tx.From = from + tx.To = to + tx.Sequence = sequence + tx.Direction = direction + tx.Type = types.TxNativeTokenTransfer + tx.Meta = types.NativeTokenTransfer{ + Name: "Theta Fuel", + Symbol: "TFUEL", + TokenID: "tfuel", + Decimals: 18, + Value: types.Amount(output.Coins.Tfuelwei), + From: from, + To: to, + } + + return tx, true + } + + return tx, false +} + +// Get transaction direction +func getDirection(a string, inputs Input, outputs Output) (dir types.Direction, err error) { + address := strings.ToLower(a) + inAddr := inputs.Address + outAddr := outputs.Address + + switch { + case inAddr == address && outAddr == address: + return types.DirectionSelf, nil + case inAddr == address && outAddr != address: + return types.DirectionOutgoing, nil + case inAddr != address && outAddr == address: + return types.DirectionIncoming, nil + } + + return "", fmt.Errorf("direction unknown") +} diff --git a/platform/theta/transaction_test.go b/platform/theta/transaction_test.go new file mode 100644 index 000000000..77fdc0b34 --- /dev/null +++ b/platform/theta/transaction_test.go @@ -0,0 +1,123 @@ +package theta + +import ( + "encoding/json" + "testing" + + "github.com/stretchr/testify/assert" + "github.com/trustwallet/golibs/coin" + "github.com/trustwallet/golibs/mock" + "github.com/trustwallet/golibs/types" +) + +var ( + thetaTransfer, _ = mock.JsonStringFromFilePath("mocks/" + "theta_transfer.json") + tFuelTransfer, _ = mock.JsonStringFromFilePath("mocks/" + "tfuel_transfer.json") + + expectedTransferTrx = types.Tx{ + ID: "0x413d8423fd1e6df99fc57f425dfd58c791c877657b364c62c15905ade5114a70", + Coin: coin.THETA, + From: "0xac0eeb6ee3e32e2c74e14ac74155063e4f4f981f", + To: "0x0a7d7141e9abe5d1c760cffa1129c6eb94f35a2a", + Fee: "2000000000000", + Date: 1557136781, + Type: "transfer", + Status: types.StatusCompleted, + Block: 700321, + Sequence: 43, + Direction: types.DirectionOutgoing, + Meta: types.Transfer{ + Value: "4000000000000000000", + Symbol: "THETA", + Decimals: 18, + }, + } + + expectedTfuelTransfer = types.Tx{ + ID: "0x558cb5ec877119c2c84a677277efb5b3059adb830c6e74971b3dbe93221b7132", + Coin: coin.THETA, + From: "0x0a7d7141e9abe5d1c760cffa1129c6eb94f35a2a", + To: "0xac0eeb6ee3e32e2c74e14ac74155063e4f4f981f", + Fee: "2000000000000", + Date: 1557136821, + Type: types.TxNativeTokenTransfer, + Status: types.StatusCompleted, + Sequence: 44, + Block: 700327, + Direction: types.DirectionIncoming, + Meta: types.NativeTokenTransfer{ + Name: "Theta Fuel", + Symbol: "TFUEL", + TokenID: "tfuel", + Decimals: 18, + Value: "44324000000000000", + From: "0x0a7d7141e9abe5d1c760cffa1129c6eb94f35a2a", + To: "0xac0eeb6ee3e32e2c74e14ac74155063e4f4f981f", + }, + } +) + +func TestNormalize(t *testing.T) { + tests := []struct { + Transaction string + Address string + Token string + Expected types.Tx + }{ + {thetaTransfer, "0xac0eeb6ee3e32e2c74e14ac74155063e4f4f981f", "", expectedTransferTrx}, + {tFuelTransfer, "0xac0eeb6ee3e32e2c74e14ac74155063e4f4f981f", "tfuel", expectedTfuelTransfer}, + } + + for _, test := range tests { + var trx Tx + + tErr := json.Unmarshal([]byte(test.Transaction), &trx) + if tErr != nil { + t.Fatal("THETA: Can't unmarshal transaction", tErr) + } + + var readyTx types.Tx + normTx, ok := Normalize(&trx, test.Address, test.Token) + if !ok { + t.Fatal("THETA: Can't normalize transaction", readyTx) + } + readyTx = normTx + + actual, err := json.Marshal(&readyTx) + if err != nil { + t.Fatal(err) + } + + expected, err := json.Marshal(&test.Expected) + if err != nil { + t.Fatal(err) + } + + assert.JSONEq(t, string(actual), string(expected)) + } +} + +func TestGetDirection(t *testing.T) { + var addrChecksum = "0x42616C88c7076FbE6e1596b734c13356b5A508a4" + var addr = "0x42616c88c7076fbe6e1596b734c13356b5a508a4" + var otherAddr = "0x8665a3cbc02ff17cf9d712e8a20f3d7bb1444517" + + tests := []struct { + address string + expectedDir types.Direction + trxInput Input + trxOutput Output + }{ + {address: addrChecksum, expectedDir: types.DirectionSelf, trxInput: Input{Address: addr}, trxOutput: Output{Address: addr}}, + {address: addrChecksum, expectedDir: types.DirectionOutgoing, trxInput: Input{Address: addr}, trxOutput: Output{Address: otherAddr}}, + {address: addrChecksum, expectedDir: types.DirectionIncoming, trxInput: Input{Address: otherAddr}, trxOutput: Output{Address: addr}}, + } + + for _, test := range tests { + actualDir, err := getDirection(test.address, test.trxInput, test.trxOutput) + if err != nil { + t.Fatal(err) + } + assert.Equal(t, test.expectedDir, actualDir, test.expectedDir) + } +} diff --git a/platform/tron/util.go b/platform/tron/address.go similarity index 76% rename from platform/tron/util.go rename to platform/tron/address.go index c7ef9d736..086bc16c8 100644 --- a/platform/tron/util.go +++ b/platform/tron/address.go @@ -3,8 +3,8 @@ package tron import ( "crypto/sha256" "encoding/hex" + "github.com/mr-tron/base58" - "github.com/trustwallet/blockatlas/pkg/errors" ) // HexToAddress converts a hex representation of a Tron address @@ -12,8 +12,7 @@ import ( func HexToAddress(hexAddr string) (b58 string, err error) { bytes, err := hex.DecodeString(hexAddr) if err != nil { - return "", errors.E(err, errors.TypePlatformUnmarshal, - errors.Params{"hexAddr": hexAddr}).PushToSentry() + return "", err } var checksum [32]byte checksum = sha256.Sum256(bytes) diff --git a/platform/tron/address_test.go b/platform/tron/address_test.go new file mode 100644 index 000000000..d8c6e0fdf --- /dev/null +++ b/platform/tron/address_test.go @@ -0,0 +1,31 @@ +package tron + +import "testing" + +func TestHexToAddress(t *testing.T) { + tests := []struct { + name string + hexAddr string + want string + wantErr bool + }{ + { + name: "Test hex to base58 address", + hexAddr: "4182dd6b9966724ae2fdc79b416c7588da67ff1b35", + want: "TMuA6YqfCeX8EhbfYEg5y7S4DqzSJireY9", + wantErr: false, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + gotB58, err := HexToAddress(tt.hexAddr) + if (err != nil) != tt.wantErr { + t.Errorf("HexToAddress() error = %v, wantErr %v", err, tt.wantErr) + return + } + if gotB58 != tt.want { + t.Errorf("HexToAddress() = %v, want %v", gotB58, tt.want) + } + }) + } +} diff --git a/platform/tron/api.go b/platform/tron/api.go deleted file mode 100644 index d21ff4f9a..000000000 --- a/platform/tron/api.go +++ /dev/null @@ -1,257 +0,0 @@ -package tron - -import ( - "encoding/hex" - "github.com/spf13/viper" - "github.com/trustwallet/blockatlas/coin" - "github.com/trustwallet/blockatlas/pkg/blockatlas" - "github.com/trustwallet/blockatlas/pkg/errors" - "github.com/trustwallet/blockatlas/pkg/logger" - "sync" -) - -type Platform struct { - client Client -} - -const Annual = 0.74 - -func (p *Platform) Init() error { - p.client = Client{blockatlas.InitClient(viper.GetString("tron.api"))} - return nil -} - -func (p *Platform) Coin() coin.Coin { - return coin.Coins[coin.TRX] -} - -func (p *Platform) CurrentBlockNumber() (int64, error) { - return p.client.CurrentBlockNumber() -} - -func (p *Platform) GetBlockByNumber(num int64) (*blockatlas.Block, error) { - block, err := p.client.GetBlockByNumber(num) - if err != nil { - return nil, err - } - - txsChan := p.NormalizeBlockTxs(block.Txs) - txs := make(blockatlas.TxPage, 0) - for cTxs := range txsChan { - txs = append(txs, cTxs) - } - - return &blockatlas.Block{ - Number: num, - Txs: txs, - }, nil -} - -func (p *Platform) NormalizeBlockTxs(srcTxs []Tx) chan blockatlas.Tx { - txChan := make(chan blockatlas.Tx, len(srcTxs)) - var wg sync.WaitGroup - for _, srcTx := range srcTxs { - wg.Add(1) - go func(s Tx, c chan blockatlas.Tx) { - defer wg.Done() - p.NormalizeBlockChannel(s, c) - }(srcTx, txChan) - } - wg.Wait() - close(txChan) - return txChan -} - -func (p *Platform) NormalizeBlockChannel(srcTx Tx, txChan chan blockatlas.Tx) { - if len(srcTx.Data.Contracts) == 0 { - return - } - - tx, err := Normalize(srcTx) - if err != nil { - return - } - transfer := srcTx.Data.Contracts[0].Parameter.Value - if len(transfer.AssetName) > 0 { - assetName, err := hex.DecodeString(transfer.AssetName[:]) - if err == nil { - info, err := p.client.GetTokenInfo(string(assetName)) - if err == nil && len(info.Data) > 0 { - setTokenMeta(tx, srcTx, info.Data[0]) - } - } - } - txChan <- *tx -} - -func (p *Platform) GetTxsByAddress(address string) (blockatlas.TxPage, error) { - Txs, err := p.client.GetTxsOfAddress(address, "") - if err != nil && len(Txs) == 0 { - return nil, err - } - - txs := make(blockatlas.TxPage, 0) - for _, srcTx := range Txs { - tx, err := Normalize(srcTx) - if err != nil { - continue - } - - if len(srcTx.Data.Contracts) > 0 && srcTx.Data.Contracts[0].Type == TransferContract { - txs = append(txs, *tx) - } else { - continue - } - } - - return txs, nil -} - -func (p *Platform) GetTokenTxsByAddress(address, token string) (blockatlas.TxPage, error) { - tokenTxs, err := p.client.GetTxsOfAddress(address, token) - if err != nil { - return nil, errors.E(err, "TRON: failed to get token from address", errors.TypePlatformApi, - errors.Params{"address": address, "token": token}).PushToSentry() - } - - txs := make(blockatlas.TxPage, 0) - - if len(tokenTxs) == 0 { - return txs, nil - } - - info, err := p.client.GetTokenInfo(token) - if err != nil || len(info.Data) == 0 { - return nil, errors.E(err, "TRON: failed to get token info", errors.TypePlatformApi, - errors.Params{"address": address, "token": token}).PushToSentry() - } - - for _, srcTx := range tokenTxs { - tx, err := Normalize(srcTx) - if err != nil { - logger.Error(err) - continue - } - setTokenMeta(tx, srcTx, info.Data[0]) - txs = append(txs, *tx) - } - - return txs, nil -} - -func (p *Platform) GetTokenListByAddress(address string) (blockatlas.TokenPage, error) { - tokens, err := p.client.GetAccount(address) - if err != nil { - return nil, err - } - tokenPage := make(blockatlas.TokenPage, 0) - if len(tokens.Data) == 0 { - return tokenPage, nil - } - - var tokenIds []string - for _, v := range tokens.Data[0].AssetsV2 { - tokenIds = append(tokenIds, v.Key) - } - - tokensChan := p.getTokens(tokenIds) - for info := range tokensChan { - tokenPage = append(tokenPage, info) - } - return tokenPage, nil -} - -func (p *Platform) getTokens(ids []string) chan blockatlas.Token { - tkChan := make(chan blockatlas.Token, len(ids)) - var wg sync.WaitGroup - for _, id := range ids { - wg.Add(1) - go func(i string, c chan blockatlas.Token) { - defer wg.Done() - err := p.getTokensChannel(i, c) - if err != nil { - logger.Error(err) - } - }(id, tkChan) - } - wg.Wait() - close(tkChan) - return tkChan -} - -func (p *Platform) getTokensChannel(id string, tkChan chan blockatlas.Token) error { - info, err := p.client.GetTokenInfo(id) - if err != nil || len(info.Data) == 0 { - logger.Error(err, "GetTokenInfo: invalid token") - return err - } - asset := NormalizeToken(info.Data[0]) - tkChan <- asset - return nil -} - -func NormalizeToken(info AssetInfo) blockatlas.Token { - return blockatlas.Token{ - Name: info.Name, - Symbol: info.Symbol, - TokenID: info.ID, - Coin: coin.TRX, - Decimals: info.Decimals, - Type: blockatlas.TokenTypeTRC10, - } -} - -func setTokenMeta(tx *blockatlas.Tx, srcTx Tx, tokenInfo AssetInfo) { - transfer := srcTx.Data.Contracts[0].Parameter.Value - tx.Meta = blockatlas.TokenTransfer{ - Name: tokenInfo.Name, - Symbol: tokenInfo.Symbol, - TokenID: tokenInfo.ID, - Decimals: tokenInfo.Decimals, - Value: transfer.Amount, - From: tx.From, - To: tx.To, - } -} - -/// Normalize converts a Tron transaction into the generic model -func Normalize(srcTx Tx) (*blockatlas.Tx, error) { - if len(srcTx.Data.Contracts) == 0 { - return nil, errors.E("TRON: transfer without contract", errors.TypePlatformApi, - errors.Params{"tx": srcTx}).PushToSentry() - } - - contract := srcTx.Data.Contracts[0] - if contract.Type != TransferContract && contract.Type != TransferAssetContract { - return nil, errors.E("TRON: invalid contract transfer", errors.TypePlatformApi, - errors.Params{"tx": srcTx, "type": contract.Type}) - } - - transfer := contract.Parameter.Value - from, err := HexToAddress(transfer.OwnerAddress) - if err != nil { - return nil, errors.E(err, "TRON: failed to get from address", errors.TypePlatformApi, - errors.Params{"tx": srcTx}).PushToSentry() - } - to, err := HexToAddress(transfer.ToAddress) - if err != nil { - return nil, errors.E(err, "TRON: failed to get to address", errors.TypePlatformApi, - errors.Params{"tx": srcTx}).PushToSentry() - } - - return &blockatlas.Tx{ - ID: srcTx.ID, - Coin: coin.TRX, - Date: srcTx.BlockTime / 1000, - From: from, - To: to, - Fee: "0", - Block: 0, - Status: blockatlas.StatusCompleted, - Meta: blockatlas.Transfer{ - Value: transfer.Amount, - Symbol: coin.Coins[coin.TRX].Symbol, - Decimals: coin.Coins[coin.TRX].Decimals, - }, - }, nil -} diff --git a/platform/tron/api_test.go b/platform/tron/api_test.go deleted file mode 100644 index 12d1a4209..000000000 --- a/platform/tron/api_test.go +++ /dev/null @@ -1,150 +0,0 @@ -package tron - -import ( - "encoding/json" - "github.com/stretchr/testify/assert" - "github.com/trustwallet/blockatlas/coin" - "github.com/trustwallet/blockatlas/pkg/blockatlas" - "testing" -) - -const transferSrc = ` -{ - "block_timestamp": 1564797900000, - "raw_data": { - "contract": [ - { - "parameter": { - "value": { - "amount": 100666888000000, - "owner_address": "4182dd6b9966724ae2fdc79b416c7588da67ff1b35", - "to_address": "410583a68a3bcd86c25ab1bee482bac04a216b0261" - } - }, - "type": "TransferContract" - } - ] - }, - "txID": "24a10f7a503e78adc0d7e380b68005531b09e16b9e3f7b524e33f40985d287df" -} -` - -const tokenTransferSrc = ` -{ - "block_timestamp": 1564797900000, - "raw_data": { - "contract": [ - { - "parameter": { - "value": { - "amount": 2776267, - "asset_name": "1002000", - "owner_address": "4182dd6b9966724ae2fdc79b416c7588da67ff1b35", - "to_address": "410583a68a3bcd86c25ab1bee482bac04a216b0261" - } - }, - "type": "TransferAssetContract" - } - ] - }, - "txID": "24a10f7a503e78adc0d7e380b68005531b09e16b9e3f7b524e33f40985d287df" -} -` - -var transferDst = blockatlas.Tx{ - ID: "24a10f7a503e78adc0d7e380b68005531b09e16b9e3f7b524e33f40985d287df", - Coin: coin.TRX, - From: "TMuA6YqfCeX8EhbfYEg5y7S4DqzSJireY9", - To: "TAUN6FwrnwwmaEqYcckffC7wYmbaS6cBiX", - Fee: "0", // TODO - Date: 1564797900, - Block: 0, // TODO - Status: blockatlas.StatusCompleted, - Meta: blockatlas.Transfer{ - Value: "100666888000000", - Symbol: "TRX", - Decimals: 6, - }, -} - -var tokenTransferDst = blockatlas.Tx{ - ID: "24a10f7a503e78adc0d7e380b68005531b09e16b9e3f7b524e33f40985d287df", - Coin: coin.TRX, - From: "TMuA6YqfCeX8EhbfYEg5y7S4DqzSJireY9", - To: "TAUN6FwrnwwmaEqYcckffC7wYmbaS6cBiX", - Fee: "0", // TODO - Date: 1564797900, - Block: 0, // TODO - Status: blockatlas.StatusCompleted, - Meta: blockatlas.TokenTransfer{ - Name: "BitTorrent", - Symbol: "BTT", - TokenID: "1002000", - Decimals: 6, - Value: "2776267", - From: "TMuA6YqfCeX8EhbfYEg5y7S4DqzSJireY9", - To: "TAUN6FwrnwwmaEqYcckffC7wYmbaS6cBiX", - }, -} - -var assetInfo = AssetInfo{Name: "BitTorrent", Symbol: "BTT", Decimals: 6, ID: "1002000"} - -type test struct { - name string - apiResponse string - expected *blockatlas.Tx -} - -func TestNormalizeTokenTransfer(t *testing.T) { - testNormalizeTokenTransfer(t, &test{ - name: "token transfer", - apiResponse: tokenTransferSrc, - expected: &tokenTransferDst, - }) -} - -func testNormalizeTokenTransfer(t *testing.T, _test *test) { - var srcTx Tx - err := json.Unmarshal([]byte(_test.apiResponse), &srcTx) - assert.NoError(t, err) - assert.NotNil(t, srcTx) - res, err := Normalize(srcTx) - assert.NoError(t, err) - assert.NotNil(t, res) - setTokenMeta(res, srcTx, assetInfo) - assert.Equal(t, _test.expected, res) -} - -func TestNormalize(t *testing.T) { - testNormalize(t, &test{ - name: "transfer", - apiResponse: transferSrc, - expected: &transferDst, - }) -} - -func testNormalize(t *testing.T, _test *test) { - var srcTx Tx - err := json.Unmarshal([]byte(_test.apiResponse), &srcTx) - assert.NoError(t, err) - assert.NotNil(t, srcTx) - res, err := Normalize(srcTx) - assert.NoError(t, err) - assert.NotNil(t, res) - assert.Equal(t, _test.expected, res) -} - -var tokenDst = blockatlas.Token{ - Name: "Test", - Symbol: "TST", - Decimals: 8, - TokenID: "1", - Coin: 195, - Type: "TRC10", -} - -func TestNormalizeToken(t *testing.T) { - asset := AssetInfo{Name: "Test", Symbol: "TST", ID: "1", Decimals: 8} - actual := NormalizeToken(asset) - assert.Equal(t, tokenDst, actual) -} diff --git a/platform/tron/base.go b/platform/tron/base.go new file mode 100644 index 000000000..ca52fca15 --- /dev/null +++ b/platform/tron/base.go @@ -0,0 +1,24 @@ +package tron + +import ( + "github.com/trustwallet/golibs/client" + "github.com/trustwallet/golibs/coin" + "github.com/trustwallet/golibs/network/middleware" +) + +type Platform struct { + client Client +} + +func Init(api, apiKey string) *Platform { + request := client.InitClient(api, middleware.SentryErrorHandler) + //TODO: Add when ready + //request.Headers = map[string]string{"TRON-PRO-API-KEY": apiKey} + return &Platform{ + client: Client{request}, + } +} + +func (p *Platform) Coin() coin.Coin { + return coin.Tron() +} diff --git a/platform/tron/block.go b/platform/tron/block.go new file mode 100644 index 000000000..ad97d94b2 --- /dev/null +++ b/platform/tron/block.go @@ -0,0 +1,33 @@ +package tron + +import ( + "github.com/trustwallet/golibs/types" +) + +func (p *Platform) CurrentBlockNumber() (int64, error) { + return p.client.fetchCurrentBlockNumber() +} + +func (p *Platform) GetBlockByNumber(num int64) (*types.Block, error) { + block, err := p.client.fetchBlockByNumber(num) + if err != nil { + return nil, err + } + + txs := p.NormalizeBlockTxs(block.Txs) + + return &types.Block{ + Number: num, + Txs: txs, + }, nil +} + +func (p *Platform) NormalizeBlockTxs(srcTxs []Tx) []types.Tx { + txs := make([]types.Tx, 0) + for _, srcTx := range srcTxs { + if tx, err := normalize(srcTx); err == nil { + txs = append(txs, *tx) + } + } + return txs +} diff --git a/platform/tron/client.go b/platform/tron/client.go index 862126ef5..7c6899427 100644 --- a/platform/tron/client.go +++ b/platform/tron/client.go @@ -2,62 +2,72 @@ package tron import ( "fmt" - "github.com/trustwallet/blockatlas/pkg/blockatlas" - "github.com/trustwallet/blockatlas/pkg/errors" "net/url" + "time" + + "github.com/trustwallet/golibs/client" ) -type Client struct { - blockatlas.Request -} +type ( + Client struct { + client.Request + } +) -func (c *Client) CurrentBlockNumber() (int64, error) { +func (c *Client) fetchCurrentBlockNumber() (int64, error) { var block Block err := c.Post(&block, "wallet/getnowblock", nil) return block.BlockHeader.Data.Number, err } -func (c *Client) GetBlockByNumber(num int64) (Block, error) { +func (c *Client) fetchBlockByNumber(num int64) (Block, error) { var blocks Blocks err := c.Post(&blocks, "wallet/getblockbylimitnext", BlockRequest{StartNum: num, EndNum: num + 1}) if err != nil || blocks.Blocks == nil || len(blocks.Blocks) == 0 { - return Block{}, errors.E(err, "block not found", errors.Params{"block": num}) + return Block{}, err } return blocks.Blocks[0], nil } -func (c *Client) GetTxsOfAddress(address, token string) ([]Tx, error) { +func (c *Client) fetchTxsOfAddress(address, token string) ([]Tx, error) { path := fmt.Sprintf("v1/accounts/%s/transactions", url.PathEscape(address)) var txs Page - err := c.Get(&txs, path, url.Values{ - "only_confirmed": {"true"}, - "limit": {"200"}, - "token_id": {token}, - "order_by": {"block_timestamp,desc"}, - }) + err := c.GetWithCache(&txs, path, url.Values{ + "limit": {"25"}, + "token_id": {token}, + "order_by": {"block_timestamp,desc"}, + }, time.Minute*1) return txs.Txs, err } -func (c *Client) GetAccount(address string) (accounts *Account, err error) { +func (c *Client) fetchAccount(address string) (accounts *Account, err error) { path := fmt.Sprintf("v1/accounts/%s", address) - err = c.Get(&accounts, path, nil) + err = c.GetWithCache(&accounts, path, nil, time.Second*1) return } -func (c *Client) GetAccountVotes(address string) (account *AccountData, err error) { +func (c *Client) fetchAccountVotes(address string) (account *AccountData, err error) { err = c.Post(&account, "wallet/getaccount", VotesRequest{Address: address, Visible: true}) return } -func (c *Client) GetTokenInfo(id string) (asset Asset, err error) { - path := fmt.Sprintf("v1/assets/%s", id) - err = c.Get(&asset, path, nil) +func (c *Client) fetchValidators() (validators Validators, err error) { + err = c.GetWithCache(&validators, "wallet/listwitnesses", nil, time.Hour*1) return } -func (c *Client) GetValidators() (validators Validators, err error) { - err = c.Get(&validators, "wallet/listwitnesses", nil) - return +func (c *Client) fetchTRC20Transactions(address string) (TRC20Transactions, error) { + var result TRC20Transactions + path := fmt.Sprintf("v1/accounts/%s/transactions/trc20", address) + err := c.GetWithCache(&result, path, url.Values{ + "limit": {"200"}, + "order_by": {"block_timestamp,desc"}, + "only_confirmed": {"true"}, + }, time.Minute*1) + if err != nil { + return TRC20Transactions{}, err + } + return result, nil } diff --git a/platform/tron/mocks/delegation.json b/platform/tron/mocks/delegation.json new file mode 100644 index 000000000..9c02c402a --- /dev/null +++ b/platform/tron/mocks/delegation.json @@ -0,0 +1,23 @@ +{ + "address": "419241920da7d6bb487a33a6df3838e3d208f0b251", + "frozen": [ + { + "expire_time": 10437262001000, + "frozen_balance": "35000000" + } + ], + "votes": [ + { + "vote_address": "TGzz8gjYiYRqpfmDwnLxfgPuLVNmpCswVp", + "vote_count": 21 + }, + { + "vote_address": "TPMGfspxLQGom8sKutrbHcDKtHjRHFbGKw", + "vote_count": 5 + }, + { + "vote_address": "TPMGfspxLQGom8sKutrbHcDKtHjRHFbGKw", + "vote_count": 5 + } + ] +} diff --git a/platform/tron/mocks/delegation_2.json b/platform/tron/mocks/delegation_2.json new file mode 100644 index 000000000..ade0c411b --- /dev/null +++ b/platform/tron/mocks/delegation_2.json @@ -0,0 +1,15 @@ +{ + "address": "419241920da7d6bb487a33a6df3838e3d208f0b251", + "frozen": [ + { + "expire_time": 1569465251000, + "frozen_balance": "5000000" + } + ], + "votes": [ + { + "vote_address": "TPMGfspxLQGom8sKutrbHcDKtHjRHFbGKw", + "vote_count": 5 + } + ] +} diff --git a/platform/tron/mocks/token_txs_response.json b/platform/tron/mocks/token_txs_response.json new file mode 100644 index 000000000..b0929ef01 --- /dev/null +++ b/platform/tron/mocks/token_txs_response.json @@ -0,0 +1,442 @@ +[ + { + "id": "fb078403adfee637608c3906d9d21dd158611aba149b9993f43d0f292ce543a0", + "coin": 195, + "from": "TM1zzNDZD2DPASbKcgdVoTYhfmYgtfwx9D", + "to": "TGg7zHY9qd36aN3jLVDDRuiFeJjaaAtx8A", + "fee": "0", + "date": 1592757117, + "block": 0, + "status": "completed", + "sequence": 0, + "type": "token_transfer", + "memo": "", + "metadata": { + "name": "Tether USD", + "symbol": "USDT", + "token_id": "TR7NHqjeKQxGTCi8q8ZY4pL8otSzgjLj6t", + "decimals": 6, + "value": "500000000", + "from": "TM1zzNDZD2DPASbKcgdVoTYhfmYgtfwx9D", + "to": "TGg7zHY9qd36aN3jLVDDRuiFeJjaaAtx8A" + } + }, + { + "id": "c4052b526e5cd21e1f023c31cce6b6a13eb9d8aeae3ae80fcefe6038dfbeb022", + "coin": 195, + "from": "TM1zzNDZD2DPASbKcgdVoTYhfmYgtfwx9D", + "to": "TXJTFuXzfoPbWKCnw47AYxMzgVPUyhJGRd", + "fee": "0", + "date": 1592757066, + "block": 0, + "status": "completed", + "sequence": 0, + "type": "token_transfer", + "memo": "", + "metadata": { + "name": "Tether USD", + "symbol": "USDT", + "token_id": "TR7NHqjeKQxGTCi8q8ZY4pL8otSzgjLj6t", + "decimals": 6, + "value": "50000000", + "from": "TM1zzNDZD2DPASbKcgdVoTYhfmYgtfwx9D", + "to": "TXJTFuXzfoPbWKCnw47AYxMzgVPUyhJGRd" + } + }, + { + "id": "c4052b526e5cd21e1f023c31cce6b6a13eb9d8aeae3ae80fcefe6038dfbeb022", + "coin": 195, + "from": "TM1zzNDZD2DPASbKcgdVoTYhfmYgtfwx9D", + "to": "TXJTFuXzfoPbWKCnw47AYxMzgVPUyhJGRd", + "fee": "0", + "date": 1592757066, + "block": 0, + "status": "completed", + "sequence": 0, + "type": "token_transfer", + "memo": "", + "metadata": { + "name": "Tether USD", + "symbol": "USDT", + "token_id": "TR7NHqjeKQxGTCi8q8ZY4pL8otSzgjLj6t", + "decimals": 6, + "value": "50000000", + "from": "TM1zzNDZD2DPASbKcgdVoTYhfmYgtfwx9D", + "to": "TXJTFuXzfoPbWKCnw47AYxMzgVPUyhJGRd" + } + }, + { + "id": "0b52a4ef9fb8c13fbfae2b8c3506333ec1d718f307062a15f170562818a01d0a", + "coin": 195, + "from": "TM1zzNDZD2DPASbKcgdVoTYhfmYgtfwx9D", + "to": "TFNEJYAKBVgc17X6fPppZ8ayaf9yswmMYV", + "fee": "0", + "date": 1592756784, + "block": 0, + "status": "completed", + "sequence": 0, + "type": "token_transfer", + "memo": "", + "metadata": { + "name": "Tether USD", + "symbol": "USDT", + "token_id": "TR7NHqjeKQxGTCi8q8ZY4pL8otSzgjLj6t", + "decimals": 6, + "value": "3988000000", + "from": "TM1zzNDZD2DPASbKcgdVoTYhfmYgtfwx9D", + "to": "TFNEJYAKBVgc17X6fPppZ8ayaf9yswmMYV" + } + }, + { + "id": "19d2ec6174bf64beb1061475f6429cba03b64944a763686cc3551447d0e8d9d5", + "coin": 195, + "from": "TM1zzNDZD2DPASbKcgdVoTYhfmYgtfwx9D", + "to": "TGYETHZr2MTkFDe8GqwdVFPfadofTVk4am", + "fee": "0", + "date": 1592756763, + "block": 0, + "status": "completed", + "sequence": 0, + "type": "token_transfer", + "memo": "", + "metadata": { + "name": "Tether USD", + "symbol": "USDT", + "token_id": "TR7NHqjeKQxGTCi8q8ZY4pL8otSzgjLj6t", + "decimals": 6, + "value": "640990000", + "from": "TM1zzNDZD2DPASbKcgdVoTYhfmYgtfwx9D", + "to": "TGYETHZr2MTkFDe8GqwdVFPfadofTVk4am" + } + }, + { + "id": "efb7d44305759cfb189c9fd22720609a2ddeb7fbd7c8afe1dd8851342471da8d", + "coin": 195, + "from": "TAxbLztoanFhYu4TuS5RabaJYGnUkfzNKG", + "to": "TM1zzNDZD2DPASbKcgdVoTYhfmYgtfwx9D", + "fee": "0", + "date": 1592756631, + "block": 0, + "status": "completed", + "sequence": 0, + "type": "token_transfer", + "memo": "", + "metadata": { + "name": "Tether USD", + "symbol": "USDT", + "token_id": "TR7NHqjeKQxGTCi8q8ZY4pL8otSzgjLj6t", + "decimals": 6, + "value": "1062000000", + "from": "TAxbLztoanFhYu4TuS5RabaJYGnUkfzNKG", + "to": "TM1zzNDZD2DPASbKcgdVoTYhfmYgtfwx9D" + } + }, + { + "id": "48bd90dc3f12086178e65b9389caa8b3c74683937b86d4d61cdec77f0095994a", + "coin": 195, + "from": "TM1zzNDZD2DPASbKcgdVoTYhfmYgtfwx9D", + "to": "TGg7zHY9qd36aN3jLVDDRuiFeJjaaAtx8A", + "fee": "0", + "date": 1592756610, + "block": 0, + "status": "completed", + "sequence": 0, + "type": "token_transfer", + "memo": "", + "metadata": { + "name": "Tether USD", + "symbol": "USDT", + "token_id": "TR7NHqjeKQxGTCi8q8ZY4pL8otSzgjLj6t", + "decimals": 6, + "value": "2000000", + "from": "TM1zzNDZD2DPASbKcgdVoTYhfmYgtfwx9D", + "to": "TGg7zHY9qd36aN3jLVDDRuiFeJjaaAtx8A" + } + }, + { + "id": "afd5ae7e2462c9cc899c7f730b90fd2a5e4c1315e836c92468b504ed85f0b798", + "coin": 195, + "from": "TM1zzNDZD2DPASbKcgdVoTYhfmYgtfwx9D", + "to": "TN6Wy4j37wn3vxynynrKemWhDsUBHYje3R", + "fee": "0", + "date": 1592756589, + "block": 0, + "status": "completed", + "sequence": 0, + "type": "token_transfer", + "memo": "", + "metadata": { + "name": "Tether USD", + "symbol": "USDT", + "token_id": "TR7NHqjeKQxGTCi8q8ZY4pL8otSzgjLj6t", + "decimals": 6, + "value": "1000000000", + "from": "TM1zzNDZD2DPASbKcgdVoTYhfmYgtfwx9D", + "to": "TN6Wy4j37wn3vxynynrKemWhDsUBHYje3R" + } + }, + { + "id": "3d613031f4b2a0e19deeea030d1d18599b6d9799d2dd530005ead9712c6d219d", + "coin": 195, + "from": "TM1zzNDZD2DPASbKcgdVoTYhfmYgtfwx9D", + "to": "TXP7prwMqugLFWZRwcJAWuKZ4UN4wz3ifq", + "fee": "0", + "date": 1592756583, + "block": 0, + "status": "completed", + "sequence": 0, + "type": "token_transfer", + "memo": "", + "metadata": { + "name": "Tether USD", + "symbol": "USDT", + "token_id": "TR7NHqjeKQxGTCi8q8ZY4pL8otSzgjLj6t", + "decimals": 6, + "value": "21200000", + "from": "TM1zzNDZD2DPASbKcgdVoTYhfmYgtfwx9D", + "to": "TXP7prwMqugLFWZRwcJAWuKZ4UN4wz3ifq" + } + }, + { + "id": "cbe359c2574efbdc8fc6a892ffc54812837295067c9816d41734126c82d0c141", + "coin": 195, + "from": "TM1zzNDZD2DPASbKcgdVoTYhfmYgtfwx9D", + "to": "TBStJt5wDtLqeUvGEasqd55uo1CbDTCsf5", + "fee": "0", + "date": 1592756583, + "block": 0, + "status": "completed", + "sequence": 0, + "type": "token_transfer", + "memo": "", + "metadata": { + "name": "Tether USD", + "symbol": "USDT", + "token_id": "TR7NHqjeKQxGTCi8q8ZY4pL8otSzgjLj6t", + "decimals": 6, + "value": "125000000", + "from": "TM1zzNDZD2DPASbKcgdVoTYhfmYgtfwx9D", + "to": "TBStJt5wDtLqeUvGEasqd55uo1CbDTCsf5" + } + }, + { + "id": "c87248b02a4caaa6f443c1b8c4d4588c8dd281a4687b73e6afecfba6741b50d8", + "coin": 195, + "from": "TM1zzNDZD2DPASbKcgdVoTYhfmYgtfwx9D", + "to": "TJ2qhZSQ9g5YqEAJgYfPZZxn1djbf5ogkC", + "fee": "0", + "date": 1592756583, + "block": 0, + "status": "completed", + "sequence": 0, + "type": "token_transfer", + "memo": "", + "metadata": { + "name": "Tether USD", + "symbol": "USDT", + "token_id": "TR7NHqjeKQxGTCi8q8ZY4pL8otSzgjLj6t", + "decimals": 6, + "value": "5277600000", + "from": "TM1zzNDZD2DPASbKcgdVoTYhfmYgtfwx9D", + "to": "TJ2qhZSQ9g5YqEAJgYfPZZxn1djbf5ogkC" + } + }, + { + "id": "8584f1b6a70ead8232fed19bd653ba13e4c2a8befd070f4a9a06eca3a2e3e548", + "coin": 195, + "from": "TM1zzNDZD2DPASbKcgdVoTYhfmYgtfwx9D", + "to": "TRqyhrttStrn1o7gS3mmgKrmkVw6qyw23W", + "fee": "0", + "date": 1592756583, + "block": 0, + "status": "completed", + "sequence": 0, + "type": "token_transfer", + "memo": "", + "metadata": { + "name": "Tether USD", + "symbol": "USDT", + "token_id": "TR7NHqjeKQxGTCi8q8ZY4pL8otSzgjLj6t", + "decimals": 6, + "value": "485342000", + "from": "TM1zzNDZD2DPASbKcgdVoTYhfmYgtfwx9D", + "to": "TRqyhrttStrn1o7gS3mmgKrmkVw6qyw23W" + } + }, + { + "id": "2b28b69e6747db68647acc3a62c45da5355b97acd8d2c260ee752aa9bd63a624", + "coin": 195, + "from": "TM1zzNDZD2DPASbKcgdVoTYhfmYgtfwx9D", + "to": "TLdYhJeKCLKxVm33JL8GAyi6i6zrSz8VFr", + "fee": "0", + "date": 1592756583, + "block": 0, + "status": "completed", + "sequence": 0, + "type": "token_transfer", + "memo": "", + "metadata": { + "name": "Tether USD", + "symbol": "USDT", + "token_id": "TR7NHqjeKQxGTCi8q8ZY4pL8otSzgjLj6t", + "decimals": 6, + "value": "1000000000", + "from": "TM1zzNDZD2DPASbKcgdVoTYhfmYgtfwx9D", + "to": "TLdYhJeKCLKxVm33JL8GAyi6i6zrSz8VFr" + } + }, + { + "id": "1da6576dec0bd303f56cbfb5712f782e0a56a8713cb661f8afd2f2533e5c6209", + "coin": 195, + "from": "TM1zzNDZD2DPASbKcgdVoTYhfmYgtfwx9D", + "to": "TDpRQi5HguNpasa9Cn7AJyrn646nRDAH6x", + "fee": "0", + "date": 1592756583, + "block": 0, + "status": "completed", + "sequence": 0, + "type": "token_transfer", + "memo": "", + "metadata": { + "name": "Tether USD", + "symbol": "USDT", + "token_id": "TR7NHqjeKQxGTCi8q8ZY4pL8otSzgjLj6t", + "decimals": 6, + "value": "2000000000", + "from": "TM1zzNDZD2DPASbKcgdVoTYhfmYgtfwx9D", + "to": "TDpRQi5HguNpasa9Cn7AJyrn646nRDAH6x" + } + }, + { + "id": "f9c86cce1873cb816d6cd8718e76df8839172add293bbc8d11a5f98c80f9e322", + "coin": 195, + "from": "TM1zzNDZD2DPASbKcgdVoTYhfmYgtfwx9D", + "to": "TGy3K5iDbxm8SM34UTWWniNsS13FtLnHkK", + "fee": "0", + "date": 1592756583, + "block": 0, + "status": "completed", + "sequence": 0, + "type": "token_transfer", + "memo": "", + "metadata": { + "name": "Tether USD", + "symbol": "USDT", + "token_id": "TR7NHqjeKQxGTCi8q8ZY4pL8otSzgjLj6t", + "decimals": 6, + "value": "24216600000", + "from": "TM1zzNDZD2DPASbKcgdVoTYhfmYgtfwx9D", + "to": "TGy3K5iDbxm8SM34UTWWniNsS13FtLnHkK" + } + }, + { + "id": "75eb35734857daa79c38ef923a7e7eb2e3dfb23d2722762fd2b180651021643f", + "coin": 195, + "from": "TGMTZMty79L9psKi5b4vwXZPJaiCb9k6mV", + "to": "TM1zzNDZD2DPASbKcgdVoTYhfmYgtfwx9D", + "fee": "0", + "date": 1592756541, + "block": 0, + "status": "completed", + "sequence": 0, + "type": "token_transfer", + "memo": "", + "metadata": { + "name": "Tether USD", + "symbol": "USDT", + "token_id": "TR7NHqjeKQxGTCi8q8ZY4pL8otSzgjLj6t", + "decimals": 6, + "value": "8241997837", + "from": "TGMTZMty79L9psKi5b4vwXZPJaiCb9k6mV", + "to": "TM1zzNDZD2DPASbKcgdVoTYhfmYgtfwx9D" + } + }, + { + "id": "adee73dadce006ff848ff30d8c5c41f033be2e5e1a8b875f6dbbaab524177d08", + "coin": 195, + "from": "TUwgGpDrVBc3uDZg3Tj9BZZN8xkLK29yzH", + "to": "TM1zzNDZD2DPASbKcgdVoTYhfmYgtfwx9D", + "fee": "0", + "date": 1592756220, + "block": 0, + "status": "completed", + "sequence": 0, + "type": "token_transfer", + "memo": "", + "metadata": { + "name": "Tether USD", + "symbol": "USDT", + "token_id": "TR7NHqjeKQxGTCi8q8ZY4pL8otSzgjLj6t", + "decimals": 6, + "value": "18000000000", + "from": "TUwgGpDrVBc3uDZg3Tj9BZZN8xkLK29yzH", + "to": "TM1zzNDZD2DPASbKcgdVoTYhfmYgtfwx9D" + } + }, + { + "id": "3655a1156c9adcb876c6c9c9e0f5f1f39704ac4c7296fea05fedf5ca8f6b1a19", + "coin": 195, + "from": "TMaDtMFGJ8BBiNXchGBQmRBWi2mpfi2kdV", + "to": "TM1zzNDZD2DPASbKcgdVoTYhfmYgtfwx9D", + "fee": "0", + "date": 1592755962, + "block": 0, + "status": "completed", + "sequence": 0, + "type": "token_transfer", + "memo": "", + "metadata": { + "name": "Tether USD", + "symbol": "USDT", + "token_id": "TR7NHqjeKQxGTCi8q8ZY4pL8otSzgjLj6t", + "decimals": 6, + "value": "863399098", + "from": "TMaDtMFGJ8BBiNXchGBQmRBWi2mpfi2kdV", + "to": "TM1zzNDZD2DPASbKcgdVoTYhfmYgtfwx9D" + } + }, + { + "id": "03574741eb0016050a19f181e4acc4b20b70f41e11e63140c9556c31eae09fba", + "coin": 195, + "from": "TM1zzNDZD2DPASbKcgdVoTYhfmYgtfwx9D", + "to": "TH7AaBSjS4NYuF3r8vXQcuwVXmGrv9iwYQ", + "fee": "0", + "date": 1592755740, + "block": 0, + "status": "completed", + "sequence": 0, + "type": "token_transfer", + "memo": "", + "metadata": { + "name": "Tether USD", + "symbol": "USDT", + "token_id": "TR7NHqjeKQxGTCi8q8ZY4pL8otSzgjLj6t", + "decimals": 6, + "value": "20000000", + "from": "TM1zzNDZD2DPASbKcgdVoTYhfmYgtfwx9D", + "to": "TH7AaBSjS4NYuF3r8vXQcuwVXmGrv9iwYQ" + } + }, + { + "id": "f3aa00595996e31dbe9528a3cb21bff987f333bf1f675420ba4fa2ad43c8205f", + "coin": 195, + "from": "TM1zzNDZD2DPASbKcgdVoTYhfmYgtfwx9D", + "to": "TA1VFEzYiU8oB9P1xdhMaFJ7BZ6FvUTyug", + "fee": "0", + "date": 1592755722, + "block": 0, + "status": "completed", + "sequence": 0, + "type": "token_transfer", + "memo": "", + "metadata": { + "name": "Tether USD", + "symbol": "USDT", + "token_id": "TR7NHqjeKQxGTCi8q8ZY4pL8otSzgjLj6t", + "decimals": 6, + "value": "21161340000", + "from": "TM1zzNDZD2DPASbKcgdVoTYhfmYgtfwx9D", + "to": "TA1VFEzYiU8oB9P1xdhMaFJ7BZ6FvUTyug" + } + } +] diff --git a/platform/tron/mocks/tokens/accounts_response.json b/platform/tron/mocks/tokens/accounts_response.json new file mode 100644 index 000000000..fa3ddfdd6 --- /dev/null +++ b/platform/tron/mocks/tokens/accounts_response.json @@ -0,0 +1,87 @@ +{ + "success": true, + "meta": { "at": 1592753781505, "page_size": 1 }, + "data": [ + { + "account_resource": { "latest_consume_time_for_energy": 1592753721000 }, + "address": "4179309abcff2cf531070ca9222a1f72c4a5136874", + "asset": [ + { "key": "IPFS", "value": 1273 }, + { "key": "TRXTestCoin", "value": 113 }, + { "key": "Skypeople", "value": 145 }, + { "key": "binance", "value": 416 }, + { "key": "BitTorrent", "value": 596 }, + { "key": "ofoBike", "value": 242 }, + { "key": "FomoThreeD", "value": 62 }, + { "key": "Durex", "value": 53 }, + { "key": "Pornhub", "value": 56 }, + { "key": "NBACoin", "value": 599 }, + { "key": "HuobiToken", "value": 628 }, + { "key": "MacCoin", "value": 234 }, + { "key": "Messenger", "value": 113 }, + { "key": "Bithumb", "value": 206 }, + { "key": "James", "value": 61 }, + { "key": "RingCoin", "value": 25 }, + { "key": "DACC", "value": 7 }, + { "key": "OtonamiS", "value": 1 }, + { "key": "intrxChain", "value": 1 }, + { "key": "TRONEX", "value": 30 }, + { "key": "Petro", "value": 1 }, + { "key": "KrMaToken", "value": 200 }, + { "key": "KsumNole", "value": 7 }, + { "key": "eFilingPlus", "value": 1000 }, + { "key": "Tarquin", "value": 10 }, + { "key": "KiloReX", "value": 10 }, + { "key": "BESTCOIN", "value": 2 }, + { "key": "Makememillionaire", "value": 100 }, + { "key": "MedicCoin", "value": 1 }, + { "key": "DMT", "value": 1 }, + { "key": "MedIBlock", "value": 100 }, + { "key": "ethereum", "value": 1000 }, + { "key": "COLORBIKE", "value": 1300000 }, + { "key": "WatsonAI", "value": 11 }, + { "key": "Litcoin", "value": 10 }, + { "key": "TronMatrixAI", "value": 17 }, + { "key": "GoodKarma", "value": 100 }, + { "key": "CryptoBankCoin", "value": 12 }, + { "key": "EXODUS", "value": 12 }, + { "key": "TRONO", "value": 100 }, + { "key": "NMIToken", "value": 100 }, + { "key": "Ton", "value": 50 }, + { "key": "Twx", "value": 5 }, + { "key": "TronLottery", "value": 10 }, + { "key": "TronTokensGuardian", "value": 3 }, + { "key": "TRONONE", "value": 13 }, + { "key": "ELVIS", "value": 200 }, + { "key": "URUNIT", "value": 12 }, + { "key": "CRYPTYK", "value": 15 }, + { "key": "TronRoyal", "value": 10 } + ], + "assetV2": [ + { "key": "1000542", "value": 62 }, + { "key": "1000567", "value": 0 } + ], + "balance": 346991703615806, + "create_time": 1535532969000, + "free_asset_net_usageV2": [ + { "key": "1000542", "value": 0 }, + { "key": "1000567", "value": 0 } + ], + "free_net_usage": 4828, + "latest_consume_free_time": 1592751174000, + "latest_opration_time": 1592753721000, + "trc20": [ + { "TCFLL5dx5ZJdKnWuesXxi1VPwjLVmWZZy9": "955973733483987848990056" }, + { "TLa2f6VPqDgRE67v1736s7bJ8Ray5wYjU7": "191543058623486" }, + { "TG7Z1ptC7nRkaniDVRhHSyLycaroaS5PdK": "100000000000000" }, + { "TR7NHqjeKQxGTCi8q8ZY4pL8otSzgjLj6t": "6849738905400" }, + { "TMCMPzmosnQ8UAYW1zcBwjLTxDq8ce4Y5e": "5000000000" }, + { "TJSF4iVkzkRkYwEVNkqJkeGDaZpnFbGy9x": "500000000" }, + { "TTvVC9jv5AfDdHuGeCMcQg6QftmNnfQiVm": "20000000" }, + { "TCRhVHPv6efvXgogNMhiunAMXFKcMmv2pF": "175798" }, + { "TPt8DTDBZYfJ9fuyRjdWJr4PP68tRfptLG": "20000" }, + { "TLKyLt4MXuvvdFvUUc3Zma4rZyj2t87Mak": "1" } + ] + } + ] +} diff --git a/platform/tron/mocks/tokens/accounts_txs_response.json b/platform/tron/mocks/tokens/accounts_txs_response.json new file mode 100644 index 000000000..ce7f0870c --- /dev/null +++ b/platform/tron/mocks/tokens/accounts_txs_response.json @@ -0,0 +1,931 @@ +{ + "success": true, + "meta": { + "at": 1592755486554, + "page_size": 25, + "fingerprint": "4CwRecxbH99eRRkU2FFkGRCvoQGwphNyRcTTiM1GfUrkoQ1fG9Kcc8ADZo7pSCYXja28JWKUACy2Xt6UG1Fa5tSZh5dqpUEuTi1W", + "links": { + "next": "https://api.trongrid.io:443/v1/accounts/TM1zzNDZD2DPASbKcgdVoTYhfmYgtfwx9R/transactions?limit=25&order_by=block_timestamp%2Cdesc&token_id=&fingerprint=4CwRecxbH99eRRkU2FFkGRCvoQGwphNyRcTTiM1GfUrkoQ1fG9Kcc8ADZo7pSCYXja28JWKUACy2Xt6UG1Fa5tSZh5dqpUEuTi1W" + } + }, + "data": [ + { + "blockNumber": 20829763, + "block_timestamp": 1592755239000, + "energy_fee": 296310, + "energy_usage": 0, + "energy_usage_total": 29631, + "internal_transactions": [], + "net_fee": 3460, + "net_usage": 0, + "raw_data": { + "contract": [ + { + "parameter": { + "type_url": "type.googleapis.com/protocol.TriggerSmartContract", + "value": { + "call_value": 0, + "contract_address": "41a614f803b6fd780986a42c78ec9c7f77e6ded13c", + "data": "a9059cbb0000000000000000000000413b334848f75cf8c27ec975bcc7cc7e54f140b3c000000000000000000000000000000000000000000000000000000000cd0e33a0", + "owner_address": "4179309abcff2cf531070ca9222a1f72c4a5136874" + } + }, + "type": "TriggerSmartContract" + } + ], + "expiration": 1592758890000, + "fee_limit": 1000000000, + "ref_block_bytes": "d62e", + "ref_block_hash": "bbf7d06ee7004d5a", + "timestamp": 1592755233594 + }, + "raw_data_hex": "0a02d62e2208bbf7d06ee7004d5a4090dccfbead2e5aae01081f12a9010a31747970652e676f6f676c65617069732e636f6d2f70726f746f636f6c2e54726967676572536d617274436f6e747261637412740a154179309abcff2cf531070ca9222a1f72c4a5136874121541a614f803b6fd780986a42c78ec9c7f77e6ded13c2244a9059cbb0000000000000000000000413b334848f75cf8c27ec975bcc7cc7e54f140b3c000000000000000000000000000000000000000000000000000000000cd0e33a070bac6f0bcad2e90018094ebdc03", + "ret": [{ "code": "SUCESS", "contractRet": "SUCCESS", "fee": 299770 }], + "signature": [ + "c9a405be8b12f92747cc0f0d979606807a03edcefd154bcf517ce26f8bf681400d6cdacda11c98e7ae61d51905f7113658a786d6022b97e025f5a7e99b53845d01" + ], + "txID": "18f5908a7e208e16bfb892a5b06df75675d3142d03a0d99d270ac46143b78d06" + }, + { + "blockNumber": 20829760, + "block_timestamp": 1592755230000, + "energy_fee": 146310, + "energy_usage": 0, + "energy_usage_total": 14631, + "internal_transactions": [], + "net_fee": 3460, + "net_usage": 0, + "raw_data": { + "contract": [ + { + "parameter": { + "type_url": "type.googleapis.com/protocol.TriggerSmartContract", + "value": { + "call_value": 0, + "contract_address": "41a614f803b6fd780986a42c78ec9c7f77e6ded13c", + "data": "a9059cbb00000000000000000000004158a82464024027b8e81bd1997cc7ba8f26a01314000000000000000000000000000000000000000000000000000000001dce7a58", + "owner_address": "4179309abcff2cf531070ca9222a1f72c4a5136874" + } + }, + "type": "TriggerSmartContract" + } + ], + "expiration": 1592758881000, + "fee_limit": 1000000000, + "ref_block_bytes": "d62b", + "ref_block_hash": "38ebe631e633b827", + "timestamp": 1592755223352 + }, + "raw_data_hex": "0a02d62b220838ebe631e633b82740e895cfbead2e5aae01081f12a9010a31747970652e676f6f676c65617069732e636f6d2f70726f746f636f6c2e54726967676572536d617274436f6e747261637412740a154179309abcff2cf531070ca9222a1f72c4a5136874121541a614f803b6fd780986a42c78ec9c7f77e6ded13c2244a9059cbb00000000000000000000004158a82464024027b8e81bd1997cc7ba8f26a01314000000000000000000000000000000000000000000000000000000001dce7a5870b8f6efbcad2e90018094ebdc03", + "ret": [{ "code": "SUCESS", "contractRet": "SUCCESS", "fee": 149770 }], + "signature": [ + "39ee8b2e7ab589538f3a976644399ba60667ede4d9611229298d52f5aeb01a6624e2346703d8a19edc9f457b89a0dbb800ae87d049ad3a7d72353fde77635f1a00" + ], + "txID": "2a9eda92b9a2a0e56d29000ad24daae7d577c5db44d2b737f6a35584cd81b5e0" + }, + { + "blockNumber": 20829760, + "block_timestamp": 1592755230000, + "energy_fee": 119110, + "energy_usage": 0, + "energy_usage_total": 14631, + "internal_transactions": [], + "net_fee": 3460, + "net_usage": 0, + "raw_data": { + "contract": [ + { + "parameter": { + "type_url": "type.googleapis.com/protocol.TriggerSmartContract", + "value": { + "call_value": 0, + "contract_address": "41a614f803b6fd780986a42c78ec9c7f77e6ded13c", + "data": "a9059cbb0000000000000000000000413c51c36069e0a1fdf3278907ecd5a05e90a3ac84000000000000000000000000000000000000000000000000000000037e11d600", + "owner_address": "4179309abcff2cf531070ca9222a1f72c4a5136874" + } + }, + "type": "TriggerSmartContract" + } + ], + "expiration": 1592758881000, + "fee_limit": 1000000000, + "ref_block_bytes": "d62b", + "ref_block_hash": "38ebe631e633b827", + "timestamp": 1592755223053 + }, + "raw_data_hex": "0a02d62b220838ebe631e633b82740e895cfbead2e5aae01081f12a9010a31747970652e676f6f676c65617069732e636f6d2f70726f746f636f6c2e54726967676572536d617274436f6e747261637412740a154179309abcff2cf531070ca9222a1f72c4a5136874121541a614f803b6fd780986a42c78ec9c7f77e6ded13c2244a9059cbb0000000000000000000000413c51c36069e0a1fdf3278907ecd5a05e90a3ac84000000000000000000000000000000000000000000000000000000037e11d600708df4efbcad2e90018094ebdc03", + "ret": [{ "code": "SUCESS", "contractRet": "SUCCESS", "fee": 122570 }], + "signature": [ + "710a4b8543a9f605acc809ebe5b8a3a3b4681ebf2123fcdda39187bde86c9bc839cf6d882d9d15052b94ed6bba6474f9fdf09e73afefe40f6bad909029cadd2500" + ], + "txID": "c838b8a683d39c6f1a8a173e6fffc5cc9122acc690f5e35fa7c1935cc5eae540" + }, + { + "blockNumber": 20829742, + "block_timestamp": 1592755176000, + "energy_fee": 296310, + "energy_usage": 0, + "energy_usage_total": 29631, + "internal_transactions": [], + "net_fee": 3460, + "net_usage": 0, + "raw_data": { + "contract": [ + { + "parameter": { + "type_url": "type.googleapis.com/protocol.TriggerSmartContract", + "value": { + "call_value": 0, + "contract_address": "41a614f803b6fd780986a42c78ec9c7f77e6ded13c", + "data": "a9059cbb000000000000000000000041c80ab7aac02a3d4b3d89ee781cddce55286bcf2d000000000000000000000000000000000000000000000000000000000bebc200", + "owner_address": "4179309abcff2cf531070ca9222a1f72c4a5136874" + } + }, + "type": "TriggerSmartContract" + } + ], + "expiration": 1592758830000, + "fee_limit": 1000000000, + "ref_block_bytes": "d61a", + "ref_block_hash": "b1015d64daa873a3", + "timestamp": 1592755172703 + }, + "raw_data_hex": "0a02d61a2208b1015d64daa873a340b087ccbead2e5aae01081f12a9010a31747970652e676f6f676c65617069732e636f6d2f70726f746f636f6c2e54726967676572536d617274436f6e747261637412740a154179309abcff2cf531070ca9222a1f72c4a5136874121541a614f803b6fd780986a42c78ec9c7f77e6ded13c2244a9059cbb000000000000000000000041c80ab7aac02a3d4b3d89ee781cddce55286bcf2d000000000000000000000000000000000000000000000000000000000bebc20070dfeaecbcad2e90018094ebdc03", + "ret": [{ "code": "SUCESS", "contractRet": "SUCCESS", "fee": 299770 }], + "signature": [ + "a7583c4e402eff463b083de5cfcbaadc46ed8601e2346f20d01eb0ec7a6824d869be27371f8c0e5a38a708df724be60a818b9647757bdde73ed743ff9324115c01" + ], + "txID": "ad631a0e55bd2bb64747bf388dc92084c32506843c19a0a2b69234b4d4e56a6b" + }, + { + "blockNumber": 20829732, + "block_timestamp": 1592755146000, + "energy_fee": 231500, + "energy_usage": 0, + "energy_usage_total": 29631, + "internal_transactions": [], + "net_fee": 3460, + "net_usage": 0, + "raw_data": { + "contract": [ + { + "parameter": { + "type_url": "type.googleapis.com/protocol.TriggerSmartContract", + "value": { + "call_value": 0, + "contract_address": "41a614f803b6fd780986a42c78ec9c7f77e6ded13c", + "data": "a9059cbb0000000000000000000000410d4fd52433f30edd0b512f59fa021527bbd7de610000000000000000000000000000000000000000000000000000000001c9c380", + "owner_address": "4179309abcff2cf531070ca9222a1f72c4a5136874" + } + }, + "type": "TriggerSmartContract" + } + ], + "expiration": 1592758800000, + "fee_limit": 1000000000, + "ref_block_bytes": "d610", + "ref_block_hash": "2a14293035535e85", + "timestamp": 1592755142312 + }, + "raw_data_hex": "0a02d61022082a14293035535e8540809dcabead2e5aae01081f12a9010a31747970652e676f6f676c65617069732e636f6d2f70726f746f636f6c2e54726967676572536d617274436f6e747261637412740a154179309abcff2cf531070ca9222a1f72c4a5136874121541a614f803b6fd780986a42c78ec9c7f77e6ded13c2244a9059cbb0000000000000000000000410d4fd52433f30edd0b512f59fa021527bbd7de610000000000000000000000000000000000000000000000000000000001c9c38070a8fdeabcad2e90018094ebdc03", + "ret": [{ "code": "SUCESS", "contractRet": "SUCCESS", "fee": 234960 }], + "signature": [ + "3095c2130ee5d4da72246a17098b587c25108e1c1884f9128911e079997dd25c45e0b0acfc99e3ee4367c4670e2117dd24884c32ae0ea15ec9f9368910e4c42801" + ], + "txID": "f1920eefa4de8370bc349fbd6ca73e24d9000d9d8fe5c71260a2902d3b49b02a" + }, + { + "blockNumber": 20829718, + "block_timestamp": 1592755104000, + "energy_fee": 166720, + "energy_usage": 0, + "energy_usage_total": 29631, + "internal_transactions": [], + "net_fee": 3460, + "net_usage": 0, + "raw_data": { + "contract": [ + { + "parameter": { + "type_url": "type.googleapis.com/protocol.TriggerSmartContract", + "value": { + "call_value": 0, + "contract_address": "41a614f803b6fd780986a42c78ec9c7f77e6ded13c", + "data": "a9059cbb00000000000000000000004135c4d4a5544d25a2f25a7cda73d57c45a36578bc0000000000000000000000000000000000000000000000000000000010089d40", + "owner_address": "4179309abcff2cf531070ca9222a1f72c4a5136874" + } + }, + "type": "TriggerSmartContract" + } + ], + "expiration": 1592758761000, + "fee_limit": 1000000000, + "ref_block_bytes": "d603", + "ref_block_hash": "f84579e34d118430", + "timestamp": 1592755101713 + }, + "raw_data_hex": "0a02d6032208f84579e34d11843040a8ecc7bead2e5aae01081f12a9010a31747970652e676f6f676c65617069732e636f6d2f70726f746f636f6c2e54726967676572536d617274436f6e747261637412740a154179309abcff2cf531070ca9222a1f72c4a5136874121541a614f803b6fd780986a42c78ec9c7f77e6ded13c2244a9059cbb00000000000000000000004135c4d4a5544d25a2f25a7cda73d57c45a36578bc0000000000000000000000000000000000000000000000000000000010089d407091c0e8bcad2e90018094ebdc03", + "ret": [{ "code": "SUCESS", "contractRet": "SUCCESS", "fee": 170180 }], + "signature": [ + "816b2747c6c1f6be139d233118b4b1e3c3942d62f56d1b0c8a496851ea233c5c1b6e0e0a13e22c3a4c1bd106eb6c0e987d5c84f9fcc29ee7b86bd4d1874ade9601" + ], + "txID": "cec1061166e4924123356b8066872b641956691d1b1f11a12f293c54e7178362" + }, + { + "blockNumber": 20829716, + "block_timestamp": 1592755098000, + "energy_fee": 0, + "energy_usage": 0, + "energy_usage_total": 0, + "internal_transactions": [], + "net_fee": 2690, + "net_usage": 0, + "raw_data": { + "contract": [ + { + "parameter": { + "type_url": "type.googleapis.com/protocol.TransferContract", + "value": { + "amount": 13195916000, + "owner_address": "4179309abcff2cf531070ca9222a1f72c4a5136874", + "to_address": "41d9378a9849912a41ec1f0e4677c074edf0516241" + } + }, + "type": "TransferContract" + } + ], + "expiration": 1592758749000, + "fee_limit": 0, + "ref_block_bytes": "d5ff", + "ref_block_hash": "c753125289c79c7c", + "timestamp": 1592755089996 + }, + "raw_data_hex": "0a02d5ff2208c753125289c79c7c40c88ec7bead2e5a69080112650a2d747970652e676f6f676c65617069732e636f6d2f70726f746f636f6c2e5472616e73666572436f6e747261637412340a154179309abcff2cf531070ca9222a1f72c4a5136874121541d9378a9849912a41ec1f0e4677c074edf051624118e0e5a6943170cce4e7bcad2e", + "ret": [{ "code": "SUCESS", "contractRet": "SUCCESS", "fee": 2690 }], + "signature": [ + "bae63e4214b0ab611079beabca020c82fbcada902f1f0c13106e7c4ba463efb25610d13b00b28cd19b54f648b88a4b05a08583b44b4f4179c2c605b42b22ad4b00" + ], + "txID": "3fca53c08ccb48bb625439a58998713d8ecc3dc1348cc3cfab912e0815b62b1a" + }, + { + "blockNumber": 20829708, + "block_timestamp": 1592755074000, + "energy_fee": 146310, + "energy_usage": 0, + "energy_usage_total": 14631, + "internal_transactions": [], + "net_fee": 3460, + "net_usage": 0, + "raw_data": { + "contract": [ + { + "parameter": { + "type_url": "type.googleapis.com/protocol.TriggerSmartContract", + "value": { + "call_value": 0, + "contract_address": "41a614f803b6fd780986a42c78ec9c7f77e6ded13c", + "data": "a9059cbb000000000000000000000041dd61209cd00224690ace233bb7257b054a49015a0000000000000000000000000000000000000000000000000000000005fc2678", + "owner_address": "4179309abcff2cf531070ca9222a1f72c4a5136874" + } + }, + "type": "TriggerSmartContract" + } + ], + "expiration": 1592758719000, + "fee_limit": 1000000000, + "ref_block_bytes": "d5f5", + "ref_block_hash": "84843b5d1de30802", + "timestamp": 1592755061404 + }, + "raw_data_hex": "0a02d5f5220884843b5d1de308024098a4c5bead2e5aae01081f12a9010a31747970652e676f6f676c65617069732e636f6d2f70726f746f636f6c2e54726967676572536d617274436f6e747261637412740a154179309abcff2cf531070ca9222a1f72c4a5136874121541a614f803b6fd780986a42c78ec9c7f77e6ded13c2244a9059cbb000000000000000000000041dd61209cd00224690ace233bb7257b054a49015a0000000000000000000000000000000000000000000000000000000005fc2678709c85e6bcad2e90018094ebdc03", + "ret": [{ "code": "SUCESS", "contractRet": "SUCCESS", "fee": 149770 }], + "signature": [ + "6dd6709cee109df62c3a7f196f45d3efa16c25738c1c4ea371cce18443016c8911a2d65fd4f2d7b4932aed34634169adc981db081522b094e63d9528882b3de801" + ], + "txID": "8e886732999efe30e0d7c93eee40c41f058f33c82194141317768810a5a84b82" + }, + { + "blockNumber": 20829681, + "block_timestamp": 1592754993000, + "energy_fee": 231500, + "energy_usage": 0, + "energy_usage_total": 29631, + "internal_transactions": [], + "net_fee": 3460, + "net_usage": 0, + "raw_data": { + "contract": [ + { + "parameter": { + "type_url": "type.googleapis.com/protocol.TriggerSmartContract", + "value": { + "call_value": 0, + "contract_address": "41a614f803b6fd780986a42c78ec9c7f77e6ded13c", + "data": "a9059cbb000000000000000000000041dd61209cd00224690ace233bb7257b054a49015a0000000000000000000000000000000000000000000000000000000005e5eb10", + "owner_address": "4179309abcff2cf531070ca9222a1f72c4a5136874" + } + }, + "type": "TriggerSmartContract" + } + ], + "expiration": 1592758638000, + "fee_limit": 1000000000, + "ref_block_bytes": "d5da", + "ref_block_hash": "3234615516f16ee9", + "timestamp": 1592754980996 + }, + "raw_data_hex": "0a02d5da22083234615516f16ee940b0abc0bead2e5aae01081f12a9010a31747970652e676f6f676c65617069732e636f6d2f70726f746f636f6c2e54726967676572536d617274436f6e747261637412740a154179309abcff2cf531070ca9222a1f72c4a5136874121541a614f803b6fd780986a42c78ec9c7f77e6ded13c2244a9059cbb000000000000000000000041dd61209cd00224690ace233bb7257b054a49015a0000000000000000000000000000000000000000000000000000000005e5eb10708491e1bcad2e90018094ebdc03", + "ret": [{ "code": "SUCESS", "contractRet": "SUCCESS", "fee": 234960 }], + "signature": [ + "896243c9d9c8ba595deafb81b7c4fc283271e0f46aa7031f270d91a383ce997a09f4a3aa6fb0478a7dac9b7df295dcf232f8bf4941583848f45bd8e258f9482e01" + ], + "txID": "8b7c9f9f29cbf9ced22761f918d19471b3bb638438e6cc23e8104fed7dda1ef3" + }, + { + "blockNumber": 20829627, + "block_timestamp": 1592754831000, + "energy_fee": 0, + "energy_usage": 0, + "energy_usage_total": 0, + "internal_transactions": [], + "net_fee": 2850, + "net_usage": 0, + "raw_data": { + "contract": [ + { + "parameter": { + "type_url": "type.googleapis.com/protocol.TransferAssetContract", + "value": { + "amount": 7639170000000, + "asset_name": "1002000", + "owner_address": "4179309abcff2cf531070ca9222a1f72c4a5136874", + "to_address": "410a60e164aa897ef76779164dff6e36161980c6fb" + } + }, + "type": "TransferAssetContract" + } + ], + "expiration": 1592758479000, + "fee_limit": 0, + "ref_block_bytes": "d5a5", + "ref_block_hash": "462e1cfdbe99a85b", + "timestamp": 1592754820511 + }, + "raw_data_hex": "0a02d5a52208462e1cfdbe99a85b4098d1b6bead2e5a79080212750a32747970652e676f6f676c65617069732e636f6d2f70726f746f636f6c2e5472616e736665724173736574436f6e7472616374123f0a073130303230303012154179309abcff2cf531070ca9222a1f72c4a51368741a15410a60e164aa897ef76779164dff6e36161980c6fb2080c98e90aade01709fabd7bcad2e", + "ret": [{ "code": "SUCESS", "contractRet": "SUCCESS", "fee": 2850 }], + "signature": [ + "b49c878a8e85339fc4917e7f20625b38b941871c86572d2c01322ec26575c7024c34b498e464109a03f8e42df24cc0868910a0e7b1f7c174f5005a483a93dac600" + ], + "txID": "79010512f8e58574cbd066d1a1bd1c7f46f65e59e3b7733010047ff8350f15f1" + }, + { + "blockNumber": 20829617, + "block_timestamp": 1592754801000, + "energy_fee": 296310, + "energy_usage": 0, + "energy_usage_total": 29631, + "internal_transactions": [], + "net_fee": 3460, + "net_usage": 0, + "raw_data": { + "contract": [ + { + "parameter": { + "type_url": "type.googleapis.com/protocol.TriggerSmartContract", + "value": { + "call_value": 0, + "contract_address": "41a614f803b6fd780986a42c78ec9c7f77e6ded13c", + "data": "a9059cbb0000000000000000000000412b764790f38a7373d56dfdf4f866fa027e28c8af0000000000000000000000000000000000000000000000000000000071006010", + "owner_address": "4179309abcff2cf531070ca9222a1f72c4a5136874" + } + }, + "type": "TriggerSmartContract" + } + ], + "expiration": 1592758449000, + "fee_limit": 1000000000, + "ref_block_bytes": "d59b", + "ref_block_hash": "beab372f7f7d493b", + "timestamp": 1592754790236 + }, + "raw_data_hex": "0a02d59b2208beab372f7f7d493b40e8e6b4bead2e5aae01081f12a9010a31747970652e676f6f676c65617069732e636f6d2f70726f746f636f6c2e54726967676572536d617274436f6e747261637412740a154179309abcff2cf531070ca9222a1f72c4a5136874121541a614f803b6fd780986a42c78ec9c7f77e6ded13c2244a9059cbb0000000000000000000000412b764790f38a7373d56dfdf4f866fa027e28c8af000000000000000000000000000000000000000000000000000000007100601070dcbed5bcad2e90018094ebdc03", + "ret": [{ "code": "SUCESS", "contractRet": "SUCCESS", "fee": 299770 }], + "signature": [ + "52b662780f176048c4fd9e8db15756d0ef397cb60a8be6ea3421993ec2c6e1636d9aaf8a596f9255c182284e1efbd5410e2a11d10b82b4e4fec5a43ffea357cc01" + ], + "txID": "809ec9beb99cf756bb02155199a35b766f3ec18dd6bea6b3d69dd38f6b51138f" + }, + { + "blockNumber": 20829617, + "block_timestamp": 1592754801000, + "energy_fee": 166700, + "energy_usage": 0, + "energy_usage_total": 29631, + "internal_transactions": [], + "net_fee": 3460, + "net_usage": 0, + "raw_data": { + "contract": [ + { + "parameter": { + "type_url": "type.googleapis.com/protocol.TriggerSmartContract", + "value": { + "call_value": 0, + "contract_address": "41a614f803b6fd780986a42c78ec9c7f77e6ded13c", + "data": "a9059cbb000000000000000000000041d8692da59c130875e13587a82bc93b917c49526a0000000000000000000000000000000000000000000000000000000054c92b70", + "owner_address": "4179309abcff2cf531070ca9222a1f72c4a5136874" + } + }, + "type": "TriggerSmartContract" + } + ], + "expiration": 1592758449000, + "fee_limit": 1000000000, + "ref_block_bytes": "d59b", + "ref_block_hash": "beab372f7f7d493b", + "timestamp": 1592754789857 + }, + "raw_data_hex": "0a02d59b2208beab372f7f7d493b40e8e6b4bead2e5aae01081f12a9010a31747970652e676f6f676c65617069732e636f6d2f70726f746f636f6c2e54726967676572536d617274436f6e747261637412740a154179309abcff2cf531070ca9222a1f72c4a5136874121541a614f803b6fd780986a42c78ec9c7f77e6ded13c2244a9059cbb000000000000000000000041d8692da59c130875e13587a82bc93b917c49526a0000000000000000000000000000000000000000000000000000000054c92b7070e1bbd5bcad2e90018094ebdc03", + "ret": [{ "code": "SUCESS", "contractRet": "SUCCESS", "fee": 170160 }], + "signature": [ + "fe96d2be46a37f89531d10cdca823ec82c603a3bb9f858aa76db20468e8d9d6058de643460e11b50e0982fa6ab6b81439cee6c9286b5d6bb7c18206e2ab066fb01" + ], + "txID": "bc0c429e33d3c668e5e5a55831efb3aba7e917c52cd3892aeb252f1a7b2ddb41" + }, + { + "blockNumber": 20829596, + "block_timestamp": 1592754738000, + "energy_fee": 166700, + "energy_usage": 0, + "energy_usage_total": 29631, + "internal_transactions": [], + "net_fee": 3460, + "net_usage": 0, + "raw_data": { + "contract": [ + { + "parameter": { + "type_url": "type.googleapis.com/protocol.TriggerSmartContract", + "value": { + "call_value": 0, + "contract_address": "41a614f803b6fd780986a42c78ec9c7f77e6ded13c", + "data": "a9059cbb000000000000000000000041ec853dc8fe0dab78d3234ba356ebae7984da322c00000000000000000000000000000000000000000000000000000004a817c800", + "owner_address": "4179309abcff2cf531070ca9222a1f72c4a5136874" + } + }, + "type": "TriggerSmartContract" + } + ], + "expiration": 1592758386000, + "fee_limit": 1000000000, + "ref_block_bytes": "d586", + "ref_block_hash": "4007c65312ba945c", + "timestamp": 1592754729408 + }, + "raw_data_hex": "0a02d58622084007c65312ba945c40d0fab0bead2e5aae01081f12a9010a31747970652e676f6f676c65617069732e636f6d2f70726f746f636f6c2e54726967676572536d617274436f6e747261637412740a154179309abcff2cf531070ca9222a1f72c4a5136874121541a614f803b6fd780986a42c78ec9c7f77e6ded13c2244a9059cbb000000000000000000000041ec853dc8fe0dab78d3234ba356ebae7984da322c00000000000000000000000000000000000000000000000000000004a817c80070c0e3d1bcad2e90018094ebdc03", + "ret": [{ "code": "SUCESS", "contractRet": "SUCCESS", "fee": 170160 }], + "signature": [ + "93119466b23346e095d256537f2bf8c639dd157f896eaaff972f0be83663bca34a21df4e25fa61ba071588a58f98874a58705844a8cc36a321bf30e722028c8201" + ], + "txID": "3bcd581a833abb16529e1f5187615866ba72f2e61c590c993f5b461ba5073d45" + }, + { + "blockNumber": 20829592, + "block_timestamp": 1592754726000, + "energy_fee": 296310, + "energy_usage": 0, + "energy_usage_total": 29631, + "internal_transactions": [], + "net_fee": 3460, + "net_usage": 0, + "raw_data": { + "contract": [ + { + "parameter": { + "type_url": "type.googleapis.com/protocol.TriggerSmartContract", + "value": { + "call_value": 0, + "contract_address": "41a614f803b6fd780986a42c78ec9c7f77e6ded13c", + "data": "a9059cbb0000000000000000000000413c51c36069e0a1fdf3278907ecd5a05e90a3ac8400000000000000000000000000000000000000000000000000000000001e8480", + "owner_address": "4179309abcff2cf531070ca9222a1f72c4a5136874" + } + }, + "type": "TriggerSmartContract" + } + ], + "expiration": 1592758377000, + "fee_limit": 1000000000, + "ref_block_bytes": "d583", + "ref_block_hash": "0bc07e9ae4eb32b0", + "timestamp": 1592754719032 + }, + "raw_data_hex": "0a02d58322080bc07e9ae4eb32b040a8b4b0bead2e5aae01081f12a9010a31747970652e676f6f676c65617069732e636f6d2f70726f746f636f6c2e54726967676572536d617274436f6e747261637412740a154179309abcff2cf531070ca9222a1f72c4a5136874121541a614f803b6fd780986a42c78ec9c7f77e6ded13c2244a9059cbb0000000000000000000000413c51c36069e0a1fdf3278907ecd5a05e90a3ac8400000000000000000000000000000000000000000000000000000000001e848070b892d1bcad2e90018094ebdc03", + "ret": [{ "code": "SUCESS", "contractRet": "SUCCESS", "fee": 299770 }], + "signature": [ + "80fe656c430afb348327f279a2d454d277bf64564111e49118ed85f1021528920ba5be044956084f543a087a61aa14b595a4fc2cc6aff2ad2ac5d7533a6b122f01" + ], + "txID": "3baff897a2b39720727549216ea6f4bc580eed2f239967e158e9e7ea74146822" + }, + { + "blockNumber": 20829589, + "block_timestamp": 1592754717000, + "energy_fee": 0, + "energy_usage": 0, + "energy_usage_total": 0, + "internal_transactions": [], + "net_fee": 2690, + "net_usage": 0, + "raw_data": { + "contract": [ + { + "parameter": { + "type_url": "type.googleapis.com/protocol.TransferContract", + "value": { + "amount": 8737000000, + "owner_address": "4179309abcff2cf531070ca9222a1f72c4a5136874", + "to_address": "412886fdc89587dbe8a57d0b9589581bd084384d5f" + } + }, + "type": "TransferContract" + } + ], + "expiration": 1592758368000, + "fee_limit": 0, + "ref_block_bytes": "d580", + "ref_block_hash": "ebf8d3b3837d87a8", + "timestamp": 1592754708731 + }, + "raw_data_hex": "0a02d5802208ebf8d3b3837d87a84080eeafbead2e5a69080112650a2d747970652e676f6f676c65617069732e636f6d2f70726f746f636f6c2e5472616e73666572436f6e747261637412340a154179309abcff2cf531070ca9222a1f72c4a51368741215412886fdc89587dbe8a57d0b9589581bd084384d5f18c09490c62070fbc1d0bcad2e", + "ret": [{ "code": "SUCESS", "contractRet": "SUCCESS", "fee": 2690 }], + "signature": [ + "b92bdde424aee97b4e7a63716056daa963afce89701bf6d8c8b1b6221f65afb94b8ff3865650aff83d590cad87359ae5f272ed732738093a0a9aa587cc3503aa01" + ], + "txID": "b38fb6328e1fa622b7762eed856778551845c33723491e36baf357f00cc48002" + }, + { + "blockNumber": 20829585, + "block_timestamp": 1592754705000, + "energy_fee": 43900, + "energy_usage": 0, + "energy_usage_total": 14631, + "internal_transactions": [], + "net_fee": 3460, + "net_usage": 0, + "raw_data": { + "contract": [ + { + "parameter": { + "type_url": "type.googleapis.com/protocol.TriggerSmartContract", + "value": { + "call_value": 0, + "contract_address": "41a614f803b6fd780986a42c78ec9c7f77e6ded13c", + "data": "a9059cbb0000000000000000000000416128e41b6aa8c531b05999c2861f846459fb10e60000000000000000000000000000000000000000000000000000000005f5e100", + "owner_address": "4179309abcff2cf531070ca9222a1f72c4a5136874" + } + }, + "type": "TriggerSmartContract" + } + ], + "expiration": 1592758356000, + "fee_limit": 1000000000, + "ref_block_bytes": "d57c", + "ref_block_hash": "c7c6e5795625dc5b", + "timestamp": 1592754698724 + }, + "raw_data_hex": "0a02d57c2208c7c6e5795625dc5b40a090afbead2e5aae01081f12a9010a31747970652e676f6f676c65617069732e636f6d2f70726f746f636f6c2e54726967676572536d617274436f6e747261637412740a154179309abcff2cf531070ca9222a1f72c4a5136874121541a614f803b6fd780986a42c78ec9c7f77e6ded13c2244a9059cbb0000000000000000000000416128e41b6aa8c531b05999c2861f846459fb10e60000000000000000000000000000000000000000000000000000000005f5e10070e4f3cfbcad2e90018094ebdc03", + "ret": [{ "code": "SUCESS", "contractRet": "SUCCESS", "fee": 47360 }], + "signature": [ + "b90e38665957e47ba8f7731e3b8c943471cd6ef9a95efcd25ad880323f2e397b56927e943c7e605a1996900fe269db6edbc7d7ff094f23393c6546ef0927bae300" + ], + "txID": "d8d53a627fa9f885ad77dcc2f3d3a5eceece36d1ef0f54990dff900484550304" + }, + { + "blockNumber": 20829577, + "block_timestamp": 1592754681000, + "energy_fee": 296310, + "energy_usage": 0, + "energy_usage_total": 29631, + "internal_transactions": [], + "net_fee": 3460, + "net_usage": 0, + "raw_data": { + "contract": [ + { + "parameter": { + "type_url": "type.googleapis.com/protocol.TriggerSmartContract", + "value": { + "call_value": 0, + "contract_address": "41a614f803b6fd780986a42c78ec9c7f77e6ded13c", + "data": "a9059cbb000000000000000000000041dd81641cca9a855b7a657153fdda9b3f469693660000000000000000000000000000000000000000000000000000000217a31ba0", + "owner_address": "4179309abcff2cf531070ca9222a1f72c4a5136874" + } + }, + "type": "TriggerSmartContract" + } + ], + "expiration": 1592758335000, + "fee_limit": 1000000000, + "ref_block_bytes": "d575", + "ref_block_hash": "003bba00242a2488", + "timestamp": 1592754678392 + }, + "raw_data_hex": "0a02d5752208003bba00242a24884098ecadbead2e5aae01081f12a9010a31747970652e676f6f676c65617069732e636f6d2f70726f746f636f6c2e54726967676572536d617274436f6e747261637412740a154179309abcff2cf531070ca9222a1f72c4a5136874121541a614f803b6fd780986a42c78ec9c7f77e6ded13c2244a9059cbb000000000000000000000041dd81641cca9a855b7a657153fdda9b3f469693660000000000000000000000000000000000000000000000000000000217a31ba070f8d4cebcad2e90018094ebdc03", + "ret": [{ "code": "SUCESS", "contractRet": "SUCCESS", "fee": 299770 }], + "signature": [ + "0abe6787b18631ae746b4a9c9669e3e878b88c3628a3656e3709b4036b14414525bdb9cdb3c97fce48c9d21f2afab9492a436861e2e85ec1f68bab078859eb1d01" + ], + "txID": "b419c05c877e0176619ec3659470c71822a7840a91a940169eaaf1abb9c38fea" + }, + { + "blockNumber": 20829564, + "block_timestamp": 1592754642000, + "energy_fee": 43900, + "energy_usage": 0, + "energy_usage_total": 14631, + "internal_transactions": [], + "net_fee": 3460, + "net_usage": 0, + "raw_data": { + "contract": [ + { + "parameter": { + "type_url": "type.googleapis.com/protocol.TriggerSmartContract", + "value": { + "call_value": 0, + "contract_address": "41a614f803b6fd780986a42c78ec9c7f77e6ded13c", + "data": "a9059cbb000000000000000000000041a3af64559a63856c625b02e9def8a4dc0f63f38b0000000000000000000000000000000000000000000000000000000010c18918", + "owner_address": "4179309abcff2cf531070ca9222a1f72c4a5136874" + } + }, + "type": "TriggerSmartContract" + } + ], + "expiration": 1592758287000, + "fee_limit": 1000000000, + "ref_block_bytes": "d565", + "ref_block_hash": "afd9deb62b6fa5e0", + "timestamp": 1592754628020 + }, + "raw_data_hex": "0a02d5652208afd9deb62b6fa5e04098f5aabead2e5aae01081f12a9010a31747970652e676f6f676c65617069732e636f6d2f70726f746f636f6c2e54726967676572536d617274436f6e747261637412740a154179309abcff2cf531070ca9222a1f72c4a5136874121541a614f803b6fd780986a42c78ec9c7f77e6ded13c2244a9059cbb000000000000000000000041a3af64559a63856c625b02e9def8a4dc0f63f38b0000000000000000000000000000000000000000000000000000000010c1891870b4cbcbbcad2e90018094ebdc03", + "ret": [{ "code": "SUCESS", "contractRet": "SUCCESS", "fee": 47360 }], + "signature": [ + "070c1a53f2fc6b12825b99c9179899e1effbbdf2fad17d273b64bc47f16ee53a0f56096d4ef6ce58aeee65083dcdef8f3c808d6889a990c23a8d45a84cd69bf101" + ], + "txID": "abb6c40f8f8afcc69fb5b549ffb17bd779fa6588dbbbd5e4ee8568839462b37a" + }, + { + "blockNumber": 20829535, + "block_timestamp": 1592754555000, + "energy_fee": 296310, + "energy_usage": 0, + "energy_usage_total": 29631, + "internal_transactions": [], + "net_fee": 3460, + "net_usage": 0, + "raw_data": { + "contract": [ + { + "parameter": { + "type_url": "type.googleapis.com/protocol.TriggerSmartContract", + "value": { + "call_value": 0, + "contract_address": "41a614f803b6fd780986a42c78ec9c7f77e6ded13c", + "data": "a9059cbb0000000000000000000000410ae0647bbaa1aebafcc9a360d0e22a791a215c930000000000000000000000000000000000000000000000000000000011e1a300", + "owner_address": "4179309abcff2cf531070ca9222a1f72c4a5136874" + } + }, + "type": "TriggerSmartContract" + } + ], + "expiration": 1592758206000, + "fee_limit": 1000000000, + "ref_block_bytes": "d54a", + "ref_block_hash": "d27814b2e9763d5d", + "timestamp": 1592754547598 + }, + "raw_data_hex": "0a02d54a2208d27814b2e9763d5d40b0fca5bead2e5aae01081f12a9010a31747970652e676f6f676c65617069732e636f6d2f70726f746f636f6c2e54726967676572536d617274436f6e747261637412740a154179309abcff2cf531070ca9222a1f72c4a5136874121541a614f803b6fd780986a42c78ec9c7f77e6ded13c2244a9059cbb0000000000000000000000410ae0647bbaa1aebafcc9a360d0e22a791a215c930000000000000000000000000000000000000000000000000000000011e1a300708ed7c6bcad2e90018094ebdc03", + "ret": [{ "code": "SUCESS", "contractRet": "SUCCESS", "fee": 299770 }], + "signature": [ + "6a0f4d4d5021c46d522f45552b20218ea16c437e6e87130339c90752f63f7a805763699bad3b22fb3199efdce75f1929ac94482be8551107b051ae4b9ef532bb01" + ], + "txID": "7da3a7819e4de9311464963f829e3ceeff0a045bbd587030deba863a04d250db" + }, + { + "blockNumber": 20829504, + "block_timestamp": 1592754462000, + "energy_fee": 166700, + "energy_usage": 0, + "energy_usage_total": 29631, + "internal_transactions": [], + "net_fee": 3460, + "net_usage": 0, + "raw_data": { + "contract": [ + { + "parameter": { + "type_url": "type.googleapis.com/protocol.TriggerSmartContract", + "value": { + "call_value": 0, + "contract_address": "41a614f803b6fd780986a42c78ec9c7f77e6ded13c", + "data": "a9059cbb000000000000000000000041042b5bc43cf6aabae0533f4f671eb810615c32be0000000000000000000000000000000000000000000000000000000054c92b70", + "owner_address": "4179309abcff2cf531070ca9222a1f72c4a5136874" + } + }, + "type": "TriggerSmartContract" + } + ], + "expiration": 1592758116000, + "fee_limit": 1000000000, + "ref_block_bytes": "d52c", + "ref_block_hash": "9486bdd9554ef09e", + "timestamp": 1592754457197 + }, + "raw_data_hex": "0a02d52c22089486bdd9554ef09e40a0bda0bead2e5aae01081f12a9010a31747970652e676f6f676c65617069732e636f6d2f70726f746f636f6c2e54726967676572536d617274436f6e747261637412740a154179309abcff2cf531070ca9222a1f72c4a5136874121541a614f803b6fd780986a42c78ec9c7f77e6ded13c2244a9059cbb000000000000000000000041042b5bc43cf6aabae0533f4f671eb810615c32be0000000000000000000000000000000000000000000000000000000054c92b7070ed94c1bcad2e90018094ebdc03", + "ret": [{ "code": "SUCESS", "contractRet": "SUCCESS", "fee": 170160 }], + "signature": [ + "2bfe810fa90d3aee965ff990fd68490ce9c8421844c1e792a57faeb556e5c9b004499016ace19afdb49ba65531c2d829890b4c6a14a7e58c6b71bfdacc7709e201" + ], + "txID": "4d5e74b87f782060e0657a48898626a51a1bf2dcccfc2083955fa4f43e4516b0" + }, + { + "blockNumber": 20829499, + "block_timestamp": 1592754447000, + "energy_fee": 0, + "energy_usage": 0, + "energy_usage_total": 0, + "internal_transactions": [], + "net_fee": 0, + "net_usage": 268, + "raw_data": { + "contract": [ + { + "parameter": { + "type_url": "type.googleapis.com/protocol.TransferContract", + "value": { + "amount": 2538461, + "owner_address": "41da03247c21301eaf0538c1b9f79e5c8ea7cbb386", + "to_address": "4179309abcff2cf531070ca9222a1f72c4a5136874" + } + }, + "type": "TransferContract" + } + ], + "expiration": 1592758089000, + "fee_limit": 0, + "ref_block_bytes": "d523", + "ref_block_hash": "dc512cab1e07f960", + "timestamp": 1592754430099 + }, + "raw_data_hex": "0a02d5232208dc512cab1e07f96040a8ea9ebead2e5a68080112640a2d747970652e676f6f676c65617069732e636f6d2f70726f746f636f6c2e5472616e73666572436f6e747261637412330a1541da03247c21301eaf0538c1b9f79e5c8ea7cbb38612154179309abcff2cf531070ca9222a1f72c4a513687418ddf79a017093c1bfbcad2e", + "ret": [{ "code": "SUCESS", "contractRet": "SUCCESS", "fee": 0 }], + "signature": [ + "0b542abf1657965deeb06123636f6e4ccaea5f4ab0a14f81f3164b286cb6ede37c62d701c796ae86cbd5c908009e5ac6db73d4532a9976ce5b30df47460957d601" + ], + "txID": "82efc8456a3c38a0919af416a53363405ced78db7c13e1b94a79ebcea98f9909" + }, + { + "blockNumber": 20829498, + "block_timestamp": 1592754444000, + "energy_fee": 0, + "energy_usage": 0, + "energy_usage_total": 0, + "internal_transactions": [], + "net_fee": 0, + "net_usage": 268, + "raw_data": { + "contract": [ + { + "parameter": { + "type_url": "type.googleapis.com/protocol.TransferContract", + "value": { + "amount": 30000000, + "owner_address": "41f3eb90cf03d6301e1d10b6095113494bc704992c", + "to_address": "4179309abcff2cf531070ca9222a1f72c4a5136874" + } + }, + "type": "TransferContract" + } + ], + "expiration": 1592758089000, + "fee_limit": 0, + "ref_block_bytes": "d523", + "ref_block_hash": "dc512cab1e07f960", + "timestamp": 1592754429791 + }, + "raw_data_hex": "0a02d5232208dc512cab1e07f96040a8ea9ebead2e5a68080112640a2d747970652e676f6f676c65617069732e636f6d2f70726f746f636f6c2e5472616e73666572436f6e747261637412330a1541f3eb90cf03d6301e1d10b6095113494bc704992c12154179309abcff2cf531070ca9222a1f72c4a5136874188087a70e70dfbebfbcad2e", + "ret": [{ "code": "SUCESS", "contractRet": "SUCCESS", "fee": 0 }], + "signature": [ + "d44a181a6ff560bbcd8a89f9b14247f3d3c781020404eb6462926f3e60dfe32c38ee17f0e752346229de30db033352240152891a168285581558f80af90f83fd00" + ], + "txID": "a336bd174c127d38bf2325bc9c927059af099e8cfb91159750a1b1be16dd0bd4" + }, + { + "blockNumber": 20829498, + "block_timestamp": 1592754444000, + "energy_fee": 0, + "energy_usage": 0, + "energy_usage_total": 0, + "internal_transactions": [], + "net_fee": 0, + "net_usage": 268, + "raw_data": { + "contract": [ + { + "parameter": { + "type_url": "type.googleapis.com/protocol.TransferContract", + "value": { + "amount": 111337320, + "owner_address": "41b4fd934c73429b27c1e9180e04ccfc44c14f15a9", + "to_address": "4179309abcff2cf531070ca9222a1f72c4a5136874" + } + }, + "type": "TransferContract" + } + ], + "expiration": 1592758086000, + "fee_limit": 0, + "ref_block_bytes": "d522", + "ref_block_hash": "9ecd3926187cf28e", + "timestamp": 1592754429463 + }, + "raw_data_hex": "0a02d52222089ecd3926187cf28e40f0d29ebead2e5a68080112640a2d747970652e676f6f676c65617069732e636f6d2f70726f746f636f6c2e5472616e73666572436f6e747261637412330a1541b4fd934c73429b27c1e9180e04ccfc44c14f15a912154179309abcff2cf531070ca9222a1f72c4a513687418e8be8b357097bcbfbcad2e", + "ret": [{ "code": "SUCESS", "contractRet": "SUCCESS", "fee": 0 }], + "signature": [ + "a40ce5f8ab4d9283fd9982eb38aa2a8b8ad9aeaa9bfc8acc220673a367fd420c034f89110e74a99745a96e103b883a85036c64e1c992a7a12c594f11954bacca01" + ], + "txID": "007bbcc3855f4bf51bd76e63d7776160c115c803e227f7c44c7d1fd1bd587611" + }, + { + "blockNumber": 20829498, + "block_timestamp": 1592754444000, + "energy_fee": 0, + "energy_usage": 0, + "energy_usage_total": 0, + "internal_transactions": [], + "net_fee": 0, + "net_usage": 268, + "raw_data": { + "contract": [ + { + "parameter": { + "type_url": "type.googleapis.com/protocol.TransferContract", + "value": { + "amount": 200000000, + "owner_address": "413c5d20a6b1747c65903e2874614d6b8a038b818c", + "to_address": "4179309abcff2cf531070ca9222a1f72c4a5136874" + } + }, + "type": "TransferContract" + } + ], + "expiration": 1592758086000, + "fee_limit": 0, + "ref_block_bytes": "d522", + "ref_block_hash": "9ecd3926187cf28e", + "timestamp": 1592754429137 + }, + "raw_data_hex": "0a02d52222089ecd3926187cf28e40f0d29ebead2e5a68080112640a2d747970652e676f6f676c65617069732e636f6d2f70726f746f636f6c2e5472616e73666572436f6e747261637412330a15413c5d20a6b1747c65903e2874614d6b8a038b818c12154179309abcff2cf531070ca9222a1f72c4a5136874188084af5f70d1b9bfbcad2e", + "ret": [{ "code": "SUCESS", "contractRet": "SUCCESS", "fee": 0 }], + "signature": [ + "9192ee355f2b8c4b21cb68d5b5b2647a4ccb3a00c2bdaeb65cddef4785e7a31e364e21ef3c8b78628c8d342d6f7727ab391b064c1f0b02105e300108ca9cf88800" + ], + "txID": "9351e87b129142844f000a52911daf36fc95677dfe2846abcd28ea0d8fe2e2ea" + }, + { + "blockNumber": 20829498, + "block_timestamp": 1592754444000, + "energy_fee": 0, + "energy_usage": 0, + "energy_usage_total": 0, + "internal_transactions": [], + "net_fee": 0, + "net_usage": 269, + "raw_data": { + "contract": [ + { + "parameter": { + "type_url": "type.googleapis.com/protocol.TransferContract", + "value": { + "amount": 511000000, + "owner_address": "414a5a0f19fd4b1c85208764a7a8cdcdb88171fc71", + "to_address": "4179309abcff2cf531070ca9222a1f72c4a5136874" + } + }, + "type": "TransferContract" + } + ], + "expiration": 1592758086000, + "fee_limit": 0, + "ref_block_bytes": "d522", + "ref_block_hash": "9ecd3926187cf28e", + "timestamp": 1592754428706 + }, + "raw_data_hex": "0a02d52222089ecd3926187cf28e40f0d29ebead2e5a69080112650a2d747970652e676f6f676c65617069732e636f6d2f70726f746f636f6c2e5472616e73666572436f6e747261637412340a15414a5a0f19fd4b1c85208764a7a8cdcdb88171fc7112154179309abcff2cf531070ca9222a1f72c4a513687418c0fbd4f30170a2b6bfbcad2e", + "ret": [{ "code": "SUCESS", "contractRet": "SUCCESS", "fee": 0 }], + "signature": [ + "fac73d7f6540a63c27717cbe04197d8ae89bd906f6c59eba71cc3a2630e29d9b6e0e4400b5e316289e5b6608d84a1a47673674605e48776f8d97aa3dedcfc60301" + ], + "txID": "008ebda5749c38e26a69717faa66e6f4fd8a0d358c9b947192765cc9843cff5a" + } + ] +} diff --git a/platform/tron/mocks/tokens/asset_1000542_response.json b/platform/tron/mocks/tokens/asset_1000542_response.json new file mode 100644 index 000000000..b365fc6a1 --- /dev/null +++ b/platform/tron/mocks/tokens/asset_1000542_response.json @@ -0,0 +1,19 @@ +{ + "success": true, + "meta": { "at": 1592754266101, "page_size": 1 }, + "data": [ + { + "id": 1000542, + "abbr": "FOM", + "description": "Fomo3D is a decentralized, trustless blockchain game.", + "name": "FomoThreeD", + "num": 1, + "total_supply": 80000000000, + "trx_num": 1000000, + "url": "https://fomo3d.games/", + "owner_address": "4134f1b9c19cf40f565661697eb47b0090ac779507", + "start_time": 1534348821000, + "end_time": 1924876800000 + } + ] +} diff --git a/platform/tron/mocks/tokens/asset_1000567_response.json b/platform/tron/mocks/tokens/asset_1000567_response.json new file mode 100644 index 000000000..b8dd645fc --- /dev/null +++ b/platform/tron/mocks/tokens/asset_1000567_response.json @@ -0,0 +1,20 @@ +{ + "success": true, + "meta": { "at": 1592754347268, "page_size": 1 }, + "data": [ + { + "id": 1000567, + "abbr": "os", + "description": "Open Decentralized Search Engine", + "frozen_supply": [{ "frozen_amount": 74000000000, "frozen_days": 3652 }], + "name": "OtonamiS", + "num": 100, + "total_supply": 99000000000, + "trx_num": 1000000, + "url": "https://OtonamiS.com", + "owner_address": "413cea69143b5a5b1ff15d847a7e30e3bffa6a2247", + "start_time": 1534773969000, + "end_time": 1566280800000 + } + ] +} diff --git a/platform/tron/mocks/tokens/asset_tr7nh_response.json b/platform/tron/mocks/tokens/asset_tr7nh_response.json new file mode 100644 index 000000000..afd44c32b --- /dev/null +++ b/platform/tron/mocks/tokens/asset_tr7nh_response.json @@ -0,0 +1,5 @@ +{ + "success": true, + "meta": { "at": 1592754347268, "page_size": 1 }, + "data": [] +} diff --git a/platform/tron/mocks/tokens/tokens_response.json b/platform/tron/mocks/tokens/tokens_response.json new file mode 100644 index 000000000..da85d0769 --- /dev/null +++ b/platform/tron/mocks/tokens/tokens_response.json @@ -0,0 +1,12 @@ +[ + "c195_tTCFLL5dx5ZJdKnWuesXxi1VPwjLVmWZZy9", + "c195_tTCRhVHPv6efvXgogNMhiunAMXFKcMmv2pF", + "c195_tTG7Z1ptC7nRkaniDVRhHSyLycaroaS5PdK", + "c195_tTJSF4iVkzkRkYwEVNkqJkeGDaZpnFbGy9x", + "c195_tTLKyLt4MXuvvdFvUUc3Zma4rZyj2t87Mak", + "c195_tTLa2f6VPqDgRE67v1736s7bJ8Ray5wYjU7", + "c195_tTMCMPzmosnQ8UAYW1zcBwjLTxDq8ce4Y5e", + "c195_tTPt8DTDBZYfJ9fuyRjdWJr4PP68tRfptLG", + "c195_tTR7NHqjeKQxGTCi8q8ZY4pL8otSzgjLj6t", + "c195_tTTvVC9jv5AfDdHuGeCMcQg6QftmNnfQiVm" +] diff --git a/platform/tron/mocks/tokens/trc20_response.json b/platform/tron/mocks/tokens/trc20_response.json new file mode 100644 index 000000000..bb72b3408 --- /dev/null +++ b/platform/tron/mocks/tokens/trc20_response.json @@ -0,0 +1,2107 @@ +{ + "trc20token_balances": [ + { + "name": "BeeHive", + "symbol": "Bee", + "decimals": 8, + "contract_address": "TG7Z1ptC7nRkaniDVRhHSyLycaroaS5PdK", + "balance": "100000000000000" + }, + { + "name": "NoleCoin", + "symbol": "NOLE", + "decimals": 6, + "contract_address": "TPt8DTDBZYfJ9fuyRjdWJr4PP68tRfptLG", + "balance": "20000", + "priceInTrx": 20.0 + }, + { + "name": "Enme Token", + "symbol": "EME", + "decimals": 6, + "contract_address": "TCRhVHPv6efvXgogNMhiunAMXFKcMmv2pF", + "balance": "175798" + }, + { + "name": "PYRO Network", + "symbol": "PYRO", + "decimals": 6, + "contract_address": "TMCMPzmosnQ8UAYW1zcBwjLTxDq8ce4Y5e", + "balance": "5000000000", + "priceInTrx": 0.005821 + }, + { + "name": "Wuhan Fried Bats", + "symbol": "WUHAN", + "decimals": 4, + "contract_address": "TSzjFRf8bQ46kRndWaHYKSq1P5HzRJfPvr", + "balance": "690000" + }, + { + "name": "WINK", + "symbol": "WIN", + "decimals": 6, + "contract_address": "TLa2f6VPqDgRE67v1736s7bJ8Ray5wYjU7", + "balance": "191543058623486", + "priceInTrx": 0.004665 + }, + { + "name": "Mono Token", + "symbol": "MONO", + "decimals": 18, + "contract_address": "TLKyLt4MXuvvdFvUUc3Zma4rZyj2t87Mak", + "balance": "1" + }, + { + "name": "HelGro", + "symbol": "HGRO", + "decimals": 6, + "contract_address": "TTvVC9jv5AfDdHuGeCMcQg6QftmNnfQiVm", + "balance": "20000000" + }, + { + "name": "JUST GOV", + "symbol": "JST", + "decimals": 18, + "contract_address": "TCFLL5dx5ZJdKnWuesXxi1VPwjLVmWZZy9", + "balance": "955973733483987848990056", + "priceInTrx": 0.3133 + }, + { + "name": "Tether USD", + "symbol": "USDT", + "decimals": 6, + "contract_address": "TR7NHqjeKQxGTCi8q8ZY4pL8otSzgjLj6t", + "balance": "6781725898163", + "priceInTrx": 64.102564 + } + ], + "allowExchange": [], + "address": "TM1zzNDZD2DPASbKcgdVoTYhfmYgtfwx9R", + "frozen_supply": [], + "bandwidth": { + "energyRemaining": 0, + "totalEnergyLimit": 90000000000, + "totalEnergyWeight": 1446707995, + "netUsed": 0, + "storageLimit": 0, + "storagePercentage": 0.0, + "assets": { + "1000542": { + "netPercentage": 0.0, + "netLimit": 0, + "netRemaining": 0, + "netUsed": 0 + }, + "1002446": { + "netPercentage": 0.0, + "netLimit": 0, + "netRemaining": 0, + "netUsed": 0 + }, + "1002721": { + "netPercentage": 0.0, + "netLimit": 0, + "netRemaining": 0, + "netUsed": 0 + }, + "1001510": { + "netPercentage": 0.0, + "netLimit": 0, + "netRemaining": 0, + "netUsed": 0 + }, + "1002962": { + "netPercentage": 0.0, + "netLimit": 0, + "netRemaining": 0, + "netUsed": 0 + }, + "1001479": { + "netPercentage": 0.0, + "netLimit": 0, + "netRemaining": 0, + "netUsed": 0 + }, + "1002288": { + "netPercentage": 0.0, + "netLimit": 0, + "netRemaining": 0, + "netUsed": 0 + }, + "1001594": { + "netPercentage": 0.0, + "netLimit": 0, + "netRemaining": 0, + "netUsed": 0 + }, + "1002683": { + "netPercentage": 0.0, + "netLimit": 0, + "netRemaining": 0, + "netUsed": 0 + }, + "1000541": { + "netPercentage": 0.0, + "netLimit": 0, + "netRemaining": 0, + "netUsed": 0 + }, + "1001079": { + "netPercentage": 0.0, + "netLimit": 0, + "netRemaining": 0, + "netUsed": 0 + }, + "1000145": { + "netPercentage": 0.0, + "netLimit": 0, + "netRemaining": 0, + "netUsed": 0 + }, + "1002608": { + "netPercentage": 0.0, + "netLimit": 0, + "netRemaining": 0, + "netUsed": 0 + }, + "1000821": { + "netPercentage": 0.0, + "netLimit": 0, + "netRemaining": 0, + "netUsed": 0 + }, + "1002845": { + "netPercentage": 0.0, + "netLimit": 0, + "netRemaining": 0, + "netUsed": 0 + }, + "1001759": { + "netPercentage": 0.0, + "netLimit": 0, + "netRemaining": 0, + "netUsed": 0 + }, + "1002726": { + "netPercentage": 0.0, + "netLimit": 0, + "netRemaining": 0, + "netUsed": 0 + }, + "1001230": { + "netPercentage": 0.0, + "netLimit": 0, + "netRemaining": 0, + "netUsed": 0 + }, + "1001467": { + "netPercentage": 0.0, + "netLimit": 0, + "netRemaining": 0, + "netUsed": 0 + }, + "1002798": { + "netPercentage": 0.0, + "netLimit": 0, + "netRemaining": 0, + "netUsed": 0 + }, + "1000894": { + "netPercentage": 0.0, + "netLimit": 0, + "netRemaining": 0, + "netUsed": 0 + }, + "1000532": { + "netPercentage": 0.0, + "netLimit": 0, + "netRemaining": 0, + "netUsed": 0 + }, + "1002830": { + "netPercentage": 0.0, + "netLimit": 0, + "netRemaining": 0, + "netUsed": 0 + }, + "1000017": { + "netPercentage": 0.0, + "netLimit": 0, + "netRemaining": 0, + "netUsed": 0 + }, + "1000494": { + "netPercentage": 0.0, + "netLimit": 0, + "netRemaining": 0, + "netUsed": 0 + }, + "1002398": { + "netPercentage": 0.0, + "netLimit": 0, + "netRemaining": 0, + "netUsed": 0 + }, + "1002552": { + "netPercentage": 0.0, + "netLimit": 0, + "netRemaining": 0, + "netUsed": 0 + }, + "1002551": { + "netPercentage": 0.0, + "netLimit": 0, + "netRemaining": 0, + "netUsed": 0 + }, + "1002672": { + "netPercentage": 0.0, + "netLimit": 0, + "netRemaining": 0, + "netUsed": 0 + }, + "1002037": { + "netPercentage": 0.0, + "netLimit": 0, + "netRemaining": 0, + "netUsed": 0 + }, + "1002950": { + "netPercentage": 0.0, + "netLimit": 0, + "netRemaining": 0, + "netUsed": 0 + }, + "1000935": { + "netPercentage": 0.0, + "netLimit": 0, + "netRemaining": 0, + "netUsed": 0 + }, + "1000938": { + "netPercentage": 0.0, + "netLimit": 0, + "netRemaining": 0, + "netUsed": 0 + }, + "1002438": { + "netPercentage": 0.0, + "netLimit": 0, + "netRemaining": 0, + "netUsed": 0 + }, + "1000491": { + "netPercentage": 0.0, + "netLimit": 0, + "netRemaining": 0, + "netUsed": 0 + }, + "1000096": { + "netPercentage": 0.0, + "netLimit": 0, + "netRemaining": 0, + "netUsed": 0 + }, + "1002671": { + "netPercentage": 0.0, + "netLimit": 0, + "netRemaining": 0, + "netUsed": 0 + }, + "1000493": { + "netPercentage": 0.0, + "netLimit": 0, + "netRemaining": 0, + "netUsed": 0 + }, + "1001064": { + "netPercentage": 0.0, + "netLimit": 0, + "netRemaining": 0, + "netUsed": 0 + }, + "1001581": { + "netPercentage": 0.0, + "netLimit": 0, + "netRemaining": 0, + "netUsed": 0 + }, + "1002270": { + "netPercentage": 0.0, + "netLimit": 0, + "netRemaining": 0, + "netUsed": 0 + }, + "1000322": { + "netPercentage": 0.0, + "netLimit": 0, + "netRemaining": 0, + "netUsed": 0 + }, + "1002589": { + "netPercentage": 0.0, + "netLimit": 0, + "netRemaining": 0, + "netUsed": 0 + }, + "1001411": { + "netPercentage": 0.0, + "netLimit": 0, + "netRemaining": 0, + "netUsed": 0 + }, + "1002467": { + "netPercentage": 0.0, + "netLimit": 0, + "netRemaining": 0, + "netUsed": 0 + }, + "1002742": { + "netPercentage": 0.0, + "netLimit": 0, + "netRemaining": 0, + "netUsed": 0 + }, + "1001414": { + "netPercentage": 0.0, + "netLimit": 0, + "netRemaining": 0, + "netUsed": 0 + }, + "1001535": { + "netPercentage": 0.0, + "netLimit": 0, + "netRemaining": 0, + "netUsed": 0 + }, + "1000567": { + "netPercentage": 0.0, + "netLimit": 0, + "netRemaining": 0, + "netUsed": 0 + }, + "1000165": { + "netPercentage": 0.0, + "netLimit": 0, + "netRemaining": 0, + "netUsed": 0 + }, + "1001011": { + "netPercentage": 0.0, + "netLimit": 0, + "netRemaining": 0, + "netUsed": 0 + }, + "1002342": { + "netPercentage": 0.0, + "netLimit": 0, + "netRemaining": 0, + "netUsed": 0 + }, + "1001132": { + "netPercentage": 0.0, + "netLimit": 0, + "netRemaining": 0, + "netUsed": 0 + }, + "1000562": { + "netPercentage": 0.0, + "netLimit": 0, + "netRemaining": 0, + "netUsed": 0 + }, + "1000287": { + "netPercentage": 0.0, + "netLimit": 0, + "netRemaining": 0, + "netUsed": 0 + }, + "1001815": { + "netPercentage": 0.0, + "netLimit": 0, + "netRemaining": 0, + "netUsed": 0 + }, + "1002907": { + "netPercentage": 0.0, + "netLimit": 0, + "netRemaining": 0, + "netUsed": 0 + }, + "1002746": { + "netPercentage": 0.0, + "netLimit": 0, + "netRemaining": 0, + "netUsed": 0 + }, + "1002748": { + "netPercentage": 0.0, + "netLimit": 0, + "netRemaining": 0, + "netUsed": 0 + }, + "1001090": { + "netPercentage": 0.0, + "netLimit": 0, + "netRemaining": 0, + "netUsed": 0 + }, + "1000278": { + "netPercentage": 0.0, + "netLimit": 0, + "netRemaining": 0, + "netUsed": 0 + }, + "1000157": { + "netPercentage": 0.0, + "netLimit": 0, + "netRemaining": 0, + "netUsed": 0 + }, + "1002578": { + "netPercentage": 0.0, + "netLimit": 0, + "netRemaining": 0, + "netUsed": 0 + }, + "1002577": { + "netPercentage": 0.0, + "netLimit": 0, + "netRemaining": 0, + "netUsed": 0 + }, + "1002852": { + "netPercentage": 0.0, + "netLimit": 0, + "netRemaining": 0, + "netUsed": 0 + }, + "1002459": { + "netPercentage": 0.0, + "netLimit": 0, + "netRemaining": 0, + "netUsed": 0 + }, + "1000396": { + "netPercentage": 0.0, + "netLimit": 0, + "netRemaining": 0, + "netUsed": 0 + }, + "1002573": { + "netPercentage": 0.0, + "netLimit": 0, + "netRemaining": 0, + "netUsed": 0 + }, + "1002454": { + "netPercentage": 0.0, + "netLimit": 0, + "netRemaining": 0, + "netUsed": 0 + }, + "1000959": { + "netPercentage": 0.0, + "netLimit": 0, + "netRemaining": 0, + "netUsed": 0 + }, + "1002736": { + "netPercentage": 0.0, + "netLimit": 0, + "netRemaining": 0, + "netUsed": 0 + }, + "1002858": { + "netPercentage": 0.0, + "netLimit": 0, + "netRemaining": 0, + "netUsed": 0 + }, + "1003022": { + "netPercentage": 0.0, + "netLimit": 0, + "netRemaining": 0, + "netUsed": 0 + }, + "1001038": { + "netPercentage": 0.0, + "netLimit": 0, + "netRemaining": 0, + "netUsed": 0 + }, + "1000983": { + "netPercentage": 0.0, + "netLimit": 0, + "netRemaining": 0, + "netUsed": 0 + }, + "1001433": { + "netPercentage": 0.0, + "netLimit": 0, + "netRemaining": 0, + "netUsed": 0 + }, + "1000743": { + "netPercentage": 0.0, + "netLimit": 0, + "netRemaining": 0, + "netUsed": 0 + }, + "1001953": { + "netPercentage": 0.0, + "netLimit": 0, + "netRemaining": 0, + "netUsed": 0 + }, + "1002646": { + "netPercentage": 0.0, + "netLimit": 0, + "netRemaining": 0, + "netUsed": 0 + }, + "1000985": { + "netPercentage": 0.0, + "netLimit": 0, + "netRemaining": 0, + "netUsed": 0 + }, + "1002524": { + "netPercentage": 0.0, + "netLimit": 0, + "netRemaining": 0, + "netUsed": 0 + }, + "1002001": { + "netPercentage": 0.0, + "netLimit": 0, + "netRemaining": 0, + "netUsed": 0 + }, + "1002881": { + "netPercentage": 0.0, + "netLimit": 0, + "netRemaining": 0, + "netUsed": 0 + }, + "1002488": { + "netPercentage": 0.0, + "netLimit": 0, + "netRemaining": 0, + "netUsed": 0 + }, + "1002521": { + "netPercentage": 0.0, + "netLimit": 0, + "netRemaining": 0, + "netUsed": 0 + }, + "1002762": { + "netPercentage": 0.0, + "netLimit": 0, + "netRemaining": 0, + "netUsed": 0 + }, + "1002927": { + "netPercentage": 0.0, + "netLimit": 0, + "netRemaining": 0, + "netUsed": 0 + }, + "1002926": { + "netPercentage": 0.0, + "netLimit": 0, + "netRemaining": 0, + "netUsed": 0 + }, + "1000745": { + "netPercentage": 0.0, + "netLimit": 0, + "netRemaining": 0, + "netUsed": 0 + }, + "1000744": { + "netPercentage": 0.0, + "netLimit": 0, + "netRemaining": 0, + "netUsed": 0 + }, + "1000746": { + "netPercentage": 0.0, + "netLimit": 0, + "netRemaining": 0, + "netUsed": 0 + }, + "1002000": { + "netPercentage": 0.0, + "netLimit": 0, + "netRemaining": 0, + "netUsed": 0 + }, + "1000181": { + "netPercentage": 0.0, + "netLimit": 0, + "netRemaining": 0, + "netUsed": 0 + }, + "1002116": { + "netPercentage": 0.0, + "netLimit": 0, + "netRemaining": 0, + "netUsed": 0 + }, + "1001301": { + "netPercentage": 0.0, + "netLimit": 0, + "netRemaining": 0, + "netUsed": 0 + }, + "1001425": { + "netPercentage": 0.0, + "netLimit": 0, + "netRemaining": 0, + "netUsed": 0 + }, + "1002876": { + "netPercentage": 0.0, + "netLimit": 0, + "netRemaining": 0, + "netUsed": 0 + }, + "1000176": { + "netPercentage": 0.0, + "netLimit": 0, + "netRemaining": 0, + "netUsed": 0 + }, + "1000451": { + "netPercentage": 0.0, + "netLimit": 0, + "netRemaining": 0, + "netUsed": 0 + }, + "1003049": { + "netPercentage": 0.0, + "netLimit": 0, + "netRemaining": 0, + "netUsed": 0 + }, + "1002597": { + "netPercentage": 0.0, + "netLimit": 0, + "netRemaining": 0, + "netUsed": 0 + }, + "1002918": { + "netPercentage": 0.0, + "netLimit": 0, + "netRemaining": 0, + "netUsed": 0 + }, + "1002636": { + "netPercentage": 0.0, + "netLimit": 0, + "netRemaining": 0, + "netUsed": 0 + }, + "1002999": { + "netPercentage": 0.0, + "netLimit": 0, + "netRemaining": 0, + "netUsed": 0 + }, + "1001825": { + "netPercentage": 0.0, + "netLimit": 0, + "netRemaining": 0, + "netUsed": 0 + }, + "1000856": { + "netPercentage": 0.0, + "netLimit": 0, + "netRemaining": 0, + "netUsed": 0 + }, + "1002517": { + "netPercentage": 0.0, + "netLimit": 0, + "netRemaining": 0, + "netUsed": 0 + }, + "1002230": { + "netPercentage": 0.0, + "netLimit": 0, + "netRemaining": 0, + "netUsed": 0 + }, + "1002071": { + "netPercentage": 0.0, + "netLimit": 0, + "netRemaining": 0, + "netUsed": 0 + }, + "1003041": { + "netPercentage": 0.0, + "netLimit": 0, + "netRemaining": 0, + "netUsed": 0 + }, + "1002072": { + "netPercentage": 0.0, + "netLimit": 0, + "netRemaining": 0, + "netUsed": 0 + }, + "1000003": { + "netPercentage": 0.0, + "netLimit": 0, + "netRemaining": 0, + "netUsed": 0 + }, + "1000520": { + "netPercentage": 0.0, + "netLimit": 0, + "netRemaining": 0, + "netUsed": 0 + }, + "1000884": { + "netPercentage": 0.0, + "netLimit": 0, + "netRemaining": 0, + "netUsed": 0 + }, + "1002544": { + "netPercentage": 0.0, + "netLimit": 0, + "netRemaining": 0, + "netUsed": 0 + }, + "1001854": { + "netPercentage": 0.0, + "netLimit": 0, + "netRemaining": 0, + "netUsed": 0 + }, + "1002822": { + "netPercentage": 0.0, + "netLimit": 0, + "netRemaining": 0, + "netUsed": 0 + }, + "1000006": { + "netPercentage": 0.0, + "netLimit": 0, + "netRemaining": 0, + "netUsed": 0 + }, + "1002662": { + "netPercentage": 0.0, + "netLimit": 0, + "netRemaining": 0, + "netUsed": 0 + }, + "1002669": { + "netPercentage": 0.0, + "netLimit": 0, + "netRemaining": 0, + "netUsed": 0 + }, + "1002384": { + "netPercentage": 0.0, + "netLimit": 0, + "netRemaining": 0, + "netUsed": 0 + }, + "1002263": { + "netPercentage": 0.0, + "netLimit": 0, + "netRemaining": 0, + "netUsed": 0 + }, + "1001203": { + "netPercentage": 0.0, + "netLimit": 0, + "netRemaining": 0, + "netUsed": 0 + }, + "1002897": { + "netPercentage": 0.0, + "netLimit": 0, + "netRemaining": 0, + "netUsed": 0 + }, + "1001565": { + "netPercentage": 0.0, + "netLimit": 0, + "netRemaining": 0, + "netUsed": 0 + }, + "1002775": { + "netPercentage": 0.0, + "netLimit": 0, + "netRemaining": 0, + "netUsed": 0 + }, + "1002657": { + "netPercentage": 0.0, + "netLimit": 0, + "netRemaining": 0, + "netUsed": 0 + }, + "1001204": { + "netPercentage": 0.0, + "netLimit": 0, + "netRemaining": 0, + "netUsed": 0 + }, + "1001446": { + "netPercentage": 0.0, + "netLimit": 0, + "netRemaining": 0, + "netUsed": 0 + }, + "1002892": { + "netPercentage": 0.0, + "netLimit": 0, + "netRemaining": 0, + "netUsed": 0 + }, + "1002939": { + "netPercentage": 0.0, + "netLimit": 0, + "netRemaining": 0, + "netUsed": 0 + }, + "1002814": { + "netPercentage": 0.0, + "netLimit": 0, + "netRemaining": 0, + "netUsed": 0 + }, + "1002250": { + "netPercentage": 0.0, + "netLimit": 0, + "netRemaining": 0, + "netUsed": 0 + }, + "1002099": { + "netPercentage": 0.0, + "netLimit": 0, + "netRemaining": 0, + "netUsed": 0 + }, + "1000190": { + "netPercentage": 0.0, + "netLimit": 0, + "netRemaining": 0, + "netUsed": 0 + } + }, + "netPercentage": 0.0, + "storageUsed": 0, + "storageRemaining": 0, + "freeNetLimit": 5000, + "energyUsed": 0, + "freeNetRemaining": 211, + "netLimit": 0, + "netRemaining": 0, + "energyLimit": 0, + "freeNetUsed": 4789, + "totalNetWeight": 26789943446, + "freeNetPercentage": 0.9578, + "energyPercentage": 0.0, + "totalNetLimit": 43200000000 + }, + "accountType": 0, + "exchanges": [], + "frozen": { "total": 0, "balances": [] }, + "accountResource": { "frozen_balance_for_energy": {} }, + "tokenBalances": [ + { "balance": 346976329314696, "name": "_" }, + { "balance": 1273, "name": "1000003" }, + { "balance": 113, "name": "1000006" }, + { "balance": 145, "name": "1000165" }, + { "balance": 416, "name": "1000520" }, + { "balance": 596, "name": "1000491" }, + { + "balance": 242, + "name": "1000176", + "owner_address": "THG48yHsR6inxrCJk2hhxZPsFLq1ehP88V" + }, + { "balance": 62, "name": "1000542" }, + { + "balance": 53, + "name": "1000494", + "owner_address": "TXJnVqqwLSNmdXDLWn1Yfjhe8aZH2oaAuq" + }, + { "balance": 56, "name": "1000493" }, + { "balance": 599, "name": "1000744" }, + { "balance": 628, "name": "1000746" }, + { "balance": 234, "name": "1000743" }, + { "balance": 113, "name": "1000396" }, + { + "balance": 206, + "name": "1000745", + "owner_address": "TPCEi45wZQ1PPChUg5uqoK1D5kKnjCR8Li" + }, + { + "balance": 61, + "name": "1000821", + "owner_address": "TBm3Peu51gYwn2iPwNEDxc9vBMc3eRGUGu" + }, + { "balance": 25, "name": "1000541" }, + { + "balance": 7, + "name": "1000278", + "owner_address": "TRMUimDekf9nDLuVMp6TKzcw4axNnajGJr" + }, + { + "balance": 1, + "name": "1000567", + "owner_address": "TFXJMhB4ZKBfcQWfCLbSyQGhonHXABaWku" + }, + { + "balance": 1, + "name": "1000856", + "owner_address": "TXf3X8YMdDho2xwA6QDbFZiTGPnk8ghfLm" + }, + { "balance": 30, "name": "1000884" }, + { "balance": 1, "name": "1000894" }, + { + "balance": 200, + "name": "1000181", + "owner_address": "TEmTbbvH5ZPJPZ8CbffjqonFRiAAFgfc9o" + }, + { + "balance": 7, + "name": "1000935", + "owner_address": "TPVkcFYTEi9Dia45AveiTcaYoaU9ux7xC7" + }, + { + "balance": 1000, + "name": "1000938", + "owner_address": "TNgkWTabK1rMWwgLjmLdsZbzYfGTx5Tpe9" + }, + { + "balance": 10, + "name": "1000017", + "owner_address": "TV6qcwSp38uESiDczxxb7zbJX1h2LfDs78" + }, + { + "balance": 10, + "name": "1001011", + "owner_address": "TNUbeTQXPtRXtBX3dJboVkhdhaiws29Aky" + }, + { + "balance": 2, + "name": "1001038", + "owner_address": "TFujVDp8U578L2AtsorYN3pwdXmH2HxbQv" + }, + { + "balance": 100, + "name": "1000983", + "owner_address": "TYmiZ7xCeqboiizb2jsjVQuRABXzVSjKFR" + }, + { + "balance": 1, + "name": "1001203", + "owner_address": "TBmaT8mcrdkrRL2Q6ur7grMYAcaGtfxsz7" + }, + { + "balance": 1, + "name": "1000190", + "owner_address": "TNXjXURue38Wa641pmqMH4vbJN1WZLKMnr" + }, + { "balance": 100, "name": "1001204" }, + { "balance": 1000, "name": "1001230" }, + { + "balance": 1300000, + "name": "1001301", + "owner_address": "TVgJEbc9NEYxVr1h6rJQiMqySePsJQDCA7" + }, + { "balance": 11, "name": "1000959" }, + { "balance": 10, "name": "1001425" }, + { + "balance": 17, + "name": "1001433", + "owner_address": "TWPMz6FPEAV6qP4VRMG3Y69ftEov1R7YWT" + }, + { "balance": 100, "name": "1001446" }, + { + "balance": 12, + "name": "1001411", + "owner_address": "TPL6zNujtEQ8kp213n58UxAhGRCU3aozkc" + }, + { "balance": 12, "name": "1001467" }, + { + "balance": 100, + "name": "1001414", + "owner_address": "TT43DgfxgMdR4BVZNua4YCwG34AgfGN6Uu" + }, + { + "balance": 100, + "name": "1001510", + "owner_address": "TPKq9bVZyM2sZ8XersMmXhy1NbjhdxRwwj" + }, + { + "balance": 50, + "name": "1001565", + "owner_address": "TKY7Vmq78b2c83fLXrPijkhQkk4EJtfViD" + }, + { "balance": 5, "name": "1001535" }, + { + "balance": 10, + "name": "1000532", + "owner_address": "TGQwBNht8h3zev4gBtDMoQjWE2WJm1Zr9B" + }, + { + "balance": 3, + "name": "1001479", + "owner_address": "TC9FtB1EoiV3jfXgZvmqUmfeCmdWNmCxdY" + }, + { + "balance": 13, + "name": "1001090", + "owner_address": "TU1LUTYDMG6iihimUpAmdnnBthawPKh1cm", + "priceInTrx": 0.00436 + }, + { + "balance": 200, + "name": "1001759", + "owner_address": "TWKWWJAFBYyjvLtfqKCSeMyUW7TjWhkY4e" + }, + { + "balance": 12, + "name": "1000096", + "owner_address": "TSfjkVSKJGW4aybDQcxi4bpythU7WCXV3v" + }, + { "balance": 15, "name": "1001594" }, + { + "balance": 10, + "name": "1001815", + "owner_address": "TB3iM1RsKXagV7hdz2QpWnaChptwrU3tCL" + }, + { + "balance": 10, + "name": "1001064", + "owner_address": "THnWV416C9mfJ1LFwopUjGXZEr1xFtAdrD" + }, + { + "balance": 5192508733304578, + "name": "1002000", + "owner_address": "TF5Bn4cJCT6GVeUgyCN4rBhDg42KBrpAjg", + "priceInTrx": 0.0189 + }, + { + "balance": 7742069, + "name": "1002037", + "owner_address": "TBekuTCZwPG2o88SmiS58VALkxBemoX4yS" + }, + { "balance": 585, "name": "1002001" }, + { + "balance": 5441, + "name": "1002071", + "owner_address": "TS79aik831csqUnQgnqrKG6hov2iL8yPbD" + }, + { + "balance": 80312957663126, + "name": "1002072", + "owner_address": "TP6PtaBSMM6sfWtWWD9k77YHWGmh7K3Lae" + }, + { + "balance": 520, + "name": "1000451", + "owner_address": "THPXuypwcnWo4wi5KqFfuRjgjeT5khUDKF" + }, + { + "balance": 10011237, + "name": "1001953", + "owner_address": "TSyG9BdjsGE2GoHG9eeYKMns6zMQFDmbvS" + }, + { + "balance": 5, + "name": "1000562", + "owner_address": "TWqKTJ5JhyD7rsbbWzEvS5ZZD9Q5QPPvSH" + }, + { + "balance": 50000000, + "name": "1002099", + "owner_address": "TYWmiPERm9kWUcnduqaE5jxT7eeZxfn5SQ" + }, + { + "balance": 625100, + "name": "1001581", + "owner_address": "TNkRSKWP7VvdrisTwC8iNzUV6MRoEJh6xx" + }, + { + "balance": 11000000, + "name": "1002342", + "owner_address": "TUCd8NiBUuxrjz1kSrUbAg2JXu6o27Ukrq" + }, + { + "balance": 7, + "name": "1000322", + "owner_address": "TDGy2M9qWBepSHDEutWWxWd1JZfmAed3BP", + "priceInTrx": 0.000422 + }, + { + "balance": 12, + "name": "1001825", + "owner_address": "TPcUbNeYwwYqbX23w3sVf1X61cwpAfPK2T" + }, + { + "balance": 1000, + "name": "1002384", + "owner_address": "TFYuPxyjDTvH1TLm2phpzJFw7AhjCgu8xP" + }, + { + "balance": 44444, + "name": "1001132", + "owner_address": "TWDUanVdxEShjpbiX57ExztMCDy8vCFcHh" + }, + { + "balance": 30000000, + "name": "1002398", + "owner_address": "TUXSuMg41nJXm9TuDgF6EZWjEbP2vx1Hd4" + }, + { + "balance": 10000060, + "name": "1002116", + "owner_address": "TAEvo6MgLgV3A75L3cr3BAsLDJikWcAt3j" + }, + { + "balance": 50000000, + "name": "1002446", + "owner_address": "TJKf72NjL1cR49SHfDnPTXTFjRwjgr7v8Z" + }, + { + "balance": 10000000, + "name": "1002459", + "owner_address": "TNWy3mX85JsX2mPLgLc4cKJiWtJahhz3t3" + }, + { + "balance": 1, + "name": "1001079", + "owner_address": "TLQfc5EwZQqZc6jMNkMpxyJy5wucA6UX24" + }, + { + "balance": 12345, + "name": "1002467", + "owner_address": "TP429SKrsp4BoTiEFXHj4TNSJwqDFsygnr" + }, + { + "balance": 1234, + "name": "1002230", + "owner_address": "TWB9Q1JoB3fSLsahNq31gydRxYyWxDhSyk" + }, + { + "balance": 10000000, + "name": "1002288", + "owner_address": "TPzfpaaKUPgJPZ39YeyvBaTYNXBYpnhxDg" + }, + { + "balance": 5, + "name": "1002488", + "owner_address": "TMeAzhdgzu1sFMTsP75BffJ2tEzuGsYqR6" + }, + { + "balance": 666, + "name": "1002438", + "owner_address": "TMqNJwD3qVmuRxzzP3Q4A24fuByVBKQ39E" + }, + { + "balance": 10000000, + "name": "1002517", + "owner_address": "TP9m11ERHhE1qgDtL83c2AHHNkWvdUfKTz" + }, + { + "balance": 10000000000, + "name": "1002521", + "owner_address": "TJUwM4qk1et2nNKuESQ7UVHPjAHoRqAz3T" + }, + { + "balance": 13699, + "name": "1000157", + "owner_address": "TUahmv54ZiDnjQWG2VAeyMphebXQ4m6Hb5" + }, + { + "balance": 65895, + "name": "1002524", + "owner_address": "TRzZeBPt69utiWx1po5ghLH8uSP8uJGsa5" + }, + { + "balance": 16, + "name": "1000287", + "owner_address": "TFZCyZ18XNzMfEr6W5kLkGrs4HVmou9H3y" + }, + { + "balance": 10000000, + "name": "1002544", + "owner_address": "TQHBbjES5DNjDfDHBbpnh9qcDM7mVjSVcL" + }, + { + "balance": 10000000000, + "name": "1002551", + "owner_address": "TVrGxBCQkWjQ52D7S67UgFsUzcX4E8EsNB" + }, + { + "balance": 10000000, + "name": "1002573", + "owner_address": "TBfmGqmZtdEQNuYCz8s1izBUDxZbkPmMcj" + }, + { + "balance": 10000000, + "name": "1002552", + "owner_address": "TCxeAH2ajBqoWzqV9m5YiFTyeQ5FvzVqSH" + }, + { + "balance": 1000000, + "name": "1002578", + "owner_address": "TUjBG7C1CU7X75UmacnyrRTYLmbSeX7iDa" + }, + { + "balance": 2555000, + "name": "1002270", + "owner_address": "TMSpdYHCgZuxM7AjqKsjGMM1cpxraFuZGp" + }, + { + "balance": 10000000, + "name": "1002597", + "owner_address": "TDEBhgsdGTSzrgMsPDUQ1pt59fR6wWR7Rq" + }, + { + "balance": 10000000, + "name": "1002636", + "owner_address": "TKL54NcGXvBckkGbPjYzAmdwFs3usv8VY9" + }, + { + "balance": 100000000, + "name": "1002250", + "owner_address": "THUHfNqiYo4KS3GLM8MUU4x3wek9uPD47d" + }, + { + "balance": 1000000, + "name": "1002662", + "owner_address": "TEV5PJWga6crSeNLHmHaaco8fon6nm74wJ" + }, + { + "balance": 10000000, + "name": "1002672", + "owner_address": "TBHJCf3nymJPt1hVPjSJfH5ssJLdNMPepe" + }, + { + "balance": 24120, + "name": "1002657", + "owner_address": "TCKiVea721ycNAWonb2dpwr65AJkMiGSFb" + }, + { + "balance": 1000000, + "name": "1002683", + "owner_address": "TL6YggMQQ3YFEc41wesBMHZjDxcGpX3y5q" + }, + { + "balance": 3000000, + "name": "1002671", + "owner_address": "TDQ5q4Hf6UqR43Smp67sndMQfdTcGgP88s" + }, + { + "balance": 20, + "name": "1002577", + "owner_address": "TGZzci6a9wtcSiNekqYLP84ECRoaJ6pBwY" + }, + { + "balance": 10000000, + "name": "1002721", + "owner_address": "TUkUgsTTo74B9XG9da4d2NsaZqCKLNFwNS" + }, + { + "balance": 10000, + "name": "1002726", + "owner_address": "TRXw3Ggt3xs3fHbcoark1aeKwUZFKTYcsS" + }, + { + "balance": 21092024781, + "name": "1002263", + "owner_address": "TD5AwyiTNbKN9jQqyMzwQ6NLrWGbtAcotK" + }, + { + "balance": 10000000, + "name": "1002736", + "owner_address": "TBB19fMCf19wuiu5omtA1nAqALPpo4oa32" + }, + { + "balance": 10000000, + "name": "1002646", + "owner_address": "TRUnzvtzT6o35M4XHUvKr48yCZjw4dQyvp" + }, + { + "balance": 7392000000, + "name": "1002589", + "owner_address": "TUL9NhGQkRFLTRcHGkdoSniAeVaNPZGgot" + }, + { + "balance": 10000000, + "name": "1002742", + "owner_address": "TWfrNPVGDh1tyPVM79bfEASb7jw2bLbZPJ" + }, + { + "balance": 8822711275000000, + "name": "1002762", + "owner_address": "TRChSJM8TjQj7vvJCN9W8WBcfkJq2eBxgv" + }, + { "balance": 10000000, "name": "1002775" }, + { + "balance": 10000000, + "name": "1002798", + "owner_address": "TBitZMK7YSUb2Q1Cm537D5iAZSJkaPdN9c" + }, + { + "balance": 95, + "name": "1001854", + "owner_address": "TSMeDkfmX6m1NZmDBrVtGPnACJCUWVkx4p" + }, + { + "balance": 10000000, + "name": "1002746", + "owner_address": "TQbbAyfcrKERXjUDf8TZfcdtjFQbCSgEfc" + }, + { + "balance": 2000000, + "name": "1002669", + "owner_address": "THhgpkHBdJDDWBPnZKRgzdvRr3qCtAa2cv" + }, + { + "balance": 10000000, + "name": "1002814", + "owner_address": "TNvq4y2A2beBENtcGknwhX6XHgk8hqgnVh" + }, + { + "balance": 10000000, + "name": "1002830", + "owner_address": "THLLMnsEKEci5e5dJHnW28QQU8AujGhSoK" + }, + { + "balance": 10000000, + "name": "1002845", + "owner_address": "TUzpDkzjWkZasA6Dx7nx5PPskMkCcNxVyQ" + }, + { + "balance": 10000000, + "name": "1002858", + "owner_address": "TRKJcugHJeffVpCAFGapZMwuH8HaTWjbof" + }, + { + "balance": 200, + "name": "1002454", + "owner_address": "TDCGkNf3XB3jRGg7bhFkNynkGw7q4kV3z9" + }, + { + "balance": 10000000, + "name": "1002876", + "owner_address": "TGqiinRV6nn8GbF5LX7zue4fpjstG1gVvu" + }, + { + "balance": 20000000, + "name": "1002881", + "owner_address": "TWpKN6y3NVXm5mMjGmPEtLpS6boGM4q8T4" + }, + { + "balance": 350, + "name": "1000145", + "owner_address": "TNFcvwJgvBRg2Dq5Qyx1gxcvqU3dwPyVNc" + }, + { + "balance": 10000000, + "name": "1002892", + "owner_address": "TECsVV1kTtx48sbdjvptq544h4H3Qqr24c" + }, + { + "balance": 10000000, + "name": "1002897", + "owner_address": "TPKqse19ALipJ1uBZHGWHzuTrQqZa4HtaM" + }, + { + "balance": 2055000000, + "name": "1002822", + "owner_address": "TURy9pFLskqTWgkZqUCUdPXkezZfYL76YQ" + }, + { + "balance": 1000000, + "name": "1002852", + "owner_address": "TUmad3hCqxu78n8GuULrdJMUB4qmTUYgv3" + }, + { + "balance": 10000000, + "name": "1002907", + "owner_address": "TKC9HMUXx3qLE7d19KWzWVjFxEcWQdSYK9" + }, + { + "balance": 10000000, + "name": "1002927", + "owner_address": "TAwRvFAqfB4bbzVCVPgGATZV5uMVs9UyVL" + }, + { + "balance": 10000000, + "name": "1002926", + "owner_address": "TF5jfDiQ3d7T5ihcBxeWS9S8xSR5tS738x" + }, + { + "balance": 1000000, + "name": "1002748", + "owner_address": "TTUAmhh9k2Yegf3TxZc86vG5E9kT24vgcw" + }, + { + "balance": 189990000000, + "name": "1002950", + "owner_address": "TNCZCGDPQ69ieJFsY1jZUohXmR46A4kM24" + }, + { + "balance": 10, + "name": "1000985", + "owner_address": "TRH5jmPx77UnMvfdvfo2m3FCkZVcBiFvqP" + }, + { + "balance": 10000000, + "name": "1002962", + "owner_address": "TFDwGwod9qopreRiirsFMwPzX4v2r662P4" + }, + { + "balance": 10000000, + "name": "1002918", + "owner_address": "TKGpTks1myPrJ9ZtEdLgpjvg1RMR2wGAFz" + }, + { + "balance": 1000, + "name": "1002608", + "owner_address": "TDPsSgBQznKEffdTMq3aspsvrmFfhL7ZcP" + }, + { + "balance": 10000000, + "name": "1002999", + "owner_address": "TTL52uBzTG7qorL7BQYdjGUY3HWWr9Kvao" + }, + { + "balance": 100000000000, + "name": "1003022", + "owner_address": "TAAJiJ1NgkEkE3w1PQk4dA8XH9rpfk5eVE" + }, + { + "balance": 1000000000, + "name": "1003041", + "owner_address": "TQADZoww5HstdsJM1GXwstqsRRnmrkThzY" + }, + { + "balance": 10000000, + "name": "1003049", + "owner_address": "THFJwSN5Z3zTc5TvkSiVh8m4kQMZaTMaqk" + }, + { + "balance": 1, + "name": "1002939", + "owner_address": "TAsSw8hUddYi8AN8EkDuAMS9r8pkriyUxs" + } + ], + "balances": [ + { "balance": 346976329314696, "name": "_" }, + { "balance": 1273, "name": "1000003" }, + { "balance": 113, "name": "1000006" }, + { "balance": 145, "name": "1000165" }, + { "balance": 416, "name": "1000520" }, + { "balance": 596, "name": "1000491" }, + { + "balance": 242, + "name": "1000176", + "owner_address": "THG48yHsR6inxrCJk2hhxZPsFLq1ehP88V" + }, + { "balance": 62, "name": "1000542" }, + { + "balance": 53, + "name": "1000494", + "owner_address": "TXJnVqqwLSNmdXDLWn1Yfjhe8aZH2oaAuq" + }, + { "balance": 56, "name": "1000493" }, + { "balance": 599, "name": "1000744" }, + { "balance": 628, "name": "1000746" }, + { "balance": 234, "name": "1000743" }, + { "balance": 113, "name": "1000396" }, + { + "balance": 206, + "name": "1000745", + "owner_address": "TPCEi45wZQ1PPChUg5uqoK1D5kKnjCR8Li" + }, + { + "balance": 61, + "name": "1000821", + "owner_address": "TBm3Peu51gYwn2iPwNEDxc9vBMc3eRGUGu" + }, + { "balance": 25, "name": "1000541" }, + { + "balance": 7, + "name": "1000278", + "owner_address": "TRMUimDekf9nDLuVMp6TKzcw4axNnajGJr" + }, + { + "balance": 1, + "name": "1000567", + "owner_address": "TFXJMhB4ZKBfcQWfCLbSyQGhonHXABaWku" + }, + { + "balance": 1, + "name": "1000856", + "owner_address": "TXf3X8YMdDho2xwA6QDbFZiTGPnk8ghfLm" + }, + { "balance": 30, "name": "1000884" }, + { "balance": 1, "name": "1000894" }, + { + "balance": 200, + "name": "1000181", + "owner_address": "TEmTbbvH5ZPJPZ8CbffjqonFRiAAFgfc9o" + }, + { + "balance": 7, + "name": "1000935", + "owner_address": "TPVkcFYTEi9Dia45AveiTcaYoaU9ux7xC7" + }, + { + "balance": 1000, + "name": "1000938", + "owner_address": "TNgkWTabK1rMWwgLjmLdsZbzYfGTx5Tpe9" + }, + { + "balance": 10, + "name": "1000017", + "owner_address": "TV6qcwSp38uESiDczxxb7zbJX1h2LfDs78" + }, + { + "balance": 10, + "name": "1001011", + "owner_address": "TNUbeTQXPtRXtBX3dJboVkhdhaiws29Aky" + }, + { + "balance": 2, + "name": "1001038", + "owner_address": "TFujVDp8U578L2AtsorYN3pwdXmH2HxbQv" + }, + { + "balance": 100, + "name": "1000983", + "owner_address": "TYmiZ7xCeqboiizb2jsjVQuRABXzVSjKFR" + }, + { + "balance": 1, + "name": "1001203", + "owner_address": "TBmaT8mcrdkrRL2Q6ur7grMYAcaGtfxsz7" + }, + { + "balance": 1, + "name": "1000190", + "owner_address": "TNXjXURue38Wa641pmqMH4vbJN1WZLKMnr" + }, + { "balance": 100, "name": "1001204" }, + { "balance": 1000, "name": "1001230" }, + { + "balance": 1300000, + "name": "1001301", + "owner_address": "TVgJEbc9NEYxVr1h6rJQiMqySePsJQDCA7" + }, + { "balance": 11, "name": "1000959" }, + { "balance": 10, "name": "1001425" }, + { + "balance": 17, + "name": "1001433", + "owner_address": "TWPMz6FPEAV6qP4VRMG3Y69ftEov1R7YWT" + }, + { "balance": 100, "name": "1001446" }, + { + "balance": 12, + "name": "1001411", + "owner_address": "TPL6zNujtEQ8kp213n58UxAhGRCU3aozkc" + }, + { "balance": 12, "name": "1001467" }, + { + "balance": 100, + "name": "1001414", + "owner_address": "TT43DgfxgMdR4BVZNua4YCwG34AgfGN6Uu" + }, + { + "balance": 100, + "name": "1001510", + "owner_address": "TPKq9bVZyM2sZ8XersMmXhy1NbjhdxRwwj" + }, + { + "balance": 50, + "name": "1001565", + "owner_address": "TKY7Vmq78b2c83fLXrPijkhQkk4EJtfViD" + }, + { "balance": 5, "name": "1001535" }, + { + "balance": 10, + "name": "1000532", + "owner_address": "TGQwBNht8h3zev4gBtDMoQjWE2WJm1Zr9B" + }, + { + "balance": 3, + "name": "1001479", + "owner_address": "TC9FtB1EoiV3jfXgZvmqUmfeCmdWNmCxdY" + }, + { + "balance": 13, + "name": "1001090", + "owner_address": "TU1LUTYDMG6iihimUpAmdnnBthawPKh1cm", + "priceInTrx": 0.00436 + }, + { + "balance": 200, + "name": "1001759", + "owner_address": "TWKWWJAFBYyjvLtfqKCSeMyUW7TjWhkY4e" + }, + { + "balance": 12, + "name": "1000096", + "owner_address": "TSfjkVSKJGW4aybDQcxi4bpythU7WCXV3v" + }, + { "balance": 15, "name": "1001594" }, + { + "balance": 10, + "name": "1001815", + "owner_address": "TB3iM1RsKXagV7hdz2QpWnaChptwrU3tCL" + }, + { + "balance": 10, + "name": "1001064", + "owner_address": "THnWV416C9mfJ1LFwopUjGXZEr1xFtAdrD" + }, + { + "balance": 5192508733304578, + "name": "1002000", + "owner_address": "TF5Bn4cJCT6GVeUgyCN4rBhDg42KBrpAjg", + "priceInTrx": 0.0189 + }, + { + "balance": 7742069, + "name": "1002037", + "owner_address": "TBekuTCZwPG2o88SmiS58VALkxBemoX4yS" + }, + { "balance": 585, "name": "1002001" }, + { + "balance": 5441, + "name": "1002071", + "owner_address": "TS79aik831csqUnQgnqrKG6hov2iL8yPbD" + }, + { + "balance": 80312957663126, + "name": "1002072", + "owner_address": "TP6PtaBSMM6sfWtWWD9k77YHWGmh7K3Lae" + }, + { + "balance": 520, + "name": "1000451", + "owner_address": "THPXuypwcnWo4wi5KqFfuRjgjeT5khUDKF" + }, + { + "balance": 10011237, + "name": "1001953", + "owner_address": "TSyG9BdjsGE2GoHG9eeYKMns6zMQFDmbvS" + }, + { + "balance": 5, + "name": "1000562", + "owner_address": "TWqKTJ5JhyD7rsbbWzEvS5ZZD9Q5QPPvSH" + }, + { + "balance": 50000000, + "name": "1002099", + "owner_address": "TYWmiPERm9kWUcnduqaE5jxT7eeZxfn5SQ" + }, + { + "balance": 625100, + "name": "1001581", + "owner_address": "TNkRSKWP7VvdrisTwC8iNzUV6MRoEJh6xx" + }, + { + "balance": 11000000, + "name": "1002342", + "owner_address": "TUCd8NiBUuxrjz1kSrUbAg2JXu6o27Ukrq" + }, + { + "balance": 7, + "name": "1000322", + "owner_address": "TDGy2M9qWBepSHDEutWWxWd1JZfmAed3BP", + "priceInTrx": 0.000422 + }, + { + "balance": 12, + "name": "1001825", + "owner_address": "TPcUbNeYwwYqbX23w3sVf1X61cwpAfPK2T" + }, + { + "balance": 1000, + "name": "1002384", + "owner_address": "TFYuPxyjDTvH1TLm2phpzJFw7AhjCgu8xP" + }, + { + "balance": 44444, + "name": "1001132", + "owner_address": "TWDUanVdxEShjpbiX57ExztMCDy8vCFcHh" + }, + { + "balance": 30000000, + "name": "1002398", + "owner_address": "TUXSuMg41nJXm9TuDgF6EZWjEbP2vx1Hd4" + }, + { + "balance": 10000060, + "name": "1002116", + "owner_address": "TAEvo6MgLgV3A75L3cr3BAsLDJikWcAt3j" + }, + { + "balance": 50000000, + "name": "1002446", + "owner_address": "TJKf72NjL1cR49SHfDnPTXTFjRwjgr7v8Z" + }, + { + "balance": 10000000, + "name": "1002459", + "owner_address": "TNWy3mX85JsX2mPLgLc4cKJiWtJahhz3t3" + }, + { + "balance": 1, + "name": "1001079", + "owner_address": "TLQfc5EwZQqZc6jMNkMpxyJy5wucA6UX24" + }, + { + "balance": 12345, + "name": "1002467", + "owner_address": "TP429SKrsp4BoTiEFXHj4TNSJwqDFsygnr" + }, + { + "balance": 1234, + "name": "1002230", + "owner_address": "TWB9Q1JoB3fSLsahNq31gydRxYyWxDhSyk" + }, + { + "balance": 10000000, + "name": "1002288", + "owner_address": "TPzfpaaKUPgJPZ39YeyvBaTYNXBYpnhxDg" + }, + { + "balance": 5, + "name": "1002488", + "owner_address": "TMeAzhdgzu1sFMTsP75BffJ2tEzuGsYqR6" + }, + { + "balance": 666, + "name": "1002438", + "owner_address": "TMqNJwD3qVmuRxzzP3Q4A24fuByVBKQ39E" + }, + { + "balance": 10000000, + "name": "1002517", + "owner_address": "TP9m11ERHhE1qgDtL83c2AHHNkWvdUfKTz" + }, + { + "balance": 10000000000, + "name": "1002521", + "owner_address": "TJUwM4qk1et2nNKuESQ7UVHPjAHoRqAz3T" + }, + { + "balance": 13699, + "name": "1000157", + "owner_address": "TUahmv54ZiDnjQWG2VAeyMphebXQ4m6Hb5" + }, + { + "balance": 65895, + "name": "1002524", + "owner_address": "TRzZeBPt69utiWx1po5ghLH8uSP8uJGsa5" + }, + { + "balance": 16, + "name": "1000287", + "owner_address": "TFZCyZ18XNzMfEr6W5kLkGrs4HVmou9H3y" + }, + { + "balance": 10000000, + "name": "1002544", + "owner_address": "TQHBbjES5DNjDfDHBbpnh9qcDM7mVjSVcL" + }, + { + "balance": 10000000000, + "name": "1002551", + "owner_address": "TVrGxBCQkWjQ52D7S67UgFsUzcX4E8EsNB" + }, + { + "balance": 10000000, + "name": "1002573", + "owner_address": "TBfmGqmZtdEQNuYCz8s1izBUDxZbkPmMcj" + }, + { + "balance": 10000000, + "name": "1002552", + "owner_address": "TCxeAH2ajBqoWzqV9m5YiFTyeQ5FvzVqSH" + }, + { + "balance": 1000000, + "name": "1002578", + "owner_address": "TUjBG7C1CU7X75UmacnyrRTYLmbSeX7iDa" + }, + { + "balance": 2555000, + "name": "1002270", + "owner_address": "TMSpdYHCgZuxM7AjqKsjGMM1cpxraFuZGp" + }, + { + "balance": 10000000, + "name": "1002597", + "owner_address": "TDEBhgsdGTSzrgMsPDUQ1pt59fR6wWR7Rq" + }, + { + "balance": 10000000, + "name": "1002636", + "owner_address": "TKL54NcGXvBckkGbPjYzAmdwFs3usv8VY9" + }, + { + "balance": 100000000, + "name": "1002250", + "owner_address": "THUHfNqiYo4KS3GLM8MUU4x3wek9uPD47d" + }, + { + "balance": 1000000, + "name": "1002662", + "owner_address": "TEV5PJWga6crSeNLHmHaaco8fon6nm74wJ" + }, + { + "balance": 10000000, + "name": "1002672", + "owner_address": "TBHJCf3nymJPt1hVPjSJfH5ssJLdNMPepe" + }, + { + "balance": 24120, + "name": "1002657", + "owner_address": "TCKiVea721ycNAWonb2dpwr65AJkMiGSFb" + }, + { + "balance": 1000000, + "name": "1002683", + "owner_address": "TL6YggMQQ3YFEc41wesBMHZjDxcGpX3y5q" + }, + { + "balance": 3000000, + "name": "1002671", + "owner_address": "TDQ5q4Hf6UqR43Smp67sndMQfdTcGgP88s" + }, + { + "balance": 20, + "name": "1002577", + "owner_address": "TGZzci6a9wtcSiNekqYLP84ECRoaJ6pBwY" + }, + { + "balance": 10000000, + "name": "1002721", + "owner_address": "TUkUgsTTo74B9XG9da4d2NsaZqCKLNFwNS" + }, + { + "balance": 10000, + "name": "1002726", + "owner_address": "TRXw3Ggt3xs3fHbcoark1aeKwUZFKTYcsS" + }, + { + "balance": 21092024781, + "name": "1002263", + "owner_address": "TD5AwyiTNbKN9jQqyMzwQ6NLrWGbtAcotK" + }, + { + "balance": 10000000, + "name": "1002736", + "owner_address": "TBB19fMCf19wuiu5omtA1nAqALPpo4oa32" + }, + { + "balance": 10000000, + "name": "1002646", + "owner_address": "TRUnzvtzT6o35M4XHUvKr48yCZjw4dQyvp" + }, + { + "balance": 7392000000, + "name": "1002589", + "owner_address": "TUL9NhGQkRFLTRcHGkdoSniAeVaNPZGgot" + }, + { + "balance": 10000000, + "name": "1002742", + "owner_address": "TWfrNPVGDh1tyPVM79bfEASb7jw2bLbZPJ" + }, + { + "balance": 8822711275000000, + "name": "1002762", + "owner_address": "TRChSJM8TjQj7vvJCN9W8WBcfkJq2eBxgv" + }, + { "balance": 10000000, "name": "1002775" }, + { + "balance": 10000000, + "name": "1002798", + "owner_address": "TBitZMK7YSUb2Q1Cm537D5iAZSJkaPdN9c" + }, + { + "balance": 95, + "name": "1001854", + "owner_address": "TSMeDkfmX6m1NZmDBrVtGPnACJCUWVkx4p" + }, + { + "balance": 10000000, + "name": "1002746", + "owner_address": "TQbbAyfcrKERXjUDf8TZfcdtjFQbCSgEfc" + }, + { + "balance": 2000000, + "name": "1002669", + "owner_address": "THhgpkHBdJDDWBPnZKRgzdvRr3qCtAa2cv" + }, + { + "balance": 10000000, + "name": "1002814", + "owner_address": "TNvq4y2A2beBENtcGknwhX6XHgk8hqgnVh" + }, + { + "balance": 10000000, + "name": "1002830", + "owner_address": "THLLMnsEKEci5e5dJHnW28QQU8AujGhSoK" + }, + { + "balance": 10000000, + "name": "1002845", + "owner_address": "TUzpDkzjWkZasA6Dx7nx5PPskMkCcNxVyQ" + }, + { + "balance": 10000000, + "name": "1002858", + "owner_address": "TRKJcugHJeffVpCAFGapZMwuH8HaTWjbof" + }, + { + "balance": 200, + "name": "1002454", + "owner_address": "TDCGkNf3XB3jRGg7bhFkNynkGw7q4kV3z9" + }, + { + "balance": 10000000, + "name": "1002876", + "owner_address": "TGqiinRV6nn8GbF5LX7zue4fpjstG1gVvu" + }, + { + "balance": 20000000, + "name": "1002881", + "owner_address": "TWpKN6y3NVXm5mMjGmPEtLpS6boGM4q8T4" + }, + { + "balance": 350, + "name": "1000145", + "owner_address": "TNFcvwJgvBRg2Dq5Qyx1gxcvqU3dwPyVNc" + }, + { + "balance": 10000000, + "name": "1002892", + "owner_address": "TECsVV1kTtx48sbdjvptq544h4H3Qqr24c" + }, + { + "balance": 10000000, + "name": "1002897", + "owner_address": "TPKqse19ALipJ1uBZHGWHzuTrQqZa4HtaM" + }, + { + "balance": 2055000000, + "name": "1002822", + "owner_address": "TURy9pFLskqTWgkZqUCUdPXkezZfYL76YQ" + }, + { + "balance": 1000000, + "name": "1002852", + "owner_address": "TUmad3hCqxu78n8GuULrdJMUB4qmTUYgv3" + }, + { + "balance": 10000000, + "name": "1002907", + "owner_address": "TKC9HMUXx3qLE7d19KWzWVjFxEcWQdSYK9" + }, + { + "balance": 10000000, + "name": "1002927", + "owner_address": "TAwRvFAqfB4bbzVCVPgGATZV5uMVs9UyVL" + }, + { + "balance": 10000000, + "name": "1002926", + "owner_address": "TF5jfDiQ3d7T5ihcBxeWS9S8xSR5tS738x" + }, + { + "balance": 1000000, + "name": "1002748", + "owner_address": "TTUAmhh9k2Yegf3TxZc86vG5E9kT24vgcw" + }, + { + "balance": 189990000000, + "name": "1002950", + "owner_address": "TNCZCGDPQ69ieJFsY1jZUohXmR46A4kM24" + }, + { + "balance": 10, + "name": "1000985", + "owner_address": "TRH5jmPx77UnMvfdvfo2m3FCkZVcBiFvqP" + }, + { + "balance": 10000000, + "name": "1002962", + "owner_address": "TFDwGwod9qopreRiirsFMwPzX4v2r662P4" + }, + { + "balance": 10000000, + "name": "1002918", + "owner_address": "TKGpTks1myPrJ9ZtEdLgpjvg1RMR2wGAFz" + }, + { + "balance": 1000, + "name": "1002608", + "owner_address": "TDPsSgBQznKEffdTMq3aspsvrmFfhL7ZcP" + }, + { + "balance": 10000000, + "name": "1002999", + "owner_address": "TTL52uBzTG7qorL7BQYdjGUY3HWWr9Kvao" + }, + { + "balance": 100000000000, + "name": "1003022", + "owner_address": "TAAJiJ1NgkEkE3w1PQk4dA8XH9rpfk5eVE" + }, + { + "balance": 1000000000, + "name": "1003041", + "owner_address": "TQADZoww5HstdsJM1GXwstqsRRnmrkThzY" + }, + { + "balance": 10000000, + "name": "1003049", + "owner_address": "THFJwSN5Z3zTc5TvkSiVh8m4kQMZaTMaqk" + }, + { + "balance": 1, + "name": "1002939", + "owner_address": "TAsSw8hUddYi8AN8EkDuAMS9r8pkriyUxs" + } + ], + "balance": 346976329314696, + "voteTotal": 0, + "name": "", + "delegated": { + "sentDelegatedBandwidth": [], + "sentDelegatedResource": [], + "receivedDelegatedResource": [], + "receivedDelegatedBandwidth": [] + }, + "totalTransactionCount": 508552, + "representative": { + "lastWithDrawTime": 0, + "allowance": 0, + "enabled": false, + "url": "" + }, + "activePermissions": [] +} diff --git a/platform/tron/mocks/tokens/txs_empty_response.json b/platform/tron/mocks/tokens/txs_empty_response.json new file mode 100644 index 000000000..f9b0e1de5 --- /dev/null +++ b/platform/tron/mocks/tokens/txs_empty_response.json @@ -0,0 +1,12 @@ +{ + "success": true, + "meta": { + "at": 1592757318961, + "page_size": 20, + "fingerprint": "AYa6eBNpCs5E2DnumiJJJWJ3n2PYMBRFvU7BLjXD49Jm779DJ1C1hUgjwJAmQx5Y2BnkStKMjzQvcALKeQJYfW51m6sY7YEWW", + "links": { + "next": "https://api.trongrid.io:443/v1/accounts/TM1zzNDZD2DPASbKcgdVoTYhfmYgtfwx9R/transactions?fingerprint=AYa6eBNpCs5E2DnumiJJJWJ3n2PYMBRFvU7BLjXD49Jm779DJ1C1hUgjwJAmQx5Y2BnkStKMjzQvcALKeQJYfW51m6sY7YEWW" + } + }, + "data": [] +} diff --git a/platform/tron/mocks/tokens/txs_trc20_response.json b/platform/tron/mocks/tokens/txs_trc20_response.json new file mode 100644 index 000000000..3655b74d2 --- /dev/null +++ b/platform/tron/mocks/tokens/txs_trc20_response.json @@ -0,0 +1,295 @@ +{ + "success": true, + "meta": { + "at": 1592757126588, + "page_size": 20, + "fingerprint": "2tmLC90HQEnpnJ02w3n", + "links": { + "next": "https://api.trongrid.io:443/v1/accounts/TM1zzNDZD2DPASbKcgdVoTYhfmYgtfwx9D/transactions/trc20?fingerprint=2tmLC90HQEnpnJ02w3n" + } + }, + "data": [ + { + "block_timestamp": 1592757117000, + "value": "500000000", + "type": "Transfer", + "transaction_id": "fb078403adfee637608c3906d9d21dd158611aba149b9993f43d0f292ce543a0", + "from": "TM1zzNDZD2DPASbKcgdVoTYhfmYgtfwx9D", + "to": "TGg7zHY9qd36aN3jLVDDRuiFeJjaaAtx8A", + "token_info": { + "address": "TR7NHqjeKQxGTCi8q8ZY4pL8otSzgjLj6t", + "name": "Tether USD", + "symbol": "USDT", + "decimals": 6 + }, + "_unconfirmed": true + }, + { + "block_timestamp": 1592757066000, + "value": "50000000", + "type": "Transfer", + "transaction_id": "c4052b526e5cd21e1f023c31cce6b6a13eb9d8aeae3ae80fcefe6038dfbeb022", + "from": "TM1zzNDZD2DPASbKcgdVoTYhfmYgtfwx9D", + "to": "TXJTFuXzfoPbWKCnw47AYxMzgVPUyhJGRd", + "token_info": { + "address": "TR7NHqjeKQxGTCi8q8ZY4pL8otSzgjLj6t", + "name": "Tether USD", + "symbol": "USDT", + "decimals": 6 + }, + "_unconfirmed": true + }, + { + "from": "TM1zzNDZD2DPASbKcgdVoTYhfmYgtfwx9D", + "to": "TXJTFuXzfoPbWKCnw47AYxMzgVPUyhJGRd", + "block_timestamp": 1592757066000, + "value": "50000000", + "type": "Transfer", + "transaction_id": "c4052b526e5cd21e1f023c31cce6b6a13eb9d8aeae3ae80fcefe6038dfbeb022", + "token_info": { + "name": "Tether USD", + "symbol": "USDT", + "decimals": 6, + "address": "TR7NHqjeKQxGTCi8q8ZY4pL8otSzgjLj6t" + } + }, + { + "from": "TM1zzNDZD2DPASbKcgdVoTYhfmYgtfwx9D", + "to": "TFNEJYAKBVgc17X6fPppZ8ayaf9yswmMYV", + "block_timestamp": 1592756784000, + "value": "3988000000", + "type": "Transfer", + "transaction_id": "0b52a4ef9fb8c13fbfae2b8c3506333ec1d718f307062a15f170562818a01d0a", + "token_info": { + "name": "Tether USD", + "symbol": "USDT", + "decimals": 6, + "address": "TR7NHqjeKQxGTCi8q8ZY4pL8otSzgjLj6t" + } + }, + { + "from": "TM1zzNDZD2DPASbKcgdVoTYhfmYgtfwx9D", + "to": "TGYETHZr2MTkFDe8GqwdVFPfadofTVk4am", + "block_timestamp": 1592756763000, + "value": "640990000", + "type": "Transfer", + "transaction_id": "19d2ec6174bf64beb1061475f6429cba03b64944a763686cc3551447d0e8d9d5", + "token_info": { + "name": "Tether USD", + "symbol": "USDT", + "decimals": 6, + "address": "TR7NHqjeKQxGTCi8q8ZY4pL8otSzgjLj6t" + } + }, + { + "from": "TAxbLztoanFhYu4TuS5RabaJYGnUkfzNKG", + "to": "TM1zzNDZD2DPASbKcgdVoTYhfmYgtfwx9D", + "block_timestamp": 1592756631000, + "value": "1062000000", + "type": "Transfer", + "transaction_id": "efb7d44305759cfb189c9fd22720609a2ddeb7fbd7c8afe1dd8851342471da8d", + "token_info": { + "name": "Tether USD", + "symbol": "USDT", + "decimals": 6, + "address": "TR7NHqjeKQxGTCi8q8ZY4pL8otSzgjLj6t" + } + }, + { + "from": "TM1zzNDZD2DPASbKcgdVoTYhfmYgtfwx9D", + "to": "TGg7zHY9qd36aN3jLVDDRuiFeJjaaAtx8A", + "block_timestamp": 1592756610000, + "value": "2000000", + "type": "Transfer", + "transaction_id": "48bd90dc3f12086178e65b9389caa8b3c74683937b86d4d61cdec77f0095994a", + "token_info": { + "name": "Tether USD", + "symbol": "USDT", + "decimals": 6, + "address": "TR7NHqjeKQxGTCi8q8ZY4pL8otSzgjLj6t" + } + }, + { + "from": "TM1zzNDZD2DPASbKcgdVoTYhfmYgtfwx9D", + "to": "TN6Wy4j37wn3vxynynrKemWhDsUBHYje3R", + "block_timestamp": 1592756589000, + "value": "1000000000", + "type": "Transfer", + "transaction_id": "afd5ae7e2462c9cc899c7f730b90fd2a5e4c1315e836c92468b504ed85f0b798", + "token_info": { + "name": "Tether USD", + "symbol": "USDT", + "decimals": 6, + "address": "TR7NHqjeKQxGTCi8q8ZY4pL8otSzgjLj6t" + } + }, + { + "from": "TM1zzNDZD2DPASbKcgdVoTYhfmYgtfwx9D", + "to": "TXP7prwMqugLFWZRwcJAWuKZ4UN4wz3ifq", + "block_timestamp": 1592756583000, + "value": "21200000", + "type": "Transfer", + "transaction_id": "3d613031f4b2a0e19deeea030d1d18599b6d9799d2dd530005ead9712c6d219d", + "token_info": { + "name": "Tether USD", + "symbol": "USDT", + "decimals": 6, + "address": "TR7NHqjeKQxGTCi8q8ZY4pL8otSzgjLj6t" + } + }, + { + "from": "TM1zzNDZD2DPASbKcgdVoTYhfmYgtfwx9D", + "to": "TBStJt5wDtLqeUvGEasqd55uo1CbDTCsf5", + "block_timestamp": 1592756583000, + "value": "125000000", + "type": "Transfer", + "transaction_id": "cbe359c2574efbdc8fc6a892ffc54812837295067c9816d41734126c82d0c141", + "token_info": { + "name": "Tether USD", + "symbol": "USDT", + "decimals": 6, + "address": "TR7NHqjeKQxGTCi8q8ZY4pL8otSzgjLj6t" + } + }, + { + "from": "TM1zzNDZD2DPASbKcgdVoTYhfmYgtfwx9D", + "to": "TJ2qhZSQ9g5YqEAJgYfPZZxn1djbf5ogkC", + "block_timestamp": 1592756583000, + "value": "5277600000", + "type": "Transfer", + "transaction_id": "c87248b02a4caaa6f443c1b8c4d4588c8dd281a4687b73e6afecfba6741b50d8", + "token_info": { + "name": "Tether USD", + "symbol": "USDT", + "decimals": 6, + "address": "TR7NHqjeKQxGTCi8q8ZY4pL8otSzgjLj6t" + } + }, + { + "from": "TM1zzNDZD2DPASbKcgdVoTYhfmYgtfwx9D", + "to": "TRqyhrttStrn1o7gS3mmgKrmkVw6qyw23W", + "block_timestamp": 1592756583000, + "value": "485342000", + "type": "Transfer", + "transaction_id": "8584f1b6a70ead8232fed19bd653ba13e4c2a8befd070f4a9a06eca3a2e3e548", + "token_info": { + "name": "Tether USD", + "symbol": "USDT", + "decimals": 6, + "address": "TR7NHqjeKQxGTCi8q8ZY4pL8otSzgjLj6t" + } + }, + { + "from": "TM1zzNDZD2DPASbKcgdVoTYhfmYgtfwx9D", + "to": "TLdYhJeKCLKxVm33JL8GAyi6i6zrSz8VFr", + "block_timestamp": 1592756583000, + "value": "1000000000", + "type": "Transfer", + "transaction_id": "2b28b69e6747db68647acc3a62c45da5355b97acd8d2c260ee752aa9bd63a624", + "token_info": { + "name": "Tether USD", + "symbol": "USDT", + "decimals": 6, + "address": "TR7NHqjeKQxGTCi8q8ZY4pL8otSzgjLj6t" + } + }, + { + "from": "TM1zzNDZD2DPASbKcgdVoTYhfmYgtfwx9D", + "to": "TDpRQi5HguNpasa9Cn7AJyrn646nRDAH6x", + "block_timestamp": 1592756583000, + "value": "2000000000", + "type": "Transfer", + "transaction_id": "1da6576dec0bd303f56cbfb5712f782e0a56a8713cb661f8afd2f2533e5c6209", + "token_info": { + "name": "Tether USD", + "symbol": "USDT", + "decimals": 6, + "address": "TR7NHqjeKQxGTCi8q8ZY4pL8otSzgjLj6t" + } + }, + { + "from": "TM1zzNDZD2DPASbKcgdVoTYhfmYgtfwx9D", + "to": "TGy3K5iDbxm8SM34UTWWniNsS13FtLnHkK", + "block_timestamp": 1592756583000, + "value": "24216600000", + "type": "Transfer", + "transaction_id": "f9c86cce1873cb816d6cd8718e76df8839172add293bbc8d11a5f98c80f9e322", + "token_info": { + "name": "Tether USD", + "symbol": "USDT", + "decimals": 6, + "address": "TR7NHqjeKQxGTCi8q8ZY4pL8otSzgjLj6t" + } + }, + { + "from": "TGMTZMty79L9psKi5b4vwXZPJaiCb9k6mV", + "to": "TM1zzNDZD2DPASbKcgdVoTYhfmYgtfwx9D", + "block_timestamp": 1592756541000, + "value": "8241997837", + "type": "Transfer", + "transaction_id": "75eb35734857daa79c38ef923a7e7eb2e3dfb23d2722762fd2b180651021643f", + "token_info": { + "name": "Tether USD", + "symbol": "USDT", + "decimals": 6, + "address": "TR7NHqjeKQxGTCi8q8ZY4pL8otSzgjLj6t" + } + }, + { + "from": "TUwgGpDrVBc3uDZg3Tj9BZZN8xkLK29yzH", + "to": "TM1zzNDZD2DPASbKcgdVoTYhfmYgtfwx9D", + "block_timestamp": 1592756220000, + "value": "18000000000", + "type": "Transfer", + "transaction_id": "adee73dadce006ff848ff30d8c5c41f033be2e5e1a8b875f6dbbaab524177d08", + "token_info": { + "name": "Tether USD", + "symbol": "USDT", + "decimals": 6, + "address": "TR7NHqjeKQxGTCi8q8ZY4pL8otSzgjLj6t" + } + }, + { + "from": "TMaDtMFGJ8BBiNXchGBQmRBWi2mpfi2kdV", + "to": "TM1zzNDZD2DPASbKcgdVoTYhfmYgtfwx9D", + "block_timestamp": 1592755962000, + "value": "863399098", + "type": "Transfer", + "transaction_id": "3655a1156c9adcb876c6c9c9e0f5f1f39704ac4c7296fea05fedf5ca8f6b1a19", + "token_info": { + "name": "Tether USD", + "symbol": "USDT", + "decimals": 6, + "address": "TR7NHqjeKQxGTCi8q8ZY4pL8otSzgjLj6t" + } + }, + { + "from": "TM1zzNDZD2DPASbKcgdVoTYhfmYgtfwx9D", + "to": "TH7AaBSjS4NYuF3r8vXQcuwVXmGrv9iwYQ", + "block_timestamp": 1592755740000, + "value": "20000000", + "type": "Transfer", + "transaction_id": "03574741eb0016050a19f181e4acc4b20b70f41e11e63140c9556c31eae09fba", + "token_info": { + "name": "Tether USD", + "symbol": "USDT", + "decimals": 6, + "address": "TR7NHqjeKQxGTCi8q8ZY4pL8otSzgjLj6t" + } + }, + { + "from": "TM1zzNDZD2DPASbKcgdVoTYhfmYgtfwx9D", + "to": "TA1VFEzYiU8oB9P1xdhMaFJ7BZ6FvUTyug", + "block_timestamp": 1592755722000, + "value": "21161340000", + "type": "Transfer", + "transaction_id": "f3aa00595996e31dbe9528a3cb21bff987f333bf1f675420ba4fa2ad43c8205f", + "token_info": { + "name": "Tether USD", + "symbol": "USDT", + "decimals": 6, + "address": "TR7NHqjeKQxGTCi8q8ZY4pL8otSzgjLj6t" + } + } + ] +} diff --git a/platform/tron/mocks/transfer.json b/platform/tron/mocks/transfer.json new file mode 100644 index 000000000..44bade683 --- /dev/null +++ b/platform/tron/mocks/transfer.json @@ -0,0 +1,18 @@ +{ + "block_timestamp": 1564797900000, + "raw_data": { + "contract": [ + { + "parameter": { + "value": { + "amount": 100666888000000, + "owner_address": "4182dd6b9966724ae2fdc79b416c7588da67ff1b35", + "to_address": "410583a68a3bcd86c25ab1bee482bac04a216b0261" + } + }, + "type": "TransferContract" + } + ] + }, + "txID": "24a10f7a503e78adc0d7e380b68005531b09e16b9e3f7b524e33f40985d287df" +} diff --git a/platform/tron/mocks/txs_response.json b/platform/tron/mocks/txs_response.json new file mode 100644 index 000000000..1de56a7e2 --- /dev/null +++ b/platform/tron/mocks/txs_response.json @@ -0,0 +1,100 @@ +[ + { + "id": "3fca53c08ccb48bb625439a58998713d8ecc3dc1348cc3cfab912e0815b62b1a", + "coin": 195, + "from": "TM1zzNDZD2DPASbKcgdVoTYhfmYgtfwx9R", + "to": "TVmkAmaQrY6raatYozLtcQCGqWP6VaPnHU", + "fee": "0", + "date": 1592755098, + "block": 0, + "status": "completed", + "sequence": 0, + "type": "transfer", + "memo": "", + "metadata": { "value": "13195916000", "symbol": "TRX", "decimals": 6 } + }, + { + "id": "b38fb6328e1fa622b7762eed856778551845c33723491e36baf357f00cc48002", + "coin": 195, + "from": "TM1zzNDZD2DPASbKcgdVoTYhfmYgtfwx9R", + "to": "TDfVk6U7i6m82ZCRprbrfz7QE3sTEnN1Xs", + "fee": "0", + "date": 1592754717, + "block": 0, + "status": "completed", + "sequence": 0, + "type": "transfer", + "memo": "", + "metadata": { "value": "8737000000", "symbol": "TRX", "decimals": 6 } + }, + { + "id": "82efc8456a3c38a0919af416a53363405ced78db7c13e1b94a79ebcea98f9909", + "coin": 195, + "from": "TVqx5Dx54HgBQFfpN7KN4MWiHEnRXbch7a", + "to": "TM1zzNDZD2DPASbKcgdVoTYhfmYgtfwx9R", + "fee": "0", + "date": 1592754447, + "block": 0, + "status": "completed", + "sequence": 0, + "type": "transfer", + "memo": "", + "metadata": { "value": "2538461", "symbol": "TRX", "decimals": 6 } + }, + { + "id": "a336bd174c127d38bf2325bc9c927059af099e8cfb91159750a1b1be16dd0bd4", + "coin": 195, + "from": "TYCwQ4bC1mHR6heAe1qgHrktFtyJ8mKkC3", + "to": "TM1zzNDZD2DPASbKcgdVoTYhfmYgtfwx9R", + "fee": "0", + "date": 1592754444, + "block": 0, + "status": "completed", + "sequence": 0, + "type": "transfer", + "memo": "", + "metadata": { "value": "30000000", "symbol": "TRX", "decimals": 6 } + }, + { + "id": "007bbcc3855f4bf51bd76e63d7776160c115c803e227f7c44c7d1fd1bd587611", + "coin": 195, + "from": "TSUCQKEKhXREEaod5WgSKETKjYUhL2TUV7", + "to": "TM1zzNDZD2DPASbKcgdVoTYhfmYgtfwx9R", + "fee": "0", + "date": 1592754444, + "block": 0, + "status": "completed", + "sequence": 0, + "type": "transfer", + "memo": "", + "metadata": { "value": "111337320", "symbol": "TRX", "decimals": 6 } + }, + { + "id": "9351e87b129142844f000a52911daf36fc95677dfe2846abcd28ea0d8fe2e2ea", + "coin": 195, + "from": "TFUP7BdBj61oyTHt52McZC5Q1w6CKzyNCN", + "to": "TM1zzNDZD2DPASbKcgdVoTYhfmYgtfwx9R", + "fee": "0", + "date": 1592754444, + "block": 0, + "status": "completed", + "sequence": 0, + "type": "transfer", + "memo": "", + "metadata": { "value": "200000000", "symbol": "TRX", "decimals": 6 } + }, + { + "id": "008ebda5749c38e26a69717faa66e6f4fd8a0d358c9b947192765cc9843cff5a", + "coin": 195, + "from": "TGkLtfPuPhkG4RzewwkgNHfPxTwb5YRq6b", + "to": "TM1zzNDZD2DPASbKcgdVoTYhfmYgtfwx9R", + "fee": "0", + "date": 1592754444, + "block": 0, + "status": "completed", + "sequence": 0, + "type": "transfer", + "memo": "", + "metadata": { "value": "511000000", "symbol": "TRX", "decimals": 6 } + } +] diff --git a/platform/tron/model.go b/platform/tron/model.go index 54eac7576..03d3a88a0 100644 --- a/platform/tron/model.go +++ b/platform/tron/model.go @@ -1,116 +1,147 @@ package tron -import ( - "github.com/trustwallet/blockatlas/pkg/blockatlas" +import "github.com/trustwallet/golibs/types" + +type ( + BlockRequest struct { + StartNum int64 `json:"startNum"` + EndNum int64 `json:"endNum"` + } + + Blocks struct { + Blocks []Block `json:"block"` + } + + Block struct { + BlockId string `json:"blockID"` + Txs []Tx `json:"transactions"` + BlockHeader struct { + Data BlockData `json:"raw_data"` + } `json:"block_header"` + } + + BlockData struct { + Number int64 `json:"number"` + Timestamp int64 `json:"timestamp"` + } + + Page struct { + Success bool `json:"success"` + Error string `json:"error,omitempty"` + Txs []Tx `json:"data"` + } + + Tx struct { + ID string `json:"txID"` + BlockTime int64 `json:"block_timestamp"` + Data TxData `json:"raw_data"` + } + + TxData struct { + Timestamp int64 `json:"timestamp"` + Contracts []Contract `json:"contract"` + } + + ContractType string + + Contract struct { + Type ContractType `json:"type"` + Parameter struct { + Value TransferValue `json:"value"` + } `json:"parameter"` + } + + TransferValue struct { + Amount types.Amount `json:"amount"` + OwnerAddress string `json:"owner_address"` + ToAddress string `json:"to_address"` + AssetName string `json:"asset_name,omitempty"` + } + + Account struct { + Data []AccountData `json:"data"` + } + + AccountData struct { + Balance uint `json:"balance"` + AssetsV2 []AssetV2 `json:"assetV2"` + Votes []Votes `json:"votes"` + Frozen []Frozen `json:"frozen"` + Trc20 []map[string]string `json:"trc20"` + } + + AssetV2 struct { + Key string `json:"key"` + } + + Votes struct { + VoteAddress string `json:"vote_address"` + VoteCount int `json:"vote_count"` + } + + Frozen struct { + ExpireTime int64 `json:"expire_time"` + FrozenBalance interface{} `json:"frozen_balance,string"` // nolint + } + + Asset struct { + Data []AssetInfo `json:"data"` + } + + AssetInfo struct { + Name string `json:"name"` + Symbol string `json:"abbr"` + ID uint `json:"id"` + Decimals uint `json:"precision"` + } + + Validators struct { + Witnesses []Validator `json:"witnesses"` + } + + Validator struct { + Address string `json:"address"` + } + + VotesRequest struct { + Address string `json:"address"` + Visible bool `json:"visible"` + } + + TRC20Transactions struct { + Data []TRC20Transaction `json:"data"` + } + + TRC20Transaction struct { + From string `json:"from"` + To string `json:"to"` + BlockTimestamp int64 `json:"block_timestamp"` + Value string `json:"value"` + Type string `json:"type"` + TransactionID string `json:"transaction_id"` + TokenInfo TRC20TokenInfo `json:"token_info"` + } + + TRC20TokenInfo struct { + Name string `json:"name"` + Symbol string `json:"symbol"` + Decimals int `json:"decimals"` + Address string `json:"address"` + } + + ExplorerResponse struct { + ExplorerTrc20Tokens []ExplorerTrc20Tokens `json:"trc20token_balances"` + } + + ExplorerTrc20Tokens struct { + Name string `json:"name"` + Symbol string `json:"symbol"` + Decimals int `json:"decimals"` + ContractAddress string `json:"contract_address"` + } ) -type BlockRequest struct { - StartNum int64 `json:"startNum"` - EndNum int64 `json:"endNum"` -} - -type Blocks struct { - Blocks []Block `json:"block"` -} - -type Block struct { - BlockId string `json:"blockID"` - Txs []Tx `json:"transactions"` - BlockHeader struct { - Data BlockData `json:"raw_data"` - } `json:"block_header"` -} - -type BlockData struct { - Number int64 `json:"number"` - Timestamp int64 `json:"timestamp"` -} - -type Page struct { - Success bool `json:"success"` - Error string `json:"error,omitempty"` - Txs []Tx `json:"data"` -} - -type Tx struct { - ID string `json:"txID"` - BlockTime int64 `json:"block_timestamp"` - Data TxData `json:"raw_data"` -} - -type TxData struct { - Timestamp int64 `json:"timestamp"` - Contracts []Contract `json:"contract"` -} - -type ContractType string - const ( TransferContract ContractType = "TransferContract" TransferAssetContract ContractType = "TransferAssetContract" - CreateSmartContract ContractType = "CreateSmartContract" - TriggerSmartContract ContractType = "TriggerSmartContract" ) - -type Contract struct { - Type ContractType `json:"type"` - Parameter struct { - Value TransferValue `json:"value"` - } `json:"parameter"` -} - -type TransferValue struct { - Amount blockatlas.Amount `json:"amount"` - OwnerAddress string `json:"owner_address"` - ToAddress string `json:"to_address"` - AssetName string `json:"asset_name,omitempty"` -} - -type Account struct { - Data []AccountData `json:"data"` -} - -type AccountData struct { - Balance uint `json:"balance"` - AssetsV2 []AssetV2 `json:"assetV2"` - Votes []Votes `json:"votes"` - Frozen []Frozen `json:"frozen"` -} - -type AssetV2 struct { - Key string `json:"key"` -} - -type Votes struct { - VoteAddress string `json:"vote_address"` - VoteCount int `json:"vote_count"` -} - -type Frozen struct { - ExpireTime int64 `json:"expire_time"` - FrozenBalance interface{} `json:"frozen_balance,string"` -} - -type Asset struct { - Data []AssetInfo `json:"data"` -} - -type AssetInfo struct { - Name string `json:"name"` - Symbol string `json:"abbr"` - ID string `json:"id"` - Decimals uint `json:"precision"` -} - -type Validators struct { - Witnesses []Validator `json:"witnesses"` -} - -type Validator struct { - Address string `json:"address"` -} - -type VotesRequest struct { - Address string `json:"address"` - Visible bool `json:"visible"` -} diff --git a/platform/tron/stake.go b/platform/tron/stake.go index 817b856a9..54e276de7 100644 --- a/platform/tron/stake.go +++ b/platform/tron/stake.go @@ -1,17 +1,32 @@ package tron import ( - "github.com/trustwallet/blockatlas/pkg/blockatlas" - "github.com/trustwallet/blockatlas/pkg/errors" - "github.com/trustwallet/blockatlas/pkg/logger" - services "github.com/trustwallet/blockatlas/services/assets" "strconv" "time" + + log "github.com/sirupsen/logrus" + "github.com/trustwallet/blockatlas/pkg/blockatlas" + "github.com/trustwallet/blockatlas/services/assets" + "github.com/trustwallet/golibs/types" ) +const Annual = 0.74 + +func (p *Platform) GetActiveValidators() (blockatlas.StakeValidators, error) { + validators, err := assets.GetValidatorsMap(p) + if err != nil { + return nil, err + } + result := make(blockatlas.StakeValidators, 0, len(validators)) + for _, v := range validators { + result = append(result, v) + } + return result, nil +} + func (p *Platform) GetValidators() (blockatlas.ValidatorPage, error) { results := make(blockatlas.ValidatorPage, 0) - validators, err := p.client.GetValidators() + validators, err := p.client.fetchValidators() if err != nil { return results, err } @@ -31,7 +46,7 @@ func (p *Platform) GetDetails() blockatlas.StakingDetails { func getDetails() blockatlas.StakingDetails { return blockatlas.StakingDetails{ Reward: blockatlas.StakingReward{Annual: Annual}, - MinimumAmount: blockatlas.Amount("1000000"), + MinimumAmount: types.Amount("1000000"), LockTime: 259200, Type: blockatlas.DelegationTypeDelegate, } @@ -39,14 +54,14 @@ func getDetails() blockatlas.StakingDetails { func (p *Platform) GetDelegations(address string) (blockatlas.DelegationsPage, error) { results := make(blockatlas.DelegationsPage, 0) - votes, err := p.client.GetAccountVotes(address) + votes, err := p.client.fetchAccountVotes(address) if err != nil { return nil, err } if len(votes.Votes) == 0 { return results, nil } - validators, err := services.GetValidatorsMap(p) + validators, err := assets.GetValidatorsMap(p) if err != nil { return nil, err } @@ -55,7 +70,7 @@ func (p *Platform) GetDelegations(address string) (blockatlas.DelegationsPage, e } func (p *Platform) UndelegatedBalance(address string) (string, error) { - account, err := p.client.GetAccount(address) + account, err := p.client.fetchAccount(address) if err != nil { return "0", err } @@ -67,14 +82,14 @@ func (p *Platform) UndelegatedBalance(address string) (string, error) { } func normalizeValidator(v Validator) (validator blockatlas.Validator, ok bool) { - address, err := HexToAddress(v.Address) + a, err := HexToAddress(v.Address) if err != nil { return validator, false } return blockatlas.Validator{ Status: true, - ID: address, + ID: a, Details: getDetails(), }, true } @@ -84,7 +99,7 @@ func NormalizeDelegations(data *AccountData, validators blockatlas.ValidatorMap) for _, v := range data.Votes { validator, ok := validators[v.VoteAddress] if !ok { - logger.Error(errors.E("Validator not found", errors.Params{"address": v.VoteAddress, "platform": "tron"})) + log.WithFields(log.Fields{"address": v.VoteAddress, "platform": "tron"}).Warn("Validator not found") continue } delegation := blockatlas.Delegation{ diff --git a/platform/tron/stake_test.go b/platform/tron/stake_test.go index c9ae23a83..26c0e1246 100644 --- a/platform/tron/stake_test.go +++ b/platform/tron/stake_test.go @@ -2,132 +2,96 @@ package tron import ( "encoding/json" + "testing" + "github.com/stretchr/testify/assert" "github.com/trustwallet/blockatlas/pkg/blockatlas" - "testing" + "github.com/trustwallet/golibs/mock" ) -func TestNormalizeValidator(t *testing.T) { - validator := Validator{Address: "414d1ef8673f916debb7e2515a8f3ecaf2611034aa"} +var ( + delegationsSrc1, _ = mock.JsonStringFromFilePath("mocks/" + "delegation.json") + delegationsSrc2, _ = mock.JsonStringFromFilePath("mocks/" + "delegation_2.json") - actual, _ := normalizeValidator(validator) - expected := blockatlas.Validator{ + validator1 = blockatlas.StakeValidator{ ID: "TGzz8gjYiYRqpfmDwnLxfgPuLVNmpCswVp", Status: true, + Info: blockatlas.StakeValidatorInfo{ + Name: "Sesameseed", + Description: "Sesameseed is a blockchain community providing fair and transparent representation in delegated governance by rewarding Voters for their participation on Tron and Ontology.", + Image: "https://assets.trustwalletapp.com/blockchains/tron/validators/assets/tgzz8gjyiyrqpfmdwnlxfgpulvnmpcswvp/logo.png", + Website: "https://www.sesameseed.org", + }, Details: blockatlas.StakingDetails{ Reward: blockatlas.StakingReward{ - Annual: Annual, + Annual: 4.32, }, LockTime: 259200, MinimumAmount: "1000000", - Type: blockatlas.DelegationTypeDelegate, }, } - assert.Equal(t, expected, actual) -} -const delegationsSrc1 = ` -{ - "address": "419241920da7d6bb487a33a6df3838e3d208f0b251", - "frozen": [ - { - "expire_time": 10437262001000, - "frozen_balance": "35000000" - } - ], - "votes": [ - { - "vote_address": "TGzz8gjYiYRqpfmDwnLxfgPuLVNmpCswVp", - "vote_count": 21 - }, - { - "vote_address": "TPMGfspxLQGom8sKutrbHcDKtHjRHFbGKw", - "vote_count": 5 - }, - { - "vote_address": "TPMGfspxLQGom8sKutrbHcDKtHjRHFbGKw", - "vote_count": 5 + validator2 = blockatlas.StakeValidator{ + ID: "TPMGfspxLQGom8sKutrbHcDKtHjRHFbGKw", + Status: true, + Info: blockatlas.StakeValidatorInfo{ + Name: "InfStones", + Description: "World's leading cloud infrastructure and staking as a service provicer for blockchains. Supernodes on EOS, TRON, VeChain, Ontology, LOOM, IOST and many other chains.", + Image: "https://assets.trustwalletapp.com/blockchains/tron/validators/assets/tpmgfspxlqgom8skutrbhcdkthjrhfbgkw/logo.png", + Website: "https://infstones.io/", + }, + Details: blockatlas.StakingDetails{ + Reward: blockatlas.StakingReward{ + Annual: 4.32, + }, + LockTime: 259200, + MinimumAmount: "1000000", + }, } - ] -}` -const delegationsSrc2 = ` -{ - "address": "419241920da7d6bb487a33a6df3838e3d208f0b251", - "frozen": [ - { - "expire_time": 1569465251000, - "frozen_balance": "5000000" + delegation1 = blockatlas.Delegation{ + Delegator: validator1, + Value: "21000000", + Status: blockatlas.DelegationStatusPending, + } + delegation2 = blockatlas.Delegation{ + Delegator: validator2, + Value: "5000000", + Status: blockatlas.DelegationStatusPending, } - ], - "votes": [ - { - "vote_address": "TPMGfspxLQGom8sKutrbHcDKtHjRHFbGKw", - "vote_count": 5 + delegation3 = blockatlas.Delegation{ + Delegator: validator2, + Value: "5000000", + Status: blockatlas.DelegationStatusPending, } - ] -}` + delegation4 = blockatlas.Delegation{ + Delegator: validator2, + Value: "5000000", + Status: blockatlas.DelegationStatusActive, + } + validatorMap = blockatlas.ValidatorMap{ + "TGzz8gjYiYRqpfmDwnLxfgPuLVNmpCswVp": validator1, + "TPMGfspxLQGom8sKutrbHcDKtHjRHFbGKw": validator2, + } +) -var validator1 = blockatlas.StakeValidator{ - ID: "TGzz8gjYiYRqpfmDwnLxfgPuLVNmpCswVp", - Status: true, - Info: blockatlas.StakeValidatorInfo{ - Name: "Sesameseed", - Description: "Sesameseed is a blockchain community providing fair and transparent representation in delegated governance by rewarding Voters for their participation on Tron and Ontology.", - Image: "https://raw.githubusercontent.com/trustwallet/assets/master/blockchains/tron/validators/assets/tgzz8gjyiyrqpfmdwnlxfgpulvnmpcswvp/logo.png", - Website: "https://www.sesameseed.org", - }, - Details: blockatlas.StakingDetails{ - Reward: blockatlas.StakingReward{ - Annual: 4.32, - }, - LockTime: 259200, - MinimumAmount: "1000000", - }, -} +func TestNormalizeValidator(t *testing.T) { + validator := Validator{Address: "414d1ef8673f916debb7e2515a8f3ecaf2611034aa"} -var validator2 = blockatlas.StakeValidator{ - ID: "TPMGfspxLQGom8sKutrbHcDKtHjRHFbGKw", - Status: true, - Info: blockatlas.StakeValidatorInfo{ - Name: "InfStones", - Description: "World's leading cloud infrastructure and staking as a service provicer for blockchains. Supernodes on EOS, TRON, VeChain, Ontology, LOOM, IOST and many other chains.", - Image: "https://raw.githubusercontent.com/trustwallet/assets/master/blockchains/tron/validators/assets/tpmgfspxlqgom8skutrbhcdkthjrhfbgkw/logo.png", - Website: "https://infstones.io/", - }, - Details: blockatlas.StakingDetails{ - Reward: blockatlas.StakingReward{ - Annual: 4.32, + actual, _ := normalizeValidator(validator) + expected := blockatlas.Validator{ + ID: "TGzz8gjYiYRqpfmDwnLxfgPuLVNmpCswVp", + Status: true, + Details: blockatlas.StakingDetails{ + Reward: blockatlas.StakingReward{ + Annual: Annual, + }, + LockTime: 259200, + MinimumAmount: "1000000", + Type: blockatlas.DelegationTypeDelegate, }, - LockTime: 259200, - MinimumAmount: "1000000", - }, -} - -var delegation1 = blockatlas.Delegation{ - Delegator: validator1, - Value: "21000000", - Status: blockatlas.DelegationStatusPending, -} -var delegation2 = blockatlas.Delegation{ - Delegator: validator2, - Value: "5000000", - Status: blockatlas.DelegationStatusPending, -} -var delegation3 = blockatlas.Delegation{ - Delegator: validator2, - Value: "5000000", - Status: blockatlas.DelegationStatusPending, -} -var delegation4 = blockatlas.Delegation{ - Delegator: validator2, - Value: "5000000", - Status: blockatlas.DelegationStatusActive, -} - -var validatorMap = blockatlas.ValidatorMap{ - "TGzz8gjYiYRqpfmDwnLxfgPuLVNmpCswVp": validator1, - "TPMGfspxLQGom8sKutrbHcDKtHjRHFbGKw": validator2, + } + assert.Equal(t, expected, actual) } func TestNormalizeDelegations(t *testing.T) { diff --git a/platform/tron/token.go b/platform/tron/token.go new file mode 100644 index 000000000..72062bdc0 --- /dev/null +++ b/platform/tron/token.go @@ -0,0 +1,28 @@ +package tron + +import ( + "github.com/trustwallet/golibs/asset" + "github.com/trustwallet/golibs/types" +) + +func (p *Platform) GetTokenListByAddress(address string) ([]types.Token, error) { + return []types.Token{}, nil +} + +func (p *Platform) GetTokenListIdsByAddress(address string) ([]string, error) { + assetIds := make([]string, 0) + tokens, err := p.client.fetchAccount(address) + if err != nil { + return assetIds, err + } + if len(tokens.Data) == 0 { + return assetIds, nil + } + for _, trc20Tokens := range tokens.Data[0].Trc20 { + for assetId := range trc20Tokens { + assetIds = append(assetIds, asset.BuildID(p.Coin().ID, assetId)) + } + } + + return assetIds, nil +} diff --git a/platform/tron/token_test.go b/platform/tron/token_test.go new file mode 100644 index 000000000..f7af4dd7a --- /dev/null +++ b/platform/tron/token_test.go @@ -0,0 +1,100 @@ +package tron + +import ( + "encoding/json" + "fmt" + "net/http" + "net/http/httptest" + "sort" + "testing" + + "github.com/stretchr/testify/assert" + "github.com/trustwallet/golibs/mock" +) + +func TestPlatform_GetTokenListByAddress(t *testing.T) { + server := httptest.NewServer(createMockedAPI()) + defer server.Close() + + p := Init(server.URL, server.URL) + res, err := p.GetTokenListIdsByAddress("TM1zzNDZD2DPASbKcgdVoTYhfmYgtfwx9R") + assert.Nil(t, err) + sort.Slice(res, func(i, j int) bool { + return res[i] < res[j] + }) + rawRes, err := json.Marshal(res) + assert.Nil(t, err) + assert.JSONEq(t, wantedTokensResponse, string(rawRes)) +} + +var ( + wantedTokensResponse, _ = mock.JsonStringFromFilePath("mocks/tokens/tokens_response.json") + mockedAccountsTransactionsResponse, _ = mock.JsonStringFromFilePath("mocks/tokens/accounts_txs_response.json") + mockedTrc20Response, _ = mock.JsonStringFromFilePath("mocks/tokens/trc20_response.json") + mockedTransactionsTrc20Response, _ = mock.JsonStringFromFilePath("mocks/tokens/txs_trc20_response.json") + mockedTransactionsEmptyResponse, _ = mock.JsonStringFromFilePath("mocks/tokens/txs_empty_response.json") + mockedAsset1000542Response, _ = mock.JsonStringFromFilePath("mocks/tokens/asset_1000542_response.json") + mockedAsset1000567Response, _ = mock.JsonStringFromFilePath("mocks/tokens/asset_1000567_response.json") + mockedAssetTR7NHResponse, _ = mock.JsonStringFromFilePath("mocks/tokens/asset_tr7nh_response.json") + mockedAccountsResponse, _ = mock.JsonStringFromFilePath("mocks/tokens/accounts_response.json") +) + +func createMockedAPI() http.Handler { + r := http.NewServeMux() + + r.HandleFunc("/v1/accounts/TM1zzNDZD2DPASbKcgdVoTYhfmYgtfwx9R", func(w http.ResponseWriter, r *http.Request) { + w.WriteHeader(http.StatusOK) + if _, err := fmt.Fprint(w, mockedAccountsResponse); err != nil { + panic(err) + } + }) + + r.HandleFunc("/v1/assets/1000542", func(w http.ResponseWriter, r *http.Request) { + w.WriteHeader(http.StatusOK) + if _, err := fmt.Fprint(w, mockedAsset1000542Response); err != nil { + panic(err) + } + }) + + r.HandleFunc("/v1/assets/1000567", func(w http.ResponseWriter, r *http.Request) { + w.WriteHeader(http.StatusOK) + if _, err := fmt.Fprint(w, mockedAsset1000567Response); err != nil { + panic(err) + } + }) + r.HandleFunc("/v1/assets/TR7NHqjeKQxGTCi8q8ZY4pL8otSzgjLj6t", func(w http.ResponseWriter, r *http.Request) { + w.WriteHeader(http.StatusOK) + if _, err := fmt.Fprint(w, mockedAssetTR7NHResponse); err != nil { + panic(err) + } + }) + + r.HandleFunc("/api/account", func(w http.ResponseWriter, r *http.Request) { + w.WriteHeader(http.StatusOK) + if _, err := fmt.Fprint(w, mockedTrc20Response); err != nil { + panic(err) + } + }) + r.HandleFunc("/v1/accounts/TM1zzNDZD2DPASbKcgdVoTYhfmYgtfwx9R/transactions", func(w http.ResponseWriter, r *http.Request) { + w.WriteHeader(http.StatusOK) + if _, err := fmt.Fprint(w, mockedAccountsTransactionsResponse); err != nil { + panic(err) + } + }) + + r.HandleFunc("/v1/accounts/TM1zzNDZD2DPASbKcgdVoTYhfmYgtfwx9D/transactions", func(w http.ResponseWriter, r *http.Request) { + w.WriteHeader(http.StatusOK) + if _, err := fmt.Fprint(w, mockedTransactionsEmptyResponse); err != nil { + panic(err) + } + }) + + r.HandleFunc("/v1/accounts/TM1zzNDZD2DPASbKcgdVoTYhfmYgtfwx9D/transactions/trc20", func(w http.ResponseWriter, r *http.Request) { + w.WriteHeader(http.StatusOK) + if _, err := fmt.Fprint(w, mockedTransactionsTrc20Response); err != nil { + panic(err) + } + }) + + return r +} diff --git a/platform/tron/transaction.go b/platform/tron/transaction.go new file mode 100644 index 000000000..0eaa161c4 --- /dev/null +++ b/platform/tron/transaction.go @@ -0,0 +1,123 @@ +package tron + +import ( + "errors" + "strconv" + + "github.com/trustwallet/golibs/coin" + "github.com/trustwallet/golibs/types" +) + +func (p *Platform) GetTxsByAddress(address string) (types.Txs, error) { + Txs, err := p.client.fetchTxsOfAddress(address, "") + if err != nil && len(Txs) == 0 { + return nil, err + } + + txs := make(types.Txs, 0) + for _, srcTx := range Txs { + tx, err := normalize(srcTx) + if err != nil { + continue + } + + if len(srcTx.Data.Contracts) > 0 && srcTx.Data.Contracts[0].Type == TransferContract { + txs = append(txs, *tx) + } else { + continue + } + } + + return txs, nil +} + +func (p *Platform) GetTokenTxsByAddress(address, token string) (types.Txs, error) { + unknownTokenType := errors.New("unknownTokenType") + tokenType := getTokenType(token) + + switch tokenType { + case types.TRC10: + return types.Txs{}, nil + case types.TRC20: + trc20Transactions, err := p.client.fetchTRC20Transactions(address) + if err != nil { + return nil, err + } + return normalizeTRC20Transactions(trc20Transactions), nil + default: + return nil, unknownTokenType + } +} + +func getTokenType(token string) types.TokenType { + _, err := strconv.Atoi(token) + if err != nil { + return types.TRC20 + } else { + return types.TRC10 + } +} + +func normalizeTRC20Transactions(transactions TRC20Transactions) types.Txs { + txs := make(types.Txs, 0, len(transactions.Data)) + for _, rawTx := range transactions.Data { + tx := types.Tx{ + ID: rawTx.TransactionID, + Coin: coin.TRON, + Date: rawTx.BlockTimestamp / 1000, + From: rawTx.From, + To: rawTx.To, + Fee: "0", + Block: 0, + Status: types.StatusCompleted, + Meta: types.TokenTransfer{ + Name: rawTx.TokenInfo.Name, + Symbol: rawTx.TokenInfo.Symbol, + TokenID: rawTx.TokenInfo.Address, + Decimals: uint(rawTx.TokenInfo.Decimals), + Value: types.Amount(rawTx.Value), + From: rawTx.From, + To: rawTx.To, + }, + } + txs = append(txs, tx) + } + return txs +} + +func normalize(srcTx Tx) (*types.Tx, error) { + if len(srcTx.Data.Contracts) == 0 { + return nil, errors.New("no contracts") + } + + contract := srcTx.Data.Contracts[0] + if contract.Type != TransferContract && contract.Type != TransferAssetContract { + return nil, errors.New("TRON: invalid contract transfer") + } + + transfer := contract.Parameter.Value + from, err := HexToAddress(transfer.OwnerAddress) + if err != nil { + return nil, err + } + to, err := HexToAddress(transfer.ToAddress) + if err != nil { + return nil, err + } + + return &types.Tx{ + ID: srcTx.ID, + Coin: coin.TRON, + Date: srcTx.BlockTime / 1000, + From: from, + To: to, + Fee: "0", + Block: 0, + Status: types.StatusCompleted, + Meta: types.Transfer{ + Value: transfer.Amount, + Symbol: coin.Tron().Symbol, + Decimals: coin.Tron().Decimals, + }, + }, nil +} diff --git a/platform/tron/transaction_test.go b/platform/tron/transaction_test.go new file mode 100644 index 000000000..40138116c --- /dev/null +++ b/platform/tron/transaction_test.go @@ -0,0 +1,101 @@ +package tron + +import ( + "encoding/json" + "net/http/httptest" + "testing" + + "github.com/stretchr/testify/assert" + "github.com/trustwallet/golibs/coin" + "github.com/trustwallet/golibs/mock" + "github.com/trustwallet/golibs/types" +) + +var ( + transferSrc, _ = mock.JsonStringFromFilePath("mocks/" + "transfer.json") + wantedTransactionsWithToken, _ = mock.JsonStringFromFilePath("mocks/" + "token_txs_response.json") + wantedTransactionsOnly, _ = mock.JsonStringFromFilePath("mocks/" + "txs_response.json") + + transferDst = types.Tx{ + ID: "24a10f7a503e78adc0d7e380b68005531b09e16b9e3f7b524e33f40985d287df", + Coin: coin.TRON, + From: "TMuA6YqfCeX8EhbfYEg5y7S4DqzSJireY9", + To: "TAUN6FwrnwwmaEqYcckffC7wYmbaS6cBiX", + Fee: "0", // TODO + Date: 1564797900, + Block: 0, // TODO + Status: types.StatusCompleted, + Meta: types.Transfer{ + Value: "100666888000000", + Symbol: "TRX", + Decimals: 6, + }, + } +) + +type test struct { + name string + apiResponse string + expected *types.Tx +} + +func TestNormalize(t *testing.T) { + testNormalize(t, &test{ + name: "transfer", + apiResponse: transferSrc, + expected: &transferDst, + }) +} + +func testNormalize(t *testing.T, _test *test) { + var srcTx Tx + err := json.Unmarshal([]byte(_test.apiResponse), &srcTx) + assert.NoError(t, err) + assert.NotNil(t, srcTx) + res, err := normalize(srcTx) + assert.NoError(t, err) + assert.NotNil(t, res) + assert.Equal(t, _test.expected, res) +} + +func TestPlatform_GetTxsByAddress(t *testing.T) { + server := httptest.NewServer(createMockedAPI()) + defer server.Close() + + p := Init(server.URL, server.URL) + res, err := p.GetTxsByAddress("TM1zzNDZD2DPASbKcgdVoTYhfmYgtfwx9R") + assert.Nil(t, err) + + rawRes, err := json.Marshal(res) + assert.Nil(t, err) + assert.JSONEq(t, wantedTransactionsOnly, string(rawRes)) +} + +func TestPlatform_GetTokenTxsByAddress(t *testing.T) { + server := httptest.NewServer(createMockedAPI()) + defer server.Close() + + p := Init(server.URL, server.URL) + res, err := p.GetTokenTxsByAddress("TM1zzNDZD2DPASbKcgdVoTYhfmYgtfwx9D", "TR7NHqjeKQxGTCi8q8ZY4pL8otSzgjLj6t") + assert.Nil(t, err) + + rawRes, err := json.Marshal(res) + assert.Nil(t, err) + assert.JSONEq(t, wantedTransactionsWithToken, string(rawRes)) +} + +func Test_getTokenType(t *testing.T) { + tests := []struct { + name string + token string + want types.TokenType + }{ + {"default trc20", "TR7NHqjeKQxGTCi8q8ZY4pL8otSzgjLj6t", types.TRC20}, + {"default trc10", "1002001", types.TRC10}, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + assert.Equal(t, tt.want, getTokenType(tt.token)) + }) + } +} diff --git a/platform/tron/util_test.go b/platform/tron/util_test.go deleted file mode 100644 index 85e8bda18..000000000 --- a/platform/tron/util_test.go +++ /dev/null @@ -1,15 +0,0 @@ -package tron - -import "testing" - -func TestHexToAddress(t *testing.T) { - in := "4182dd6b9966724ae2fdc79b416c7588da67ff1b35" - expected := "TMuA6YqfCeX8EhbfYEg5y7S4DqzSJireY9" - got, err := HexToAddress(in) - if err != nil { - t.Fatal(err) - } - if expected != got { - t.Fatalf("expected %s, got %s", expected, got) - } -} diff --git a/platform/vechain/api.go b/platform/vechain/api.go deleted file mode 100644 index 0121cb1a0..000000000 --- a/platform/vechain/api.go +++ /dev/null @@ -1,222 +0,0 @@ -package vechain - -import ( - "github.com/spf13/viper" - "github.com/trustwallet/blockatlas/coin" - "github.com/trustwallet/blockatlas/pkg/address" - "github.com/trustwallet/blockatlas/pkg/blockatlas" - "github.com/trustwallet/blockatlas/pkg/errors" - "github.com/trustwallet/blockatlas/pkg/logger" - "github.com/trustwallet/blockatlas/pkg/numbers" - "strconv" - "sync" -) - -type Platform struct { - client Client -} - -func (p *Platform) Init() error { - p.client = Client{blockatlas.InitClient(viper.GetString("vechain.api"))} - return nil -} - -func (p *Platform) Coin() coin.Coin { - return coin.Coins[coin.VET] -} - -func (p *Platform) CurrentBlockNumber() (int64, error) { - return p.client.GetCurrentBlock() -} - -func (p *Platform) GetBlockByNumber(num int64) (*blockatlas.Block, error) { - block, err := p.client.GetBlockByNumber(num) - if err != nil { - return nil, err - } - cTxs := p.getTransactionsByIDs(block.Transactions) - txs := make(blockatlas.TxPage, 0) - for t := range cTxs { - txs = append(txs, t...) - } - return &blockatlas.Block{ - Number: num, - ID: block.Id, - Txs: txs, - }, nil -} - -func (p *Platform) GetTokenTxsByAddress(address, token string) (blockatlas.TxPage, error) { - curBlock, err := p.CurrentBlockNumber() - if err != nil { - return nil, err - } - events, err := p.client.GetLogsEvent(address, token, curBlock) - if err != nil { - return nil, err - } - eventsIDs := make([]string, 0) - for _, event := range events { - eventsIDs = append(eventsIDs, event.Meta.TxId) - } - - cTxs := p.getTransactionsByIDs(eventsIDs) - txs := make(blockatlas.TxPage, 0) - for t := range cTxs { - txs = append(txs, t...) - } - return txs, nil -} - -func (p *Platform) getTransactionsByIDs(ids []string) chan blockatlas.TxPage { - txChan := make(chan blockatlas.TxPage, len(ids)) - var wg sync.WaitGroup - for _, id := range ids { - wg.Add(1) - go func(i string, c chan blockatlas.TxPage) { - defer wg.Done() - err := p.getTransactionChannel(i, c) - if err != nil { - logger.Error(err) - } - }(id, txChan) - } - wg.Wait() - close(txChan) - return txChan -} - -func (p *Platform) getTransactionChannel(id string, txChan chan blockatlas.TxPage) error { - srcTx, err := p.client.GetTransactionByID(id) - if err != nil { - return errors.E(err, "Failed to get tx", errors.TypePlatformUnmarshal, - errors.Params{"id": id}).PushToSentry() - } - - receipt, err := p.client.GetTransactionReceiptByID(id) - if err != nil { - return errors.E(err, "Failed to get tx id receipt", errors.TypePlatformUnmarshal, - errors.Params{"id": id}).PushToSentry() - } - - txs, err := NormalizeTokenTransaction(srcTx, receipt) - if err != nil { - return errors.E(err, "Failed to NormalizeBlockTransactions tx", errors.TypePlatformUnmarshal, - errors.Params{"tx": srcTx}).PushToSentry() - } - txChan <- txs - return nil -} - -func NormalizeTokenTransaction(srcTx Tx, receipt TxReceipt) (blockatlas.TxPage, error) { - if receipt.Outputs == nil || len(receipt.Outputs) == 0 { - return blockatlas.TxPage{}, errors.E("NormalizeBlockTransaction: Clauses not found", errors.Params{"tx": srcTx}).PushToSentry() - } - - origin := address.EIP55Checksum(blockatlas.GetValidParameter(srcTx.Origin, srcTx.Meta.TxOrigin)) - - fee, err := numbers.HexToDecimal(receipt.Paid) - if err != nil { - return blockatlas.TxPage{}, err - } - - txs := make(blockatlas.TxPage, 0) - for _, output := range receipt.Outputs { - if len(output.Events) == 0 || len(output.Events[0].Topics) < 3 { - continue - } - event := output.Events[0] // TODO add support for multisend - to := address.EIP55Checksum(event.Address) - value, err := numbers.HexToDecimal(event.Data) - if err != nil { - continue - } - - txs = append(txs, blockatlas.Tx{ - ID: srcTx.Id, - Coin: coin.VET, - From: origin, - To: to, - Fee: blockatlas.Amount(fee), - Date: srcTx.Meta.BlockTimestamp, - Type: blockatlas.TxTokenTransfer, - Block: srcTx.Meta.BlockNumber, - Status: blockatlas.StatusCompleted, - Meta: blockatlas.TokenTransfer{ - Name: "", // TODO replace with real name for other coins - TokenID: to, - Value: blockatlas.Amount(value), - Symbol: "VTHO", // TODO replace with real symbol for other coins - Decimals: 18, // TODO Not all tokens have decimal 18 https://github.com/vechain/token-registry/tree/master/tokens/main - From: origin, - To: address.EIP55Checksum(getRecipientAddress(event.Topics[2])), - }, - }) - } - return txs, nil -} - -func (p *Platform) GetTxsByAddress(address string) (blockatlas.TxPage, error) { - headBlock, err := p.CurrentBlockNumber() - if err != nil { - return nil, err - } - transfers, err := p.client.GetTransactions(address, headBlock) - if err != nil { - return nil, err - } - - txs := make(blockatlas.TxPage, 0) - for _, t := range transfers { - trxId, err := p.client.GetTransactionByID(t.Meta.TxId) - if err != nil{ - continue - } - tx, err := NormalizeTransaction(t, trxId) - if err != nil { - continue - } - txs = append(txs, tx) - } - return txs, nil -} - -func NormalizeTransaction(srcTx LogTransfer, trxId Tx) (blockatlas.Tx, error) { - value, err := numbers.HexToDecimal(srcTx.Amount) - if err != nil { - return blockatlas.Tx{}, err - } - - fee := strconv.Itoa(trxId.Gas) - - return blockatlas.Tx{ - ID: srcTx.Meta.TxId, - Coin: coin.VET, - From: address.EIP55Checksum(srcTx.Sender), - To: address.EIP55Checksum(srcTx.Recipient), - Fee: blockatlas.Amount(fee), - Date: srcTx.Meta.BlockTimestamp, - Type: blockatlas.TxTransfer, - Block: srcTx.Meta.BlockNumber, - Status: blockatlas.StatusCompleted, - Meta: blockatlas.Transfer{ - Value: blockatlas.Amount(value), - Symbol: coin.Coins[coin.VET].Symbol, - Decimals: 18, - }, - }, nil -} - -func hexToInt(hex string) (uint64, error) { - nonceStr, err := numbers.HexToDecimal(hex) - if err != nil { - return 0, err - } - return strconv.ParseUint(nonceStr, 10, 64) -} - -// Substring recipient address from clause data and appends 0x -// 0x000000000000000000000000b5e883349e68ab59307d1604555ac890fac47128 => 0xb5e883349e68ab59307d1604555ac890fac47128 -func getRecipientAddress(hex string) string { - return "0x" + hex[len(hex)-40:] -} diff --git a/platform/vechain/api_test.go b/platform/vechain/api_test.go deleted file mode 100644 index 01aa8cfdc..000000000 --- a/platform/vechain/api_test.go +++ /dev/null @@ -1,225 +0,0 @@ -package vechain - -import ( - "encoding/json" - "github.com/stretchr/testify/assert" - "github.com/trustwallet/blockatlas/coin" - "github.com/trustwallet/blockatlas/pkg/blockatlas" - "testing" -) - -const transferSrc = `{ - "sender": "0xb5e883349e68ab59307d1604555ac890fac47128", - "recipient": "0x2c7a8d5cce0d5e6a8a31233b7dc3dae9aae4b405", - "amount": "0x12b1815d00738000", - "meta": { - "blockID": "0x004313a4bd4286e821b684cc1749deb3df12fa2a8114435fbd35baa155e82016", - "blockNumber": 4395940, - "blockTimestamp": 1574410670, - "txID": "0x702edd54bd4e13e0012798cc8b2dfa52f7150173945103d203fae26b8e3d2ed7", - "txOrigin": "0xb5e883349e68ab59307d1604555ac890fac47128", - "clauseIndex": 0 - } - }` -const trxId = `{ - "gas": 21000, - "nonce": "0x8cff29df64a414f8" -}` - -var expectedTransfer = blockatlas.Tx{ - ID: "0x702edd54bd4e13e0012798cc8b2dfa52f7150173945103d203fae26b8e3d2ed7", - Coin: coin.VET, - From: "0xB5e883349e68aB59307d1604555AC890fAC47128", - To: "0x2c7A8d5ccE0d5E6a8a31233B7Dc3DAE9AaE4b405", - Date: 1574410670, - Type: blockatlas.TxTransfer, - Fee: blockatlas.Amount("21000"), - Status: blockatlas.StatusCompleted, - Block: 4395940, - Meta: blockatlas.Transfer{ - Value: blockatlas.Amount("1347000000000000000"), - Decimals: 18, - Symbol: "VET", - }, -} - -func TestNormalizeTransaction(t *testing.T) { - tests := []struct { - name string - txData string - txId string - expected blockatlas.Tx - }{ - {"Test normalize VET transfer transaction", transferSrc, trxId, expectedTransfer}, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - var tx LogTransfer - err := json.Unmarshal([]byte(tt.txData), &tx) - assert.Nil(t, err) - - var tId Tx - errTrxID := json.Unmarshal([]byte(tt.txId), &tId) - assert.Nil(t, errTrxID) - - actual, err := NormalizeTransaction(tx, tId) - assert.Nil(t, err) - - assert.Equal(t, tt.expected, actual, "tx don't equal") - }) - } -} - -const transferLogSrc = `{ - "id": "0x42f5eba46ddcc458243c753545a3faa849502d078efbc5b74baddea9e6ea5b04", - "chainTag": 74, - "blockRef": "0x0042e02a2ae04200", - "expiration": 720, - "clauses": [ - { - "to": "0x0000000000000000000000000000456e65726779", - "value": "0x0", - "data": "0xa9059cbb000000000000000000000000b5e883349e68ab59307d1604555ac890fac47128000000000000000000000000000000000000000000000003afb087b876900000" - } - ], - "gasPriceCoef": 0, - "gas": 80000, - "origin": "0x2c7a8d5cce0d5e6a8a31233b7dc3dae9aae4b405", - "delegator": null, - "nonce": "0x4a8569d", - "dependsOn": null, - "size": 189, - "meta": { - "blockID": "0x0042e02cebd1bec003d31526dba338c1b9eeeefdef722fb147e9d31690fbff1e", - "blockNumber": 4382764, - "blockTimestamp": 1574278180 - } -}` - -const trxReceipt = `{ - "gasUsed": 36582, - "gasPayer": "0x2c7a8d5cce0d5e6a8a31233b7dc3dae9aae4b405", - "paid": "0x1fbad5f2e25570000", - "reward": "0x984d9c8dd8008000", - "reverted": false, - "meta": { - "blockID": "0x0042e02cebd1bec003d31526dba338c1b9eeeefdef722fb147e9d31690fbff1e", - "blockNumber": 4382764, - "blockTimestamp": 1574278180, - "txID": "0x42f5eba46ddcc458243c753545a3faa849502d078efbc5b74baddea9e6ea5b04", - "txOrigin": "0x2c7a8d5cce0d5e6a8a31233b7dc3dae9aae4b405" - }, - "outputs": [ - { - "contractAddress": null, - "events": [ - { - "address": "0x0000000000000000000000000000456e65726779", - "topics": [ - "0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef", - "0x0000000000000000000000002c7a8d5cce0d5e6a8a31233b7dc3dae9aae4b405", - "0x000000000000000000000000b5e883349e68ab59307d1604555ac890fac47128" - ], - "data": "0x000000000000000000000000000000000000000000000003afb087b876900000" - } - ], - "transfers": [] - } - ] -}` - -var expectedTransferLog = blockatlas.TxPage{ - { - ID: "0x42f5eba46ddcc458243c753545a3faa849502d078efbc5b74baddea9e6ea5b04", - Coin: coin.VET, - From: "0x2c7A8d5ccE0d5E6a8a31233B7Dc3DAE9AaE4b405", - To: "0x0000000000000000000000000000456E65726779", - Date: 1574278180, - Type: blockatlas.TxTokenTransfer, - Fee: blockatlas.Amount("36582000000000000000"), - Status: blockatlas.StatusCompleted, - Block: 4382764, - Meta: blockatlas.TokenTransfer{ - Name: "", - Symbol: "VTHO", - TokenID: "0x0000000000000000000000000000456E65726779", - From: "0x2c7A8d5ccE0d5E6a8a31233B7Dc3DAE9AaE4b405", - To: "0xB5e883349e68aB59307d1604555AC890fAC47128", - Value: blockatlas.Amount("68000000000000000000"), - Decimals: 18, - }, - }, -} - -func TestNormalizeTokenTransaction(t *testing.T) { - tests := []struct { - name string - txData string - txReceipt string - expected blockatlas.TxPage - }{ - {"Normalize VIP180 token transfer", transferLogSrc, trxReceipt, expectedTransferLog}, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - var tx Tx - err := json.Unmarshal([]byte(tt.txData), &tx) - assert.Nil(t, err) - - var receipt TxReceipt - errR := json.Unmarshal([]byte(tt.txReceipt), &receipt) - assert.Nil(t, errR) - - actual, err := NormalizeTokenTransaction(tx, receipt) - assert.Nil(t, err) - - assert.Equal(t, len(actual), 1, "tx could not be normalized") - assert.Equal(t, tt.expected, actual, "tx don't equal") - }) - } -} - -func Test_hexToInt(t *testing.T) { - tests := []struct { - name string - hex string - expected uint64 - wantErr bool - }{ - {"value 1", "0x603ca6b1879375dc", 6934600807657731548, false}, - {"value 2", "0x38d7ea4c68000", 1000000000000000, false}, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - got, err := hexToInt(tt.hex) - if (err != nil) != tt.wantErr { - t.Errorf("hexToInt() error = %v, wantErr %v", err, tt.wantErr) - return - } - if got != tt.expected { - t.Errorf("hexToInt() got = %v, want %v", got, tt.expected) - } - }) - } -} - -func Test_getRecipientAddress(t *testing.T) { - type args struct { - hex string - } - tests := []struct { - name string - hex string - want string - }{ - {"hex 1", "0x000000000000000000000000b5e883349e68ab59307d1604555ac890fac47128", "0xb5e883349e68ab59307d1604555ac890fac47128"}, - {"hex 2", "0x000000000000000000000000f3586684107ce0859c44aa2b2e0fb8cd8731a15a", "0xf3586684107ce0859c44aa2b2e0fb8cd8731a15a"}, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - if got := getRecipientAddress(tt.hex); got != tt.want { - t.Errorf("getRecipientAddress() = %v, want %v", got, tt.want) - } - }) - } -} diff --git a/platform/vechain/base.go b/platform/vechain/base.go new file mode 100644 index 000000000..17d2979fd --- /dev/null +++ b/platform/vechain/base.go @@ -0,0 +1,21 @@ +package vechain + +import ( + "github.com/trustwallet/golibs/client" + "github.com/trustwallet/golibs/coin" + "github.com/trustwallet/golibs/network/middleware" +) + +type Platform struct { + client Client +} + +func Init(api string) *Platform { + return &Platform{ + client: Client{client.InitJSONClient(api, middleware.SentryErrorHandler)}, + } +} + +func (p *Platform) Coin() coin.Coin { + return coin.Vechain() +} diff --git a/platform/vechain/block.go b/platform/vechain/block.go new file mode 100644 index 000000000..5cb22b387 --- /dev/null +++ b/platform/vechain/block.go @@ -0,0 +1,21 @@ +package vechain + +import "github.com/trustwallet/golibs/types" + +func (p *Platform) CurrentBlockNumber() (int64, error) { + return p.client.GetCurrentBlock() +} + +func (p *Platform) GetBlockByNumber(num int64) (*types.Block, error) { + block, err := p.client.GetBlockByNumber(num) + if err != nil { + return nil, err + } + + txs, err := p.getTransactionsByIDs(block.Transactions) + if err != nil { + return nil, err + } + + return &types.Block{Number: num, Txs: txs}, nil +} diff --git a/platform/vechain/client.go b/platform/vechain/client.go index 919fe8d7f..42803b722 100644 --- a/platform/vechain/client.go +++ b/platform/vechain/client.go @@ -2,12 +2,13 @@ package vechain import ( "fmt" - "github.com/trustwallet/blockatlas/pkg/blockatlas" "strings" + + "github.com/trustwallet/golibs/client" ) type Client struct { - blockatlas.Request + client.Request } func (c *Client) GetCurrentBlock() (int64, error) { @@ -62,6 +63,11 @@ func (c *Client) GetTransactionReceiptByID(id string) (transaction TxReceipt, er return } +func (c *Client) GetAccount(address string) (account Account, err error) { + err = c.Get(&account, "accounts/"+address, nil) + return +} + // Creates hex based on address as required for topic criteria // 0xB5e883349e68aB59307d1604555AC890fAC47128 => 0x000000000000000000000000B5e883349e68aB59307d1604555AC890fAC47128 func getFilter(hex string) string { diff --git a/platform/vechain/mocks/incoming_vtho_receipt.json b/platform/vechain/mocks/incoming_vtho_receipt.json new file mode 100644 index 000000000..6e18c6bc8 --- /dev/null +++ b/platform/vechain/mocks/incoming_vtho_receipt.json @@ -0,0 +1,31 @@ +{ + "gasUsed": 36582, + "gasPayer": "0xb5e883349e68ab59307d1604555ac890fac47128", + "paid": "0x1fbad5f2e25570000", + "reward": "0x984d9c8dd8008000", + "reverted": false, + "meta": { + "blockID": "0x007ac4b1a18c0fc3a11f44285d6a42eff591a99312d303c105a4f4de7fa10575", + "blockNumber": 8045745, + "blockTimestamp": 1610958460, + "txID": "0xb356fa7b3a371f1518a5f9bc51e951d0dac2ef04d58b532c7ca50a52aa5cddb4", + "txOrigin": "0xb5e883349e68ab59307d1604555ac890fac47128" + }, + "outputs": [ + { + "contractAddress": null, + "events": [ + { + "address": "0x0000000000000000000000000000456e65726779", + "topics": [ + "0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef", + "0x000000000000000000000000b5e883349e68ab59307d1604555ac890fac47128", + "0x000000000000000000000000e99399dd211ef54c301a5d1aa813471d92122ea8" + ], + "data": "0x00000000000000000000000000000000000000000000003635c9adc5dea00000" + } + ], + "transfers": [] + } + ] +} diff --git a/platform/vechain/mocks/incoming_vtho_tx.json b/platform/vechain/mocks/incoming_vtho_tx.json new file mode 100644 index 000000000..93c7737c7 --- /dev/null +++ b/platform/vechain/mocks/incoming_vtho_tx.json @@ -0,0 +1,25 @@ +{ + "id": "0xb356fa7b3a371f1518a5f9bc51e951d0dac2ef04d58b532c7ca50a52aa5cddb4", + "chainTag": 74, + "blockRef": "0x007ac4b0b0c47a00", + "expiration": 720, + "clauses": [ + { + "to": "0x0000000000000000000000000000456e65726779", + "value": "0x0", + "data": "0xa9059cbb000000000000000000000000e99399dd211ef54c301a5d1aa813471d92122ea800000000000000000000000000000000000000000000003635c9adc5dea00000" + } + ], + "gasPriceCoef": 0, + "gas": 43245, + "origin": "0xb5e883349e68ab59307d1604555ac890fac47128", + "delegator": null, + "nonce": "0x2a2e2da5", + "dependsOn": null, + "size": 188, + "meta": { + "blockID": "0x007ac4b1a18c0fc3a11f44285d6a42eff591a99312d303c105a4f4de7fa10575", + "blockNumber": 8045745, + "blockTimestamp": 1610958460 + } +} diff --git a/platform/vechain/mocks/outgoing_vtho_receipt.json b/platform/vechain/mocks/outgoing_vtho_receipt.json new file mode 100644 index 000000000..72b86278d --- /dev/null +++ b/platform/vechain/mocks/outgoing_vtho_receipt.json @@ -0,0 +1,31 @@ +{ + "gasUsed": 36518, + "gasPayer": "0xe99399dd211ef54c301a5d1aa813471d92122ea8", + "paid": "0x1fac9ff84f3b70000", + "reward": "0x980966417c508000", + "reverted": false, + "meta": { + "blockID": "0x007ac4bc8090b67c3e3c395e5e986226eab3a8619250807cf32b0c247f6d513c", + "blockNumber": 8045756, + "blockTimestamp": 1610958570, + "txID": "0x0677f91de4787d295087acec0a7ba317b0019fbf296fed630fdb5afbfca97a58", + "txOrigin": "0xe99399dd211ef54c301a5d1aa813471d92122ea8" + }, + "outputs": [ + { + "contractAddress": null, + "events": [ + { + "address": "0x0000000000000000000000000000456e65726779", + "topics": [ + "0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef", + "0x000000000000000000000000e99399dd211ef54c301a5d1aa813471d92122ea8", + "0x000000000000000000000000b5e883349e68ab59307d1604555ac890fac47128" + ], + "data": "0x0000000000000000000000000000000000000000000000006124fee993bc0000" + } + ], + "transfers": [] + } + ] +} diff --git a/platform/vechain/mocks/outgoing_vtho_tx.json b/platform/vechain/mocks/outgoing_vtho_tx.json new file mode 100644 index 000000000..93a05cbab --- /dev/null +++ b/platform/vechain/mocks/outgoing_vtho_tx.json @@ -0,0 +1,25 @@ +{ + "id": "0x0677f91de4787d295087acec0a7ba317b0019fbf296fed630fdb5afbfca97a58", + "chainTag": 74, + "blockRef": "0x007ac4babac47a00", + "expiration": 720, + "clauses": [ + { + "to": "0x0000000000000000000000000000456e65726779", + "value": "0x0", + "data": "0xa9059cbb000000000000000000000000b5e883349e68ab59307d1604555ac890fac471280000000000000000000000000000000000000000000000006124fee993bc0000" + } + ], + "gasPriceCoef": 0, + "gas": 43181, + "origin": "0xe99399dd211ef54c301a5d1aa813471d92122ea8", + "delegator": null, + "nonce": "0x2bb08067", + "dependsOn": null, + "size": 188, + "meta": { + "blockID": "0x007ac4bc8090b67c3e3c395e5e986226eab3a8619250807cf32b0c247f6d513c", + "blockNumber": 8045756, + "blockTimestamp": 1610958570 + } +} diff --git a/platform/vechain/mocks/reverted_receipt.json b/platform/vechain/mocks/reverted_receipt.json new file mode 100644 index 000000000..70877ac3f --- /dev/null +++ b/platform/vechain/mocks/reverted_receipt.json @@ -0,0 +1,15 @@ +{ + "gasUsed": 82618, + "gasPayer": "0x7cffb7632252bae3766734d61f148f0ea78fc08c", + "paid": "0x47a8e194565390000", + "reward": "0x157f76dfb37f78000", + "reverted": true, + "meta": { + "blockID": "0x0079ce53965d837f959154813e163ce4d89f51421bdd540f3facb454929ab7fe", + "blockNumber": 7982675, + "blockTimestamp": 1610326580, + "txID": "0x7fae32a743e42eaec54642e2a5742a185299f5b4bedaf12c60f65705661de932", + "txOrigin": "0x7cffb7632252bae3766734d61f148f0ea78fc08c" + }, + "outputs": [] +} diff --git a/platform/vechain/mocks/reverted_tx.json b/platform/vechain/mocks/reverted_tx.json new file mode 100644 index 000000000..fa130c379 --- /dev/null +++ b/platform/vechain/mocks/reverted_tx.json @@ -0,0 +1,30 @@ +{ + "id": "0x7fae32a743e42eaec54642e2a5742a185299f5b4bedaf12c60f65705661de932", + "chainTag": 74, + "blockRef": "0x0079ce52eccee5e8", + "expiration": 18, + "clauses": [ + { + "to": "0xf8e1faa0367298b55f57ed17f7a2ff3f5f1d1628", + "value": "0x0", + "data": "0x095ea7b3000000000000000000000000c96b1e1a436c5ecf150ac7a7de64c0eec73883e000000000000000000000000000000000000000000000001043561a8829300000" + }, + { + "to": "0xc96b1e1a436c5ecf150ac7a7de64c0eec73883e0", + "value": "0x0", + "data": "0x6d6aa5bb000000000000000000000000000000000000000000000000000000003b9aca5800000000000000000000000000000000000000000000001043561a8829300000" + } + ], + "gasPriceCoef": 0, + "gas": 82618, + "origin": "0x7cffb7632252bae3766734d61f148f0ea78fc08c", + "delegator": null, + "nonce": "0x15a6dce553e53070", + "dependsOn": null, + "size": 286, + "meta": { + "blockID": "0x0079ce53965d837f959154813e163ce4d89f51421bdd540f3facb454929ab7fe", + "blockNumber": 7982675, + "blockTimestamp": 1610326580 + } +} diff --git a/platform/vechain/mocks/transfer.json b/platform/vechain/mocks/transfer.json new file mode 100644 index 000000000..0df4afced --- /dev/null +++ b/platform/vechain/mocks/transfer.json @@ -0,0 +1,13 @@ +{ + "sender": "0xb5e883349e68ab59307d1604555ac890fac47128", + "recipient": "0x2c7a8d5cce0d5e6a8a31233b7dc3dae9aae4b405", + "amount": "0x12b1815d00738000", + "meta": { + "blockID": "0x004313a4bd4286e821b684cc1749deb3df12fa2a8114435fbd35baa155e82016", + "blockNumber": 4395940, + "blockTimestamp": 1574410670, + "txID": "0x702edd54bd4e13e0012798cc8b2dfa52f7150173945103d203fae26b8e3d2ed7", + "txOrigin": "0xb5e883349e68ab59307d1604555ac890fac47128", + "clauseIndex": 0 + } +} diff --git a/platform/vechain/mocks/tx_id.json b/platform/vechain/mocks/tx_id.json new file mode 100644 index 000000000..8aa9827c3 --- /dev/null +++ b/platform/vechain/mocks/tx_id.json @@ -0,0 +1,4 @@ +{ + "gas": 21000, + "nonce": "0x8cff29df64a414f8" +} diff --git a/platform/vechain/model.go b/platform/vechain/model.go index 159d014d7..4e1fda3a9 100644 --- a/platform/vechain/model.go +++ b/platform/vechain/model.go @@ -5,6 +5,13 @@ const ( rangeUnit = "block" ) +const ( + gasTokenName = "VeThor" + gasTokenSymbol = "VTHO" + gasTokenAddress = "0x0000000000000000000000000000456E65726779" + gasTokenDecimals = 18 +) + type LogRequest struct { Options Options `json:"options,omitempty"` CriteriaSet []CriteriaSet `json:"criteriaSet,omitempty"` @@ -48,8 +55,9 @@ type Tx struct { } type TxReceipt struct { - Paid string `json:"paid"` - Outputs []Output `json:"outputs"` + Reverted bool `json:"reverted"` + Paid string `json:"paid"` + Outputs []Output `json:"outputs"` } type Output struct { @@ -85,3 +93,7 @@ type LogMeta struct { BlockNumber uint64 `json:"blockNumber,omitempty"` BlockTimestamp int64 `json:"blockTimestamp,omitempty"` } + +type Account struct { + Balance string `json:"balance"` +} diff --git a/platform/vechain/stake.go b/platform/vechain/stake.go new file mode 100644 index 000000000..802e81a0d --- /dev/null +++ b/platform/vechain/stake.go @@ -0,0 +1,53 @@ +package vechain + +import ( + "github.com/trustwallet/blockatlas/pkg/blockatlas" + "github.com/trustwallet/blockatlas/services/assets" + "github.com/trustwallet/golibs/numbers" +) + +const ( + // The current value comes from https://www.stakingrewards.com/asset/vechain + Annual = 1.35 +) + +func (p *Platform) GetActiveValidators() (blockatlas.StakeValidators, error) { + validators, err := assets.GetValidatorsMap(p) + if err != nil { + return nil, err + } + result := make(blockatlas.StakeValidators, 0, len(validators)) + for _, v := range validators { + result = append(result, v) + } + return result, nil +} + +func (p *Platform) GetDetails() blockatlas.StakingDetails { + return blockatlas.StakingDetails{ + Reward: blockatlas.StakingReward{Annual: Annual}, + MinimumAmount: "0", + LockTime: 0, + Type: blockatlas.DelegationTypeAuto, + } +} + +func (p *Platform) UndelegatedBalance(address string) (string, error) { + acc, err := p.client.GetAccount(address) + if err != nil { + return "0", err + } + balance, err := numbers.HexToDecimal(acc.Balance) + if err != nil { + return "0", err + } + return balance, nil +} + +func (p *Platform) GetValidators() (blockatlas.ValidatorPage, error) { + return blockatlas.ValidatorPage{}, nil +} + +func (p *Platform) GetDelegations(address string) (blockatlas.DelegationsPage, error) { + return blockatlas.DelegationsPage{}, nil +} diff --git a/platform/vechain/transaction.go b/platform/vechain/transaction.go new file mode 100644 index 000000000..376e3c98e --- /dev/null +++ b/platform/vechain/transaction.go @@ -0,0 +1,298 @@ +package vechain + +import ( + "errors" + "strconv" + + "github.com/trustwallet/blockatlas/pkg/blockatlas" + "github.com/trustwallet/golibs/address" + "github.com/trustwallet/golibs/coin" + "github.com/trustwallet/golibs/numbers" + "github.com/trustwallet/golibs/types" +) + +func (p *Platform) GetTokenTxsByAddress(address, token string) (page types.Txs, err error) { + if token != gasTokenAddress { + return + } + + blockNumber, err := p.CurrentBlockNumber() + if err != nil { + return + } + + events, err := p.client.GetLogsEvent(address, token, blockNumber) + if err != nil { + return + } + + eventsIDs := make([]string, 0) + for _, event := range events { + eventsIDs = append(eventsIDs, event.Meta.TxId) + } + + txs, err := p.getTransactionsByIDs(eventsIDs) + if err != nil { + return + } + + // NormalizeTokenTransaction won't set tx direction anymore, set it here + for _, tx := range txs { + updateTransactionDirection(&tx, address) + } + + return txs, nil +} + +func (p *Platform) getTransactionsByIDs(ids []string) (types.Txs, error) { + page := types.Txs{} + for _, id := range ids { + tx, err := p.client.GetTransactionByID(id) + if err != nil { + return nil, err + } + + receipt, err := p.client.GetTransactionReceiptByID(id) + if err != nil { + return page, err + } + + txs, err := NormalizeTokenTransaction(tx, receipt) + if err != nil { + return page, err + } + page = append(page, txs...) + } + return page, nil +} + +func NormalizeTokenTransaction(srcTx Tx, receipt TxReceipt) (types.Txs, error) { + // the only supported Token on VeChain is its Gas token + if receipt.Reverted { + return normalizeRevertedTokenTransaction(srcTx, receipt) + } + + txs := make(types.Txs, 0) + + if receipt.Outputs == nil || len(receipt.Outputs) == 0 { + return types.Txs{}, errors.New("NormalizeBlockTransaction: receipt.Outputs not found: " + srcTx.Id) + } + + for _, output := range receipt.Outputs { + if len(output.Events) == 0 || len(output.Events[0].Topics) < 3 { + continue + } + + fee, err := numbers.HexToDecimal(receipt.Paid) + if err != nil { + return txs, err + } + + originSender, err := address.EIP55Checksum(blockatlas.GetValidParameter(srcTx.Origin, srcTx.Meta.TxOrigin)) + if err != nil { + return txs, err + } + + event := output.Events[0] + + value, err := numbers.HexToDecimal(event.Data) + if err != nil { + continue + } + + originReceiver, err := address.EIP55Checksum(event.Address) + if err != nil { + continue + } + + if originReceiver != gasTokenAddress { + continue + } + + topicsTo, err := address.EIP55Checksum(getRecipientAddress(event.Topics[2])) + if err != nil { + continue + } + + txs = append(txs, types.Tx{ + ID: srcTx.Id, + Coin: coin.VECHAIN, + From: originSender, + To: originReceiver, + Fee: types.Amount(fee), + Date: srcTx.Meta.BlockTimestamp, + Type: types.TxTokenTransfer, + Block: srcTx.Meta.BlockNumber, + Status: types.StatusCompleted, + Meta: types.TokenTransfer{ + Name: gasTokenName, + TokenID: originReceiver, + Value: types.Amount(value), + Symbol: gasTokenSymbol, + Decimals: gasTokenDecimals, + From: originSender, + To: topicsTo, + }, + }) + } + return txs, nil +} + +func normalizeRevertedTokenTransaction(srcTx Tx, receipt TxReceipt) (types.Txs, error) { + txs := make(types.Txs, 0) + + fee, err := numbers.HexToDecimal(receipt.Paid) + if err != nil { + return txs, err + } + + originSender, err := address.EIP55Checksum(blockatlas.GetValidParameter(srcTx.Origin, srcTx.Meta.TxOrigin)) + if err != nil { + return txs, err + } + + var to string + if len(srcTx.Clauses) > 0 { + to = srcTx.Clauses[0].To + if checksumTo, err := address.EIP55Checksum(to); err == nil { + to = checksumTo + } + } else { + return txs, errors.New("NormalizeBlockTransaction: srcTx.Clauses not found: " + srcTx.Id) + } + + if to != gasTokenAddress { + return txs, nil + } + + txs = append(txs, types.Tx{ + ID: srcTx.Id, + Coin: coin.VECHAIN, + From: originSender, + To: to, + Fee: types.Amount(fee), + Date: srcTx.Meta.BlockTimestamp, + Type: types.TxTokenTransfer, + Block: srcTx.Meta.BlockNumber, + Status: types.StatusError, + Meta: types.TokenTransfer{ + Name: gasTokenName, + TokenID: gasTokenAddress, + Value: "0", + Symbol: gasTokenSymbol, + Decimals: gasTokenDecimals, + From: originSender, + To: to, + }, + }) + return txs, nil +} + +func (p *Platform) GetTxsByAddress(address string) (types.Txs, error) { + headBlock, err := p.CurrentBlockNumber() + if err != nil { + return nil, err + } + transfers, err := p.client.GetTransactions(address, headBlock) + if err != nil { + return nil, err + } + + txs := make(types.Txs, 0) + for _, t := range transfers { + trxId, err := p.client.GetTransactionByID(t.Meta.TxId) + if err != nil { + continue + } + tx, err := p.NormalizeTransaction(t, trxId, address) + if err != nil { + continue + } + txs = append(txs, tx) + } + return txs, nil +} + +func (p *Platform) NormalizeTransaction(srcTx LogTransfer, trxId Tx, addr string) (tx types.Tx, err error) { + value, err := numbers.HexToDecimal(srcTx.Amount) + if err != nil { + return + } + + fee := strconv.Itoa(trxId.Gas) + sender, err := address.EIP55Checksum(srcTx.Sender) + if err != nil { + return + } + recipient, err := address.EIP55Checksum(srcTx.Recipient) + if err != nil { + return + } + addrChecksum, err := address.EIP55Checksum(addr) + if err != nil { + return + } + + direction, err := getTransactionDirection(sender, recipient, addrChecksum) + if err != nil { + return types.Tx{}, err + } + + return types.Tx{ + ID: srcTx.Meta.TxId, + Coin: p.Coin().ID, + From: sender, + To: recipient, + Fee: types.Amount(fee), + Date: srcTx.Meta.BlockTimestamp, + Type: types.TxTransfer, + Block: srcTx.Meta.BlockNumber, + Direction: direction, + Status: types.StatusCompleted, + Meta: types.Transfer{ + Value: types.Amount(value), + Symbol: p.Coin().Symbol, + Decimals: p.Coin().Decimals, + }, + }, nil +} + +func hexToInt(hex string) (uint64, error) { + nonceStr, err := numbers.HexToDecimal(hex) + if err != nil { + return 0, err + } + return strconv.ParseUint(nonceStr, 10, 64) +} + +// Substring recipient address from clause data and appends 0x +// 0x000000000000000000000000b5e883349e68ab59307d1604555ac890fac47128 => 0xb5e883349e68ab59307d1604555ac890fac47128 +func getRecipientAddress(hex string) string { + return "0x" + hex[len(hex)-40:] +} + +func updateTransactionDirection(tx *types.Tx, addr string) { + meta, ok := tx.Meta.(types.TokenTransfer) + if !ok { + return + } + direction, err := getTransactionDirection(tx.From, meta.To, addr) + if err != nil { + return + } + tx.Direction = direction +} + +func getTransactionDirection(sender, recipient, addr string) (types.Direction, error) { + if sender != addr && recipient != addr { + return "", errors.New("Unknown direction") + } + if sender == addr && recipient == addr { + return types.DirectionSelf, nil + } + if sender == addr { + return types.DirectionOutgoing, nil + } else { + return types.DirectionIncoming, nil + } +} diff --git a/platform/vechain/transaction_test.go b/platform/vechain/transaction_test.go new file mode 100644 index 000000000..e159a15a8 --- /dev/null +++ b/platform/vechain/transaction_test.go @@ -0,0 +1,229 @@ +package vechain + +import ( + "encoding/json" + "testing" + + "github.com/stretchr/testify/assert" + "github.com/trustwallet/golibs/coin" + "github.com/trustwallet/golibs/mock" + "github.com/trustwallet/golibs/types" +) + +func TestNormalizeTransaction(t *testing.T) { + var ( + transferSrc, _ = mock.JsonStringFromFilePath("mocks/transfer.json") + trxId, _ = mock.JsonStringFromFilePath("mocks/tx_id.json") + ) + + tests := []struct { + name string + addr string + txData string + txId string + expected types.Tx + }{ + {"Test normalize VET transfer transaction", "0xb5e883349e68ab59307d1604555ac890fac47128", transferSrc, trxId, types.Tx{ + ID: "0x702edd54bd4e13e0012798cc8b2dfa52f7150173945103d203fae26b8e3d2ed7", + Coin: coin.VECHAIN, + From: "0xB5e883349e68aB59307d1604555AC890fAC47128", + To: "0x2c7A8d5ccE0d5E6a8a31233B7Dc3DAE9AaE4b405", + Date: 1574410670, + Type: types.TxTransfer, + Fee: types.Amount("21000"), + Status: types.StatusCompleted, + Block: 4395940, + Direction: types.DirectionOutgoing, + Meta: types.Transfer{ + Value: types.Amount("1347000000000000000"), + Decimals: 18, + Symbol: "VET", + }, + }}, + } + + platform := Platform{} + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + var tx LogTransfer + err := json.Unmarshal([]byte(tt.txData), &tx) + assert.Nil(t, err) + + var tId Tx + errTrxID := json.Unmarshal([]byte(tt.txId), &tId) + assert.Nil(t, errTrxID) + + actual, err := platform.NormalizeTransaction(tx, tId, tt.addr) + assert.Nil(t, err) + + assert.Equal(t, tt.expected, actual, "tx don't equal") + }) + } +} + +func TestNormalizeTokenTransaction(t *testing.T) { + tests := []struct { + name string + txFile string + receiptFile string + address string + expected types.Txs + wantErr error + }{ + { + name: "Normalize outgoing VTHO tx", + txFile: "outgoing_vtho_tx.json", + receiptFile: "outgoing_vtho_receipt.json", + address: "0xe99399dd211eF54c301A5d1AA813471d92122eA8", + expected: types.Txs{{ + ID: "0x0677f91de4787d295087acec0a7ba317b0019fbf296fed630fdb5afbfca97a58", + Coin: coin.VECHAIN, + From: "0xe99399dd211eF54c301A5d1AA813471d92122eA8", + To: "0x0000000000000000000000000000456E65726779", + Date: 1610958570, + Type: types.TxTokenTransfer, + Fee: types.Amount("36518000000000000000"), + Status: types.StatusCompleted, + Block: 8045756, + Direction: types.DirectionOutgoing, + Meta: types.TokenTransfer{ + Name: gasTokenName, + Symbol: gasTokenSymbol, + TokenID: "0x0000000000000000000000000000456E65726779", + From: "0xe99399dd211eF54c301A5d1AA813471d92122eA8", + To: "0xB5e883349e68aB59307d1604555AC890fAC47128", + Value: types.Amount("7000000000000000000"), + Decimals: 18, + }, + }}, + wantErr: nil, + }, + { + name: "Normalize incoming VTHO tx", + txFile: "incoming_vtho_tx.json", + receiptFile: "incoming_vtho_receipt.json", + address: "0xe99399dd211eF54c301A5d1AA813471d92122eA8", + expected: types.Txs{{ + ID: "0xb356fa7b3a371f1518a5f9bc51e951d0dac2ef04d58b532c7ca50a52aa5cddb4", + Coin: coin.VECHAIN, + From: "0xB5e883349e68aB59307d1604555AC890fAC47128", + To: "0x0000000000000000000000000000456E65726779", + Date: 1610958460, + Type: types.TxTokenTransfer, + Fee: types.Amount("36582000000000000000"), + Status: types.StatusCompleted, + Block: 8045745, + Direction: types.DirectionIncoming, + Meta: types.TokenTransfer{ + Name: gasTokenName, + Symbol: gasTokenSymbol, + TokenID: "0x0000000000000000000000000000456E65726779", + From: "0xB5e883349e68aB59307d1604555AC890fAC47128", + To: "0xe99399dd211eF54c301A5d1AA813471d92122eA8", + Value: types.Amount("1000000000000000000000"), + Decimals: 18, + }, + }}, + wantErr: nil, + }, + { + name: "Normalize reverted token transfer", + txFile: "reverted_tx.json", + receiptFile: "reverted_receipt.json", + address: "0x7cFFB7632252Bae3766734d61F148f0Ea78Fc08C", + expected: types.Txs{}, + wantErr: nil, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + var tx Tx + err := mock.JsonModelFromFilePath("mocks/"+tt.txFile, &tx) + assert.Nil(t, err) + + var receipt TxReceipt + err = mock.JsonModelFromFilePath("mocks/"+tt.receiptFile, &receipt) + assert.Nil(t, err) + + actual, err := NormalizeTokenTransaction(tx, receipt) + assert.Equal(t, err, tt.wantErr) + + if len(actual) != 0 { + updateTransactionDirection(&actual[0], tt.address) + } + assert.Equal(t, tt.expected, actual, "tx don't equal") + }) + } +} + +func Test_hexToInt(t *testing.T) { + tests := []struct { + name string + hex string + expected uint64 + wantErr bool + }{ + {"value 1", "0x603ca6b1879375dc", 6934600807657731548, false}, + {"value 2", "0x38d7ea4c68000", 1000000000000000, false}, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + got, err := hexToInt(tt.hex) + if (err != nil) != tt.wantErr { + t.Errorf("hexToInt() error = %v, wantErr %v", err, tt.wantErr) + return + } + if got != tt.expected { + t.Errorf("hexToInt() got = %v, want %v", got, tt.expected) + } + }) + } +} + +func Test_getRecipientAddress(t *testing.T) { + tests := []struct { + name string + hex string + want string + }{ + {"hex 1", "0x000000000000000000000000b5e883349e68ab59307d1604555ac890fac47128", "0xb5e883349e68ab59307d1604555ac890fac47128"}, + {"hex 2", "0x000000000000000000000000f3586684107ce0859c44aa2b2e0fb8cd8731a15a", "0xf3586684107ce0859c44aa2b2e0fb8cd8731a15a"}, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + if got := getRecipientAddress(tt.hex); got != tt.want { + t.Errorf("getRecipientAddress() = %v, want %v", got, tt.want) + } + }) + } +} + +func Test_getTransactionDirection(t *testing.T) { + addr1 := "0xb5e883349e68ab59307d1604555ac890fac47128" + addr2 := "0eec2bbedbb8b18357dab0b753cd1893bb832284" + tests := []struct { + name string + sender string + recipient string + address string + expected types.Direction + expectErr bool + }{ + {"Self direction for addr1", addr1, addr1, addr1, types.DirectionSelf, false}, + {"Self direction for addr2", addr2, addr2, addr2, types.DirectionSelf, false}, + {"Out direction", addr1, addr2, addr1, types.DirectionOutgoing, false}, + {"In direction", addr1, addr2, addr2, types.DirectionIncoming, false}, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + actual, err := getTransactionDirection(tt.sender, tt.recipient, tt.address) + if tt.expectErr { + assert.NotNil(t, err) + } + assert.Equal(t, tt.expected, actual) + }) + } +} diff --git a/platform/waves/api.go b/platform/waves/api.go deleted file mode 100644 index fe987f8a8..000000000 --- a/platform/waves/api.go +++ /dev/null @@ -1,91 +0,0 @@ -package waves - -import ( - "github.com/spf13/viper" - "github.com/trustwallet/blockatlas/pkg/blockatlas" - "strconv" - - "github.com/trustwallet/blockatlas/coin" -) - -type Platform struct { - client Client -} - -func (p *Platform) Init() error { - p.client = Client{blockatlas.InitClient(viper.GetString("waves.api"))} - return nil -} - -func (p *Platform) Coin() coin.Coin { - return coin.Coins[coin.WAVES] -} - -func (p *Platform) CurrentBlockNumber() (int64, error) { - currentBlock, err := p.client.GetCurrentBlock() - if err != nil { - return 0, err - } - return currentBlock.Height, nil -} - -func (p *Platform) GetBlockByNumber(num int64) (*blockatlas.Block, error) { - srcTxs, err := p.client.GetBlockByNumber(num) - if err != nil { - return nil, err - } - txs := NormalizeTxs(srcTxs.Transactions) - - return &blockatlas.Block{ - Number: num, - Txs: txs, - }, nil -} - -func (p *Platform) GetTxsByAddress(address string) (blockatlas.TxPage, error) { - addressTxs, err := p.client.GetTxs(address, 25) - if err != nil { - return nil, err - } - - txs := NormalizeTxs(addressTxs) - - return txs, nil -} - -func NormalizeTxs(srcTxs []Transaction) (txs []blockatlas.Tx) { - for _, srcTx := range srcTxs { - tx, ok := NormalizeTx(&srcTx) - if !ok || len(txs) >= blockatlas.TxPerPage { - continue - } - txs = append(txs, tx) - } - return -} - -func NormalizeTx(srcTx *Transaction) (tx blockatlas.Tx, ok bool) { - var result blockatlas.Tx - - if srcTx.Type == 4 && len(srcTx.AssetId) == 0 { - result = blockatlas.Tx{ - ID: srcTx.Id, - Coin: coin.WAVES, - From: srcTx.Sender, - To: srcTx.Recipient, - Fee: blockatlas.Amount(strconv.Itoa(int(srcTx.Fee))), - Date: int64(srcTx.Timestamp) / 1000, - Block: srcTx.Block, - Memo: srcTx.Attachment, - Status: blockatlas.StatusCompleted, - Meta: blockatlas.Transfer{ - Value: blockatlas.Amount(strconv.Itoa(int(srcTx.Amount))), - Symbol: coin.Coins[coin.WAVES].Symbol, - Decimals: coin.Coins[coin.WAVES].Decimals, - }, - } - return result, true - } - - return result, false -} diff --git a/platform/waves/api_test.go b/platform/waves/api_test.go deleted file mode 100644 index 0848cc02d..000000000 --- a/platform/waves/api_test.go +++ /dev/null @@ -1,195 +0,0 @@ -package waves - -import ( - "bytes" - "encoding/json" - "github.com/trustwallet/blockatlas/pkg/blockatlas" - "testing" -) - -const transferV1 = ` -{ - "type":4, - "id":"7QoQc9qMUBCfY4QV35mgBsT8eTXybvGkM2HTumtAvBUL", - "sender":"3PLrCnhKyX5iFbGDxbqqMvea5VAqxMcinPW", - "senderPublicKey":"Ao159h5j1piHBhoEbCAYyaiKNd6uoKvcdwzRZF9za3Vv", - "fee":100000, - "timestamp":1561048131740, - "signature":"4WjDwn5t34PLHzgH1NfA4DYdt4PdTbGQDjDdxwKrp82QTQSHFRrgSJXWU2FTYe82afvgUDhnipSKxaiGzMWWo2HW", - "proofs":["4WjDwn5t34PLHzgH1NfA4DYdt4PdTbGQDjDdxwKrp82QTQSHFRrgSJXWU2FTYe82afvgUDhnipSKxaiGzMWWo2HW"], - "version":1, - "recipient":"3PKWyVAmHom1sevggiXVfbGUc3kS85qT4Va", - "assetId":null, - "feeAssetId":null, - "feeAsset":null, - "amount":9481600000, - "attachment":"", - "height":1580410 -}` - -const differentTxs = ` -[[ - { - "type": 10, - "timestamp": 1516171819000, - "sender": "3MtrNP7AkTRuBhX4CBti6iT21pQpEnmHtyw", - "fee": 100000, - "alias": "ALIAS" - }, - { - "type":10, - "id":"9q7X84wFuVvKqRdDQeWbtBmpsHt9SXFbvPPtUuKBVxxr", - "sender":"3MtrNP7AkTRuBhX4CBti6iT21pQpEnmHtyw", - "senderPublicKey":"G6h72icCSjdW2A89QWDb37hyXJoYKq3XuCUJY2joS3EU", - "fee":100000000, - "timestamp":46305781705234713, - "signature":"4gQyPXzJFEzMbsCd9u5n3B2WauEc4172ssyrXCL882oNa8NfNihnpKianHXrHWnZs1RzDLbQ9rcRYnSqxKWfEPJG", - "alias":"dajzmj6gfuzmbfnhamsbuxivc" - }, - { - "type": 4, - "id": "52GG9U2e6foYRKp5vAzsTQ86aDAABfRJ7synz7ohBp19", - "sender": "3NBVqYXrapgJP9atQccdBPAgJPwHDKkh6A8", - "senderPublicKey": "CRxqEuxhdZBEHX42MU4FfyJxuHmbDBTaHMhM3Uki7pLw", - "recipient": "3NBVqYXrapgJP9atQccdBPAgJPwHDKkh6A8", - "assetId": null, - "amount": 100000, - "feeAsset": null, - "fee": 100000, - "timestamp": 1479313236091, - "attachment": "string", - "signature": "GknccUA79dBcwWgKjqB7vYHcnsj7caYETfncJhRkkaetbQon7DxbpMmvK9LYqUkirJp17geBJCRTNkHEoAjtsUm", - "height": 7782 - }, - { - "type": 2, - "id": "4XE4M9eSoVWVdHwDYXqZsXhEc4q8PH9mDMUBegCSBBVHJyP2Yb1ZoGi59c1Qzq2TowLmymLNkFQjWp95CdddnyBW", - "fee": 100000, - "timestamp": 1479313097422, - "signature": "4XE4M9eSoVWVdHwDYXqZsXhEc4q8PH9mDMUBegCSBBVHJyP2Yb1ZoGi59c1Qzq2TowLmymLNkFQjWp95CdddnyBW", - "sender": "3NBVqYXrapgJP9atQccdBPAgJPwHDKkh6A8", - "senderPublicKey": "CRxqEuxhdZBEHX42MU4FfyJxuHmbDBTaHMhM3Uki7pLw", - "recipient": "3N9iRMou3pgmyPbFZn5QZQvBTQBkL2fR6R1", - "amount": 1000000000 - } -]]` - -var transferV1Obj = blockatlas.Tx{ - ID: "7QoQc9qMUBCfY4QV35mgBsT8eTXybvGkM2HTumtAvBUL", - Coin: 5741564, - From: "3PLrCnhKyX5iFbGDxbqqMvea5VAqxMcinPW", - To: "3PKWyVAmHom1sevggiXVfbGUc3kS85qT4Va", - Fee: "100000", - Date: 1561048131, - Block: 1580410, - Status: blockatlas.StatusCompleted, - Memo: "", - Meta: blockatlas.Transfer{ - Value: blockatlas.Amount("9481600000"), - Symbol: "WAVES", - Decimals: 8, - }, -} - -var differentTxsObj = blockatlas.Tx{ - ID: "52GG9U2e6foYRKp5vAzsTQ86aDAABfRJ7synz7ohBp19", - Coin: 5741564, - From: "3NBVqYXrapgJP9atQccdBPAgJPwHDKkh6A8", - To: "3NBVqYXrapgJP9atQccdBPAgJPwHDKkh6A8", - Fee: "100000", - Date: 1479313236, - Block: 7782, - Memo: "string", - Status: blockatlas.StatusCompleted, - Meta: blockatlas.Transfer{ - Value: blockatlas.Amount("100000"), - Symbol: "WAVES", - Decimals: 8, - }, -} - -type txParseTest struct { - name string - apiResponse string - expected *blockatlas.Tx -} - -type txFilterTest struct { - name string - apiResponse string - expected blockatlas.Tx -} - -func TestNormalize(t *testing.T) { - testParseTx(t, &txParseTest{ - name: "transfer", - apiResponse: transferV1, - expected: &transferV1Obj, - }) - testFilterTxs(t, &txFilterTest{ - name: "filter transfer transactions txParseTest", - apiResponse: differentTxs, - expected: differentTxsObj, - }) -} - -func testParseTx(t *testing.T, _test *txParseTest) { - var tx Transaction - err := json.Unmarshal([]byte(_test.apiResponse), &tx) - if err != nil { - t.Error(err) - return - } - - res, _ := NormalizeTx(&tx) - - resJSON, err := json.Marshal(&res) - if err != nil { - t.Fatal(err) - } - - dstJSON, err := json.Marshal(&_test.expected) - if err != nil { - t.Fatal(err) - } - - if !bytes.Equal(resJSON, dstJSON) { - println(string(resJSON)) - println(string(dstJSON)) - t.Error(_test.name + ": tx don't equal") - } -} - -func testFilterTxs(t *testing.T, _test *txFilterTest) { - var txs [][]Transaction - err := json.Unmarshal([]byte(_test.apiResponse), &txs) - if err != nil { - t.Error(err) - return - } - var res blockatlas.Tx - for _, tx := range txs[0] { - if tx.Type == 4 { - n, ok := NormalizeTx(&tx) - if ok { - res = n - } - } - } - - resJSON, err := json.Marshal(&res) - if err != nil { - t.Fatal(err) - } - - dstJSON, err := json.Marshal(&_test.expected) - if err != nil { - t.Fatal(err) - } - - if !bytes.Equal(resJSON, dstJSON) { - println(string(resJSON)) - println(string(dstJSON)) - t.Error(_test.name + ": txs don't equal") - } -} diff --git a/platform/waves/base.go b/platform/waves/base.go new file mode 100644 index 000000000..2a38b9a7b --- /dev/null +++ b/platform/waves/base.go @@ -0,0 +1,21 @@ +package waves + +import ( + "github.com/trustwallet/golibs/client" + "github.com/trustwallet/golibs/coin" + "github.com/trustwallet/golibs/network/middleware" +) + +type Platform struct { + client Client +} + +func Init(api string) *Platform { + return &Platform{ + client: Client{client.InitClient(api, middleware.SentryErrorHandler)}, + } +} + +func (p *Platform) Coin() coin.Coin { + return coin.Coins[coin.WAVES] +} diff --git a/platform/waves/block.go b/platform/waves/block.go new file mode 100644 index 000000000..7edfad969 --- /dev/null +++ b/platform/waves/block.go @@ -0,0 +1,24 @@ +package waves + +import "github.com/trustwallet/golibs/types" + +func (p *Platform) CurrentBlockNumber() (int64, error) { + currentBlock, err := p.client.GetCurrentBlock() + if err != nil { + return 0, err + } + return currentBlock.Height, nil +} + +func (p *Platform) GetBlockByNumber(num int64) (*types.Block, error) { + srcTxs, err := p.client.GetBlockByNumber(num) + if err != nil { + return nil, err + } + txs := NormalizeTxs(srcTxs.Transactions) + + return &types.Block{ + Number: num, + Txs: txs, + }, nil +} diff --git a/platform/waves/client.go b/platform/waves/client.go index cab7d0c5c..37c7f77a4 100644 --- a/platform/waves/client.go +++ b/platform/waves/client.go @@ -2,11 +2,12 @@ package waves import ( "fmt" - "github.com/trustwallet/blockatlas/pkg/blockatlas" + + "github.com/trustwallet/golibs/client" ) type Client struct { - blockatlas.Request + client.Request } func (c *Client) GetTxs(address string, limit int) ([]Transaction, error) { diff --git a/platform/waves/mocks/different_txs.json b/platform/waves/mocks/different_txs.json new file mode 100644 index 000000000..2c1cdae4a --- /dev/null +++ b/platform/waves/mocks/different_txs.json @@ -0,0 +1,47 @@ +[ + [ + { + "type": 10, + "timestamp": 1516171819000, + "sender": "3MtrNP7AkTRuBhX4CBti6iT21pQpEnmHtyw", + "fee": 100000, + "alias": "ALIAS" + }, + { + "type": 10, + "id": "9q7X84wFuVvKqRdDQeWbtBmpsHt9SXFbvPPtUuKBVxxr", + "sender": "3MtrNP7AkTRuBhX4CBti6iT21pQpEnmHtyw", + "senderPublicKey": "G6h72icCSjdW2A89QWDb37hyXJoYKq3XuCUJY2joS3EU", + "fee": 100000000, + "timestamp": 46305781705234713, + "signature": "4gQyPXzJFEzMbsCd9u5n3B2WauEc4172ssyrXCL882oNa8NfNihnpKianHXrHWnZs1RzDLbQ9rcRYnSqxKWfEPJG", + "alias": "dajzmj6gfuzmbfnhamsbuxivc" + }, + { + "type": 4, + "id": "52GG9U2e6foYRKp5vAzsTQ86aDAABfRJ7synz7ohBp19", + "sender": "3NBVqYXrapgJP9atQccdBPAgJPwHDKkh6A8", + "senderPublicKey": "CRxqEuxhdZBEHX42MU4FfyJxuHmbDBTaHMhM3Uki7pLw", + "recipient": "3NBVqYXrapgJP9atQccdBPAgJPwHDKkh6A8", + "assetId": null, + "amount": 100000, + "feeAsset": null, + "fee": 100000, + "timestamp": 1479313236091, + "attachment": "string", + "signature": "GknccUA79dBcwWgKjqB7vYHcnsj7caYETfncJhRkkaetbQon7DxbpMmvK9LYqUkirJp17geBJCRTNkHEoAjtsUm", + "height": 7782 + }, + { + "type": 2, + "id": "4XE4M9eSoVWVdHwDYXqZsXhEc4q8PH9mDMUBegCSBBVHJyP2Yb1ZoGi59c1Qzq2TowLmymLNkFQjWp95CdddnyBW", + "fee": 100000, + "timestamp": 1479313097422, + "signature": "4XE4M9eSoVWVdHwDYXqZsXhEc4q8PH9mDMUBegCSBBVHJyP2Yb1ZoGi59c1Qzq2TowLmymLNkFQjWp95CdddnyBW", + "sender": "3NBVqYXrapgJP9atQccdBPAgJPwHDKkh6A8", + "senderPublicKey": "CRxqEuxhdZBEHX42MU4FfyJxuHmbDBTaHMhM3Uki7pLw", + "recipient": "3N9iRMou3pgmyPbFZn5QZQvBTQBkL2fR6R1", + "amount": 1000000000 + } + ] +] diff --git a/platform/waves/mocks/transfer.json b/platform/waves/mocks/transfer.json new file mode 100644 index 000000000..db2a2e229 --- /dev/null +++ b/platform/waves/mocks/transfer.json @@ -0,0 +1,20 @@ +{ + "type": 4, + "id": "7QoQc9qMUBCfY4QV35mgBsT8eTXybvGkM2HTumtAvBUL", + "sender": "3PLrCnhKyX5iFbGDxbqqMvea5VAqxMcinPW", + "senderPublicKey": "Ao159h5j1piHBhoEbCAYyaiKNd6uoKvcdwzRZF9za3Vv", + "fee": 100000, + "timestamp": 1561048131740, + "signature": "4WjDwn5t34PLHzgH1NfA4DYdt4PdTbGQDjDdxwKrp82QTQSHFRrgSJXWU2FTYe82afvgUDhnipSKxaiGzMWWo2HW", + "proofs": [ + "4WjDwn5t34PLHzgH1NfA4DYdt4PdTbGQDjDdxwKrp82QTQSHFRrgSJXWU2FTYe82afvgUDhnipSKxaiGzMWWo2HW" + ], + "version": 1, + "recipient": "3PKWyVAmHom1sevggiXVfbGUc3kS85qT4Va", + "assetId": null, + "feeAssetId": null, + "feeAsset": null, + "amount": 9481600000, + "attachment": "", + "height": 1580410 +} diff --git a/platform/waves/transaction.go b/platform/waves/transaction.go new file mode 100644 index 000000000..670d658f3 --- /dev/null +++ b/platform/waves/transaction.go @@ -0,0 +1,56 @@ +package waves + +import ( + "strconv" + + "github.com/trustwallet/golibs/coin" + "github.com/trustwallet/golibs/types" +) + +func (p *Platform) GetTxsByAddress(address string) (types.Txs, error) { + addressTxs, err := p.client.GetTxs(address, 25) + if err != nil { + return nil, err + } + + txs := NormalizeTxs(addressTxs) + + return txs, nil +} + +func NormalizeTxs(srcTxs []Transaction) (txs types.Txs) { + for _, srcTx := range srcTxs { + tx, ok := NormalizeTx(&srcTx) + if !ok || len(txs) >= types.TxPerPage { + continue + } + txs = append(txs, tx) + } + return +} + +func NormalizeTx(srcTx *Transaction) (tx types.Tx, ok bool) { + var result types.Tx + + if srcTx.Type == 4 && len(srcTx.AssetId) == 0 { + result = types.Tx{ + ID: srcTx.Id, + Coin: coin.WAVES, + From: srcTx.Sender, + To: srcTx.Recipient, + Fee: types.Amount(strconv.Itoa(int(srcTx.Fee))), + Date: int64(srcTx.Timestamp) / 1000, + Block: srcTx.Block, + Memo: srcTx.Attachment, + Status: types.StatusCompleted, + Meta: types.Transfer{ + Value: types.Amount(strconv.Itoa(int(srcTx.Amount))), + Symbol: coin.Coins[coin.WAVES].Symbol, + Decimals: coin.Coins[coin.WAVES].Decimals, + }, + } + return result, true + } + + return result, false +} diff --git a/platform/waves/transaction_test.go b/platform/waves/transaction_test.go new file mode 100644 index 000000000..9aa4f876b --- /dev/null +++ b/platform/waves/transaction_test.go @@ -0,0 +1,127 @@ +package waves + +import ( + "encoding/json" + "testing" + + "github.com/stretchr/testify/assert" + "github.com/trustwallet/golibs/mock" + "github.com/trustwallet/golibs/types" +) + +var ( + transferV1, _ = mock.JsonStringFromFilePath("mocks/" + "transfer.json") + differentTxs, _ = mock.JsonStringFromFilePath("mocks/" + "different_txs.json") + + transferV1Obj = types.Tx{ + ID: "7QoQc9qMUBCfY4QV35mgBsT8eTXybvGkM2HTumtAvBUL", + Coin: 5741564, + From: "3PLrCnhKyX5iFbGDxbqqMvea5VAqxMcinPW", + To: "3PKWyVAmHom1sevggiXVfbGUc3kS85qT4Va", + Fee: "100000", + Date: 1561048131, + Block: 1580410, + Status: types.StatusCompleted, + Memo: "", + Meta: types.Transfer{ + Value: types.Amount("9481600000"), + Symbol: "WAVES", + Decimals: 8, + }, + } + + differentTxsObj = types.Tx{ + ID: "52GG9U2e6foYRKp5vAzsTQ86aDAABfRJ7synz7ohBp19", + Coin: 5741564, + From: "3NBVqYXrapgJP9atQccdBPAgJPwHDKkh6A8", + To: "3NBVqYXrapgJP9atQccdBPAgJPwHDKkh6A8", + Fee: "100000", + Date: 1479313236, + Block: 7782, + Memo: "string", + Status: types.StatusCompleted, + Meta: types.Transfer{ + Value: types.Amount("100000"), + Symbol: "WAVES", + Decimals: 8, + }, + } +) + +type txParseTest struct { + name string + apiResponse string + expected *types.Tx +} + +type txFilterTest struct { + name string + apiResponse string + expected types.Tx +} + +func TestNormalize(t *testing.T) { + testParseTx(t, &txParseTest{ + name: "transfer", + apiResponse: transferV1, + expected: &transferV1Obj, + }) + testFilterTxs(t, &txFilterTest{ + name: "filter transfer transactions txParseTest", + apiResponse: differentTxs, + expected: differentTxsObj, + }) +} + +func testParseTx(t *testing.T, _test *txParseTest) { + var tx Transaction + err := json.Unmarshal([]byte(_test.apiResponse), &tx) + if err != nil { + t.Error(err) + return + } + + res, _ := NormalizeTx(&tx) + + resJSON, err := json.Marshal(&res) + if err != nil { + t.Fatal(err) + } + + dstJSON, err := json.Marshal(&_test.expected) + if err != nil { + t.Fatal(err) + } + + assert.JSONEq(t, string(resJSON), string(dstJSON)) +} + +func testFilterTxs(t *testing.T, _test *txFilterTest) { + var txs [][]Transaction + err := json.Unmarshal([]byte(_test.apiResponse), &txs) + if err != nil { + t.Error(err) + return + } + var res types.Tx + for _, tx := range txs[0] { + if tx.Type == 4 { + n, ok := NormalizeTx(&tx) + if ok { + res = n + } + } + } + + resJSON, err := json.Marshal(&res) + if err != nil { + t.Fatal(err) + } + + dstJSON, err := json.Marshal(&_test.expected) + if err != nil { + t.Fatal(err) + } + + assert.JSONEq(t, string(resJSON), string(dstJSON)) +} diff --git a/platform/zilliqa/api.go b/platform/zilliqa/api.go deleted file mode 100644 index 46ec69d73..000000000 --- a/platform/zilliqa/api.go +++ /dev/null @@ -1,102 +0,0 @@ -package zilliqa - -import ( - "strconv" - - "github.com/trustwallet/blockatlas/coin" - "github.com/trustwallet/blockatlas/pkg/blockatlas" - - "github.com/spf13/viper" -) - -type Platform struct { - client Client - rpcClient RpcClient - udClient Client -} - -func (p *Platform) Init() error { - p.client = Client{blockatlas.InitClient(viper.GetString("zilliqa.api"))} - p.client.Headers["X-APIKEY"] = viper.GetString("zilliqa.key") - - p.rpcClient = RpcClient{blockatlas.InitClient(viper.GetString("zilliqa.rpc"))} - p.udClient = Client{blockatlas.InitClient(viper.GetString("zilliqa.lookup"))} - return nil -} - -func (p *Platform) Coin() coin.Coin { - return coin.Coins[coin.ZIL] -} - -func (p *Platform) CurrentBlockNumber() (int64, error) { - info, err := p.rpcClient.GetBlockchainInfo() - if err != nil { - return 0, err - } - block, err := strconv.ParseInt(info.NumTxBlocks, 10, 64) - if err != nil { - return 0, err - } - - return block, nil -} - -func (p *Platform) GetBlockByNumber(num int64) (*blockatlas.Block, error) { - var normalized []blockatlas.Tx - txs, err := p.rpcClient.GetTxInBlock(num) - if err != nil { - return nil, err - } - - for _, srcTx := range txs { - tx := Normalize(&srcTx) - normalized = append(normalized, tx) - } - block := blockatlas.Block{ - Number: num, - Txs: normalized, - } - - return &block, nil -} - -func (p *Platform) GetTxsByAddress(address string) (blockatlas.TxPage, error) { - var normalized []blockatlas.Tx - txs, err := p.client.GetTxsOfAddress(address) - - if err != nil { - return nil, err - } - - for _, srcTx := range txs { - tx := Normalize(&srcTx) - if len(normalized) >= blockatlas.TxPerPage { - break - } - normalized = append(normalized, tx) - } - - return normalized, nil -} - -func Normalize(srcTx *Tx) (tx blockatlas.Tx) { - tx = blockatlas.Tx{ - ID: srcTx.Hash, - Coin: coin.ZIL, - Date: srcTx.Timestamp / 1000, - From: srcTx.From, - To: srcTx.To, - Fee: blockatlas.Amount(srcTx.Fee), - Block: srcTx.BlockHeight, - Sequence: srcTx.NonceValue(), - Meta: blockatlas.Transfer{ - Value: blockatlas.Amount(srcTx.Value), - Symbol: coin.Coins[coin.ZIL].Symbol, - Decimals: coin.Coins[coin.ZIL].Decimals, - }, - } - if !srcTx.ReceiptSuccess { - tx.Status = blockatlas.StatusFailed - } - return tx -} diff --git a/platform/zilliqa/api_test.go b/platform/zilliqa/api_test.go deleted file mode 100644 index 8395e71de..000000000 --- a/platform/zilliqa/api_test.go +++ /dev/null @@ -1,86 +0,0 @@ -package zilliqa - -import ( - "bytes" - "encoding/json" - "github.com/trustwallet/blockatlas/pkg/blockatlas" - "testing" - - "github.com/trustwallet/blockatlas/coin" -) - -const transferTransaction = ` -{ - "hash": "0xd44413c79e7518152f3b05ef1edff8ef59afd06119b16d09c8bc72e94fed7843", - "blockHeight": 104282, - "from": "0x88af5ba10796d9091d6893eed4db23ef0bbbca37", - "to": "0x7fccacf066a5f26ee3affc2ed1fa9810deaa632c", - "value": "7997000000000", - "fee": "1000000000", - "timestamp": 1557889788637, - "signature": "0xF0F159C5B47079E36AABC7693E61FEE9D104BDE34F4FEADA62A5066F6363E05B382E65B9381CE8138CC6824A5B62CC60EDA8B7CF13A65264F8482279DF6F768B", - "nonce": "3", - "receiptSuccess": true, - "events": [] -}` - -var transferDst = blockatlas.Tx{ - ID: "0xd44413c79e7518152f3b05ef1edff8ef59afd06119b16d09c8bc72e94fed7843", - Coin: coin.ZIL, - From: "0x88af5ba10796d9091d6893eed4db23ef0bbbca37", - To: "0x7fccacf066a5f26ee3affc2ed1fa9810deaa632c", - Fee: "1000000000", - Date: 1557889788, - Block: 104282, - Status: blockatlas.StatusCompleted, - Sequence: 3, - Memo: "", - Meta: blockatlas.Transfer{ - Value: "7997000000000", - Symbol: "ZIL", - Decimals: 12, - }, -} - -type test struct { - name string - apiResponse string - expected *blockatlas.Tx - token string -} - -func TestNormalize(t *testing.T) { - testNormalize(t, &test{ - name: "transfer", - apiResponse: transferTransaction, - expected: &transferDst, - token: "", - }) -} - -func testNormalize(t *testing.T, _test *test) { - var srcTx Tx - err := json.Unmarshal([]byte(_test.apiResponse), &srcTx) - if err != nil { - t.Error(err) - return - } - - tx := Normalize(&srcTx) - - resJSON, err := json.Marshal(&tx) - if err != nil { - t.Fatal(err) - } - - dstJSON, err := json.Marshal(_test.expected) - if err != nil { - t.Fatal(err) - } - - if !bytes.Equal(resJSON, dstJSON) { - println(string(resJSON)) - println(string(dstJSON)) - t.Error("transfer: tx don't equal") - } -} diff --git a/platform/zilliqa/base.go b/platform/zilliqa/base.go new file mode 100644 index 000000000..7f4b87573 --- /dev/null +++ b/platform/zilliqa/base.go @@ -0,0 +1,24 @@ +package zilliqa + +import ( + "github.com/trustwallet/blockatlas/platform/zilliqa/rpc" + "github.com/trustwallet/blockatlas/platform/zilliqa/viewblock" + "github.com/trustwallet/golibs/coin" +) + +type Platform struct { + client viewblock.Client + rpcClient rpc.Client +} + +func Init(api, apiKey, rpcUrl string) *Platform { + p := &Platform{ + client: viewblock.InitClient(api, apiKey), + rpcClient: rpc.InitClient(rpcUrl), + } + return p +} + +func (p *Platform) Coin() coin.Coin { + return coin.Zilliqa() +} diff --git a/platform/zilliqa/block.go b/platform/zilliqa/block.go new file mode 100644 index 000000000..1b409f37d --- /dev/null +++ b/platform/zilliqa/block.go @@ -0,0 +1,48 @@ +package zilliqa + +import ( + "strconv" + + "github.com/trustwallet/blockatlas/platform/zilliqa/viewblock" + "github.com/trustwallet/golibs/types" +) + +func (p *Platform) CurrentBlockNumber() (int64, error) { + info, err := p.rpcClient.GetBlockchainInfo() + if err != nil { + return 0, err + } + block, err := strconv.ParseInt(info.NumTxBlocks, 10, 64) + if err != nil { + return 0, err + } + + return block, nil +} + +func (p *Platform) GetBlockByNumber(num int64) (*types.Block, error) { + var normalized types.Txs + var txs []viewblock.Tx + + header, rpcTxs, err := p.rpcClient.GetTxInBlock(num) + if err != nil { + return nil, err + } + + for _, tx := range rpcTxs { + if tx := TxFromRpc(tx, header); tx != nil { + txs = append(txs, *tx) + } + } + + for _, srcTx := range txs { + tx := Normalize(&srcTx) + normalized = append(normalized, tx) + } + + block := types.Block{ + Number: num, + Txs: normalized, + } + return &block, nil +} diff --git a/platform/zilliqa/client.go b/platform/zilliqa/client.go deleted file mode 100644 index ca2fb6724..000000000 --- a/platform/zilliqa/client.go +++ /dev/null @@ -1,22 +0,0 @@ -package zilliqa - -import ( - "fmt" - - "github.com/trustwallet/blockatlas/pkg/blockatlas" -) - -type Client struct { - blockatlas.Request -} - -func (c *Client) GetTxsOfAddress(address string) (tx []Tx, err error) { - path := fmt.Sprintf("addresses/%s/txs", address) - err = c.Get(&tx, path, nil) - return -} - -func (c *Client) LookupName(name string) (response ZNSResponse, err error) { - err = c.Get(&response, "/"+name, nil) - return -} diff --git a/platform/zilliqa/mocks/transfer.json b/platform/zilliqa/mocks/transfer.json new file mode 100644 index 000000000..377285b75 --- /dev/null +++ b/platform/zilliqa/mocks/transfer.json @@ -0,0 +1,13 @@ +{ + "hash": "0xd44413c79e7518152f3b05ef1edff8ef59afd06119b16d09c8bc72e94fed7843", + "blockHeight": 104282, + "from": "0x88af5ba10796d9091d6893eed4db23ef0bbbca37", + "to": "0x7fccacf066a5f26ee3affc2ed1fa9810deaa632c", + "value": "7997000000000", + "fee": "1000000000", + "timestamp": 1557889788637, + "signature": "0xF0F159C5B47079E36AABC7693E61FEE9D104BDE34F4FEADA62A5066F6363E05B382E65B9381CE8138CC6824A5B62CC60EDA8B7CF13A65264F8482279DF6F768B", + "nonce": "3", + "receiptSuccess": true, + "events": [] +} diff --git a/platform/zilliqa/model.go b/platform/zilliqa/model.go index 68fdae0a1..43fd8ef79 100644 --- a/platform/zilliqa/model.go +++ b/platform/zilliqa/model.go @@ -4,74 +4,49 @@ import ( "encoding/hex" "math/big" "strconv" + + "github.com/trustwallet/blockatlas/platform/zilliqa/rpc" + "github.com/trustwallet/blockatlas/platform/zilliqa/viewblock" ) -type Tx struct { - Hash string `json:"hash"` - BlockHeight uint64 `json:"blockHeight"` - From string `json:"from"` - To string `json:"to"` - Value string `json:"value"` - Fee string `json:"fee"` - Timestamp int64 `json:"timestamp"` - Signature string `json:"signature"` - Nonce interface{} `json:"nonce"` - ReceiptSuccess bool `json:"receiptSuccess"` -} +func TxFromRpc(t rpc.Tx, header rpc.BlockHeader) *viewblock.Tx { + // t.recipient is not parsed correctly. Empty strings. -func (tx Tx) NonceValue() uint64 { - n, ok := tx.Nonce.(string) - if ok { - r, _ := strconv.Atoi(n) - return uint64(r) - } - nu, ok := tx.Nonce.(int) - if ok { - return uint64(nu) + to, err := hex.DecodeString(t.ToAddr) + if err != nil { + return nil } - return 0 -} - -type ChainInfo struct { - NumTxBlocks string `json:"NumTxBlocks"` -} -type TxReceipt struct { - CumulativeGas string `json:"cumulative_gas"` - EpochNum string `json:"epoch_num"` - Success bool `json:"success"` -} + timestamp, err := strconv.ParseUint(header.Timestamp, 10, 64) + if err != nil { + timestamp = 0 + } -type TxRPC struct { - ID string `json:"ID"` - Amount string `json:"amount"` - GasLimit string `json:"gasLimit"` - GasPrice string `json:"gasPrice"` - Nonce string `json:"nonce"` - Receipt TxReceipt `json:"receipt"` - SenderPubKey string `json:"senderPubKey"` - Signature string `json:"signature"` - ToAddr string `json:"toAddr"` - Version string `json:"version"` -} + height, err := strconv.ParseUint(header.Number, 10, 64) + if err != nil { + height = 0 + } -func (t *TxRPC) toTx() Tx { - to, _ := hex.DecodeString(t.ToAddr) - height, _ := strconv.ParseUint(t.Receipt.EpochNum, 10, 64) - gasLimt, _ := new(big.Int).SetString(t.GasLimit, 10) - gasPrice, _ := new(big.Int).SetString(t.GasPrice, 10) - fee := new(big.Int).Mul(gasLimt, gasPrice) + gasLimit, ok := new(big.Int).SetString(t.GasLimit, 10) + if !ok { + return nil + } + gasPrice, ok := new(big.Int).SetString(t.GasPrice, 10) + if !ok { + return nil + } + fee := new(big.Int).Mul(gasLimit, gasPrice) - tx := Tx{ + return &viewblock.Tx{ Hash: "0x" + t.ID, BlockHeight: height, From: EncodePublicKeyToAddress(t.SenderPubKey), To: EncodeKeyHashToAddress(to), Value: t.Amount, Fee: fee.String(), + Timestamp: int64(timestamp / 1000), Signature: t.Signature, Nonce: t.Nonce, ReceiptSuccess: t.Receipt.Success, } - return tx } diff --git a/platform/zilliqa/model_test.go b/platform/zilliqa/model_test.go index 7da4f5b26..d187a4c3f 100644 --- a/platform/zilliqa/model_test.go +++ b/platform/zilliqa/model_test.go @@ -4,6 +4,9 @@ import ( "encoding/json" "reflect" "testing" + + "github.com/trustwallet/blockatlas/platform/zilliqa/rpc" + "github.com/trustwallet/blockatlas/platform/zilliqa/viewblock" ) const transaction = `{ @@ -24,26 +27,29 @@ const transaction = `{ }` func TestTxRPC_toTx(t *testing.T) { - tx := Tx{ + tx := viewblock.Tx{ Hash: "0xf73cf0a229a3d71e1a5c2ac4acbab598c706e64882a2e7c5ed6e406ce69fc16c", BlockHeight: 185343, From: "zil1jrpjd8pjuv50cfkfr7eu6yrm3rn5u8rulqhqpz", To: "zil1vxdqe9ck4metep92l4lw2mju9t6wvge9zwkyyl", Value: "1380000000000", Fee: "1000000000", + Timestamp: 1603831144458, Signature: "0xF165643EA12514F62297854CE14F2C4EEFE0E19670A6A64E3C497E19442D0B36A91A8790FE320EC48DDCD3E212F0863955FB6AF5436422461916319D5133886D", Nonce: "16109", ReceiptSuccess: true, } - var txRPC TxRPC + var txRPC rpc.Tx err := json.Unmarshal([]byte(transaction), &txRPC) if err != nil { t.Error(err) return } - if got := txRPC.toTx(); !reflect.DeepEqual(got, tx) { - t.Errorf("TxRPC.toTx() = %v, want %v", got, tx) + header := rpc.BlockHeader{Number: "185343", Timestamp: "1603831144458128"} + + if got := TxFromRpc(txRPC, header); !reflect.DeepEqual(*got, tx) { + t.Errorf("TxRPC.toTx() = %v, want %v", *got, tx) } } diff --git a/platform/zilliqa/rpc.go b/platform/zilliqa/rpc.go deleted file mode 100644 index d64a468e2..000000000 --- a/platform/zilliqa/rpc.go +++ /dev/null @@ -1,51 +0,0 @@ -package zilliqa - -import ( - "github.com/trustwallet/blockatlas/pkg/blockatlas" - "strconv" - "sync" -) - -type RpcClient struct { - blockatlas.Request -} - -func (c *RpcClient) GetBlockchainInfo() (info *ChainInfo, err error) { - err = c.RpcCall(&info, "GetBlockchainInfo", nil) - return -} - -func (c *RpcClient) GetTx(hash string) (tx Tx, err error) { - err = c.RpcCall(&tx, "GetTransaction", []string{hash}) - return -} - -func (c *RpcClient) GetTxInBlock(number int64) (txs []Tx, err error) { - strNumber := strconv.FormatInt(number, 10) - var results [][]string - err = c.RpcCall(&results, "GetTransactionsForTxBlock", []string{strNumber}) - - var wg sync.WaitGroup - out := make(chan Tx) - for _, ids := range results { - for _, id := range ids { - wg.Add(1) - go func(id string) { - defer wg.Done() - tx, errTx := c.GetTx(id) - if errTx != nil { - return - } - out <- tx - }(id) - } - } - go func() { - for tx := range out { - txs = append(txs, tx) - } - }() - wg.Wait() - close(out) - return -} diff --git a/platform/zilliqa/rpc/client.go b/platform/zilliqa/rpc/client.go new file mode 100644 index 000000000..1be7edbb1 --- /dev/null +++ b/platform/zilliqa/rpc/client.go @@ -0,0 +1,95 @@ +package rpc + +import ( + "strconv" + + "github.com/mitchellh/mapstructure" + "github.com/trustwallet/golibs/client" + "github.com/trustwallet/golibs/network/middleware" +) + +type Client struct { + client.Request +} + +func InitClient(url string) Client { + return Client{client.InitClient(url, middleware.SentryErrorHandler)} +} + +func (c *Client) GetBlockchainInfo() (info *ChainInfo, err error) { + err = c.RpcCall(&info, "GetBlockchainInfo", nil) + return +} + +func (c *Client) GetTx(hash string) (tx Tx, err error) { + err = c.RpcCall(&tx, "GetTransaction", []string{hash}) + return +} + +func (c *Client) GetBlock(number int64) (block Block, err error) { + err = c.RpcCall(&block, "GetTxBlock", []string{strconv.FormatInt(number, 10)}) + return +} + +func (c *Client) GetTransactionsHashesInBlock(number int64) ([]string, error) { + strNumber := strconv.FormatInt(number, 10) + requestBody := &client.RpcRequest{ + JsonRpc: client.JsonRpcVersion, + Method: "GetTransactionsForTxBlock", + Params: []string{strNumber}, + Id: number, + } + var result HashesResponse + err := c.Post(&result, "/", requestBody) + if err != nil { + return nil, err + } + return result.Txs(), nil +} + +func (c *Client) GetTxInBlock(number int64) (header BlockHeader, txs []Tx, err error) { + hashes, err := c.GetTransactionsHashesInBlock(number) + if err != nil || len(hashes) == 0 { + return + } + + block, err := c.GetBlock(number) + if err != nil { + return + } + + // Avoid 413 Payload Too Large + elements := make([]interface{}, len(hashes)) + for i := range elements { + elements[i] = hashes[i] + } + requests := client.MakeBatchRequests(elements, 500, mapHash) + + var responses []client.RpcResponse + for _, reqs := range requests { + resps, e := c.RpcBatchCall(reqs) + if e != nil { + err = e + return + } + responses = append(responses, resps...) + } + + for _, result := range responses { + var tx Tx + if mapstructure.Decode(result.Result, &tx) != nil { + continue + } + txs = append(txs, tx) + } + + return block.Header, txs, nil +} + +func mapHash(hash interface{}) client.RpcRequest { + array := []interface{}{hash} + return client.RpcRequest{ + Method: "GetTransaction", + Params: array, + } +} diff --git a/platform/zilliqa/rpc/model.go b/platform/zilliqa/rpc/model.go new file mode 100644 index 000000000..802088adf --- /dev/null +++ b/platform/zilliqa/rpc/model.go @@ -0,0 +1,66 @@ +package rpc + +import "github.com/trustwallet/golibs/client" + +type BlockTxs [][]string + +func (b BlockTxs) txs() []string { + txs := make([]string, 0) + for _, ids := range b { + txs = append(txs, ids...) + } + return txs +} + +type ChainInfo struct { + NumTxBlocks string `json:"NumTxBlocks"` +} + +type Receipt struct { + CumulativeGas string `json:"cumulative_gas"` + EpochNum string `json:"epoch_num"` + Success bool `json:"success"` +} + +type Tx struct { + ID string `json:"ID"` + Amount string `json:"amount"` + GasLimit string `json:"gasLimit"` + GasPrice string `json:"gasPrice"` + Nonce string `json:"nonce"` + Receipt Receipt `json:"receipt"` + SenderPubKey string `json:"senderPubKey"` + Signature string `json:"signature"` + ToAddr string `json:"toAddr"` + Version string `json:"version"` +} + +type HashesResponse struct { + ID int `json:"id"` + Jsonrpc string `json:"jsonrpc"` + Result [][]string `json:"result"` +} + +func (h HashesResponse) Txs() []string { + var result []string + for _, subRes := range h.Result { + result = append(result, subRes...) + } + return result +} + +type BlockTxRpc struct { + JsonRpc string `json:"jsonrpc"` + Error *client.RpcError `json:"error,omitempty"` + Result BlockTxs `json:"result,omitempty"` + Id string `json:"id,omitempty"` +} + +type Block struct { + Header BlockHeader `json:"header"` +} + +type BlockHeader struct { + Number string `json:"BlockNum"` + Timestamp string `json:"Timestamp"` +} diff --git a/platform/zilliqa/rpc/model_test.go b/platform/zilliqa/rpc/model_test.go new file mode 100644 index 000000000..d30dc5014 --- /dev/null +++ b/platform/zilliqa/rpc/model_test.go @@ -0,0 +1,28 @@ +package rpc + +import ( + "reflect" + "testing" +) + +func TestBlockTxs_txs(t *testing.T) { + tests := []struct { + name string + b BlockTxs + want []string + }{ + {"test 1 tx", BlockTxs{{"tx1"}, {}}, []string{"tx1"}}, + {"test 2 txs 1", BlockTxs{{"tx1"}, {"tx2"}}, []string{"tx1", "tx2"}}, + {"test 2 txs 2", BlockTxs{{"tx1", "tx2"}}, []string{"tx1", "tx2"}}, + {"test 3 txs 1", BlockTxs{{"tx1", "tx2"}, {"tx3"}}, []string{"tx1", "tx2", "tx3"}}, + {"test 3 txs 2", BlockTxs{{"tx1"}, {"tx2"}, {"tx3"}}, []string{"tx1", "tx2", "tx3"}}, + {"test 4 txs", BlockTxs{{"tx1", "tx2"}, {"tx3"}, {"tx4"}}, []string{"tx1", "tx2", "tx3", "tx4"}}, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + if got := tt.b.txs(); !reflect.DeepEqual(got, tt.want) { + t.Errorf("txs() = %v, want %v", got, tt.want) + } + }) + } +} diff --git a/platform/zilliqa/transaction.go b/platform/zilliqa/transaction.go new file mode 100644 index 000000000..c2cd1782d --- /dev/null +++ b/platform/zilliqa/transaction.go @@ -0,0 +1,49 @@ +package zilliqa + +import ( + "github.com/trustwallet/blockatlas/platform/zilliqa/viewblock" + "github.com/trustwallet/golibs/coin" + "github.com/trustwallet/golibs/types" +) + +func (p *Platform) GetTxsByAddress(address string) (types.Txs, error) { + var normalized types.Txs + txs, err := p.client.GetTxsOfAddress(address) + + if err != nil { + return nil, err + } + + for _, srcTx := range txs { + tx := Normalize(&srcTx) + if len(normalized) >= types.TxPerPage { + break + } + normalized = append(normalized, tx) + } + + return normalized, nil +} + +func Normalize(srcTx *viewblock.Tx) (tx types.Tx) { + tx = types.Tx{ + ID: srcTx.Hash, + Coin: coin.ZILLIQA, + Date: srcTx.Timestamp / 1000, + From: srcTx.From, + To: srcTx.To, + Fee: types.Amount(srcTx.Fee), + Block: srcTx.BlockHeight, + Status: types.StatusCompleted, + Sequence: srcTx.NonceValue(), + Meta: types.Transfer{ + Value: types.Amount(srcTx.Value), + Symbol: coin.Zilliqa().Symbol, + Decimals: coin.Zilliqa().Decimals, + }, + } + if !srcTx.ReceiptSuccess { + tx.Status = types.StatusError + } + return tx +} diff --git a/platform/zilliqa/transaction_test.go b/platform/zilliqa/transaction_test.go new file mode 100644 index 000000000..674e2a296 --- /dev/null +++ b/platform/zilliqa/transaction_test.go @@ -0,0 +1,57 @@ +package zilliqa + +import ( + "reflect" + "testing" + + "github.com/trustwallet/blockatlas/platform/zilliqa/viewblock" + "github.com/trustwallet/golibs/coin" + "github.com/trustwallet/golibs/mock" + "github.com/trustwallet/golibs/types" +) + +func TestNormalizeTx(t *testing.T) { + type args struct { + filename string + } + tests := []struct { + name string + args args + wantTx types.Tx + wantErr bool + }{ + { + name: "Test normalize transaction", + args: args{ + filename: "transfer.json", + }, + wantTx: types.Tx{ + ID: "0xd44413c79e7518152f3b05ef1edff8ef59afd06119b16d09c8bc72e94fed7843", + Coin: coin.ZILLIQA, + From: "0x88af5ba10796d9091d6893eed4db23ef0bbbca37", + To: "0x7fccacf066a5f26ee3affc2ed1fa9810deaa632c", + Fee: "1000000000", + Date: 1557889788, + Block: 104282, + Status: types.StatusCompleted, + Sequence: 3, + Memo: "", + Meta: types.Transfer{ + Value: "7997000000000", + Symbol: "ZIL", + Decimals: 12, + }, + }, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + var srcTx viewblock.Tx + _ = mock.JsonModelFromFilePath("mocks/"+tt.args.filename, &srcTx) + gotTx := Normalize(&srcTx) + if !reflect.DeepEqual(gotTx, tt.wantTx) { + t.Errorf("NormalizeTx() gotTx = %v, want %v", gotTx, tt.wantTx) + } + }) + } +} diff --git a/platform/zilliqa/viewblock/client.go b/platform/zilliqa/viewblock/client.go new file mode 100644 index 000000000..7cc9a276a --- /dev/null +++ b/platform/zilliqa/viewblock/client.go @@ -0,0 +1,24 @@ +package viewblock + +import ( + "fmt" + + "github.com/trustwallet/golibs/client" + "github.com/trustwallet/golibs/network/middleware" +) + +type Client struct { + client.Request +} + +func InitClient(api, apiKey string) Client { + c := Client{client.InitClient(api, middleware.SentryErrorHandler)} + c.Headers["X-APIKEY"] = apiKey + return c +} + +func (c *Client) GetTxsOfAddress(address string) (tx []Tx, err error) { + path := fmt.Sprintf("addresses/%s/txs", address) + err = c.Get(&tx, path, nil) + return +} diff --git a/platform/zilliqa/viewblock/model.go b/platform/zilliqa/viewblock/model.go new file mode 100644 index 000000000..0d79d3963 --- /dev/null +++ b/platform/zilliqa/viewblock/model.go @@ -0,0 +1,34 @@ +package viewblock + +import ( + "strconv" +) + +type Tx struct { + Hash string `json:"hash"` + BlockHeight uint64 `json:"blockHeight"` + From string `json:"from"` + To string `json:"to"` + Value string `json:"value"` + Fee string `json:"fee"` + Timestamp int64 `json:"timestamp"` + Signature string `json:"signature"` + Nonce interface{} `json:"nonce"` + ReceiptSuccess bool `json:"receiptSuccess"` +} + +func (tx Tx) NonceValue() uint64 { + switch n := tx.Nonce.(type) { + case string: + r, err := strconv.Atoi(n) + if err != nil { + break + } + return uint64(r) + case int: + return uint64(n) + case float64: + return uint64(n) + } + return 0 +} diff --git a/platform/zilliqa/viewblock/model_test.go b/platform/zilliqa/viewblock/model_test.go new file mode 100644 index 000000000..c6fed418e --- /dev/null +++ b/platform/zilliqa/viewblock/model_test.go @@ -0,0 +1,28 @@ +package viewblock + +import ( + "testing" +) + +func TestTx_NonceValue(t *testing.T) { + tests := []struct { + name string + nonce interface{} + want uint64 + }{ + {"test int", 0, 0}, + {"test float", 3.4, 3}, + {"test string", "33", 33}, + {"test error string", "test", 0}, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + tx := Tx{ + Nonce: tt.nonce, + } + if got := tx.NonceValue(); got != tt.want { + t.Errorf("NonceValue() = %v, want %v", got, tt.want) + } + }) + } +} diff --git a/platform/zilliqa/zns.go b/platform/zilliqa/zns.go deleted file mode 100644 index d104614e9..000000000 --- a/platform/zilliqa/zns.go +++ /dev/null @@ -1,23 +0,0 @@ -package zilliqa - -import ( - CoinType "github.com/trustwallet/blockatlas/coin" - "github.com/trustwallet/blockatlas/pkg/blockatlas" -) - -type ZNSResponse struct { - Addresses map[string]string -} - -func (p *Platform) Lookup(coins []uint64, name string) ([]blockatlas.Resolved, error) { - var result []blockatlas.Resolved - resp, err := p.udClient.LookupName(name) - if err != nil { - return result, err - } - for _, coin := range coins { - symbol := CoinType.Coins[uint(coin)].Symbol - result = append(result, blockatlas.Resolved{Coin: coin, Result: resp.Addresses[symbol]}) - } - return result, nil -} diff --git a/services/assets/client.go b/services/assets/client.go index 8aa5f822e..0abde523f 100644 --- a/services/assets/client.go +++ b/services/assets/client.go @@ -1,92 +1,24 @@ package assets import ( - "github.com/trustwallet/blockatlas/coin" - "github.com/trustwallet/blockatlas/pkg/blockatlas" - "github.com/trustwallet/blockatlas/pkg/errors" - "sort" "time" + + "github.com/trustwallet/golibs/network/middleware" + + "github.com/trustwallet/golibs/client" + "github.com/trustwallet/golibs/coin" ) const ( - AssetsURL = "https://raw.githubusercontent.com/trustwallet/assets/master/blockchains/" + URL = "https://assets.trustwalletapp.com/blockchains/" ) -func GetValidatorsMap(api blockatlas.StakeAPI) (blockatlas.ValidatorMap, error) { - validatorList, err := GetValidators(api) - if err != nil { - return nil, err - } - validators := make(blockatlas.ValidatorMap) - for _, v := range validatorList { - validators[v.ID] = v - } - return validators, nil -} - -func GetValidators(api blockatlas.StakeAPI) ([]blockatlas.StakeValidator, error) { - assetsValidators, err := GetValidatorsInfo(api.Coin()) - if err != nil { - return nil, errors.E(err, "unable to fetch validators list from the registry").PushToSentry() - } - - validators, err := api.GetValidators() - if err != nil { - return nil, err - } - results := NormalizeValidators(validators, assetsValidators, api.Coin()) - sort.Slice(results, func(i, j int) bool { - return results[i].Details.Reward.Annual > results[j].Details.Reward.Annual - }) - return results, nil -} - -func GetValidatorsInfo(coin coin.Coin) ([]AssetValidator, error) { - var results []AssetValidator - request := blockatlas.Request{ - BaseUrl: AssetsURL + coin.Handle, - HttpClient: blockatlas.DefaultClient, - ErrorHandler: blockatlas.DefaultErrorHandler, - } +func GetValidatorsInfo(coin coin.Coin) (AssetValidators, error) { + var results AssetValidators + request := client.InitClient(URL+coin.Handle, middleware.SentryErrorHandler) err := request.GetWithCache(&results, "validators/list.json", nil, time.Hour*1) if err != nil { - return nil, errors.E(err, errors.Params{"coin": coin.Handle}).PushToSentry() + return nil, err } return results, nil } - -func NormalizeValidators(validators []blockatlas.Validator, assets []AssetValidator, coin coin.Coin) []blockatlas.StakeValidator { - results := make([]blockatlas.StakeValidator, 0) - for _, v := range validators { - for _, v2 := range assets { - if v.ID == v2.ID && !v2.Status.Disabled { - results = append(results, NormalizeValidator(v, v2, coin)) - } - } - } - return results -} - -func NormalizeValidator(plainValidator blockatlas.Validator, validator AssetValidator, coin coin.Coin) blockatlas.StakeValidator { - details := plainValidator.Details - details.Reward.Annual = calculateAnnual(details.Reward.Annual, validator.Payout.Commission) - return blockatlas.StakeValidator{ - ID: validator.ID, - Status: plainValidator.Status, - Info: blockatlas.StakeValidatorInfo{ - Name: validator.Name, - Description: validator.Description, - Image: GetImage(coin, plainValidator.ID), - Website: validator.Website, - }, - Details: details, - } -} - -func calculateAnnual(annual float64, commission float64) float64 { - return (annual * (100 - commission)) / 100 -} - -func GetImage(c coin.Coin, ID string) string { - return AssetsURL + c.Handle + "/validators/assets/" + ID + "/logo.png" -} diff --git a/services/assets/client_test.go b/services/assets/client_test.go deleted file mode 100644 index 577257dc3..000000000 --- a/services/assets/client_test.go +++ /dev/null @@ -1,115 +0,0 @@ -package assets - -import ( - "github.com/stretchr/testify/assert" - "github.com/trustwallet/blockatlas/coin" - "github.com/trustwallet/blockatlas/pkg/blockatlas" - "testing" -) - -var c = coin.Coin{Handle: "cosmos"} -var validators = []blockatlas.Validator{ - { - ID: "test", - Status: true, - }, - { - ID: "test2", - Status: true, - }, -} -var assets = []AssetValidator{ - { - ID: "test", - Name: "Spider", - Description: "yo", - Website: "https://tw.com", - }, -} - -var expectedStakeValidator = blockatlas.StakeValidator{ - ID: "test", Status: true, - Info: blockatlas.StakeValidatorInfo{ - Name: "Spider", - Description: "yo", - Image: "https://raw.githubusercontent.com/trustwallet/assets/master/blockchains/cosmos/validators/assets/test/logo.png", - Website: "https://tw.com", - }, -} - -func TestGetImage(t *testing.T) { - image := GetImage(c, "TGzz8gjYiYRqpfmDwnLxfgPuLVNmpCswVp") - - expected := "https://raw.githubusercontent.com/trustwallet/assets/master/blockchains/cosmos/validators/assets/TGzz8gjYiYRqpfmDwnLxfgPuLVNmpCswVp/logo.png" - - assert.Equal(t, expected, image) -} - -func TestNormalizeValidator(t *testing.T) { - - result := NormalizeValidator(validators[0], assets[0], c) - - assert.Equal(t, expectedStakeValidator, result) -} - -func TestNormalizeValidators(t *testing.T) { - - result := NormalizeValidators(validators, assets, c) - - expected := []blockatlas.StakeValidator{expectedStakeValidator} - - assert.Equal(t, expected, result) -} - -func TestCalcAnnual(t *testing.T) { - type args struct { - annual float64 - commission float64 - } - - tests := []struct { - name string - args args - wanted float64 - }{ - { - name: "test TestCalcAnnual 1", - args: args{ - annual: 10, - commission: 10, - }, - wanted: 9, - }, - { - name: "test TestCalcAnnual 2", - args: args{ - annual: 100, - commission: 10, - }, - wanted: 90, - }, - { - name: "test TestCalcAnnual 3", - args: args{ - annual: 20, - commission: 10, - }, - wanted: 18, - }, - { - name: "test TestCalcAnnual 1", - args: args{ - annual: 30, - commission: 10, - }, - wanted: 27, - }, - } - - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - gotInfo := calculateAnnual(tt.args.annual, tt.args.commission) - assert.Equal(t, tt.wanted, gotInfo) - }) - } -} diff --git a/services/assets/model.go b/services/assets/model.go index 638718424..2f516d92c 100644 --- a/services/assets/model.go +++ b/services/assets/model.go @@ -1,18 +1,47 @@ package assets -type AssetValidator struct { - ID string `json:"id"` - Name string `json:"name"` - Description string `json:"description"` - Website string `json:"website"` - Payout ValidatorPayout `json:"payout,omitempty"` - Status ValidatorStatus `json:"status,omitempty"` -} +type ( + AssetValidators []AssetValidator + + AssetValidatorMap map[string]AssetValidator + + AssetValidator struct { + ID string `json:"id"` + Name string `json:"name"` + Description string `json:"description"` + Website string `json:"website"` + Payout ValidatorPayout `json:"payout,omitempty"` + Status ValidatorStatus `json:"status,omitempty"` + Staking StakingInfo `json:"staking,omitempty"` + } + + ValidatorPayout struct { + Commission float64 `json:"commission"` + } + + ValidatorStatus struct { + Disabled bool `json:"disabled"` + } + + StakingInfo struct { + MinDelegation float64 `json:"minDelegation"` + } +) -type ValidatorPayout struct { - Commission float64 `json:"commission"` +func (av AssetValidators) ToMap() AssetValidatorMap { + validators := make(AssetValidatorMap) + for _, v := range av { + validators[v.ID] = v + } + return validators } -type ValidatorStatus struct { - Disabled bool `json:"disabled"` +func (av AssetValidators) activeValidators() AssetValidators { + activeAssets := make(AssetValidators, 0) + for _, a := range av { + if !a.Status.Disabled { + activeAssets = append(activeAssets, a) + } + } + return activeAssets } diff --git a/services/assets/model_test.go b/services/assets/model_test.go new file mode 100644 index 000000000..e8b8e42b0 --- /dev/null +++ b/services/assets/model_test.go @@ -0,0 +1,55 @@ +package assets + +import ( + "testing" + + "github.com/stretchr/testify/assert" +) + +func TestAssetValidators_toMap(t *testing.T) { + tests := []struct { + name string + av AssetValidators + want AssetValidatorMap + }{ + {"test 1 asset", AssetValidators{{ID: "test1"}}, AssetValidatorMap{"test1": {ID: "test1"}}}, + {"test 2 assets", AssetValidators{{ID: "test1"}, {ID: "test2"}}, AssetValidatorMap{"test1": {ID: "test1"}, "test2": {ID: "test2"}}}, + {"test 3 assets", AssetValidators{{ID: "test1"}, {ID: "test2"}, {ID: "test3"}}, AssetValidatorMap{"test1": {ID: "test1"}, "test2": {ID: "test2"}, "test3": {ID: "test3"}}}, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + got := tt.av.ToMap() + assert.Equal(t, tt.want, got) + }) + } +} + +func TestAssetValidators_activeValidators(t *testing.T) { + tests := []struct { + name string + av AssetValidators + want AssetValidators + }{ + { + "test get active validators 1", + AssetValidators{{ID: "test1", Status: ValidatorStatus{false}}}, + AssetValidators{{ID: "test1", Status: ValidatorStatus{false}}}, + }, + { + "test get active validators 2", + AssetValidators{{ID: "test1", Status: ValidatorStatus{true}}}, + AssetValidators{}, + }, + { + "test get active validators 3", + AssetValidators{{ID: "test1", Status: ValidatorStatus{true}}, {ID: "test2", Status: ValidatorStatus{false}}}, + AssetValidators{{ID: "test2", Status: ValidatorStatus{false}}}, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + got := tt.av.activeValidators() + assert.Equal(t, tt.want, got) + }) + } +} diff --git a/services/assets/validator.go b/services/assets/validator.go new file mode 100644 index 000000000..17bddb5c0 --- /dev/null +++ b/services/assets/validator.go @@ -0,0 +1,74 @@ +package assets + +import ( + "sort" + + "github.com/trustwallet/blockatlas/pkg/blockatlas" + "github.com/trustwallet/golibs/coin" + "github.com/trustwallet/golibs/numbers" + "github.com/trustwallet/golibs/types" +) + +func GetValidatorsMap(api blockatlas.StakeAPI) (blockatlas.ValidatorMap, error) { + assets, validators, err := getValidators(api) + if err != nil { + return nil, err + } + results := normalizeValidators(assets, validators, api.Coin()) + return results.ToMap(), nil +} + +func getValidators(api blockatlas.StakeAPI) (AssetValidators, blockatlas.ValidatorPage, error) { + assetsValidators, err := GetValidatorsInfo(api.Coin()) + if err != nil { + return nil, nil, err + } + + validators, err := api.GetValidators() + if err != nil { + return nil, nil, err + } + return assetsValidators, validators, nil +} + +func normalizeValidators(assetsValidators AssetValidators, rpcValidators []blockatlas.Validator, coin coin.Coin) blockatlas.StakeValidators { + results := make(blockatlas.StakeValidators, 0) + assetsMap := assetsValidators.ToMap() + for _, v := range rpcValidators { + asset, ok := assetsMap[v.ID] + if !ok { + continue + } + results = append(results, normalizeValidator(v, asset, coin)) + } + + sort.Slice(results, func(i, j int) bool { + return results[i].Details.Reward.Annual > results[j].Details.Reward.Annual + }) + return results +} + +func normalizeValidator(rpcValidator blockatlas.Validator, assetValidator AssetValidator, coin coin.Coin) blockatlas.StakeValidator { + details := rpcValidator.Details + details.MinimumAmount = types.Amount(numbers.Float64toString(assetValidator.Staking.MinDelegation)) + details.Reward.Annual = calculateAnnual(details.Reward.Annual, assetValidator.Payout.Commission) + + return blockatlas.StakeValidator{ + ID: assetValidator.ID, + Status: rpcValidator.Status && !assetValidator.Status.Disabled, + Info: blockatlas.StakeValidatorInfo{ + Name: assetValidator.Name, + Description: assetValidator.Description, + Image: GetImageURL(coin, rpcValidator.ID), + Website: assetValidator.Website, + }, + Details: details, + } +} +func calculateAnnual(annual float64, commission float64) float64 { + return (annual * (100 - commission)) / 100 +} + +func GetImageURL(c coin.Coin, ID string) string { + return URL + c.Handle + "/validators/assets/" + ID + "/logo.png" +} diff --git a/services/assets/validator_test.go b/services/assets/validator_test.go new file mode 100644 index 000000000..733204e68 --- /dev/null +++ b/services/assets/validator_test.go @@ -0,0 +1,217 @@ +package assets + +import ( + "testing" + + "github.com/stretchr/testify/assert" + "github.com/trustwallet/blockatlas/pkg/blockatlas" + "github.com/trustwallet/golibs/coin" + "github.com/trustwallet/golibs/types" +) + +var ( + cosmosCoin = coin.Coin{Handle: "cosmos"} + tezosCoin = coin.Coin{Handle: "tezos"} + + validators = []blockatlas.Validator{ + { + ID: "test1", + Status: true, + }, + { + ID: "test2", + Status: true, + }, + } + + assets1 = []AssetValidator{ + { + ID: "test1", + Name: "Spider", + Description: "yo", + Website: "https://tw.com", + Status: ValidatorStatus{Disabled: false}, + }, + { + ID: "test2", + Name: "Man", + Description: "lo", + Website: "https://tw.com", + Status: ValidatorStatus{Disabled: true}, + }, + } + + assets2 = []AssetValidator{ + { + ID: "test1", + Name: "Spider", + Description: "yo", + Website: "https://tw.com", + Status: ValidatorStatus{Disabled: true}, + }, + { + ID: "test2", + Name: "Man", + Description: "lo", + Website: "https://tw.com", + Status: ValidatorStatus{Disabled: true}, + }, + } + + tezosValidators = []blockatlas.Validator{ + { + ID: "test1", + Status: true, + }, + } + + tezosAssets1 = []AssetValidator{ + { + ID: "test1", + Name: "🐠stake.fish", + Description: "Leading validator for Proof of Stake blockchains.", + Website: "https://stake.fish/", + Status: ValidatorStatus{Disabled: false}, + Staking: StakingInfo{MinDelegation: 10}, + }, + } + + expectTezosVal1 = blockatlas.StakeValidator{ + ID: "test1", Status: true, + Info: blockatlas.StakeValidatorInfo{ + Name: "🐠stake.fish", + Description: "Leading validator for Proof of Stake blockchains.", + Image: GetImageURL(tezosCoin, "test1"), + Website: "https://stake.fish/", + }, + Details: blockatlas.StakingDetails{ + MinimumAmount: types.Amount("10"), + }, + } + + expectedCosmosStakeValidator = blockatlas.StakeValidator{ + ID: "test1", Status: true, + Info: blockatlas.StakeValidatorInfo{ + Name: "Spider", + Description: "yo", + Image: GetImageURL(cosmosCoin, "test1"), + Website: "https://tw.com", + }, + Details: blockatlas.StakingDetails{ + MinimumAmount: types.Amount("0"), + }, + } + + expectedCosmosStakeValidatorDisabled1 = blockatlas.StakeValidator{ + ID: "test1", Status: false, + Info: blockatlas.StakeValidatorInfo{ + Name: "Spider", + Description: "yo", + Image: GetImageURL(cosmosCoin, "test1"), + Website: "https://tw.com", + }, + Details: blockatlas.StakingDetails{ + MinimumAmount: types.Amount("0"), + }, + } + + expectedCosmosStakeValidatorDisabled2 = blockatlas.StakeValidator{ + ID: "test2", Status: false, + Info: blockatlas.StakeValidatorInfo{ + Name: "Man", + Description: "lo", + Image: GetImageURL(cosmosCoin, "test2"), + Website: "https://tw.com", + }, + Details: blockatlas.StakingDetails{ + MinimumAmount: types.Amount("0"), + }, + } +) + +func TestGetImage(t *testing.T) { + image := GetImageURL(cosmosCoin, "TGzz8gjYiYRqpfmDwnLxfgPuLVNmpCswVp") + expected := "https://assets.trustwalletapp.com/blockchains/cosmos/validators/assets/TGzz8gjYiYRqpfmDwnLxfgPuLVNmpCswVp/logo.png" + assert.Equal(t, expected, image) +} + +func TestCalcAnnual(t *testing.T) { + type args struct { + annual float64 + commission float64 + } + + tests := []struct { + name string + args args + wanted float64 + }{ + { + name: "test TestCalcAnnual 1", + args: args{ + annual: 10, + commission: 10, + }, + wanted: 9, + }, + { + name: "test TestCalcAnnual 2", + args: args{ + annual: 100, + commission: 10, + }, + wanted: 90, + }, + { + name: "test TestCalcAnnual 3", + args: args{ + annual: 20, + commission: 10, + }, + wanted: 18, + }, + { + name: "test TestCalcAnnual 1", + args: args{ + annual: 30, + commission: 10, + }, + wanted: 27, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + gotInfo := calculateAnnual(tt.args.annual, tt.args.commission) + assert.Equal(t, tt.wanted, gotInfo) + }) + } +} + +func TestNormalizeValidator(t *testing.T) { + result := normalizeValidator(validators[0], assets1[0], cosmosCoin) + assert.Equal(t, expectedCosmosStakeValidator, result) +} + +func Test_normalizeValidators(t *testing.T) { + type args struct { + assets AssetValidators + validators []blockatlas.Validator + coin coin.Coin + } + tests := []struct { + name string + args args + want blockatlas.StakeValidators + }{ + {"normalize validator 1", args{assets1, validators, cosmosCoin}, blockatlas.StakeValidators{expectedCosmosStakeValidator, expectedCosmosStakeValidatorDisabled2}}, + {"normalize validator 2", args{assets2, validators, cosmosCoin}, blockatlas.StakeValidators{expectedCosmosStakeValidatorDisabled1, expectedCosmosStakeValidatorDisabled2}}, + {"normalize tezos validator", args{tezosAssets1, tezosValidators, tezosCoin}, blockatlas.StakeValidators{expectTezosVal1}}, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + got := normalizeValidators(tt.args.assets, tt.args.validators, tt.args.coin) + assert.Equal(t, tt.want, got) + }) + } +} diff --git a/services/notifier/base.go b/services/notifier/base.go new file mode 100644 index 000000000..a942af319 --- /dev/null +++ b/services/notifier/base.go @@ -0,0 +1,78 @@ +package notifier + +import ( + "strconv" + "strings" + + log "github.com/sirupsen/logrus" + "github.com/streadway/amqp" + "github.com/trustwallet/blockatlas/db" + "github.com/trustwallet/golibs/types" +) + +const ( + Notifier = "Notifier" +) + +func RunNotifier(database *db.Instance, delivery amqp.Delivery) error { + transactions, err := GetTransactionsFromDelivery(delivery, Notifier) + if err != nil { + log.WithFields(log.Fields{"service": Notifier, "body": string(delivery.Body), "error": err}).Error("Unable to unmarshal MQ Message") + return nil + } + + allAddresses := make([]string, 0) + for _, tx := range transactions { + allAddresses = append(allAddresses, tx.GetAddresses()...) + } + + addresses := ToUniqueAddresses(allAddresses) + for i := range addresses { + addresses[i] = strconv.Itoa(int(transactions[0].Coin)) + "_" + addresses[i] + } + + if len(transactions) == 0 { + return nil + } + subscriptions, err := database.GetSubscriptions(addresses) + if err != nil { + return nil + } + + notifications := make([]types.TransactionNotification, 0) + for _, sub := range subscriptions { + ua, _, ok := UnprefixedAddress(sub.Address) + if !ok { + continue + } + notificationsForAddress := buildNotificationsByAddress(ua, transactions) + notifications = append(notifications, notificationsForAddress...) + } + + if len(notifications) == 0 { + return nil + } + + err = publishNotifications(notifications) + if err != nil { + log.WithFields(log.Fields{"service": Notifier}).Error(err) + } + + return nil +} + +func UnprefixedAddress(address string) (string, uint, bool) { + result := strings.Split(address, "_") + if len(result) != 2 { + return "", 0, false + } + addr := result[1] + if len(addr) == 0 { + return "", 0, false + } + id, err := strconv.Atoi(result[0]) + if err != nil { + return "", 0, false + } + return addr, uint(id), true +} diff --git a/services/notifier/base_test.go b/services/notifier/base_test.go new file mode 100644 index 000000000..04c8801f7 --- /dev/null +++ b/services/notifier/base_test.go @@ -0,0 +1,58 @@ +package notifier + +import ( + "testing" +) + +func TestUnprefixedAddress(t *testing.T) { + tests := []struct { + name string + address string + want string + coin uint + ok bool + }{ + { + name: "Test invalid address", + address: "60", + want: "", + coin: 0, + ok: false, + }, + { + name: "Test invalid address 2", + address: "60_", + want: "", + coin: 0, + ok: false, + }, + { + name: "Test invalid coin", + address: "asdf_0xEA674fdDe714fd979de3EdF0F56AA9716B898ec8", + want: "", + coin: 0, + ok: false, + }, + { + name: "Test ETH", + address: "60_0xEA674fdDe714fd979de3EdF0F56AA9716B898ec8", + want: "0xEA674fdDe714fd979de3EdF0F56AA9716B898ec8", + coin: 60, + ok: true, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + got, got1, got2 := UnprefixedAddress(tt.address) + if got != tt.want { + t.Errorf("UnprefixedAddress() got = %v, want %v", got, tt.want) + } + if got1 != tt.coin { + t.Errorf("UnprefixedAddress() got1 = %v, want %v", got1, tt.coin) + } + if got2 != tt.ok { + t.Errorf("UnprefixedAddress() got2 = %v, want %v", got2, tt.ok) + } + }) + } +} diff --git a/services/notifier/delivery.go b/services/notifier/delivery.go new file mode 100644 index 000000000..4a5d3e534 --- /dev/null +++ b/services/notifier/delivery.go @@ -0,0 +1,38 @@ +package notifier + +import ( + "encoding/json" + + "github.com/trustwallet/blockatlas/internal" + "github.com/trustwallet/golibs/types" + + log "github.com/sirupsen/logrus" + "github.com/streadway/amqp" +) + +func GetTransactionsFromDelivery(delivery amqp.Delivery, service string) (types.Txs, error) { + var transactions types.Txs + + if err := json.Unmarshal(delivery.Body, &transactions); err != nil { + return nil, err + } + + log.WithFields(log.Fields{"service": service, "notifications": len(transactions)}).Info("Consumed") + + return transactions, nil +} + +func publishNotifications(notifications []types.TransactionNotification) error { + raw, err := json.Marshal(notifications) + if err != nil { + return err + } + err = internal.TxNotifications.Publish(raw) + if err != nil { + return err + } + + log.WithFields(log.Fields{"service": Notifier, "notifications": len(notifications)}).Info("Notifications send") + + return nil +} diff --git a/services/notifier/models.go b/services/notifier/models.go new file mode 100644 index 000000000..cb35e4bee --- /dev/null +++ b/services/notifier/models.go @@ -0,0 +1,62 @@ +package notifier + +import "github.com/trustwallet/golibs/types" + +func buildNotificationsByAddress(address string, txs types.Txs) []types.TransactionNotification { + transactionsByAddress := toUniqueTransactions(findTransactionsByAddress(txs, address)) + + result := make([]types.TransactionNotification, 0, len(transactionsByAddress)) + for _, tx := range transactionsByAddress { + tx.Direction = tx.GetTransactionDirection(address) + tx.InferUtxoValue(address, tx.Coin) + result = append(result, types.TransactionNotification{Action: tx.Type, Result: tx}) + } + + return result +} + +func ToUniqueAddresses(addresses []string) []string { + keys := make(map[string]bool) + var list []string + for _, entry := range addresses { + if _, value := keys[entry]; !value { + keys[entry] = true + list = append(list, entry) + } + } + return list +} + +func toUniqueTransactions(txs types.Txs) types.Txs { + keys := make(map[string]bool) + var list types.Txs + for _, entry := range txs { + key := entry.ID + string(entry.Direction) + if _, value := keys[key]; !value { + keys[key] = true + list = append(list, entry) + } + } + return list +} + +func findTransactionsByAddress(txs types.Txs, address string) types.Txs { + result := make(types.Txs, 0) + for _, tx := range txs { + if containsAddress(tx, address) { + result = append(result, tx) + } + } + return result +} + +func containsAddress(tx types.Tx, address string) bool { + allAddresses := tx.GetAddresses() + txAddresses := ToUniqueAddresses(allAddresses) + for _, a := range txAddresses { + if a == address { + return true + } + } + return false +} diff --git a/services/notifier/models_test.go b/services/notifier/models_test.go new file mode 100644 index 000000000..ee836ac4f --- /dev/null +++ b/services/notifier/models_test.go @@ -0,0 +1,146 @@ +package notifier + +import ( + "sort" + "testing" + + "github.com/stretchr/testify/assert" + "github.com/trustwallet/golibs/coin" + "github.com/trustwallet/golibs/types" +) + +var ( + nativeTokenTransfer = types.Tx{ + ID: "95CF63FAA27579A9B6AF84EF8B2DFEAC29627479E9C98E7F5AE4535E213FA4C9", + Coin: coin.BINANCE, + From: "tbnb1ttyn4csghfgyxreu7lmdu3lcplhqhxtzced45a", + To: "tbnb12hlquylu78cjylk5zshxpdj6hf3t0tahwjt3ex", + Fee: "125000", + Date: 1555117625, + Block: 7928667, + Status: types.StatusCompleted, + Memo: "test", + Meta: types.NativeTokenTransfer{ + TokenID: "YLC-D8B", + Symbol: "YLC", + Value: "210572645", + Decimals: 8, + From: "tbnb1ttyn4csghfgyxreu7lmdu3lcplhqhxtzced45a", + To: "tbnb12hlquylu78cjylk5zshxpdj6hf3t0tahwjt3ex", + }, + } + tokenTransfer = types.Tx{ + ID: "0xbcd1a43e796de4035e5e2991d8db332958e36031d54cb1d3a08d2cb790e338c4", + Coin: 60, + From: "0x08777CB1e80F45642752662B04886Df2d271E049", + To: "0xdd974D5C2e2928deA5F71b9825b8b646686BD200", + Fee: "52473000000000", + Date: 1585169424, + Block: 9742705, + Status: "completed", + Sequence: 149, + Type: "token_transfer", + Meta: types.TokenTransfer{ + Name: "Kyber Network Crystal", + Symbol: "KNC", + TokenID: "0xdd974D5C2e2928deA5F71b9825b8b646686BD200", + Decimals: 18, + Value: "100000000000000", + From: "0x08777CB1e80F45642752662B04886Df2d271E049", + To: "0x38d45371993eEc84f38FEDf93C646aA2D2267CEA", + }, + } + transfer = types.Tx{ + ID: "1681EE543FB4B5A628EF21D746E031F018E226D127044A4F9BA5EE2542A44556", + Coin: coin.BINANCE, + From: "tbnb1fhr04azuhcj0dulm7ka40y0cqjlafwae9k9gk2", + To: "tbnb1fhr04azuhcj0dulm7ka40y0cqjlafwae9k9gk2", + Fee: "125000", + Date: 1555049867, + Block: 7761368, + Status: types.StatusCompleted, + Memo: "test", + Meta: types.Transfer{ + Value: "10000000000000", + Decimals: 8, + Symbol: "BNB", + }, + } + utxoTransfer = types.Tx{ + ID: "zpub6ruK9k6YGm8BRHWvTiQcrEPnFkuRDJhR7mPYzV2LDvjpLa5CuGgrhCYVZjMGcLcFqv9b2WvsFtY2Gb3xq8NVq8qhk9veozrA2W9QaWtihrC", + Coin: coin.BITCOIN, + Inputs: []types.TxOutput{ + { + Address: "bc1qhn03cww757mnnlpkdvvfkaydxqygm86nvkm92h", + Value: "1", + }, + { + Address: "bc1qc7ekqf2t0elfsmtgr2mgd7da2up4vgq8uqk2nh", + Value: "1", + }, + { + Address: "bc1qv454wacvnenr3hzzldjqn8cgfltdlxwe96h737", + Value: "1", + }, + }, + Outputs: []types.TxOutput{ + { + Address: "bc1qjcslq88cht8llqmh3aqshjx9we9msv386jvxl6", + Value: "3", + }, + }, + From: "bc1qhn03cww757mnnlpkdvvfkaydxqygm86nvkm92h", + To: "bc1qjcslq88cht8llqmh3aqshjx9we9msv386jvxl6", + Fee: "125000", + Date: 1555117625, + Block: 592400, + Status: types.StatusCompleted, + Memo: "test", + Meta: types.Transfer{ + Value: "10000000000000", + Decimals: 8, + Symbol: "BNB", + }, + } +) + +func Test_containsAddress(t *testing.T) { + assert.True(t, containsAddress(tokenTransfer, "0x08777CB1e80F45642752662B04886Df2d271E049")) + assert.False(t, containsAddress(tokenTransfer, "0xdd974D5C2e2928deA5F71b9825b8b646686BD200")) + assert.True(t, containsAddress(tokenTransfer, "0x38d45371993eEc84f38FEDf93C646aA2D2267CEA")) + assert.False(t, containsAddress(tokenTransfer, "0xdd974D5C2e2928deA5F71b9825b8b646686BD200")) + + assert.True(t, containsAddress(transfer, "tbnb1fhr04azuhcj0dulm7ka40y0cqjlafwae9k9gk2")) + assert.False(t, containsAddress(transfer, "1681EE543FB4B5A628EF21D746E031F018E226D127044A4F9BA5EE2542A44556")) + assert.True(t, containsAddress(transfer, "tbnb1fhr04azuhcj0dulm7ka40y0cqjlafwae9k9gk2")) + + assert.True(t, containsAddress(nativeTokenTransfer, "tbnb1ttyn4csghfgyxreu7lmdu3lcplhqhxtzced45a")) + assert.False(t, containsAddress(nativeTokenTransfer, "95CF63FAA27579A9B6AF84EF8B2DFEAC29627479E9C98E7F5AE4535E213FA4C9")) + assert.True(t, containsAddress(nativeTokenTransfer, "tbnb12hlquylu78cjylk5zshxpdj6hf3t0tahwjt3ex")) + + assert.True(t, containsAddress(utxoTransfer, "bc1qhn03cww757mnnlpkdvvfkaydxqygm86nvkm92h")) + assert.False(t, containsAddress(utxoTransfer, "bc1qc7ekqf2t0elfsmtgr2mgd7da2up4vgq8uqk2nh")) + assert.False(t, containsAddress(utxoTransfer, "bc1qv454wacvnenr3hzzldjqn8cgfltdlxwe96h737")) + assert.False(t, containsAddress(utxoTransfer, "zpub6ruK9k6YGm8BRHWvTiQcrEPnFkuRDJhR7mPYzV2LDvjpLa5CuGgrhCYVZjMGcLcFqv9b2WvsFtY2Gb3xq8NVq8qhk9veozrA2W9QaWtihrC")) + assert.True(t, containsAddress(utxoTransfer, "bc1qjcslq88cht8llqmh3aqshjx9we9msv386jvxl6")) +} + +func Test_findTransactionsByAddress(t *testing.T) { + res := findTransactionsByAddress(types.Txs{nativeTokenTransfer, tokenTransfer}, "tbnb1ttyn4csghfgyxreu7lmdu3lcplhqhxtzced45a") + sort.Slice(res, func(i, j int) bool { + return res[i].ID < res[j].ID + }) + assert.Equal(t, types.Txs{nativeTokenTransfer}, res) + + resFail := findTransactionsByAddress(types.Txs{nativeTokenTransfer, tokenTransfer}, "tbnb1ttyn4csghfgyxreu7lmdu3lcplhqhxtzced") + assert.Equal(t, types.Txs{}, resFail) +} + +func Test_buildNotificationsByAddress(t *testing.T) { + notifications := buildNotificationsByAddress("tbnb1ttyn4csghfgyxreu7lmdu3lcplhqhxtzced45a", types.Txs{nativeTokenTransfer, tokenTransfer}) + sort.Slice(notifications, func(i, j int) bool { + return notifications[i].Action < notifications[j].Action + }) + nativeTokenTransfer.Direction = types.DirectionOutgoing + assert.Equal(t, nativeTokenTransfer, notifications[0].Result) +} diff --git a/services/parser/parser.go b/services/parser/parser.go new file mode 100644 index 000000000..197789545 --- /dev/null +++ b/services/parser/parser.go @@ -0,0 +1,312 @@ +package parser + +import ( + "context" + "encoding/json" + "errors" + "fmt" + "strconv" + "sync/atomic" + + "github.com/trustwallet/blockatlas/db/models" + + "github.com/getsentry/raven-go" + + "math/rand" + "sort" + "sync" + "time" + + "github.com/trustwallet/blockatlas/db" + "github.com/trustwallet/blockatlas/pkg/blockatlas" + "github.com/trustwallet/golibs/network/mq" + "github.com/trustwallet/golibs/numbers" + "github.com/trustwallet/golibs/types" + + log "github.com/sirupsen/logrus" +) + +type ( + Params struct { + Api blockatlas.BlockAPI + TransactionsExchange mq.Exchange + ParsingBlocksInterval, FetchBlocksTimeout time.Duration + MaxBlocks int64 + StopChannel chan<- struct{} + Database *db.Instance + } + + GetBlockByNumber func(num int64) (*types.Block, error) + + stop struct { + error + } +) + +func RunParser(params Params, ctx context.Context) { + log.Info("------------------------------------------------------------") + for { + select { + case <-ctx.Done(): + log.Info(fmt.Sprintf("Parser of %s stopped parsing blocks", params.Api.Coin().Handle)) + params.StopChannel <- struct{}{} + return + default: + parse(params) + } + log.Info("------------------------------------------------------------") + } +} + +func GetInterval(value int, minInterval, maxInterval time.Duration) time.Duration { + interval := time.Duration(value) * time.Millisecond + pMin := numbers.Max(minInterval.Nanoseconds(), interval.Nanoseconds()) + pMax := numbers.Min(int(maxInterval.Nanoseconds()), int(pMin)) + return time.Duration(pMax) +} + +func parse(params Params) { + coinTracker, err := params.Database.GetLastParsedBlockNumber(params.Api.Coin().Handle) + if err != nil { + time.Sleep(params.ParsingBlocksInterval) + return + } + if !coinTracker.Enabled { + time.Sleep(params.ParsingBlocksInterval) + return + } + + lastParsedBlock, currentBlock, err := GetBlocksIntervalToFetch(params, coinTracker) + if err != nil { + time.Sleep(params.ParsingBlocksInterval) + return + } + + if lastParsedBlock > currentBlock { + time.Sleep(params.ParsingBlocksInterval) + return + } + + blocks, err := FetchBlocks(params, lastParsedBlock, currentBlock) + if err != nil { + time.Sleep(params.ParsingBlocksInterval) + return + } + + err = SaveLastParsedBlock(params, blocks) + if err != nil { + log.WithFields(log.Fields{ + "operation": "run SaveLastParsedBlock", + "coin": params.Api.Coin().Handle, + "blocks": blocks, + "lastParsedBlock": lastParsedBlock, + "currentBlock": currentBlock, + "tags": raven.Tags{{Key: "coin", Value: params.Api.Coin().Handle}}, + }).Error(err) + time.Sleep(params.ParsingBlocksInterval) + return + } + + var txs types.Txs + for _, block := range blocks { + txs = append(txs, block.Txs...) + } + txs = txs.FilterTransactionsByMemo() + + err = publish(params, txs) + if err != nil { + log.WithFields(log.Fields{ + "coin": params.Api.Coin().Handle, + "transactions": len(txs), + "error": err, + }).Info("Publish Error") + } + + log.WithFields(log.Fields{ + "coin": params.Api.Coin().Handle, + "transactions": len(txs), + }).Info("Published transactions") + + log.WithFields(log.Fields{"coin": params.Api.Coin().Handle}).Info("End of parse step") +} + +func GetBlocksIntervalToFetch(params Params, tracker models.Tracker) (int64, int64, error) { + lastParsedBlock := tracker.Height + currentBlock, err := params.Api.CurrentBlockNumber() + if err != nil { + return 0, 0, errors.New(err.Error() + "Polling failed: source didn't return chain head number. lastParsedBlock: " + strconv.Itoa(int(lastParsedBlock))) + } + currentBlock -= params.Api.Coin().MinConfirmations + + return GetNextBlocksToParse(lastParsedBlock, currentBlock, params.MaxBlocks) +} + +func GetNextBlocksToParse(lastParsedBlock int64, currentBlock int64, maxBlocks int64) (int64, int64, error) { + if lastParsedBlock == currentBlock { + return lastParsedBlock, currentBlock, nil + } + if lastParsedBlock > currentBlock { + return lastParsedBlock, lastParsedBlock, nil + } + + var endParseBlock = currentBlock + var nextBlock = lastParsedBlock + 1 + + if currentBlock-lastParsedBlock > maxBlocks { + endParseBlock = nextBlock + maxBlocks + } + + return nextBlock, endParseBlock + 1, nil +} + +func FetchBlocks(params Params, lastParsedBlock, currentBlock int64) ([]types.Block, error) { + if lastParsedBlock == currentBlock { + log.WithFields(log.Fields{ + "current_block": lastParsedBlock, + "coin": params.Api.Coin().Handle, + }).Info("No new blocks") + return nil, errors.New("no new blocks") + } + + blocksCount := currentBlock - lastParsedBlock + if blocksCount < 0 { + log.WithFields(log.Fields{"coin": params.Api.Coin().Handle}).Error("Current block is 0") + return nil, errors.New("current block is 0") + } + + var ( + blocksChan = make(chan types.Block, blocksCount) + errorsChan = make(chan error, blocksCount) + totalCount int32 + wg sync.WaitGroup + ) + + for i := lastParsedBlock; i <= currentBlock-1; i++ { + wg.Add(1) + time.Sleep(params.FetchBlocksTimeout) + go func(i int64, wg *sync.WaitGroup) { + defer wg.Done() + err := fetchBlock(params.Api, i, blocksChan) + if err != nil { + errorsChan <- err + return + } + atomic.AddInt32(&totalCount, 1) + }(i, &wg) + } + + wg.Wait() + close(errorsChan) + close(blocksChan) + + if len(errorsChan) > 0 { + var ( + errorsList = make([]error, 0, len(errorsChan)) + ) + for err := range errorsChan { + errorsList = append(errorsList, err) + } + log.WithFields(log.Fields{ + "coin": params.Api.Coin().Handle, + "count": len(errorsList), + "blocks": errorsList, + "tags": raven.Tags{ + {Key: "coin", Value: params.Api.Coin().Handle}, + }, + }).Error("Fetch Blocks Errors") + + return []types.Block{}, fmt.Errorf("unable to fetch blocks: %d: %d", lastParsedBlock, currentBlock) + } + + blocks := make([]types.Block, 0, len(blocksChan)) + for block := range blocksChan { + blocks = append(blocks, block) + } + + log.WithFields(log.Fields{ + "from": lastParsedBlock, + "to": currentBlock - 1, + "total": totalCount, + "coin": params.Api.Coin().Handle}, + ).Info("Fetched blocks batch") + + return blocks, nil +} + +func fetchBlock(api blockatlas.BlockAPI, num int64, blocksChan chan<- types.Block) error { + block, err := getBlockByNumberWithRetry(5, time.Second*5, api.GetBlockByNumber, num, api.Coin().Symbol) + if err != nil { + return fmt.Errorf("%d", num) + } + blocksChan <- *block + return nil +} + +func SaveLastParsedBlock(params Params, blocks []types.Block) error { + if len(blocks) == 0 { + return nil + } + + sort.Slice(blocks, func(i, j int) bool { + return blocks[i].Number < blocks[j].Number + }) + if len(blocks)-1 < 0 { + return fmt.Errorf("cannot get last block number for %s", params.Api.Coin().Handle) + } + + lastBlockNumber := blocks[len(blocks)-1].Number + if lastBlockNumber <= 0 { + return fmt.Errorf("parser of %s failed to save last block, lastBlockNumber <= 0: %d", params.Api.Coin().Handle, lastBlockNumber) + } + err := params.Database.SetLastParsedBlockNumber(params.Api.Coin().Handle, lastBlockNumber) + if err != nil { + return err + } + + log.WithFields(log.Fields{ + "block": lastBlockNumber, + "coin": params.Api.Coin().Handle, + }).Info("Save last parsed block") + + return nil +} + +func publish(params Params, transactions types.Txs) error { + + if len(transactions) == 0 { + return nil + } + + body, err := json.Marshal(transactions) + if err != nil { + log.WithFields(log.Fields{"operation": "publish marshal", "transactions": transactions, "coin": params.Api.Coin().Handle}).Error(err) + return err + } + return params.TransactionsExchange.Publish(body) +} + +func getBlockByNumberWithRetry(attempts int, sleep time.Duration, getBlockByNumber GetBlockByNumber, n int64, symbol string) (*types.Block, error) { + r, err := getBlockByNumber(n) + if err != nil { + if s, ok := err.(stop); ok { + return nil, s.error + } + if attempts--; attempts > 0 { + // Add some randomness to prevent creating a Thundering Herd + rand.Seed(time.Now().UnixNano()) + jitter := time.Duration(rand.Int63n(int64(sleep))) + sleep = sleep + jitter/2 + + log.WithFields(log.Fields{ + "number": n, + "attempts": attempts, + "sleep": sleep.String(), + "symbol": symbol}, + ).Warn("retry GetBlockByNumber") + + time.Sleep(sleep) + return getBlockByNumberWithRetry(attempts, sleep*2, getBlockByNumber, n, symbol) + } + } + return r, err +} diff --git a/services/parser/parser_test.go b/services/parser/parser_test.go new file mode 100644 index 000000000..c340beadd --- /dev/null +++ b/services/parser/parser_test.go @@ -0,0 +1,220 @@ +package parser + +import ( + "errors" + "testing" + "time" + + "github.com/stretchr/testify/assert" + "github.com/trustwallet/blockatlas/pkg/blockatlas" + "github.com/trustwallet/golibs/coin" + "github.com/trustwallet/golibs/types" +) + +var ( + wantedMockedNumber int64 +) + +func TestFetchBlocks(t *testing.T) { + params := Params{ + Api: getMockedBlockAPI(), + TransactionsExchange: "", + ParsingBlocksInterval: 0, + FetchBlocksTimeout: 0, + MaxBlocks: 0, + StopChannel: nil, + Database: nil, + } + blocks, err := FetchBlocks(params, 0, 100) + assert.Equal(t, len(blocks), 100) + assert.Nil(t, err) +} + +func TestParser_getBlockByNumberWithRetry(t *testing.T) { + block, err := getBlockByNumberWithRetry(3, time.Millisecond*1, getBlock, 1, "") + if err != nil { + t.Error(err) + } + + if block == nil { + t.Error("block is nil") + } +} + +func TestParser_getBlockByNumberWithRetry_Error(t *testing.T) { + now := time.Now() + block, err := getBlockByNumberWithRetry(2, time.Millisecond*2, getBlock, 0, "") + elapsed := time.Since(now) + if err == nil { + t.Error("getBlockByNumberWithRetry method need fail") + } + + if block != nil { + t.Error("block object need be nil") + } + + if elapsed > time.Millisecond*7 { + t.Error("Thundering Herd prevent doesn't work") + } +} + +func getBlock(num int64) (*types.Block, error) { + if num == 0 { + return nil, errors.New("test") + } + return &types.Block{}, nil +} + +func getMockedBlockAPI() blockatlas.BlockAPI { + p := Platform{CoinIndex: 60} + return &p +} + +type Platform struct { + CoinIndex uint +} + +func (p *Platform) CurrentBlockNumber() (int64, error) { + return wantedMockedNumber, nil +} + +func (p *Platform) Coin() coin.Coin { + return coin.Coins[p.CoinIndex] +} + +func (p *Platform) GetBlockByNumber(num int64) (*types.Block, error) { + return &types.Block{}, nil +} + +func TestGetInterval(t *testing.T) { + min, _ := time.ParseDuration("2s") + max, _ := time.ParseDuration("30s") + type args struct { + blockTime int + minInterval time.Duration + maxInterval time.Duration + } + tests := []struct { + name string + args args + want time.Duration + }{ + { + "test minimum", + args{ + blockTime: 100, + minInterval: min, + maxInterval: max, + }, + min, + }, { + "test maximum", + args{ + blockTime: 600000, + minInterval: min, + maxInterval: max, + }, + max, + }, { + "test right blocktime", + args{ + blockTime: 5000, + minInterval: min, + maxInterval: max, + }, + 5000 * time.Millisecond, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + got := GetInterval(tt.args.blockTime, tt.args.minInterval, tt.args.maxInterval) + assert.EqualValues(t, tt.want, got) + }) + } +} + +func TestGetNextBlocksToParse(t *testing.T) { + type args struct { + lastParsedBlock int64 + currentBlock int64 + maxBlocks int64 + } + tests := []struct { + name string + args args + want int64 + want1 int64 + wantErr bool + }{ + { + "Test behind blocks", + args{ + lastParsedBlock: 10, + currentBlock: 25, + maxBlocks: 3, + }, + 11, + 15, + false, + }, + { + "Test when only 1 block to parse", + args{ + lastParsedBlock: 10, + currentBlock: 13, + maxBlocks: 5, + }, + 11, + 14, + false, + }, + { + "Test same block", + args{ + lastParsedBlock: 10, + currentBlock: 10, + maxBlocks: 3, + }, + 10, + 10, + false, + }, + { + "Last parsed block ahead", + args{ + lastParsedBlock: 15, + currentBlock: 10, + maxBlocks: 3, + }, + 15, + 15, + false, + }, + { + "Parse last block", + args{ + lastParsedBlock: 15, + currentBlock: 15, + maxBlocks: 3, + }, + 15, + 15, + false, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + got, got1, err := GetNextBlocksToParse(tt.args.lastParsedBlock, tt.args.currentBlock, tt.args.maxBlocks) + if (err != nil) != tt.wantErr { + t.Errorf("GetNextBlocksToParse() error = %v, wantErr %v", err, tt.wantErr) + return + } + if got != tt.want { + t.Errorf("GetNextBlocksToParse() got = %v, want %v", got, tt.want) + } + if got1 != tt.want1 { + t.Errorf("GetNextBlocksToParse() got1 = %v, want %v", got1, tt.want1) + } + }) + } +} diff --git a/services/subscriber/subscriber.go b/services/subscriber/subscriber.go new file mode 100644 index 000000000..733ae36dd --- /dev/null +++ b/services/subscriber/subscriber.go @@ -0,0 +1,47 @@ +package subscriber + +import ( + "encoding/json" + + "github.com/trustwallet/blockatlas/internal" + + log "github.com/sirupsen/logrus" + "github.com/streadway/amqp" + "github.com/trustwallet/blockatlas/db" + "github.com/trustwallet/golibs/types" +) + +func RunSubscriber(database *db.Instance, delivery amqp.Delivery) error { + var event types.SubscriptionEvent + err := json.Unmarshal(delivery.Body, &event) + if err != nil { + log.WithFields(log.Fields{"service": types.Notifications, "body": string(delivery.Body), "error": err}).Error("Unable to unmarshal MQ Message") + return nil + } + + subscriptions := event.ParseSubscriptions(event.Subscriptions) + switch event.Operation { + case types.AddSubscription: + err := database.CreateSubscriptions(subscriptions) + if err != nil { + log.WithFields(log.Fields{"service": types.Notifications, "operation": event.Operation, "subscriptions": subscriptions}).Error(err) + return err + } + log.WithFields(log.Fields{"service": types.Notifications, "operation": event.Operation, "subscriptions": len(subscriptions)}).Info("Add subscriptions") + case types.DeleteSubscription: + subscriptionsIds := make([]string, 0) + for _, subscription := range subscriptions { + subscriptionsIds = append(subscriptionsIds, subscription.AddressID()) + } + return database.DeleteSubscriptions(subscriptionsIds) + } + + // Pass over subscribed addresses to find all associated tokens to such addresses + err = internal.SubscriptionsTokens.Publish(delivery.Body) + if err != nil { + log.Error(err) + return nil + } + + return nil +} diff --git a/services/tokenindexer/api.go b/services/tokenindexer/api.go new file mode 100644 index 000000000..6a584542e --- /dev/null +++ b/services/tokenindexer/api.go @@ -0,0 +1,70 @@ +package tokenindexer + +import ( + "time" + + "github.com/trustwallet/blockatlas/pkg/blockatlas" + + "github.com/trustwallet/blockatlas/db" + "github.com/trustwallet/blockatlas/db/models" + "github.com/trustwallet/golibs/types" +) + +type Instance struct { + database *db.Instance +} + +func Init(database *db.Instance) Instance { + return Instance{database: database} +} + +func (i Instance) GetNewTokensRequest(r Request) (blockatlas.ResultsResponse, error) { + from := time.Unix(r.From, 0) + result, err := i.database.GetAssetsFrom(from) + if err != nil { + return blockatlas.ResultsResponse{}, err + } + return normalize(result), nil +} + +func (i Instance) GetTokensByAddress(r GetTokensByAddressRequest) (GetTokensByAddressResponse, error) { + list := make([]string, 0) + + for coin, coins := range r.AddressesByCoin { + for _, address := range coins { + list = append(list, types.GetAddressID(coin, address)) + } + } + from := time.Unix(int64(r.From), 0) + associations, err := i.database.GetSubscriptionsByAddressIDs(list, from) + if err != nil { + return GetTokensByAddressResponse{}, err + } + + assetIds := make([]GetTokensAsset, 0) + + for _, association := range associations { + assetIds = append(assetIds, GetTokensAsset{ + AssetId: association.Asset.Asset, + CreatedAt: association.CreatedAt.Unix(), + UpdatedAt: association.UpdatedAt.Unix(), + }) + } + + return assetIds, nil +} + +func normalize(dbAssets []models.Asset) blockatlas.ResultsResponse { + result := make([]types.Asset, 0) + for _, a := range dbAssets { + asset := types.Asset{ + Id: a.Asset, + Name: a.Name, + Symbol: a.Symbol, + Type: types.TokenType(a.Type), + Decimals: a.Decimals, + } + result = append(result, asset) + } + return blockatlas.ResultsResponse{Results: result} +} diff --git a/services/tokenindexer/indexer.go b/services/tokenindexer/indexer.go new file mode 100644 index 000000000..53826589d --- /dev/null +++ b/services/tokenindexer/indexer.go @@ -0,0 +1,145 @@ +package tokenindexer + +import ( + "strconv" + + log "github.com/sirupsen/logrus" + "github.com/streadway/amqp" + "github.com/trustwallet/blockatlas/db" + "github.com/trustwallet/blockatlas/db/models" + "github.com/trustwallet/blockatlas/services/notifier" + "github.com/trustwallet/golibs/types" +) + +const ( + TokenIndexer = "TokenIndexer" + SubscriptionsTokenIndexer = "SubscriptionsTokenIndexer" +) + +func RunTokenIndexer(database *db.Instance, delivery amqp.Delivery) error { + transactions, err := notifier.GetTransactionsFromDelivery(delivery, TokenIndexer) + if err != nil { + log.WithFields(log.Fields{"service": TokenIndexer, "body": string(delivery.Body), "error": err}).Error("Unable to unmarshal MQ Message") + return nil + } + + assetsTxs := transactions.FilterTransactionsByType([]types.TransactionType{ + types.TxContractCall, + types.TxTokenTransfer, + types.TxNativeTokenTransfer, + }) + + if len(assetsTxs) == 0 { + return nil + } + + // Add new assets to db + assets := GetAssetsFromTransactions(assetsTxs) + err = database.AddNewAssets(assets) + if err != nil { + log.WithFields(log.Fields{"service": TokenIndexer, "assets": assets}).Error("Failed to add new assets", err) + return err + } + + // Add asset <> address association + addressAssetsMap := assetsMap(assetsTxs) + + return CreateAssociations(database, addressAssetsMap) +} + +func CreateAssociations(database *db.Instance, addressAssetsMap map[string][]string) error { + associations, err := calculateSubscriptionAssetAssociations(database, addressAssetsMap) + if err != nil { + return err + } + return database.CreateSubscriptionsAssets(associations) +} + +func calculateSubscriptionAssetAssociations(database *db.Instance, addressAssetsMap map[string][]string) ([]models.SubscriptionsAssetAssociation, error) { + associations := make([]models.SubscriptionsAssetAssociation, 0) + + addressIds := make([]string, 0) + assetIds := make([]string, 0) + for addressId, assets := range addressAssetsMap { + addressIds = append(addressIds, addressId) + + assetIds = append(assetIds, assets...) + } + + if len(addressIds) == 0 || len(assetIds) == 0 { + return associations, nil + } + + subscriptions, err := database.GetSubscriptions(addressIds) + if err != nil { + return associations, err + } + + assets, err := database.GetAssetsByIDs(assetIds) + if err != nil { + return associations, err + } + + assetsMap := map[string]models.Asset{} + for _, asset := range assets { + assetsMap[asset.Asset] = asset + } + + subscriptionsMap := map[string]models.Subscription{} + for _, subscription := range subscriptions { + subscriptionsMap[subscription.Address] = subscription + } + + uniqueMap := map[string]bool{} + for addressId, assets := range addressAssetsMap { + subscription, ok := subscriptionsMap[addressId] + if !ok { + continue + } + + for _, assetId := range assets { + asset, ok := assetsMap[assetId] + if !ok { + continue + } + subscriptionKey := strconv.Itoa(int(asset.ID)) + "_" + strconv.Itoa(int(subscription.ID)) + if _, ok := uniqueMap[subscriptionKey]; !ok { + association := models.SubscriptionsAssetAssociation{ + SubscriptionId: subscription.ID, + AssetId: asset.ID, + } + associations = append(associations, association) + uniqueMap[subscriptionKey] = true + } + } + } + + return associations, nil +} + +func GetAssetsFromTransactions(txs types.Txs) []models.Asset { + var result []models.Asset + for _, tx := range txs { + assets := models.AssetsFrom(tx) + result = append(result, assets...) + } + return result +} + +func assetsMap(txs types.Txs) map[string][]string { + result := make(map[string][]string) + for _, tx := range txs { + prefix := strconv.Itoa(int(tx.Coin)) + "_" + addresses := tx.GetAddresses() + assets := models.AssetsFrom(tx) + + for _, asset := range assets { + for _, address := range addresses { + assetId := prefix + address + assetIDs := result[assetId] + result[assetId] = append(assetIDs, asset.Asset) + } + } + } + return result +} diff --git a/services/tokenindexer/indexer_subscribe.go b/services/tokenindexer/indexer_subscribe.go new file mode 100644 index 000000000..f19df1ce6 --- /dev/null +++ b/services/tokenindexer/indexer_subscribe.go @@ -0,0 +1,57 @@ +package tokenindexer + +import ( + "encoding/json" + + log "github.com/sirupsen/logrus" + "github.com/streadway/amqp" + "github.com/trustwallet/blockatlas/db" + "github.com/trustwallet/blockatlas/pkg/blockatlas" + "github.com/trustwallet/golibs/types" +) + +type ConsumerIndexer struct { + Database *db.Instance + TokensAPIs map[uint]blockatlas.TokensAPI + Delivery func(*db.Instance, map[uint]blockatlas.TokensAPI, amqp.Delivery) error + Tag string +} + +func (c ConsumerIndexer) Callback(msg amqp.Delivery) error { + return c.Delivery(c.Database, c.TokensAPIs, msg) +} + +func RunTokenIndexerSubscribe(database *db.Instance, apis map[uint]blockatlas.TokensAPI, delivery amqp.Delivery) error { + var event types.SubscriptionEvent + err := json.Unmarshal(delivery.Body, &event) + if err != nil { + log.WithFields(log.Fields{"service": SubscriptionsTokenIndexer, "body": string(delivery.Body), "error": err}).Error("Unable to unmarshal MQ Message") + return nil + } + + log.WithFields(log.Fields{"service": TokenIndexer, "event": event.Operation, "subscriptions": len(event.Subscriptions)}).Info("Processing") + + subscriptions := event.ParseSubscriptions(event.Subscriptions) + switch event.Operation { + case types.AddSubscription: + addressAssetsMap := map[string][]string{} + + for _, coinAddress := range subscriptions { + api, ok := apis[coinAddress.Coin] + if !ok { + continue + } + assetIds, err := api.GetTokenListIdsByAddress(coinAddress.Address) + if err != nil { + continue + } + addressAssetsMap[coinAddress.AddressID()] = assetIds + } + return CreateAssociations(database, addressAssetsMap) + case types.DeleteSubscription: + //No action is needed + return nil + } + + return nil +} diff --git a/services/tokenindexer/models.go b/services/tokenindexer/models.go new file mode 100644 index 000000000..704b089e6 --- /dev/null +++ b/services/tokenindexer/models.go @@ -0,0 +1,20 @@ +package tokenindexer + +type ( + Request struct { + From int64 + } + + GetTokensByAddressRequest struct { + AddressesByCoin map[string][]string `json:"addresses"` + From uint `json:"from"` + } + + GetTokensAsset struct { + AssetId string `json:"asset_id"` + CreatedAt int64 `json:"created_at"` + UpdatedAt int64 `json:"updated_at"` + } + + GetTokensByAddressResponse []GetTokensAsset +) diff --git a/storage/block.go b/storage/block.go deleted file mode 100644 index 469de1bcc..000000000 --- a/storage/block.go +++ /dev/null @@ -1,56 +0,0 @@ -package storage - -import ( - "fmt" - "sync" -) - -const ( - ATLAS_BLOCK_NUMBER = "ATLAS_BLOCK_NUMBER_%d" -) - -type BlockMap struct { - heights map[uint]int64 - lock sync.RWMutex -} - -func (bm *BlockMap) SetBlock(coin uint, b int64) { - bm.lock.Lock() - defer bm.lock.Unlock() - bm.heights[coin] = b -} - -func (bm *BlockMap) GetBlock(coin uint) (int64, bool) { - bm.lock.RLock() - defer bm.lock.RUnlock() - b, ok := bm.heights[coin] - return b, ok -} - -func (bm *BlockMap) GetHeights() map[uint]int64 { - bm.lock.RLock() - defer bm.lock.RUnlock() - return bm.heights -} - -func (s *Storage) GetBlockNumber(coin uint) (int64, error) { - b, ok := s.blockHeights.GetBlock(coin) - if ok { - return b, nil - } - - err := s.GetValue(getBlockKey(coin), &b) - if err != nil { - return 0, nil - } - return b, nil -} - -func (s *Storage) SetBlockNumber(coin uint, num int64) error { - s.blockHeights.SetBlock(coin, num) - return s.Add(getBlockKey(coin), num) -} - -func getBlockKey(coin uint) string { - return fmt.Sprintf(ATLAS_BLOCK_NUMBER, coin) -} diff --git a/storage/market.go b/storage/market.go deleted file mode 100644 index 5f7c6d436..000000000 --- a/storage/market.go +++ /dev/null @@ -1,78 +0,0 @@ -package storage - -import ( - "github.com/trustwallet/blockatlas/pkg/blockatlas" - "github.com/trustwallet/blockatlas/pkg/errors" - "github.com/trustwallet/blockatlas/pkg/logger" - "strings" -) - -const ( - EntityRates = "ATLAS_MARKET_RATES" - EntityQuotes = "ATLAS_MARKET_QUOTES" -) - -type ProviderList interface { - GetPriority(providerId string) int -} - -func (s *Storage) SaveTicker(coin *blockatlas.Ticker, pl ProviderList) error { - cd, err := s.GetTicker(coin.CoinName, coin.TokenId) - if err == nil { - op := pl.GetPriority(cd.Price.Provider) - np := pl.GetPriority(coin.Price.Provider) - if op != -1 && np > op { - return errors.E("ticker provider with less priority") - } - - if cd.LastUpdate.After(coin.LastUpdate) && op >= np { - return errors.E("ticker is outdated") - } - } - hm := createHashMap(coin.CoinName, coin.TokenId) - return s.AddHM(EntityQuotes, hm, coin) -} - -func (s *Storage) GetTicker(coin, token string) (*blockatlas.Ticker, error) { - hm := createHashMap(coin, token) - var cd *blockatlas.Ticker - err := s.GetHMValue(EntityQuotes, hm, &cd) - if err != nil { - return nil, err - } - return cd, nil -} - -func (s *Storage) SaveRates(rates blockatlas.Rates, pl ProviderList) { - for _, rate := range rates { - r, err := s.GetRate(rate.Currency) - if err == nil { - op := pl.GetPriority(r.Provider) - np := pl.GetPriority(rate.Provider) - if op != -1 && np > op { - continue - } - - if rate.Timestamp < r.Timestamp && op >= np { - continue - } - } - err = s.AddHM(EntityRates, rate.Currency, &rate) - if err != nil { - logger.Error(err, "SaveRates", logger.Params{"rate": rate}) - continue - } - } -} - -func (s *Storage) GetRate(currency string) (rate *blockatlas.Rate, err error) { - err = s.GetHMValue(EntityRates, currency, &rate) - return -} - -func createHashMap(coin, token string) string { - if len(token) == 0 { - return strings.ToUpper(coin) - } - return strings.ToUpper(strings.Join([]string{coin, token}, "_")) -} diff --git a/storage/storage.go b/storage/storage.go deleted file mode 100644 index dfd510851..000000000 --- a/storage/storage.go +++ /dev/null @@ -1,35 +0,0 @@ -package storage - -import ( - "github.com/trustwallet/blockatlas/pkg/blockatlas" - "github.com/trustwallet/blockatlas/pkg/storage/redis" -) - -type Storage struct { - redis.Redis - blockHeights BlockMap -} - -func New() *Storage { - s := new(Storage) - s.blockHeights.heights = make(map[uint]int64) - return s -} - -type Tracker interface { - GetBlockNumber(coin uint) (int64, error) - SetBlockNumber(coin uint, num int64) error -} - -type Addresses interface { - Lookup(coin uint, addresses []string) ([]blockatlas.Subscription, error) - AddSubscriptions(subscriptions []blockatlas.Subscription) - DeleteSubscriptions(subscriptions []blockatlas.Subscription) -} - -type Market interface { - SaveTicker(coin *blockatlas.Ticker, pl ProviderList) error - GetTicker(coin, token string) (*blockatlas.Ticker, error) - SaveRates(rates blockatlas.Rates, pl ProviderList) - GetRate(currency string) (*blockatlas.Rate, error) -} diff --git a/storage/subscriptions.go b/storage/subscriptions.go deleted file mode 100644 index 762dfc661..000000000 --- a/storage/subscriptions.go +++ /dev/null @@ -1,86 +0,0 @@ -package storage - -import ( - "fmt" - "github.com/trustwallet/blockatlas/pkg/blockatlas" - "github.com/trustwallet/blockatlas/pkg/errors" - "github.com/trustwallet/blockatlas/pkg/logger" -) - -const ( - ATLAS_OBSERVER = "ATLAS_OBSERVER" -) - -func (s *Storage) Lookup(coin uint, addresses []string) (observers []blockatlas.Subscription, err error) { - if len(addresses) == 0 { - err = errors.E("cannot look up an empty list") - return - } - for _, addr := range addresses { - key := getSubscriptionKey(coin, addr) - var webhooks []string - _ = s.GetHMValue(ATLAS_OBSERVER, key, &webhooks) - for _, webhook := range webhooks { - observers = append(observers, blockatlas.Subscription{Coin: coin, Address: addr, Webhook: webhook}) - } - } - return -} - -func (s *Storage) AddSubscriptions(subscriptions []blockatlas.Subscription) { - for _, sub := range subscriptions { - key := getSubscriptionKey(sub.Coin, sub.Address) - var webhooks []string - _ = s.GetHMValue(ATLAS_OBSERVER, key, &webhooks) - if webhooks == nil { - webhooks = make([]string, 0) - } - if hasObject(webhooks, sub.Webhook) { - continue - } - webhooks = append(webhooks, sub.Webhook) - err := s.AddHM(ATLAS_OBSERVER, key, webhooks) - if err != nil { - logger.Error(err, "AddSubscriptions error", errors.Params{"webhooks": webhooks, "address": sub.Address, "coin": sub.Coin}) - } - } -} - -func (s *Storage) DeleteSubscriptions(subscriptions []blockatlas.Subscription) { - for _, sub := range subscriptions { - key := getSubscriptionKey(sub.Coin, sub.Address) - var webhooks []string - err := s.GetHMValue(ATLAS_OBSERVER, key, &webhooks) - if err != nil { - continue - } - newHooks := make([]string, 0) - for _, webhook := range webhooks { - if webhook == sub.Webhook { - continue - } - newHooks = append(newHooks, webhook) - } - if len(newHooks) == 0 { - _ = s.DeleteHM(ATLAS_OBSERVER, key) - continue - } - err = s.AddHM(ATLAS_OBSERVER, key, newHooks) - if err != nil { - logger.Error(err, "DeleteSubscriptions - AddHM", errors.Params{"webhook": newHooks, "address": sub.Address, "coin": sub.Coin}) - } - } -} - -func getSubscriptionKey(coin uint, address string) string { - return fmt.Sprintf("%d-%s", coin, address) -} - -func hasObject(array []string, obj string) bool { - for _, temp := range array { - if temp == obj { - return true - } - } - return false -} diff --git a/test/main.go b/test/main.go deleted file mode 100644 index fa7fc1f75..000000000 --- a/test/main.go +++ /dev/null @@ -1,189 +0,0 @@ -package main - -import ( - "encoding/json" - "fmt" - "github.com/spf13/cobra" - "github.com/trustwallet/blockatlas/pkg/blockatlas" - "github.com/trustwallet/blockatlas/pkg/logger" - "github.com/trustwallet/blockatlas/pkg/semaphore" - "net/http" - "os" - "strings" - "sync" - "sync/atomic" - "time" - - "github.com/sirupsen/logrus" - "github.com/trustwallet/blockatlas/coin" -) - -var failedFlag int32 = 0 -var baseURL string -var requireAll bool -var concurrency int - -var app = cobra.Command{ - Use: "test ", - Short: "Test a live API", - Long: "Test a live API by requesting the sample addresses found in coin list", - Args: cobra.ExactArgs(1), - Run: run, -} - -func init() { - flags := app.Flags() - flags.BoolVarP(&requireAll, "all", "a", false, "Don't skip platforms not supported server-side") - flags.IntVarP(&concurrency, "concurrency", "c", 8, "Tests to run at once") -} - -func main() { - err := app.Execute() - if err != nil { - _, _ = fmt.Fprintln(os.Stderr, err) - os.Exit(1) - } -} - -func run(_ *cobra.Command, args []string) { - baseURL = args[0] - - logrus.SetOutput(os.Stdout) - http.DefaultClient.Timeout = 5 * time.Second - - supportedEndpoints, err := supportedEndpoints() - if err != nil { - logger.Error(err, "Failed to get supported platforms") - os.Exit(1) - } - - var supported = make(map[string]bool) - for _, ns := range supportedEndpoints { - supported[ns] = true - } - - logger.Info("Running goroutines tests", logger.Params{"goroutines": concurrency}) - - var wg sync.WaitGroup - sem := semaphore.NewSemaphore(concurrency) - - var tests []coin.Coin - - for _, c := range coin.Coins { - if !supported[c.Handle] { - if requireAll { - log(&c).Error("Platform not enabled at server but required") - atomic.StoreInt32(&failedFlag, 1) - } else { - log(&c).Warning("Platform not enabled at server, skipping") - } - continue - } - tests = append(tests, c) - } - logger.Info("Platforms to test", logger.Params{"count": len(supportedEndpoints)}) - - wg.Add(len(tests)) - for _, c := range tests { - go runTest(c, sem, &wg) - } - - wg.Wait() - - failed := atomic.LoadInt32(&failedFlag) - if failed == 1 { - logger.Fatal("Test failed") - } else { - logger.Info("Test passed") - } -} - -func log(c *coin.Coin) *logrus.Entry { - return logrus.WithField("@platform", c.Handle) -} - -func runTest(c coin.Coin, sem *semaphore.Semaphore, wg *sync.WaitGroup) { - defer wg.Done() - sem.Acquire() - defer sem.Release() - - start := time.Now() - - defer func() { - if r := recover(); r != nil { - log(&c). - WithField("error", r). - Error("Endpoint failed") - atomic.StoreInt32(&failedFlag, 1) - } - - log(&c).WithField("time", time.Since(start)).Info("Endpoint tested") - }() - - test(&c) - log(&c).Info("Endpoint works") -} - -func test(c *coin.Coin) { - res, err := http.Get(fmt.Sprintf("%s/v1/%s/%s", baseURL, c.Handle, c.SampleAddr)) - if err != nil { - panic(err) - } - defer res.Body.Close() - - if res.StatusCode != http.StatusOK { - panic("Status " + res.Status) - } - - if !strings.HasPrefix(res.Header.Get("Content-Type"), "application/json") { - panic("Unexpected Content-Type " + res.Header.Get("Content-Type")) - } - - // Parse model and read into buffer - var model struct { - Docs []blockatlas.Tx `json:"docs"` - } - dec := json.NewDecoder(res.Body) - err = dec.Decode(&model) - if err != nil { - panic(err) - } - - if len(model.Docs) == 0 { - log(c).Warning("No transactions") - return - } - - // Enumerate transactions - var lastTime = ^uint64(0) - for _, tx := range model.Docs { - point := tx.Date - - if uint64(point) <= lastTime { - lastTime = uint64(point) - } else { - panic("Transactions not in chronological order") - } - - if tx.Coin != c.ID { - panic("Wrong coin index") - } - } -} - -func supportedEndpoints() (endpoints []string, err error) { - var data struct { - Endpoints []string `json:"endpoints"` - } - res, err := http.Get(fmt.Sprintf("%s/v1/", baseURL)) - if err != nil { - return nil, err - } - defer res.Body.Close() - dec := json.NewDecoder(res.Body) - err = dec.Decode(&data) - if err != nil { - return nil, err - } - return data.Endpoints, nil -} diff --git a/test/tx_test.go b/test/tx_test.go deleted file mode 100644 index 76abb6b1e..000000000 --- a/test/tx_test.go +++ /dev/null @@ -1,188 +0,0 @@ -package main - -import ( - "github.com/stretchr/testify/assert" - "github.com/trustwallet/blockatlas/coin" - "github.com/trustwallet/blockatlas/observer" - "github.com/trustwallet/blockatlas/pkg/blockatlas" - "testing" -) - -var transferDst1 = blockatlas.Tx{ - ID: "1681EE543FB4B5A628EF21D746E031F018E226D127044A4F9BA5EE2542A44555", - Coin: coin.BNB, - From: "tbnb1fhr04azuhcj0dulm7ka40y0cqjlafwae9k9gk2", - To: "tbnb1sylyjw032eajr9cyllp26n04300qzzre38qyv5", - Fee: "125000", - Date: 1555049867, - Block: 7761368, - Status: blockatlas.StatusCompleted, - Memo: "test", - Meta: blockatlas.Transfer{ - Value: "10000000000000", - Decimals: 8, - Symbol: "BNB", - }, -} - -var transferDst2 = blockatlas.Tx{ - ID: "1681EE543FB4B5A628EF21D746E031F018E226D127044A4F9BA5EE2542A44556", - Coin: coin.BNB, - From: "tbnb1fhr04azuhcj0dulm7ka40y0cqjlafwae9k9gk2", - To: "tbnb1fhr04azuhcj0dulm7ka40y0cqjlafwae9k9gk2", - Fee: "125000", - Date: 1555049867, - Block: 7761368, - Status: blockatlas.StatusCompleted, - Memo: "test", - Meta: blockatlas.Transfer{ - Value: "10000000000000", - Decimals: 8, - Symbol: "BNB", - }, -} - -var nativeTransferDst1 = blockatlas.Tx{ - ID: "95CF63FAA27579A9B6AF84EF8B2DFEAC29627479E9C98E7F5AE4535E213FA4C9", - Coin: coin.BNB, - From: "tbnb1ttyn4csghfgyxreu7lmdu3lcplhqhxtzced45a", - To: "tbnb12hlquylu78cjylk5zshxpdj6hf3t0tahwjt3ex", - Fee: "125000", - Date: 1555117625, - Block: 7928667, - Status: blockatlas.StatusCompleted, - Memo: "test", - Meta: blockatlas.NativeTokenTransfer{ - TokenID: "YLC-D8B", - Symbol: "YLC", - Value: "210572645", - Decimals: 8, - From: "tbnb1ttyn4csghfgyxreu7lmdu3lcplhqhxtzced45a", - To: "tbnb12hlquylu78cjylk5zshxpdj6hf3t0tahwjt3ex", - }, -} - -var nativeTransferDst2 = blockatlas.Tx{ - ID: "95CF63FAA27579A9B6AF84EF8B2DFEAC29627479E9C98E7F5AE4535E213FA4D0", - Coin: coin.BNB, - From: "tbnb1ttyn4csghfgyxreu7lmdu3lcplhqhxtzced45a", - To: "tbnb12hlquylu78cjylk5zshxpdj6hf3t0tahwjt3ex", - Fee: "125000", - Date: 1555117625, - Block: 7928667, - Status: blockatlas.StatusCompleted, - Memo: "test", - Meta: blockatlas.NativeTokenTransfer{ - TokenID: "YLC-D8B", - Symbol: "YLC", - Value: "210572645", - Decimals: 8, - From: "tbnb1ttyn4csghfgyxreu7lmdu3lcplhqhxtzced45a", - To: "tbnb12hlquylu78cjylk5zshxpdj6hf3t0tahwjt3ex", - }, -} - -var utxoTransferDst1 = blockatlas.Tx{ - ID: "zpub6ruK9k6YGm8BRHWvTiQcrEPnFkuRDJhR7mPYzV2LDvjpLa5CuGgrhCYVZjMGcLcFqv9b2WvsFtY2Gb3xq8NVq8qhk9veozrA2W9QaWtihrC", - Coin: coin.BTC, - Inputs: []blockatlas.TxOutput{ - { - "bc1qhn03cww757mnnlpkdvvfkaydxqygm86nvkm92h", - "1", - }, - { - "bc1qc7ekqf2t0elfsmtgr2mgd7da2up4vgq8uqk2nh", - "1", - }, - { - "bc1qv454wacvnenr3hzzldjqn8cgfltdlxwe96h737", - "1", - }, - }, - Outputs: []blockatlas.TxOutput{ - { - "bc1qjcslq88cht8llqmh3aqshjx9we9msv386jvxl6", - "3", - }, - }, - Fee: "125000", - Date: 1555117625, - Block: 592400, - Status: blockatlas.StatusCompleted, - Memo: "test", -} - -var utxoTransferDst2 = blockatlas.Tx{ - ID: "zpub6ruK9k6YGm8BRHWvTiQcrEPnFkuRDJhR7mPYzV2LDvjpLa5CuGgrhCYVZjMGcLcFqv9b2WvsFtY2Gb3xq8NVq8qhk9veozrA2W9QaWtihrC", - Coin: coin.BTC, - Inputs: []blockatlas.TxOutput{ - { - "bc1q6e8sdxlgc7ekqkqyevtrx8wshfv7sg66z3z6ce", - "4", - }, - { - "bc1q7nn4txus4g6fc5v7d2tha35ely8mfpd8qvv6eg", - "2", - }, - }, - Outputs: []blockatlas.TxOutput{ - { - "bc1q2fpry7zwqh575huc9urwfdvjtuvz508wez56ff", - "3", - }, - { - "bc1qk3yj6h79qw7tnsg4durc9sd5fpd3qt0p0m8u5p", - "1", - }, - { - "bc1qm8836plkzft2rhh23z6j8s9s8fxrzd4zag95z8", - "2", - }, - }, - Fee: "125000", - Date: 1555117625, - Block: 592400, - Status: blockatlas.StatusCompleted, - Memo: "test", -} - -var txsBlock = blockatlas.Block{ - Number: 12345, - ID: "12345", - Txs: []blockatlas.Tx{ - transferDst1, - transferDst2, - nativeTransferDst1, - nativeTransferDst2, - }, -} - -func TestGetTxs(t *testing.T) { - txs := observer.GetTxs(&txsBlock) - assert.Equal(t, len(txs), 4) - assert.Equal(t, txs["tbnb1fhr04azuhcj0dulm7ka40y0cqjlafwae9k9gk2"].Size(), 2) - assert.Equal(t, txs["tbnb1sylyjw032eajr9cyllp26n04300qzzre38qyv5"].Size(), 1) - assert.Equal(t, txs["tbnb1ttyn4csghfgyxreu7lmdu3lcplhqhxtzced45a"].Size(), 2) - assert.Equal(t, txs["tbnb12hlquylu78cjylk5zshxpdj6hf3t0tahwjt3ex"].Size(), 2) -} - -func TestTxSet_Add(t *testing.T) { - set := blockatlas.TxSet{} - set.Add(&transferDst1) - var txs = set.Txs() - assert.Equal(t, txs[0].ID, transferDst1.ID) - set.Add(&transferDst1) - assert.Equal(t, set.Size(), 1) - set.Add(&nativeTransferDst1) - assert.Equal(t, set.Size(), 2) -} - -func TestTx_GetAddresses(t *testing.T) { - assert.Equal(t, transferDst1.GetAddresses(), []string{"tbnb1fhr04azuhcj0dulm7ka40y0cqjlafwae9k9gk2", "tbnb1sylyjw032eajr9cyllp26n04300qzzre38qyv5"}) - assert.Equal(t, nativeTransferDst1.GetAddresses(), []string{"tbnb1ttyn4csghfgyxreu7lmdu3lcplhqhxtzced45a", "tbnb12hlquylu78cjylk5zshxpdj6hf3t0tahwjt3ex"}) -} - -func TestTx_GetUtxoAddresses(t *testing.T) { - assert.Equal(t, utxoTransferDst1.GetUtxoAddresses(), []string{"bc1qhn03cww757mnnlpkdvvfkaydxqygm86nvkm92h", "bc1qc7ekqf2t0elfsmtgr2mgd7da2up4vgq8uqk2nh", "bc1qv454wacvnenr3hzzldjqn8cgfltdlxwe96h737", "bc1qjcslq88cht8llqmh3aqshjx9we9msv386jvxl6"}) - assert.Equal(t, utxoTransferDst2.GetUtxoAddresses(), []string{"bc1q6e8sdxlgc7ekqkqyevtrx8wshfv7sg66z3z6ce", "bc1q7nn4txus4g6fc5v7d2tha35ely8mfpd8qvv6eg", "bc1q2fpry7zwqh575huc9urwfdvjtuvz508wez56ff", "bc1qk3yj6h79qw7tnsg4durc9sd5fpd3qt0p0m8u5p", "bc1qm8836plkzft2rhh23z6j8s9s8fxrzd4zag95z8"}) -} diff --git a/tests/integration/db_test/db_run_test.go b/tests/integration/db_test/db_run_test.go new file mode 100644 index 000000000..986418483 --- /dev/null +++ b/tests/integration/db_test/db_run_test.go @@ -0,0 +1,26 @@ +// +build integration + +package db_test + +import ( + "os" + "testing" + + "github.com/stretchr/testify/assert" + "github.com/trustwallet/blockatlas/db" + "github.com/trustwallet/blockatlas/tests/integration/setup" +) + +var database *db.Instance + +func TestMain(m *testing.M) { + database = setup.RunPgContainer() + code := m.Run() + setup.StopPgContainer() + os.Exit(code) +} + +func TestPgSetup(t *testing.T) { + assert.NotNil(t, database) + assert.NotNil(t, database.Gorm) +} diff --git a/tests/integration/db_test/tokenindexer_test.go b/tests/integration/db_test/tokenindexer_test.go new file mode 100644 index 000000000..5a795fa93 --- /dev/null +++ b/tests/integration/db_test/tokenindexer_test.go @@ -0,0 +1,170 @@ +// +build integration + +package db_test + +import ( + "sort" + "testing" + + gocache "github.com/patrickmn/go-cache" + assert "github.com/stretchr/testify/assert" + "github.com/trustwallet/blockatlas/db/models" + "github.com/trustwallet/blockatlas/tests/integration/setup" +) + +func Test_AddNewAssets_Simple(t *testing.T) { + a := []models.Asset{ + { + Asset: "c714_a", + Decimals: 18, + Name: "A", + Symbol: "ABC", + Type: "BEP20", + }, + { + Asset: "c714_b", + Decimals: 18, + Name: "B", + Symbol: "BCD", + Type: "BEP20", + }, + } + err := database.AddNewAssets(a) + assert.Nil(t, err) + assets, err := database.GetAssetsByIDs([]string{"c714_b", "c714_a"}) + assert.Nil(t, err) + assert.NotNil(t, assets) + a = append(a, models.Asset{ + Asset: "c714_d", + Decimals: 18, + Name: "D", + Symbol: "DTS", + Type: "BEP20", + }) + err = database.AddNewAssets(a) + assert.Nil(t, err) +} + +func Test_AddNewAssets(t *testing.T) { + setup.CleanupPgContainer(database.Gorm) + database.MemoryCache = gocache.New(gocache.NoExpiration, gocache.NoExpiration) + type testsStruct struct { + Name string + Assets []models.Asset + AssetsIDs []string + WantedErr error + WantedAssets []models.Asset + } + tests := []testsStruct{ + { + Name: "Normal case", + Assets: []models.Asset{ + { + Asset: "c714_a", + Decimals: 15, + Name: "A", + Symbol: "ABC", + Type: "BEP20", + }, + { + Asset: "c714_b", + Decimals: 16, + Name: "BB", + Symbol: "BCD", + Type: "BEP20", + }, + }, + AssetsIDs: []string{"c714_a", "c714_b"}, + WantedErr: nil, + WantedAssets: []models.Asset{ + { + Asset: "c714_a", + Decimals: 15, + Name: "A", + Symbol: "ABC", + Type: "BEP20", + }, + { + Asset: "c714_b", + Decimals: 16, + Name: "BB", + Symbol: "BCD", + Type: "BEP20", + }, + }, + }, + { + Name: "Case with new tokens and old tokens", + Assets: []models.Asset{ + { + Asset: "c714_c", + Decimals: 17, + Name: "CCC", + Symbol: "FFF", + Type: "ERC20", + }, + { + Asset: "c714_d", + Decimals: 18, + Name: "DDDD", + Symbol: "RRR", + Type: "TRC20", + }, + }, + AssetsIDs: []string{"c714_a", "c714_b", "c714_c", "c714_d"}, + WantedErr: nil, + WantedAssets: []models.Asset{ + { + Asset: "c714_a", + Decimals: 15, + Name: "A", + Symbol: "ABC", + Type: "BEP20", + }, + { + Asset: "c714_b", + Decimals: 16, + Name: "BB", + Symbol: "BCD", + Type: "BEP20", + }, + { + Asset: "c714_c", + Decimals: 17, + Name: "CCC", + Symbol: "FFF", + Type: "ERC20", + }, + { + Asset: "c714_d", + Decimals: 18, + Name: "DDDD", + Symbol: "RRR", + Type: "TRC20", + }, + }, + }, + } + + for _, tt := range tests { + t.Run(tt.Name, func(t *testing.T) { + err := database.AddNewAssets(tt.Assets) + assert.Equal(t, tt.WantedErr, err) + assets, err := database.GetAssetsByIDs(tt.AssetsIDs) + assert.Nil(t, err) + sort.Slice(tt.WantedAssets, func(i, j int) bool { + return len(tt.WantedAssets[i].Name) > len(tt.WantedAssets[j].Name) + }) + sort.Slice(assets, func(i, j int) bool { + return len(assets[i].Name) > len(assets[j].Name) + }) + for i, a := range assets { + assert.Equal(t, tt.WantedAssets[i].Asset, a.Asset) + assert.Equal(t, tt.WantedAssets[i].Name, a.Name) + assert.Equal(t, tt.WantedAssets[i].Symbol, a.Symbol) + assert.Equal(t, tt.WantedAssets[i].Type, a.Type) + assert.Equal(t, tt.WantedAssets[i].Decimals, a.Decimals) + } + }) + } +} diff --git a/tests/integration/db_test/tracker_test.go b/tests/integration/db_test/tracker_test.go new file mode 100644 index 000000000..72e8b573a --- /dev/null +++ b/tests/integration/db_test/tracker_test.go @@ -0,0 +1,26 @@ +// +build integration + +package db_test + +import ( + "testing" + + "github.com/stretchr/testify/assert" + "github.com/trustwallet/blockatlas/tests/integration/setup" +) + +func TestDb_SetBlock(t *testing.T) { + setup.CleanupPgContainer(database.Gorm) + + assert.Nil(t, database.SetLastParsedBlockNumber("ethereum", 0)) + + block, err := database.GetLastParsedBlockNumber("ethereum") + assert.Nil(t, err) + assert.Equal(t, block.Height, int64(0)) + + assert.Nil(t, database.SetLastParsedBlockNumber("ethereum", 110)) + + newBlock, err := database.GetLastParsedBlockNumber("ethereum") + assert.Nil(t, err) + assert.Equal(t, newBlock.Height, int64(110)) +} diff --git a/tests/integration/setup/mq.go b/tests/integration/setup/mq.go new file mode 100644 index 000000000..4ac9146e8 --- /dev/null +++ b/tests/integration/setup/mq.go @@ -0,0 +1,38 @@ +package setup + +import ( + "fmt" + "log" + + "github.com/ory/dockertest" + "github.com/trustwallet/golibs/network/mq" +) + +var ( + mqResource *dockertest.Resource +) + +func runMQContainer() error { + var err error + pool, err := dockertest.NewPool("") + if err != nil { + log.Fatalf("Could not connect to docker: %s", err) + } + + mqResource, err = pool.Run("rabbitmq", "latest", nil) + if err != nil { + log.Fatalf("Could not start resource: %s", err) + } + + if err = pool.Retry(func() error { + return mq.Init(fmt.Sprintf("amqp://localhost:%s", mqResource.GetPort("5672/tcp"))) + }); err != nil { + return err + } + return nil +} + +func stopMQContainer() error { + mq.Close() + return mqResource.Close() +} diff --git a/tests/integration/setup/postgres.go b/tests/integration/setup/postgres.go new file mode 100644 index 000000000..036a5930b --- /dev/null +++ b/tests/integration/setup/postgres.go @@ -0,0 +1,87 @@ +package setup + +import ( + "fmt" + "log" + + "github.com/ory/dockertest" + "github.com/trustwallet/blockatlas/db" + "github.com/trustwallet/blockatlas/db/models" + "gorm.io/gorm" +) + +const ( + pgUser = "user" + pgPass = "pass" + pgDB = "blockatlas" +) + +var ( + pgResource *dockertest.Resource + pgContainerENV = []string{ + "POSTGRES_USER=" + pgUser, + "POSTGRES_PASSWORD=" + pgPass, + "POSTGRES_DB=" + pgDB, + } + + tables = []interface{}{ + &models.Tracker{}, + &models.Asset{}, + &models.Subscription{}, + &models.SubscriptionsAssetAssociation{}, + } + + url string +) + +func runPgContainerAndInitConnection() (*db.Instance, error) { + pool := runPgContainer() + var ( + dbConn *db.Instance + err error + ) + err = pool.Retry(func() error { + dbConn, err = db.New(url, false) + return err + }) + if err != nil { + return nil, err + } + autoMigrate(dbConn.Gorm) + return dbConn, nil +} + +func CleanupPgContainer(dbConn *gorm.DB) { + if err := dbConn.Migrator().DropTable(tables...); err != nil { + log.Fatal(err) + } + autoMigrate(dbConn) +} + +func autoMigrate(dbConn *gorm.DB) { + if err := dbConn.AutoMigrate(tables...); err != nil { + log.Fatal(err) + } +} + +func stopPgContainer() error { + return pgResource.Close() +} + +func runPgContainer() *dockertest.Pool { + var err error + pool, err := dockertest.NewPool("") + if err != nil { + log.Fatalf("Could not connect to docker: %s", err) + } + + pgResource, err = pool.Run("postgres", "latest", pgContainerENV) + if err != nil { + log.Fatalf("Could not start resource: %s", err) + } + + url = fmt.Sprintf("postgres://%s:%s@localhost:%s/%s?sslmode=disable", + pgUser, pgPass, pgResource.GetPort("5432/tcp"), pgDB, + ) + return pool +} diff --git a/tests/integration/setup/setup.go b/tests/integration/setup/setup.go new file mode 100644 index 000000000..0e916c8d8 --- /dev/null +++ b/tests/integration/setup/setup.go @@ -0,0 +1,32 @@ +package setup + +import ( + "github.com/trustwallet/blockatlas/db" + "log" +) + +func RunMQContainer() { + if err := runMQContainer(); err != nil { + log.Fatal(err) + } +} + +func StopMQContainer() { + if err := stopMQContainer(); err != nil { + log.Fatal(err) + } +} + +func RunPgContainer() *db.Instance { + dbConn, err := runPgContainerAndInitConnection() + if err != nil { + log.Fatal(err) + } + return dbConn +} + +func StopPgContainer() { + if err := stopPgContainer(); err != nil { + log.Fatal(err) + } +} diff --git a/tests/postman/blockatlas.postman_collection.json b/tests/postman/blockatlas.postman_collection.json new file mode 100644 index 000000000..fa8eed6ea --- /dev/null +++ b/tests/postman/blockatlas.postman_collection.json @@ -0,0 +1,1949 @@ +{ + "info": { + "_postman_id": "57634a03-7dfa-4b5b-b48e-f6321ea4ba1e", + "name": "Blockatlas", + "schema": "https://schema.getpostman.com/json/collection/v2.1.0/collection.json" + }, + "item": [ + { + "name": "platform", + "item": [ + { + "name": "transaction", + "item": [ + { + "name": "txs", + "event": [ + { + "listen": "prerequest", + "script": { + "id": "7312c9e7-5330-421a-9ca8-171101050e38", + "exec": [ + "" + ], + "type": "text/javascript" + } + }, + { + "listen": "test", + "script": { + "id": "acec8baa-0ef0-4703-ab83-c555260deffa", + "exec": [ + "var Ajv = require('ajv');", + "var ajv = new Ajv({logger: console});", + "let schema = {", + " \"type\": \"object\",", + " \"properties\": {", + " \"total\": {", + " \"type\": \"integer\"", + " },", + " \"docs\": {", + " \"type\": \"array\",", + " \"minItems\": 1,", + " \"uniqueItems\": true,", + " \"items\": {", + " \"type\": \"object\",", + " \"properties\": {", + " \"id\": {", + " \"type\": \"string\"", + " },", + " \"coin\": {", + " \"type\": \"integer\"", + " },", + " \"from\": {", + " \"type\": \"string\"", + " },", + " \"to\": {", + " \"type\": \"string\"", + " },", + " \"fee\": {", + " \"type\": \"string\"", + " },", + " \"date\": {", + " \"type\": \"integer\"", + " },", + " \"block\": {", + " \"type\": \"integer\"", + " },", + " \"status\": {", + " \"type\": \"string\"", + " },", + " \"sequence\": {", + " \"type\": \"integer\"", + " },", + " \"type\": {", + " \"type\": \"string\"", + " },", + " \"memo\": {", + " \"type\": \"string\"", + " },", + " \"metadata\": {", + " \"type\": \"object\"", + " }", + " }", + " }", + " },", + " \"status\": {", + " \"type\": \"boolean\"", + " }", + " }", + "};", + "", + "let handler = pm.variables.get(\"handler\");", + "let address = pm.variables.get(\"address\");", + "let expectedTxNum = pm.variables.get(\"expectedTxNum\") || 1;", + "let expectedTxId = pm.variables.get(\"expectedTxId\");", + "var jsonData = pm.response.json();", + "", + "// IMPORTANT Note on verification -- to serve mocked AND non-mocked tests:", + "// - if number of returned TXs is:", + "// -- less then expectedTxNum or zero --> Fail", + "// -- equals expectedTxNum, and expectedTxId is set, expectedTxId MUST be present in result", + "// -- greater than expectedTxNum (likely non-mocked), expectedTxId is NOT checked", + "", + "pm.test(handler + \" - response must be valid and have a body: \" + address, function () {", + " pm.response.to.have.status(200);", + " pm.response.to.be.ok;", + " pm.response.to.not.be.error;", + " pm.response.to.be.withBody;", + " pm.response.to.be.json;", + "});", + "", + "pm.test(handler + \" - verify has docs content: \" + address, function() {", + " pm.expect(jsonData.total).to.be.above(expectedTxNum - 1);", + "});", + "", + "pm.test(handler + \" - schema is valid: \" + address, function() {", + " pm.expect(ajv.validate(schema, jsonData)).to.be.true;", + "});", + "", + "// verify transaction ID in result (only if number of TXs matches and expected id is present) ", + "if (jsonData.total && jsonData.total == expectedTxNum) {", + " if (expectedTxId && expectedTxId.length > 0) {", + " var transactionIdFound = false;", + " for (var d in jsonData.docs) {", + " if (jsonData.docs[d].id === expectedTxId) { transactionIdFound = true; }", + " }", + " pm.test(handler + \" - verify expected txId: \" + expectedTxId, function() {", + " pm.expect(transactionIdFound).to.be.true;", + " });", + " }", + "} else if (jsonData.total && jsonData.total > expectedTxNum) {", + " // more TXs returned, likely real case, not checking TxId", + " console.log('More TXs returned, not checking TxId', jsonData.total, expectedTxNum);", + "}", + "" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "GET", + "header": [ + { + "key": "Authorization", + "value": "Bearer {{platform_auth}}", + "type": "text" + } + ], + "url": { + "raw": "{{host}}/v1/{{handler}}/{{address}}", + "host": [ + "{{host}}" + ], + "path": [ + "v1", + "{{handler}}", + "{{address}}" + ] + } + }, + "response": [] + } + ], + "event": [ + { + "listen": "prerequest", + "script": { + "id": "3f05cf7e-0439-4cd2-b41f-5ba71e465621", + "type": "text/javascript", + "exec": [ + "" + ] + } + }, + { + "listen": "test", + "script": { + "id": "de5760bf-5d29-462f-af90-ccbeaa8253f9", + "type": "text/javascript", + "exec": [ + "" + ] + } + } + ], + "protocolProfileBehavior": {}, + "_postman_isSubFolder": true + }, + { + "name": "token", + "item": [ + { + "name": "token", + "event": [ + { + "listen": "prerequest", + "script": { + "id": "7312c9e7-5330-421a-9ca8-171101050e38", + "exec": [ + "" + ], + "type": "text/javascript" + } + }, + { + "listen": "test", + "script": { + "id": "acec8baa-0ef0-4703-ab83-c555260deffa", + "exec": [ + "var Ajv = require('ajv');", + "var ajv = new Ajv({logger: console});", + "let schema = {", + " \"type\": \"object\",", + " \"properties\": {", + " \"docs\": {", + " \"type\": \"array\",", + " \"minItems\": 1,", + " \"uniqueItems\": true,", + " \"items\": {", + " \"type\": \"object\",", + " \"properties\": {", + " \"name\": {", + " \"type\": \"string\"", + " },", + " \"symbol\": {", + " \"type\": \"string\"", + " },", + " \"decimals\": {", + " \"type\": \"integer\"", + " },", + " \"token_id\": {", + " \"type\": \"string\"", + " },", + " \"coin\": {", + " \"type\": \"integer\"", + " },", + " \"type\": {", + " \"type\": \"string\"", + " }", + " }", + " }", + " }", + " }", + "};", + "", + "let handler = pm.variables.get(\"handler\");", + "let address = pm.variables.get(\"address\");", + "var jsonData = pm.response.json();", + "", + "pm.test(handler + \" - response must be valid and have a body: \" + address, function () {", + " pm.response.to.have.status(200);", + " pm.response.to.be.ok;", + " pm.response.to.not.be.error;", + " pm.response.to.be.withBody;", + " pm.response.to.be.json;", + "});", + "", + "pm.test(handler + \" - schema is valid: \" + address, function() {", + " pm.expect(ajv.validate(schema, jsonData)).to.be.true;", + "});", + "" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "GET", + "header": [], + "url": { + "raw": "{{host}}/v2/{{handler}}/tokens/{{address}}?Authorization=Bearer {{platform_auth}}", + "host": [ + "{{host}}" + ], + "path": [ + "v2", + "{{handler}}", + "tokens", + "{{address}}" + ], + "query": [ + { + "key": "Authorization", + "value": "Bearer {{platform_auth}}" + } + ] + } + }, + "response": [] + } + ], + "event": [ + { + "listen": "prerequest", + "script": { + "id": "3f05cf7e-0439-4cd2-b41f-5ba71e465621", + "type": "text/javascript", + "exec": [ + "" + ] + } + }, + { + "listen": "test", + "script": { + "id": "de5760bf-5d29-462f-af90-ccbeaa8253f9", + "type": "text/javascript", + "exec": [ + "" + ] + } + } + ], + "protocolProfileBehavior": {}, + "_postman_isSubFolder": true + }, + { + "name": "staking", + "item": [ + { + "name": "validators", + "event": [ + { + "listen": "prerequest", + "script": { + "id": "7312c9e7-5330-421a-9ca8-171101050e38", + "exec": [ + "" + ], + "type": "text/javascript" + } + }, + { + "listen": "test", + "script": { + "id": "acec8baa-0ef0-4703-ab83-c555260deffa", + "exec": [ + "var Ajv = require('ajv');", + "var ajv = new Ajv({logger: console});", + "let schema = {", + " \"type\": \"object\",", + " \"properties\": {", + " \"docs\": {", + " \"type\": \"array\",", + " \"minItems\": 1,", + " \"uniqueItems\": true,", + " \"items\": {", + " \"type\": \"object\",", + " \"properties\": {", + " \"id\": {", + " \"type\": \"string\"", + " },", + " \"status\": {", + " \"type\": \"boolean\"", + " },", + " \"info\": {", + " \"type\": \"object\",", + " \"properties\": {", + " \"name\": {", + " \"type\": \"string\"", + " },", + " \"description\": {", + " \"type\": \"string\"", + " },", + " \"image\": {", + " \"type\": \"string\"", + " },", + " \"website\": {", + " \"type\": \"string\"", + " }", + " }", + " },", + " \"details\": {", + " \"type\": \"object\",", + " \"properties\": {", + " \"locktime\": {", + " \"type\": \"integer\"", + " },", + " \"minimum_amount\": {", + " \"type\": \"string\"", + " },", + " \"type\": {", + " \"type\": \"string\"", + " },", + " \"reward\": {", + " \"type\": \"object\",", + " \"properties\": {", + " \"annual\": {", + " \"type\": \"number\"", + " }", + " }", + " }", + " }", + " }", + " }", + " }", + " }", + " }", + "};", + "", + "let handler = pm.variables.get(\"handler\");", + "var jsonData = pm.response.json();", + "", + "pm.test(handler + \" - response must be valid and have a body\", function () {", + " pm.response.to.have.status(200);", + " pm.response.to.be.ok;", + " pm.response.to.not.be.error;", + " pm.response.to.be.withBody;", + " pm.response.to.be.json;", + "});", + "", + "pm.test(handler + \" - schema is valid\", function() {", + " pm.expect(ajv.validate(schema, jsonData)).to.be.true;", + "});", + "" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "GET", + "header": [ + { + "key": "Authorization", + "value": "Bearer {{platform_auth}}", + "type": "text" + } + ], + "url": { + "raw": "{{host}}/v2/{{handler}}/staking/validators", + "host": [ + "{{host}}" + ], + "path": [ + "v2", + "{{handler}}", + "staking", + "validators" + ] + } + }, + "response": [] + }, + { + "name": "validators list", + "event": [ + { + "listen": "prerequest", + "script": { + "id": "7312c9e7-5330-421a-9ca8-171101050e38", + "exec": [ + "" + ], + "type": "text/javascript" + } + }, + { + "listen": "test", + "script": { + "id": "acec8baa-0ef0-4703-ab83-c555260deffa", + "exec": [ + "var Ajv = require('ajv');", + "var ajv = new Ajv({logger: console});", + "let schema = {", + " \"type\": \"object\",", + " \"properties\": {", + " \"docs\": {", + " \"type\": \"array\",", + " \"minItems\": 1,", + " \"uniqueItems\": true,", + " \"items\": {", + " \"type\": \"object\",", + " \"properties\": {", + " \"id\": {", + " \"type\": \"string\"", + " },", + " \"status\": {", + " \"type\": \"boolean\"", + " },", + " \"info\": {", + " \"type\": \"object\",", + " \"properties\": {", + " \"name\": {", + " \"type\": \"string\"", + " },", + " \"description\": {", + " \"type\": \"string\"", + " },", + " \"image\": {", + " \"type\": \"string\"", + " },", + " \"website\": {", + " \"type\": \"string\"", + " }", + " }", + " },", + " \"details\": {", + " \"type\": \"object\",", + " \"properties\": {", + " \"locktime\": {", + " \"type\": \"integer\"", + " },", + " \"minimum_amount\": {", + " \"type\": \"string\"", + " },", + " \"type\": {", + " \"type\": \"string\"", + " },", + " \"reward\": {", + " \"type\": \"object\",", + " \"properties\": {", + " \"annual\": {", + " \"type\": \"number\"", + " }", + " }", + " }", + " }", + " }", + " }", + " }", + " }", + " }", + "};", + "", + "let handler = pm.variables.get(\"handler\");", + "var jsonData = pm.response.json();", + "", + "pm.test(handler + \" - response must be valid and have a body\", function () {", + " pm.response.to.have.status(200);", + " pm.response.to.be.ok;", + " pm.response.to.not.be.error;", + " pm.response.to.be.withBody;", + " pm.response.to.be.json;", + "});", + "", + "pm.test(handler + \" - schema is valid\", function() {", + " pm.expect(ajv.validate(schema, jsonData)).to.be.true;", + "});", + "" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "POST", + "header": [ + { + "key": "Authorization", + "type": "text", + "value": "Bearer {{platform_auth}}" + }, + { + "key": "Content-Type", + "name": "Content-Type", + "value": "application/json", + "type": "text" + } + ], + "body": { + "mode": "raw", + "raw": "[\n\t{\n\t\t\"coin\": {{coin}}\n\t}\n]", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "{{host}}/v2/staking/list", + "host": [ + "{{host}}" + ], + "path": [ + "v2", + "staking", + "list" + ] + } + }, + "response": [] + }, + { + "name": "delegations", + "event": [ + { + "listen": "prerequest", + "script": { + "id": "7312c9e7-5330-421a-9ca8-171101050e38", + "exec": [ + "" + ], + "type": "text/javascript" + } + }, + { + "listen": "test", + "script": { + "id": "acec8baa-0ef0-4703-ab83-c555260deffa", + "exec": [ + "var Ajv = require('ajv');", + "var ajv = new Ajv({logger: console});", + "let schema = {", + " \"type\": \"object\",", + " \"properties\": {", + " \"delegations\": {", + " \"type\": \"array\",", + " \"uniqueItems\": true,", + " \"items\": {", + " \"type\": \"object\",", + " \"properties\": {", + " \"delegator\": {", + " \"type\": \"object\",", + " \"properties\": {", + " \"id\": {", + " \"type\": \"string\"", + " },", + " \"status\": {", + " \"type\": \"boolean\"", + " },", + " \"info\": {", + " \"type\": \"object\",", + " \"properties\": {", + " \"name\": {", + " \"type\": \"string\"", + " },", + " \"description\": {", + " \"type\": \"string\"", + " },", + " \"image\": {", + " \"type\": \"string\"", + " },", + " \"website\": {", + " \"type\": \"string\"", + " }", + " }", + " },", + " \"details\": {", + " \"type\": \"object\",", + " \"properties\": {", + " \"locktime\": {", + " \"type\": \"integer\"", + " },", + " \"minimum_amount\": {", + " \"type\": \"string\"", + " },", + " \"type\": {", + " \"type\": \"string\"", + " },", + " \"reward\": {", + " \"type\": \"object\",", + " \"properties\": {", + " \"annual\": {", + " \"type\": \"number\"", + " }", + " }", + " }", + " }", + " }", + " }", + " },", + " \"value\": {", + " \"type\": \"string\"", + " },", + " \"status\": {", + " \"type\": \"string\"", + " }", + " }", + " }", + " },", + " \"balance\": {", + " \"type\": \"string\"", + " },", + " \"address\": {", + " \"type\": \"string\"", + " },", + " \"coin\": {", + " \"type\": \"object\",", + " \"properties\": {", + " \"coin\": {", + " \"type\": \"integer\"", + " },", + " \"symbol\": {", + " \"type\": \"string\"", + " },", + " \"name\": {", + " \"type\": \"string\"", + " },", + " \"decimals\": {", + " \"type\": \"integer\"", + " }", + " }", + " },", + " \"details\": {", + " \"type\": \"object\",", + " \"properties\": {", + " \"locktime\": {", + " \"type\": \"integer\"", + " },", + " \"minimum_amount\": {", + " \"type\": \"string\"", + " },", + " \"type\": {", + " \"type\": \"string\"", + " },", + " \"reward\": {", + " \"type\": \"object\",", + " \"properties\": {", + " \"annual\": {", + " \"type\": \"number\"", + " }", + " }", + " }", + " }", + " }", + " }", + "};", + "", + "let handler = pm.variables.get(\"handler\");", + "let address = pm.variables.get(\"address\");", + "var jsonData = pm.response.json();", + "", + "pm.test(handler + \" - response must be valid and have a body: \" + address, function () {", + " pm.response.to.have.status(200);", + " pm.response.to.be.ok;", + " pm.response.to.not.be.error;", + " pm.response.to.be.withBody;", + " pm.response.to.be.json;", + "});", + "", + "pm.test(handler + \" - schema is valid: \" + address, function() {", + " pm.expect(ajv.validate(schema, jsonData)).to.be.true;", + "});", + "" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "GET", + "header": [], + "url": { + "raw": "{{host}}/v2/{{handler}}/staking/delegations/{{address}}?Authorization=Bearer {{platform_auth}}", + "host": [ + "{{host}}" + ], + "path": [ + "v2", + "{{handler}}", + "staking", + "delegations", + "{{address}}" + ], + "query": [ + { + "key": "Authorization", + "value": "Bearer {{platform_auth}}" + } + ] + } + }, + "response": [] + }, + { + "name": "delegations batch", + "event": [ + { + "listen": "prerequest", + "script": { + "id": "7312c9e7-5330-421a-9ca8-171101050e38", + "exec": [ + "" + ], + "type": "text/javascript" + } + }, + { + "listen": "test", + "script": { + "id": "acec8baa-0ef0-4703-ab83-c555260deffa", + "exec": [ + "var Ajv = require('ajv');", + "var ajv = new Ajv({logger: console});", + "let schema = {", + " \"type\": \"object\",", + " \"properties\": {", + " \"delegations\": {", + " \"type\": \"array\",", + " \"uniqueItems\": true,", + " \"items\": {", + " \"type\": \"object\",", + " \"properties\": {", + " \"delegator\": {", + " \"type\": \"object\",", + " \"properties\": {", + " \"id\": {", + " \"type\": \"string\"", + " },", + " \"status\": {", + " \"type\": \"boolean\"", + " },", + " \"info\": {", + " \"type\": \"object\",", + " \"properties\": {", + " \"name\": {", + " \"type\": \"string\"", + " },", + " \"description\": {", + " \"type\": \"string\"", + " },", + " \"image\": {", + " \"type\": \"string\"", + " },", + " \"website\": {", + " \"type\": \"string\"", + " }", + " }", + " },", + " \"details\": {", + " \"type\": \"object\",", + " \"properties\": {", + " \"locktime\": {", + " \"type\": \"integer\"", + " },", + " \"minimum_amount\": {", + " \"type\": \"string\"", + " },", + " \"type\": {", + " \"type\": \"string\"", + " },", + " \"reward\": {", + " \"type\": \"object\",", + " \"properties\": {", + " \"annual\": {", + " \"type\": \"number\"", + " }", + " }", + " }", + " }", + " }", + " }", + " },", + " \"value\": {", + " \"type\": \"string\"", + " },", + " \"status\": {", + " \"type\": \"string\"", + " }", + " }", + " }", + " },", + " \"balance\": {", + " \"type\": \"string\"", + " },", + " \"address\": {", + " \"type\": \"string\"", + " },", + " \"coin\": {", + " \"type\": \"object\",", + " \"properties\": {", + " \"coin\": {", + " \"type\": \"integer\"", + " },", + " \"symbol\": {", + " \"type\": \"string\"", + " },", + " \"name\": {", + " \"type\": \"string\"", + " },", + " \"decimals\": {", + " \"type\": \"integer\"", + " }", + " }", + " },", + " \"details\": {", + " \"type\": \"object\",", + " \"properties\": {", + " \"locktime\": {", + " \"type\": \"integer\"", + " },", + " \"minimum_amount\": {", + " \"type\": \"string\"", + " },", + " \"type\": {", + " \"type\": \"string\"", + " },", + " \"reward\": {", + " \"type\": \"object\",", + " \"properties\": {", + " \"annual\": {", + " \"type\": \"number\"", + " }", + " }", + " }", + " }", + " }", + " }", + "};", + "", + "let handler = pm.variables.get(\"handler\");", + "let address = pm.variables.get(\"address\");", + "var jsonData = pm.response.json();", + "", + "pm.test(handler + \" - response must be valid and have a body: \" + address, function () {", + " pm.response.to.have.status(200);", + " pm.response.to.be.ok;", + " pm.response.to.not.be.error;", + " pm.response.to.be.withBody;", + " pm.response.to.be.json;", + "});", + "", + "pm.test(handler + \" - schema is valid: \" + address, function() {", + " pm.expect(ajv.validate(schema, jsonData)).to.be.true;", + "});", + "" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "POST", + "header": [ + { + "key": "Content-Type", + "name": "Content-Type", + "value": "application/json", + "type": "text" + } + ], + "body": { + "mode": "raw", + "raw": "[\n\t{\n\t\t\"coin\": {{coin}},\n\t\t\"address\": \"{{address}}\"\n\t}\n]", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "{{host}}/v2/staking/delegations", + "host": [ + "{{host}}" + ], + "path": [ + "v2", + "staking", + "delegations" + ] + } + }, + "response": [] + } + ], + "event": [ + { + "listen": "prerequest", + "script": { + "id": "3f05cf7e-0439-4cd2-b41f-5ba71e465621", + "type": "text/javascript", + "exec": [ + "" + ] + } + }, + { + "listen": "test", + "script": { + "id": "de5760bf-5d29-462f-af90-ccbeaa8253f9", + "type": "text/javascript", + "exec": [ + "" + ] + } + } + ], + "protocolProfileBehavior": {}, + "_postman_isSubFolder": true + }, + { + "name": "collection", + "item": [ + { + "name": "collection v4", + "event": [ + { + "listen": "prerequest", + "script": { + "id": "7312c9e7-5330-421a-9ca8-171101050e38", + "exec": [ + "" + ], + "type": "text/javascript" + } + }, + { + "listen": "test", + "script": { + "id": "acec8baa-0ef0-4703-ab83-c555260deffa", + "exec": [ + "var Ajv = require('ajv');", + "var ajv = new Ajv({logger: console});", + "let schema = {", + " \"type\": \"object\",", + " \"properties\": {", + " \"total\": {", + " \"type\": \"integer\"", + " },", + " \"docs\": {", + " \"type\": \"array\",", + " \"minItems\": 1,", + " \"uniqueItems\": true,", + " \"items\": {", + " \"type\": \"object\",", + " \"properties\": {", + " \"id\": {", + " \"type\": \"string\"", + " },", + " \"collection_id\": {", + " \"type\": \"string\"", + " },", + " \"token_id\": {", + " \"type\": \"string\"", + " },", + " \"contract_address\": {", + " \"type\": \"string\"", + " },", + " \"category\": {", + " \"type\": \"string\"", + " },", + " \"image_url\": {", + " \"type\": \"string\"", + " },", + " \"external_link\": {", + " \"type\": \"string\"", + " },", + " \"provider_link\": {", + " \"type\": \"string\"", + " },", + " \"type\": {", + " \"type\": \"string\"", + " },", + " \"description\": {", + " \"type\": \"string\"", + " },", + " \"coin\": {", + " \"type\": \"integer\"", + " },", + " \"name\": {", + " \"type\": \"string\"", + " },", + " \"nft_version\": {", + " \"type\": \"string\"", + " }", + " }", + " }", + " },", + " \"status\": {", + " \"type\": \"boolean\"", + " }", + " }", + "};", + "", + "let handler = pm.variables.get(\"handler\");", + "let address = pm.variables.get(\"address\");", + "var jsonData = pm.response.json();", + "", + "pm.test(handler + \" - response must be valid and have a body: \" + address, function () {", + " pm.response.to.have.status(200);", + " pm.response.to.be.ok;", + " pm.response.to.not.be.error;", + " pm.response.to.be.withBody;", + " pm.response.to.be.json;", + "});", + "", + "pm.test(handler + \" - schema is valid: \" + address, function() {", + " pm.expect(ajv.validate(schema, jsonData)).to.be.true;", + " console.log(JSON.stringify(jsonData))", + "});", + "" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "GET", + "header": [ + { + "key": "Authorization", + "value": "Bearer {{platform_auth}}", + "type": "text" + } + ], + "url": { + "raw": "{{host}}/v4/{{handler}}/collections/{{address}}/collection/{{collection}}", + "host": [ + "{{host}}" + ], + "path": [ + "v4", + "{{handler}}", + "collections", + "{{address}}", + "collection", + "{{collection}}" + ] + } + }, + "response": [] + }, + { + "name": "collections batch v4", + "event": [ + { + "listen": "prerequest", + "script": { + "id": "7312c9e7-5330-421a-9ca8-171101050e38", + "exec": [ + "" + ], + "type": "text/javascript" + } + }, + { + "listen": "test", + "script": { + "id": "acec8baa-0ef0-4703-ab83-c555260deffa", + "exec": [ + "var Ajv = require('ajv');", + "var ajv = new Ajv({logger: console});", + "let schema = {", + " \"type\": \"object\",", + " \"properties\": {", + " \"total\": {", + " \"type\": \"integer\"", + " },", + " \"docs\": {", + " \"type\": \"array\",", + " \"minItems\": 1,", + " \"uniqueItems\": true,", + " \"items\": {", + " \"type\": \"object\",", + " \"properties\": {", + " \"id\": {", + " \"type\": \"string\"", + " },", + " \"name\": {", + " \"type\": \"string\"", + " },", + " \"image_url\": {", + " \"type\": \"string\"", + " },", + " \"external_link\": {", + " \"type\": \"string\"", + " },", + " \"total\": {", + " \"type\": \"integer\"", + " },", + " \"address\": {", + " \"type\": \"string\"", + " },", + " \"coin\": {", + " \"type\": \"integer\"", + " },", + " \"type\": {", + " \"type\": \"string\"", + " }", + " }", + " }", + " },", + " \"status\": {", + " \"type\": \"boolean\"", + " }", + " }", + "};", + "", + "let handler = pm.variables.get(\"handler\");", + "let address = pm.variables.get(\"address\");", + "var jsonData = pm.response.json();", + "", + "pm.test(handler + \" - response must be valid and have a body: \" + address, function () {", + " pm.response.to.have.status(200);", + " pm.response.to.be.ok;", + " pm.response.to.not.be.error;", + " pm.response.to.be.withBody;", + " pm.response.to.be.json;", + "});", + "", + "pm.test(handler + \" - schema is valid: \" + address, function() {", + " pm.expect(ajv.validate(schema, jsonData)).to.be.true;", + " console.log(JSON.stringify(jsonData))", + "});", + "" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "POST", + "header": [ + { + "key": "Authorization", + "value": "Bearer {{platform_auth}}", + "type": "text" + }, + { + "key": "Content-Type", + "name": "Content-Type", + "value": "application/json", + "type": "text" + } + ], + "body": { + "mode": "raw", + "raw": "{\n\t\"{{coin}}\": [\"{{address}}\"]\n}", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "{{host}}/v4/collectibles/categories", + "host": [ + "{{host}}" + ], + "path": [ + "v4", + "collectibles", + "categories" + ] + } + }, + "response": [] + } + ], + "protocolProfileBehavior": {}, + "_postman_isSubFolder": true + } + ], + "event": [ + { + "listen": "prerequest", + "script": { + "id": "40c7dd18-87ff-47d8-8607-40b79ddb5dc9", + "type": "text/javascript", + "exec": [ + "" + ] + } + }, + { + "listen": "test", + "script": { + "id": "6f376ec0-1aa2-42ad-9334-e6a4e7f5fdc7", + "type": "text/javascript", + "exec": [ + "" + ] + } + } + ], + "protocolProfileBehavior": {} + }, + { + "name": "market", + "item": [ + { + "name": "charts", + "event": [ + { + "listen": "prerequest", + "script": { + "id": "7312c9e7-5330-421a-9ca8-171101050e38", + "exec": [ + "var token_id = pm.environment.get(\"token_id\");", + "if(!token_id) {", + " pm.environment.set(\"token_id\", \"\");", + "}", + "" + ], + "type": "text/javascript" + } + }, + { + "listen": "test", + "script": { + "id": "acec8baa-0ef0-4703-ab83-c555260deffa", + "exec": [ + "var Ajv = require('ajv');", + "var ajv = new Ajv({logger: console});", + "let schema = {", + " \"type\": \"object\",", + " \"properties\": {", + " \"prices\": {", + " \"type\": \"array\",", + " \"minItems\": 10,", + " \"uniqueItems\": true,", + " \"items\": {", + " \"type\": \"object\",", + " \"properties\": {", + " \"price\": {", + " \"type\": \"number\"", + " },", + " \"date\": {", + " \"type\": \"integer\"", + " }", + " }", + " }", + " }", + " }", + "};", + "", + "var jsonData = pm.response.json();", + "", + "pm.test(\"response must be valid and have a body\", function () {", + " pm.response.to.have.status(200);", + " pm.response.to.be.ok;", + " pm.response.to.not.be.error;", + " pm.response.to.be.withBody;", + " pm.response.to.be.json;", + "});", + "", + "pm.test(\"schema is valid\", function() {", + " pm.expect(ajv.validate(schema, jsonData)).to.be.true;", + "});", + "" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "GET", + "header": [ + { + "key": "Authorization", + "type": "text", + "value": "Bearer {{market_auth}}" + } + ], + "url": { + "raw": "{{host}}/v1/market/charts?currency={{currency}}&coin={{coin}}&token={{token_id}}&time_start=1577871126", + "host": [ + "{{host}}" + ], + "path": [ + "v1", + "market", + "charts" + ], + "query": [ + { + "key": "currency", + "value": "{{currency}}" + }, + { + "key": "coin", + "value": "{{coin}}" + }, + { + "key": "token", + "value": "{{token_id}}" + }, + { + "key": "time_start", + "value": "1577871126" + } + ] + } + }, + "response": [] + }, + { + "name": "info", + "event": [ + { + "listen": "prerequest", + "script": { + "id": "7312c9e7-5330-421a-9ca8-171101050e38", + "exec": [ + "var token_id = pm.environment.get(\"token_id\");", + "if(!token_id) {", + " pm.environment.set(\"token_id\", \"\");", + "}", + "" + ], + "type": "text/javascript" + } + }, + { + "listen": "test", + "script": { + "id": "acec8baa-0ef0-4703-ab83-c555260deffa", + "exec": [ + "var Ajv = require('ajv');", + "var ajv = new Ajv({logger: console});", + "let schema = {", + " \"type\": \"object\",", + " \"properties\": {", + " \"volume_24\": {", + " \"type\": \"number\"", + " },", + " \"market_cap\": {", + " \"type\": \"number\"", + " },", + " \"circulating_supply\": {", + " \"type\": \"number\"", + " },", + " \"total_supply\": {", + " \"type\": \"number\"", + " },", + " \"info\": {", + " \"type\": \"object\",", + " \"properties\": {", + " \"name\": {", + " \"type\": \"string\"", + " },", + " \"website\": {", + " \"type\": \"string\"", + " },", + " \"source_code\": {", + " \"type\": \"string\"", + " },", + " \"whitepaper\": {", + " \"type\": \"string\"", + " },", + " \"explorers\": {", + " \"type\": \"array\"", + " },", + " \"socials\": {", + " \"type\": \"array\"", + " },", + " \"details\": {", + " \"type\": \"array\"", + " },", + " \"data_source\": {", + " \"type\": \"string\"", + " }", + " }", + " }", + " }", + "};", + "", + "var jsonData = pm.response.json();", + "", + "pm.test(\"response must be valid and have a body\", function () {", + " pm.response.to.be.withBody;", + " pm.response.to.be.json;", + "});", + "", + "pm.test(\"schema is valid\", function() {", + " pm.expect(ajv.validate(schema, jsonData)).to.be.true;", + "});", + "" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "GET", + "header": [ + { + "key": "Authorization", + "type": "text", + "value": "Bearer {{market_auth}}" + } + ], + "url": { + "raw": "{{host}}/v1/market/info?currency={{currency}}&coin={{coin}}&token={{token_id}}", + "host": [ + "{{host}}" + ], + "path": [ + "v1", + "market", + "info" + ], + "query": [ + { + "key": "currency", + "value": "{{currency}}" + }, + { + "key": "coin", + "value": "{{coin}}" + }, + { + "key": "token", + "value": "{{token_id}}" + } + ] + } + }, + "response": [] + }, + { + "name": "tickers", + "event": [ + { + "listen": "prerequest", + "script": { + "id": "7312c9e7-5330-421a-9ca8-171101050e38", + "exec": [ + "var token_id = pm.environment.get(\"token_id\");", + "if(!token_id) {", + " pm.environment.set(\"token_id\", \"\");", + "}", + "" + ], + "type": "text/javascript" + } + }, + { + "listen": "test", + "script": { + "id": "acec8baa-0ef0-4703-ab83-c555260deffa", + "exec": [ + "var Ajv = require('ajv');", + "var ajv = new Ajv({logger: console});", + "let schema = {", + " \"type\": \"object\",", + " \"properties\": {", + " \"currency\": {", + " \"type\": \"string\"", + " },", + " \"docs\": {", + " \"type\": \"array\",", + " \"uniqueItems\": true,", + " \"items\": {", + " \"type\": \"object\",", + " \"properties\": {", + " \"coin\": {", + " \"type\": \"integer\"", + " },", + " \"last_update\": {", + " \"type\": \"string\"", + " },", + " \"token_id\": {", + " \"type\": \"string\"", + " },", + " \"type\": {", + " \"type\": \"string\"", + " },", + " \"price\": {", + " \"type\": \"object\",", + " \"properties\": {", + " \"value\": {", + " \"type\": \"number\"", + " },", + " \"change_24h\": {", + " \"type\": \"number\"", + " }", + " }", + " }", + " }", + " }", + " }", + " }", + "};", + "", + "var jsonData = pm.response.json();", + "", + "pm.test(\"response must be valid and have a body\", function () {", + " pm.response.to.have.status(200);", + " pm.response.to.be.ok;", + " pm.response.to.not.be.error;", + " pm.response.to.be.withBody;", + " pm.response.to.be.json;", + "});", + "", + "pm.test(\"schema is valid\", function() {", + " pm.expect(ajv.validate(schema, jsonData)).to.be.true;", + "});", + "" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "POST", + "header": [ + { + "key": "Authorization", + "type": "text", + "value": "Bearer {{market_auth}}" + }, + { + "key": "Content-Type", + "name": "Content-Type", + "value": "application/json", + "type": "text" + } + ], + "body": { + "mode": "raw", + "raw": "{\n \"currency\": \"{{currency}}\",\n \"assets\": [\n {\n \"coin\": {{coin}},\n \"type\": \"{{type}}\",\n \"token_id\": \"{{token_id}}\"\n }\n ]\n}", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "{{host}}/v1/market/ticker", + "host": [ + "{{host}}" + ], + "path": [ + "v1", + "market", + "ticker" + ] + } + }, + "response": [] + } + ], + "event": [ + { + "listen": "prerequest", + "script": { + "id": "7cffac98-4367-49be-a96c-dcb31861001c", + "type": "text/javascript", + "exec": [ + "" + ] + } + }, + { + "listen": "test", + "script": { + "id": "4d6e8061-832a-4330-b47a-3e61cd9c93b8", + "type": "text/javascript", + "exec": [ + "" + ] + } + } + ], + "protocolProfileBehavior": {} + }, + { + "name": "healthcheck", + "item": [ + { + "name": "status", + "event": [ + { + "listen": "prerequest", + "script": { + "id": "7312c9e7-5330-421a-9ca8-171101050e38", + "exec": [ + "" + ], + "type": "text/javascript" + } + }, + { + "listen": "test", + "script": { + "id": "acec8baa-0ef0-4703-ab83-c555260deffa", + "exec": [ + "var Ajv = require('ajv');", + "var ajv = new Ajv({logger: console});", + "let schema = {", + " \"type\": \"object\",", + " \"properties\": {", + " \"status\": {", + " \"type\": \"boolean\"", + " }", + " }", + "};", + "", + "var jsonData = pm.response.json();", + "", + "pm.test(\"response must be valid and have a body\", function () {", + " pm.response.to.have.status(200);", + " pm.response.to.be.ok;", + " pm.response.to.not.be.error;", + " pm.response.to.be.withBody;", + " pm.response.to.be.json;", + "});", + "", + "pm.test(\"verify the status\", function() {", + " pm.expect(jsonData.status).to.equal(true);", + "});", + "", + "pm.test(\"schema is valid\", function() {", + " pm.expect(ajv.validate(schema, jsonData)).to.be.true;", + "});", + "" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "GET", + "header": [], + "url": { + "raw": "{{host}}/status", + "host": [ + "{{host}}" + ], + "path": [ + "status" + ] + } + }, + "response": [] + }, + { + "name": "v1", + "event": [ + { + "listen": "prerequest", + "script": { + "id": "7312c9e7-5330-421a-9ca8-171101050e38", + "exec": [ + "" + ], + "type": "text/javascript" + } + }, + { + "listen": "test", + "script": { + "id": "acec8baa-0ef0-4703-ab83-c555260deffa", + "exec": [ + "var Ajv = require('ajv');", + "var ajv = new Ajv({logger: console});", + "let schema = {", + " \"type\": \"object\",", + " \"properties\": {", + " \"endpoints\": {", + " \"type\": \"array\"", + " }", + " }", + "};", + "", + "var jsonData = pm.response.json();", + "", + "pm.test(\"response must be valid and have a body\", function () {", + " pm.response.to.have.status(200);", + " pm.response.to.be.ok;", + " pm.response.to.not.be.error;", + " pm.response.to.be.withBody;", + " pm.response.to.be.json;", + "});", + "", + "pm.test(\"schema is valid\", function() {", + " pm.expect(ajv.validate(schema, jsonData)).to.be.true;", + "});", + "" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "GET", + "header": [], + "url": { + "raw": "{{host}}/v1", + "host": [ + "{{host}}" + ], + "path": [ + "v1" + ] + } + }, + "response": [] + } + ], + "event": [ + { + "listen": "prerequest", + "script": { + "id": "2f430d33-58dd-4df5-b3bb-2826e76b89b2", + "type": "text/javascript", + "exec": [ + "" + ] + } + }, + { + "listen": "test", + "script": { + "id": "727ab826-5939-45a7-96be-d8382192a69e", + "type": "text/javascript", + "exec": [ + "" + ] + } + } + ], + "protocolProfileBehavior": {} + }, + { + "name": "mock-healthcheck", + "item": [ + { + "name": "status", + "event": [ + { + "listen": "prerequest", + "script": { + "id": "7312c9e7-5330-421a-9ca8-171101050e38", + "exec": [ + "" + ], + "type": "text/javascript" + } + }, + { + "listen": "test", + "script": { + "id": "acec8baa-0ef0-4703-ab83-c555260deffa", + "exec": [ + "var Ajv = require('ajv');", + "var ajv = new Ajv({logger: console});", + "let schema = {", + " \"status\": \"boolean\",", + " \"msg\": \"string\"", + "};", + "", + "pm.test(\"response must be valid and have a body -- HAS MOCK STARTED?\", function () {", + " pm.response.to.have.status(200);", + " pm.response.to.be.ok;", + " pm.response.to.not.be.error;", + " pm.response.to.be.withBody;", + " pm.response.to.be.json;", + "});", + "", + "var jsonData = pm.response.json();", + "", + "pm.test(\"verify the status\", function() {", + " pm.expect(jsonData.status).to.equal(true);", + "});", + "", + "pm.test(\"schema is valid\", function() {", + " pm.expect(ajv.validate(schema, jsonData)).to.be.true;", + "});", + "" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "GET", + "header": [], + "url": { + "raw": "localhost:3347/mock/mock-healthcheck", + "host": [ + "localhost:3347" + ], + "path": [ + "mock/mock-healthcheck" + ] + } + }, + "response": [] + } + ], + "event": [ + { + "listen": "prerequest", + "script": { + "id": "2f430d33-58dd-4df5-b3bb-2826e76b89b2", + "type": "text/javascript", + "exec": [ + "" + ] + } + }, + { + "listen": "test", + "script": { + "id": "727ab826-5939-45a7-96be-d8382192a69e", + "type": "text/javascript", + "exec": [ + "" + ] + } + } + ], + "protocolProfileBehavior": {} + } + ], + "event": [ + { + "listen": "prerequest", + "script": { + "id": "32821b71-3559-4ecb-97e5-84f87fc50731", + "type": "text/javascript", + "exec": [ + "" + ] + } + }, + { + "listen": "test", + "script": { + "id": "1311995e-ffa0-4801-9c9d-21a7b4c83711", + "type": "text/javascript", + "exec": [ + "" + ] + } + } + ], + "variable": [ + { + "id": "c6d3b134-d68f-4747-b5c5-a687412f2166", + "key": "host", + "value": "http://localhost:8420", + "type": "string" + }, + { + "id": "cfde5bdb-eecf-472c-b1bf-d944a63befff", + "key": "observer_auth", + "value": "test", + "type": "string" + }, + { + "id": "1455449b-6372-4c16-81d9-ed93ab4aafd7", + "key": "market_auth", + "value": "", + "type": "string" + }, + { + "id": "4180368d-8afe-4432-8ecb-48db2f778a72", + "key": "platform_auth", + "value": "", + "type": "string" + } + ], + "protocolProfileBehavior": {} +}